Files
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

292 lines
9.7 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.radialLayout = exports.proccessToFunc = exports.buildTextureDataWithTwoEdgeAttr = exports.buildTextureDataWithOneEdgeAttr = exports.buildTextureData = exports.attributesToTextureData = exports.arrayToTextureData = void 0;
var _g6Core = require("@antv/g6-core");
var _util = require("@antv/util");
var traverseTree = _g6Core.Util.traverseTree;
/**
* 将 number | Function 类型的参数转换为 return number 的 Function
* @param {number | Function} value 需要被转换的值
* @param {number} defaultV 返回函数的默认返回值
* @return {Function} 转换后的函数
*/
var proccessToFunc = exports.proccessToFunc = function proccessToFunc(value, defaultV) {
var func;
if (!value) {
func = function func(d) {
return defaultV || 1;
};
} else if ((0, _util.isNumber)(value)) {
func = function func(d) {
return value;
};
} else {
func = value;
}
return func;
};
/**
* 将节点和边数据转换为 GPU 可读的数组。并返回 maxEdgePerVetex每个节点上最多的边数
* @param {NodeConfig[]} nodes 需要被转换的值
* @param {EdgeConfig[]} edges 返回函数的默认返回值
* @return {Object} 转换后的数组及 maxEdgePerVetex 组成的对象
*/
var buildTextureData = exports.buildTextureData = function buildTextureData(nodes, edges) {
var dataArray = [];
var nodeDict = [];
var mapIdPos = {};
var i = 0;
for (i = 0; i < nodes.length; i++) {
var n = nodes[i];
mapIdPos[n.id] = i;
dataArray.push(n.x);
dataArray.push(n.y);
dataArray.push(0);
dataArray.push(0);
nodeDict.push([]);
}
for (i = 0; i < edges.length; i++) {
var e = edges[i];
nodeDict[mapIdPos[e.source]].push(mapIdPos[e.target]);
nodeDict[mapIdPos[e.target]].push(mapIdPos[e.source]);
}
var maxEdgePerVetex = 0;
for (i = 0; i < nodes.length; i++) {
var offset = dataArray.length;
var dests = nodeDict[i];
var len = dests.length;
dataArray[i * 4 + 2] = offset;
dataArray[i * 4 + 3] = dests.length;
maxEdgePerVetex = Math.max(maxEdgePerVetex, dests.length);
for (var j = 0; j < len; ++j) {
var dest = dests[j];
dataArray.push(+dest);
}
}
while (dataArray.length % 4 !== 0) {
dataArray.push(0);
}
return {
array: new Float32Array(dataArray),
maxEdgePerVetex: maxEdgePerVetex
};
};
/**
* 将节点和边数据转换为 GPU 可读的数组,每条边带有一个属性。并返回 maxEdgePerVetex每个节点上最多的边数
* @param {NodeConfig[]} nodes 节点数组
* @param {EdgeConfig[]} edges 边数组
* @param {Function} attrs 读取边属性的函数
* @return {Object} 转换后的数组及 maxEdgePerVetex 组成的对象
*/
var buildTextureDataWithOneEdgeAttr = exports.buildTextureDataWithOneEdgeAttr = function buildTextureDataWithOneEdgeAttr(nodes, edges, attrs) {
var dataArray = [];
var nodeDict = [];
var mapIdPos = {};
var i = 0;
for (i = 0; i < nodes.length; i++) {
var n = nodes[i];
mapIdPos[n.id] = i;
dataArray.push(n.x);
dataArray.push(n.y);
dataArray.push(0);
dataArray.push(0);
nodeDict.push([]);
}
for (i = 0; i < edges.length; i++) {
var e = edges[i];
nodeDict[mapIdPos[e.source]].push(mapIdPos[e.target]);
nodeDict[mapIdPos[e.source]].push(attrs(e)); // 理想边长,后续可以改成每条边不同
nodeDict[mapIdPos[e.target]].push(mapIdPos[e.source]);
nodeDict[mapIdPos[e.target]].push(attrs(e)); // 理想边长,后续可以改成每条边不同
}
var maxEdgePerVetex = 0;
for (i = 0; i < nodes.length; i++) {
var offset = dataArray.length;
var dests = nodeDict[i]; // dest 中节点 id 与边长间隔存储,即一位节点 id一位边长……
var len = dests.length;
dataArray[i * 4 + 2] = offset;
dataArray[i * 4 + 3] = len / 2; // 第四位存储与该节点相关的所有节点个数
maxEdgePerVetex = Math.max(maxEdgePerVetex, len / 2);
for (var j = 0; j < len; ++j) {
var dest = dests[j];
dataArray.push(+dest);
}
}
// 不是 4 的倍数,填充 0
while (dataArray.length % 4 !== 0) {
dataArray.push(0);
}
return {
array: new Float32Array(dataArray),
maxEdgePerVetex: maxEdgePerVetex
};
};
/**
* 将节点和边数据转换为 GPU 可读的数组,每条边带有一个以上属性。并返回 maxEdgePerVetex每个节点上最多的边数
* @param {NodeConfig[]} nodes 节点数组
* @param {EdgeConfig[]} edges 边数组
* @param {Function} attrs 读取边属性的函数
* @return {Object} 转换后的数组及 maxEdgePerVetex 组成的对象
*/
var buildTextureDataWithTwoEdgeAttr = exports.buildTextureDataWithTwoEdgeAttr = function buildTextureDataWithTwoEdgeAttr(nodes, edges, attrs1, attrs2) {
var dataArray = [];
var nodeDict = [];
var mapIdPos = {};
var i = 0;
for (i = 0; i < nodes.length; i++) {
var n = nodes[i];
mapIdPos[n.id] = i;
dataArray.push(n.x);
dataArray.push(n.y);
dataArray.push(0);
dataArray.push(0);
nodeDict.push([]);
}
for (i = 0; i < edges.length; i++) {
var e = edges[i];
nodeDict[mapIdPos[e.source]].push(mapIdPos[e.target]);
nodeDict[mapIdPos[e.source]].push(attrs1(e));
nodeDict[mapIdPos[e.source]].push(attrs2(e));
nodeDict[mapIdPos[e.source]].push(0);
nodeDict[mapIdPos[e.target]].push(mapIdPos[e.source]);
nodeDict[mapIdPos[e.target]].push(attrs1(e));
nodeDict[mapIdPos[e.target]].push(attrs2(e));
nodeDict[mapIdPos[e.target]].push(0);
}
var maxEdgePerVetex = 0;
for (i = 0; i < nodes.length; i++) {
var offset = dataArray.length;
var dests = nodeDict[i]; // dest 中节点 id 与边长间隔存储,即一位节点 id一位边长……
var len = dests.length;
// dataArray[i * 4 + 2] = offset;
// dataArray[i * 4 + 3] = len / 4; // 第四位存储与该节点相关的所有节点个数
// pack offset & length into float32: offset 20bit, length 12bit
dataArray[i * 4 + 2] = offset + 1048576 * len / 4;
dataArray[i * 4 + 3] = 0; // 第四位存储与上一次的距离差值
maxEdgePerVetex = Math.max(maxEdgePerVetex, len / 4);
for (var j = 0; j < len; ++j) {
var dest = dests[j];
dataArray.push(+dest);
}
}
// 不是 4 的倍数,填充 0
while (dataArray.length % 4 !== 0) {
dataArray.push(0);
}
return {
array: new Float32Array(dataArray),
maxEdgePerVetex: maxEdgePerVetex
};
};
/**
* transform the extended attributes of nodes or edges to a texture array
* @param {string[]} attributeNames attributes' name to be read from items and put into output array
* @param {ModelConfig[]} items the items to be read
* @return {Float32Array} the attributes' value array to be read by GPU
*/
var attributesToTextureData = exports.attributesToTextureData = function attributesToTextureData(attributeNames, items) {
var dataArray = [];
var attributeNum = attributeNames.length;
var attributeStringMap = {};
items.forEach(function (item) {
attributeNames.forEach(function (name, i) {
if (attributeStringMap[item[name]] === undefined) {
attributeStringMap[item[name]] = Object.keys(attributeStringMap).length;
}
dataArray.push(attributeStringMap[item[name]]);
// insure each node's attributes take inter number of grids
if (i === attributeNum - 1) {
while (dataArray.length % 4 !== 0) {
dataArray.push(0);
}
}
});
});
return {
array: new Float32Array(dataArray),
count: Object.keys(attributeStringMap).length
};
};
/**
* transform the number array format of extended attributes of nodes or edges to a texture array
* @param {string[]} attributeNames attributes' name to be read from items and put into output array
* @return {Float32Array} the attributes' value array to be read by GPU
*/
var arrayToTextureData = exports.arrayToTextureData = function arrayToTextureData(valueArrays) {
var dataArray = [];
var attributeNum = valueArrays.length;
var itemNum = valueArrays[0].length;
var _loop_1 = function _loop_1(j) {
valueArrays.forEach(function (valueArray, i) {
dataArray.push(valueArray[j]);
// insure each node's attributes take inter number of grids
if (i === attributeNum - 1) {
while (dataArray.length % 4 !== 0) {
dataArray.push(0);
}
}
});
};
for (var j = 0; j < itemNum; j++) {
_loop_1(j);
}
return new Float32Array(dataArray);
};
/**
*
* @param data Tree graph data
* @param layout
*/
var radialLayout = exports.radialLayout = function radialLayout(data, layout) {
// 布局方式有 H / V / LR / RL / TB / BT
var VERTICAL_LAYOUTS = ['V', 'TB', 'BT'];
var min = {
x: Infinity,
y: Infinity
};
var max = {
x: -Infinity,
y: -Infinity
};
// 默认布局是垂直布局TB此时x对应rady对应r
var rScale = 'x';
var radScale = 'y';
if (layout && VERTICAL_LAYOUTS.indexOf(layout) >= 0) {
// 若是水平布局y对应radx对应r
radScale = 'x';
rScale = 'y';
}
var count = 0;
traverseTree(data, function (node) {
count++;
if (node.x > max.x) {
max.x = node.x;
}
if (node.x < min.x) {
min.x = node.x;
}
if (node.y > max.y) {
max.y = node.y;
}
if (node.y < min.y) {
min.y = node.y;
}
return true;
});
var avgRad = Math.PI * 2 / count;
var radDiff = max[radScale] - min[radScale];
if (radDiff === 0) {
return data;
}
traverseTree(data, function (node) {
var radial = (node[radScale] - min[radScale]) / radDiff * (Math.PI * 2 - avgRad) + avgRad;
var r = Math.abs(rScale === 'x' ? node.x - data.x : node.y - data.y);
node.x = r * Math.cos(radial);
node.y = r * Math.sin(radial);
return true;
});
return data;
};