Files
lan-manager/web/node_modules/@antv/g6-plugin/es/bundling/index.js
openclaw 0a5f6a8047 Initial commit: Lan-manager project code
- Go backend (server/)
- Frontend (web/, server/static/)
- Database and deployment files
- Scripts and docs

Co-Authored-By: 狸花猫/Claude-Qwen3.6-Plus 🐾
2026-04-20 00:52:58 +08:00

437 lines
13 KiB
JavaScript

var __extends = this && this.__extends || function () {
var _extendStatics = function extendStatics(d, b) {
_extendStatics = Object.setPrototypeOf || {
__proto__: []
} instanceof Array && function (d, b) {
d.__proto__ = b;
} || function (d, b) {
for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];
};
return _extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
_extendStatics(d, b);
function __() {
this.constructor = d;
}
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
}();
import Base from '../base';
function getEucliDis(pointA, pointB, eps) {
var vx = pointA.x - pointB.x;
var vy = pointA.y - pointB.y;
if (!eps || Math.abs(vx) > eps || Math.abs(vy) > eps) {
return Math.sqrt(vx * vx + vy * vy);
}
return eps;
}
function getDotProduct(ei, ej) {
return ei.x * ej.x + ei.y * ej.y;
}
function projectPointToEdge(p, e) {
var k = (e.source.y - e.target.y) / (e.source.x - e.target.x);
var x = (k * k * e.source.x + k * (p.y - e.source.y) + p.x) / (k * k + 1);
var y = k * (x - e.source.x) + e.source.y;
return {
x: x,
y: y
};
}
var Bundling = /** @class */function (_super) {
__extends(Bundling, _super);
function Bundling(config) {
return _super.call(this, config) || this;
}
Bundling.prototype.getDefaultCfgs = function () {
return {
edgeBundles: [],
edgePoints: [],
K: 0.1,
lambda: 0.1,
divisions: 1,
divRate: 2,
cycles: 6,
iterations: 90,
iterRate: 0.6666667,
bundleThreshold: 0.6,
eps: 1e-6,
onLayoutEnd: function onLayoutEnd() {},
onTick: function onTick() {}
};
};
Bundling.prototype.init = function () {
var graph = this.get('graph');
var onTick = this.get('onTick');
var tick = function tick() {
if (onTick) {
onTick();
}
graph.refreshPositions();
};
this.set('tick', tick);
};
Bundling.prototype.bundling = function (data) {
var self = this;
self.set('data', data);
// 如果正在布局,忽略布局请求
if (self.isTicking()) {
return;
}
var edges = data.edges || [];
var nodes = data.nodes || [];
var nodeIdMap = {};
var error = false;
nodes.forEach(function (node) {
if (node.x === null || !node.y === null || node.x === undefined || !node.y === undefined) {
error = true;
}
nodeIdMap[node.id] = node;
});
if (error) throw new Error('please layout the graph or assign x and y for nodes first');
self.set('nodeIdMap', nodeIdMap);
// subdivide each edges
var divisions = self.get('divisions');
var divRate = self.get('divRate');
var edgePoints = self.divideEdges(divisions);
self.set('edgePoints', edgePoints);
// compute the bundles
var edgeBundles = self.getEdgeBundles();
self.set('edgeBundles', edgeBundles);
// iterations
var C = self.get('cycles');
var iterations = self.get('iterations');
var iterRate = self.get('iterRate');
var lambda = self.get('lambda');
for (var i = 0; i < C; i++) {
var _loop_1 = function _loop_1(j) {
var forces = [];
edges.forEach(function (e, k) {
if (e.source === e.target) return;
var source = nodeIdMap[e.source];
var target = nodeIdMap[e.target];
forces[k] = self.getEdgeForces({
source: source,
target: target
}, k, divisions, lambda);
for (var p = 0; p < divisions + 1; p++) {
edgePoints[k][p].x += forces[k][p].x;
edgePoints[k][p].y += forces[k][p].y;
}
});
};
for (var j = 0; j < iterations; j++) {
_loop_1(j);
}
// parameters for nex cycle
lambda = lambda / 2;
divisions *= divRate;
iterations *= iterRate;
edgePoints = self.divideEdges(divisions);
self.set('edgePoints', edgePoints);
}
// change the edges according to edgePoints
edges.forEach(function (e, i) {
if (e.source === e.target) return;
e.type = 'polyline';
e.controlPoints = edgePoints[i].slice(1, edgePoints[i].length - 1);
});
var graph = self.get('graph');
graph.refresh();
};
Bundling.prototype.updateBundling = function (cfg) {
var self = this;
var data = cfg.data;
if (data) {
self.set('data', data);
}
if (self.get('ticking')) {
self.set('ticking', false);
}
Object.keys(cfg).forEach(function (key) {
self.set(key, cfg[key]);
});
if (cfg.onTick) {
var graph_1 = this.get('graph');
self.set('tick', function () {
cfg.onTick();
graph_1.refresh();
});
}
self.bundling(data);
};
Bundling.prototype.divideEdges = function (divisions) {
var self = this;
var edges = self.get('data').edges;
var nodeIdMap = self.get('nodeIdMap');
var edgePoints = self.get('edgePoints');
if (!edgePoints || edgePoints === undefined) edgePoints = [];
edges.forEach(function (edge, i) {
var _a;
if (!edgePoints[i] || edgePoints[i] === undefined) {
edgePoints[i] = [];
}
var source = nodeIdMap[edge.source];
var target = nodeIdMap[edge.target];
if (divisions === 1) {
edgePoints[i].push({
x: source.x,
y: source.y
}); // source
edgePoints[i].push({
x: 0.5 * (source.x + target.x),
y: 0.5 * (source.y + target.y)
}); // mid
edgePoints[i].push({
x: target.x,
y: target.y
}); // target
} else {
var edgeLength = 0;
if (!((_a = edgePoints[i]) === null || _a === void 0 ? void 0 : _a.length)) {
// it is a straight line
edgeLength = getEucliDis({
x: source.x,
y: source.y
}, {
x: target.x,
y: target.y
});
} else {
edgeLength = self.getEdgeLength(edgePoints[i]);
}
var divisionLength_1 = edgeLength / (divisions + 1);
var currentDivisonLength_1 = divisionLength_1;
var newEdgePoints_1 = [{
x: source.x,
y: source.y
}]; // source
edgePoints[i].forEach(function (ep, j) {
if (j === 0) return;
var oriDivisionLength = getEucliDis(ep, edgePoints[i][j - 1]);
while (oriDivisionLength > currentDivisonLength_1) {
var ratio = currentDivisonLength_1 / oriDivisionLength;
var edgePoint = {
x: edgePoints[i][j - 1].x,
y: edgePoints[i][j - 1].y
};
edgePoint.x += ratio * (ep.x - edgePoints[i][j - 1].x);
edgePoint.y += ratio * (ep.y - edgePoints[i][j - 1].y);
newEdgePoints_1.push(edgePoint);
oriDivisionLength -= currentDivisonLength_1;
currentDivisonLength_1 = divisionLength_1;
}
currentDivisonLength_1 -= oriDivisionLength;
});
newEdgePoints_1.push({
x: target.x,
y: target.y
}); // target
edgePoints[i] = newEdgePoints_1;
}
});
return edgePoints;
};
/**
* 计算边的长度
* @param points
*/
Bundling.prototype.getEdgeLength = function (points) {
var length = 0;
points.forEach(function (p, i) {
if (i === 0) return;
length += getEucliDis(p, points[i - 1]);
});
return length;
};
Bundling.prototype.getEdgeBundles = function () {
var self = this;
var data = self.get('data');
var edges = data.edges || [];
var bundleThreshold = self.get('bundleThreshold');
var nodeIdMap = self.get('nodeIdMap');
var edgeBundles = self.get('edgeBundles');
if (!edgeBundles) edgeBundles = [];
edges.forEach(function (e, i) {
if (!edgeBundles[i] || edgeBundles[i] === undefined) {
edgeBundles[i] = [];
}
});
edges.forEach(function (ei, i) {
var iSource = nodeIdMap[ei.source];
var iTarget = nodeIdMap[ei.target];
edges.forEach(function (ej, j) {
if (j <= i) return;
var jSource = nodeIdMap[ej.source];
var jTarget = nodeIdMap[ej.target];
var score = self.getBundleScore({
source: iSource,
target: iTarget
}, {
source: jSource,
target: jTarget
});
if (score >= bundleThreshold) {
edgeBundles[i].push(j);
edgeBundles[j].push(i);
}
});
});
return edgeBundles;
};
Bundling.prototype.getBundleScore = function (ei, ej) {
var self = this;
ei.vx = ei.target.x - ei.source.x;
ei.vy = ei.target.y - ei.source.y;
ej.vx = ej.target.x - ej.source.x;
ej.vy = ej.target.y - ej.source.y;
ei.length = getEucliDis({
x: ei.source.x,
y: ei.source.y
}, {
x: ei.target.x,
y: ei.target.y
});
ej.length = getEucliDis({
x: ej.source.x,
y: ej.source.y
}, {
x: ej.target.x,
y: ej.target.y
});
// angle score
var aScore = self.getAngleScore(ei, ej);
// scale score
var sScore = self.getScaleScore(ei, ej);
// position score
var pScore = self.getPositionScore(ei, ej);
// visibility socre
var vScore = self.getVisibilityScore(ei, ej);
return aScore * sScore * pScore * vScore;
};
Bundling.prototype.getAngleScore = function (ei, ej) {
var dotProduct = getDotProduct({
x: ei.vx,
y: ei.vy
}, {
x: ej.vx,
y: ej.vy
});
return dotProduct / (ei.length * ej.length);
};
Bundling.prototype.getScaleScore = function (ei, ej) {
var aLength = (ei.length + ej.length) / 2;
var score = 2 / (aLength / Math.min(ei.length, ej.length) + Math.max(ei.length, ej.length) / aLength);
return score;
};
Bundling.prototype.getPositionScore = function (ei, ej) {
var aLength = (ei.length + ej.length) / 2;
var iMid = {
x: (ei.source.x + ei.target.x) / 2,
y: (ei.source.y + ei.target.y) / 2
};
var jMid = {
x: (ej.source.x + ej.target.x) / 2,
y: (ej.source.y + ej.target.y) / 2
};
var distance = getEucliDis(iMid, jMid);
return aLength / (aLength + distance);
};
Bundling.prototype.getVisibilityScore = function (ei, ej) {
var vij = this.getEdgeVisibility(ei, ej);
var vji = this.getEdgeVisibility(ej, ei);
return vij < vji ? vij : vji;
};
Bundling.prototype.getEdgeVisibility = function (ei, ej) {
var ps = projectPointToEdge(ej.source, ei);
var pt = projectPointToEdge(ej.target, ei);
var pMid = {
x: (ps.x + pt.x) / 2,
y: (ps.y + pt.y) / 2
};
var iMid = {
x: (ei.source.x + ei.target.x) / 2,
y: (ei.source.y + ei.target.y) / 2
};
return Math.max(0, 1 - 2 * getEucliDis(pMid, iMid) / getEucliDis(ps, pt));
};
Bundling.prototype.getEdgeForces = function (e, eidx, divisions, lambda) {
var self = this;
var edgePoints = self.get('edgePoints');
var K = self.get('K');
var kp = K / (getEucliDis(e.source, e.target) * (divisions + 1));
var edgePointForces = [{
x: 0,
y: 0
}];
for (var i = 1; i < divisions; i++) {
var force = {
x: 0,
y: 0
};
var spring = self.getSpringForce({
pre: edgePoints[eidx][i - 1],
cur: edgePoints[eidx][i],
next: edgePoints[eidx][i + 1]
}, kp);
var electrostatic = self.getElectrostaticForce(i, eidx);
force.x = lambda * (spring.x + electrostatic.x);
force.y = lambda * (spring.y + electrostatic.y);
edgePointForces.push(force);
}
edgePointForces.push({
x: 0,
y: 0
});
return edgePointForces;
};
Bundling.prototype.getSpringForce = function (divisions, kp) {
var x = divisions.pre.x + divisions.next.x - 2 * divisions.cur.x;
var y = divisions.pre.y + divisions.next.y - 2 * divisions.cur.y;
x *= kp;
y *= kp;
return {
x: x,
y: y
};
};
Bundling.prototype.getElectrostaticForce = function (pidx, eidx) {
var self = this;
var eps = self.get('eps');
var edgeBundles = self.get('edgeBundles');
var edgePoints = self.get('edgePoints');
var edgeBundle = edgeBundles[eidx];
var resForce = {
x: 0,
y: 0
};
edgeBundle.forEach(function (eb) {
var force = {
x: edgePoints[eb][pidx].x - edgePoints[eidx][pidx].x,
y: edgePoints[eb][pidx].y - edgePoints[eidx][pidx].y
};
if (Math.abs(force.x) > eps || Math.abs(force.y) > eps) {
var length_1 = getEucliDis(edgePoints[eb][pidx], edgePoints[eidx][pidx]);
var diff = 1 / length_1;
resForce.x += force.x * diff;
resForce.y += force.y * diff;
}
});
return resForce;
};
Bundling.prototype.isTicking = function () {
return this.get('ticking');
};
Bundling.prototype.getSimulation = function () {
return this.get('forceSimulation');
};
Bundling.prototype.destroy = function () {
if (this.get('ticking')) {
this.getSimulation().stop();
}
_super.prototype.destroy.call(this);
};
return Bundling;
}(Base);
export default Bundling;