@antv/layout
Version:
graph layout algorithm
110 lines (108 loc) • 3.5 kB
JavaScript
/**
* 通用排序核心函数
*/
function sort$1(model, compareFn) {
const nodes = model.nodes();
nodes.sort(compareFn);
model.setNodeOrder(nodes);
return model;
}
function orderByDegree(model, order = 'desc') {
return sort$1(model, (nodeA, nodeB) => {
const degreeA = model.degree(nodeA.id);
const degreeB = model.degree(nodeB.id);
if (order === 'asc') {
return degreeA - degreeB; // ascending order
}
return degreeB - degreeA; // descending order
});
}
/**
* 按 ID 排序
*/
function orderById(model) {
return sort$1(model, (nodeA, nodeB) => {
const idA = nodeA.id;
const idB = nodeB.id;
if (typeof idA === 'number' && typeof idB === 'number') {
return idA - idB;
}
return String(idA).localeCompare(String(idB));
});
}
/**
* 按自定义比较函数排序
*/
function orderBySorter(model, sorter) {
return sort$1(model, (nodeA, nodeB) => {
const a = model.originalNode(nodeA.id);
const b = model.originalNode(nodeB.id);
return sorter(a, b);
});
}
/**
* Order nodes according to graph topology
*/
function orderByTopology(model, directed = false) {
const n = model.nodeCount();
if (n === 0)
return model;
const nodes = model.nodes();
const orderedNodes = [nodes[0]];
const pickFlags = {};
pickFlags[nodes[0].id] = true;
let k = 0;
let i = 0;
model.forEachNode((node) => {
if (i !== 0) {
const currentDegree = model.degree(node.id, 'both');
const nextDegree = i < n - 1 ? model.degree(nodes[i + 1].id, 'both') : 0;
const currentNodeId = orderedNodes[k].id;
const isNeighbor = model
.neighbors(currentNodeId, 'both')
.includes(node.id);
if ((i === n - 1 || currentDegree !== nextDegree || isNeighbor) &&
!pickFlags[node.id]) {
orderedNodes.push(node);
pickFlags[node.id] = true;
k++;
}
else {
const children = directed
? model.successors(currentNodeId)
: model.neighbors(currentNodeId);
let foundChild = false;
for (let j = 0; j < children.length; j++) {
const childId = children[j];
const child = model.node(childId);
if (child &&
model.degree(childId) === model.degree(node.id) &&
!pickFlags[childId]) {
orderedNodes.push(child);
pickFlags[childId] = true;
foundChild = true;
break;
}
}
let ii = 0;
while (!foundChild) {
if (!pickFlags[nodes[ii].id]) {
orderedNodes.push(nodes[ii]);
pickFlags[nodes[ii].id] = true;
foundChild = true;
}
ii++;
if (ii === n) {
break;
}
}
}
}
i++;
});
// Update model with ordered nodes
model.setNodeOrder(orderedNodes);
return model;
}
export { orderByDegree, orderById, orderBySorter, orderByTopology };
//# sourceMappingURL=order.js.map