@antv/layout 0.2.2 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/layout.min.js +1 -1
- package/dist/layout.min.js.map +1 -1
- package/es/layout/comboCombined.js +6 -21
- package/es/layout/comboCombined.js.map +1 -1
- package/es/layout/grid.js +2 -0
- package/es/layout/grid.js.map +1 -1
- package/es/layout/types.d.ts +7 -3
- package/lib/layout/comboCombined.js +6 -21
- package/lib/layout/comboCombined.js.map +1 -1
- package/lib/layout/grid.js +2 -0
- package/lib/layout/grid.js.map +1 -1
- package/lib/layout/types.d.ts +7 -3
- package/package.json +2 -1
- package/src/index.ts +7 -0
- package/src/layout/base.ts +54 -0
- package/src/layout/circular.ts +369 -0
- package/src/layout/comboCombined.ts +391 -0
- package/src/layout/comboForce.ts +873 -0
- package/src/layout/concentric.ts +289 -0
- package/src/layout/constants.ts +21 -0
- package/src/layout/dagre/graph.ts +104 -0
- package/src/layout/dagre/index.ts +31 -0
- package/src/layout/dagre/src/acyclic.ts +58 -0
- package/src/layout/dagre/src/add-border-segments.ts +47 -0
- package/src/layout/dagre/src/coordinate-system.ts +77 -0
- package/src/layout/dagre/src/data/list.ts +60 -0
- package/src/layout/dagre/src/debug.ts +30 -0
- package/src/layout/dagre/src/greedy-fas.ts +144 -0
- package/src/layout/dagre/src/layout.ts +580 -0
- package/src/layout/dagre/src/nesting-graph.ts +143 -0
- package/src/layout/dagre/src/normalize.ts +96 -0
- package/src/layout/dagre/src/order/add-subgraph-constraints.ts +29 -0
- package/src/layout/dagre/src/order/barycenter.ts +26 -0
- package/src/layout/dagre/src/order/build-layer-graph.ts +82 -0
- package/src/layout/dagre/src/order/cross-count.ts +77 -0
- package/src/layout/dagre/src/order/index.ts +105 -0
- package/src/layout/dagre/src/order/init-data-order.ts +27 -0
- package/src/layout/dagre/src/order/init-order.ts +56 -0
- package/src/layout/dagre/src/order/resolve-conflicts.ts +152 -0
- package/src/layout/dagre/src/order/sort-subgraph.ts +105 -0
- package/src/layout/dagre/src/order/sort.ts +76 -0
- package/src/layout/dagre/src/parent-dummy-chains.ts +102 -0
- package/src/layout/dagre/src/position/bk.ts +494 -0
- package/src/layout/dagre/src/position/index.ts +82 -0
- package/src/layout/dagre/src/rank/feasible-tree.ts +165 -0
- package/src/layout/dagre/src/rank/index.ts +54 -0
- package/src/layout/dagre/src/rank/network-simplex.ts +225 -0
- package/src/layout/dagre/src/rank/util.ts +157 -0
- package/src/layout/dagre/src/util.ts +308 -0
- package/src/layout/dagre.ts +423 -0
- package/src/layout/dagreCompound.ts +518 -0
- package/src/layout/er/core.ts +117 -0
- package/src/layout/er/forceGrid.ts +95 -0
- package/src/layout/er/grid.ts +185 -0
- package/src/layout/er/index.ts +68 -0
- package/src/layout/er/mysqlWorkbench.ts +345 -0
- package/src/layout/er/type.ts +39 -0
- package/src/layout/force/force-in-a-box.ts +400 -0
- package/src/layout/force/force.ts +391 -0
- package/src/layout/force/index.ts +1 -0
- package/src/layout/forceAtlas2/body.ts +115 -0
- package/src/layout/forceAtlas2/index.ts +556 -0
- package/src/layout/forceAtlas2/quad.ts +115 -0
- package/src/layout/forceAtlas2/quadTree.ts +107 -0
- package/src/layout/fruchterman.ts +361 -0
- package/src/layout/gForce.ts +487 -0
- package/src/layout/gpu/fruchterman.ts +314 -0
- package/src/layout/gpu/fruchtermanShader.ts +204 -0
- package/src/layout/gpu/gForce.ts +406 -0
- package/src/layout/gpu/gForceShader.ts +221 -0
- package/src/layout/grid.ts +393 -0
- package/src/layout/index.ts +45 -0
- package/src/layout/layout.ts +75 -0
- package/src/layout/mds.ts +140 -0
- package/src/layout/radial/index.ts +1 -0
- package/src/layout/radial/mds.ts +51 -0
- package/src/layout/radial/radial.ts +500 -0
- package/src/layout/radial/radialNonoverlapForce.ts +189 -0
- package/src/layout/random.ts +75 -0
- package/src/layout/types.ts +425 -0
- package/src/registy/index.ts +43 -0
- package/src/util/array.ts +1 -0
- package/src/util/function.ts +64 -0
- package/src/util/gpu.ts +254 -0
- package/src/util/index.ts +6 -0
- package/src/util/math.ts +158 -0
- package/src/util/number.ts +8 -0
- package/src/util/object.ts +28 -0
- package/src/util/string.ts +18 -0
- package/CHANGELOG.md +0 -88
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Graph } from "../graph";
|
|
2
|
+
import { buildLayerMatrix } from "./util";
|
|
3
|
+
|
|
4
|
+
const debugOrdering = (g: Graph) => {
|
|
5
|
+
const layerMatrix = buildLayerMatrix(g);
|
|
6
|
+
|
|
7
|
+
const h = new Graph({ compound: true, multigraph: true }).setGraph({});
|
|
8
|
+
|
|
9
|
+
g.nodes().forEach((v: string) => {
|
|
10
|
+
h.setNode(v, { label: v });
|
|
11
|
+
h.setParent(v, `layer${g.node(v)!.rank}`);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
g.edges().forEach((e) => {
|
|
15
|
+
h.setEdge(e.v, e.w, {}, e.name);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
layerMatrix?.forEach((layer, i: number) => {
|
|
19
|
+
const layerV = `layer${i}`;
|
|
20
|
+
h.setNode(layerV, { rank: "same" as unknown as number });
|
|
21
|
+
layer?.reduce((u: string, v: string) => {
|
|
22
|
+
h.setEdge(u, v, { style: "invis" });
|
|
23
|
+
return v;
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
return h;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export default debugOrdering;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import RawList from "./data/list";
|
|
2
|
+
import { Edge, Graph } from "../graph";
|
|
3
|
+
import { Graph as RawGraph } from "@antv/graphlib";
|
|
4
|
+
|
|
5
|
+
type StateNode = {
|
|
6
|
+
v: string;
|
|
7
|
+
w?: string;
|
|
8
|
+
in: number;
|
|
9
|
+
out: number;
|
|
10
|
+
prev?: StateNode;
|
|
11
|
+
next?: StateNode;
|
|
12
|
+
};
|
|
13
|
+
class List extends RawList<StateNode> {}
|
|
14
|
+
|
|
15
|
+
class StateGraph extends RawGraph<string, StateNode, number> {}
|
|
16
|
+
|
|
17
|
+
/*
|
|
18
|
+
* A greedy heuristic for finding a feedback arc set for a graph. A feedback
|
|
19
|
+
* arc set is a set of edges that can be removed to make a graph acyclic.
|
|
20
|
+
* The algorithm comes from: P. Eades, X. Lin, and W. F. Smyth, "A fast and
|
|
21
|
+
* effective heuristic for the feedback arc set problem." This implementation
|
|
22
|
+
* adjusts that from the paper to allow for weighted edges.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
const DEFAULT_WEIGHT_FN = () => 1;
|
|
26
|
+
|
|
27
|
+
const greedyFAS = (g: Graph, weightFn?: (e: Edge) => number) => {
|
|
28
|
+
if (g.nodeCount() <= 1) return [];
|
|
29
|
+
const state = buildState(g, weightFn || DEFAULT_WEIGHT_FN);
|
|
30
|
+
const results = doGreedyFAS(state.graph, state.buckets, state.zeroIdx);
|
|
31
|
+
|
|
32
|
+
return results.map((e) => g.outEdges(e.v, e.w))?.flat();
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const doGreedyFAS = (g: StateGraph, buckets: List[], zeroIdx: number) => {
|
|
36
|
+
let results: StateNode[] = [];
|
|
37
|
+
const sources = buckets[buckets.length - 1];
|
|
38
|
+
const sinks = buckets[0];
|
|
39
|
+
|
|
40
|
+
let entry;
|
|
41
|
+
while (g.nodeCount()) {
|
|
42
|
+
while ((entry = sinks.dequeue())) {
|
|
43
|
+
removeNode(g, buckets, zeroIdx, entry);
|
|
44
|
+
}
|
|
45
|
+
while ((entry = sources.dequeue())) {
|
|
46
|
+
removeNode(g, buckets, zeroIdx, entry);
|
|
47
|
+
}
|
|
48
|
+
if (g.nodeCount()) {
|
|
49
|
+
for (let i = buckets.length - 2; i > 0; --i) {
|
|
50
|
+
entry = buckets[i].dequeue();
|
|
51
|
+
if (entry) {
|
|
52
|
+
results = results.concat(
|
|
53
|
+
removeNode(g, buckets, zeroIdx, entry, true)!
|
|
54
|
+
);
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return results;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const removeNode = (
|
|
65
|
+
g: StateGraph,
|
|
66
|
+
buckets: List[],
|
|
67
|
+
zeroIdx: number,
|
|
68
|
+
entry: StateNode,
|
|
69
|
+
collectPredecessors?: boolean
|
|
70
|
+
) => {
|
|
71
|
+
const results: StateNode[] = [];
|
|
72
|
+
|
|
73
|
+
g.inEdges(entry.v)?.forEach((edge) => {
|
|
74
|
+
const weight = g.edge(edge)!;
|
|
75
|
+
const uEntry = g.node(edge.v)!;
|
|
76
|
+
|
|
77
|
+
if (collectPredecessors) {
|
|
78
|
+
// this result not really care about in or out
|
|
79
|
+
results.push({ v: edge.v, w: edge.w, in: 0, out: 0 });
|
|
80
|
+
}
|
|
81
|
+
if (uEntry.out === undefined) uEntry.out = 0;
|
|
82
|
+
uEntry.out -= weight;
|
|
83
|
+
assignBucket(buckets, zeroIdx, uEntry);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
g.outEdges(entry.v)?.forEach((edge) => {
|
|
87
|
+
const weight = g.edge(edge)!;
|
|
88
|
+
const w = edge.w;
|
|
89
|
+
const wEntry = g.node(w)!;
|
|
90
|
+
if (wEntry.in === undefined) wEntry.in = 0;
|
|
91
|
+
wEntry.in -= weight;
|
|
92
|
+
assignBucket(buckets, zeroIdx, wEntry);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
g.removeNode(entry.v);
|
|
96
|
+
|
|
97
|
+
return collectPredecessors ? results : undefined;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const buildState = (g: Graph, weightFn?: (param: any) => number) => {
|
|
101
|
+
const fasGraph = new StateGraph();
|
|
102
|
+
let maxIn = 0;
|
|
103
|
+
let maxOut = 0;
|
|
104
|
+
|
|
105
|
+
g.nodes().forEach((v) => {
|
|
106
|
+
fasGraph.setNode(v, { v, in: 0, out: 0 });
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Aggregate weights on nodes, but also sum the weights across multi-edges
|
|
110
|
+
// into a single edge for the fasGraph.
|
|
111
|
+
g.edges().forEach((e) => {
|
|
112
|
+
const prevWeight = fasGraph.edge(e) || 0;
|
|
113
|
+
const weight = weightFn?.(e) || 1;
|
|
114
|
+
const edgeWeight = prevWeight + weight;
|
|
115
|
+
fasGraph.setEdge(e.v, e.w, edgeWeight);
|
|
116
|
+
maxOut = Math.max(maxOut, (fasGraph.node(e.v)!.out += weight));
|
|
117
|
+
maxIn = Math.max(maxIn, (fasGraph.node(e.w)!.in += weight));
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
const buckets: List[] = [];
|
|
121
|
+
const rangeMax = maxOut + maxIn + 3;
|
|
122
|
+
for (let i = 0; i < rangeMax; i++) {
|
|
123
|
+
buckets.push(new List());
|
|
124
|
+
}
|
|
125
|
+
const zeroIdx = maxIn + 1;
|
|
126
|
+
|
|
127
|
+
fasGraph.nodes().forEach((v: string) => {
|
|
128
|
+
assignBucket(buckets, zeroIdx, fasGraph.node(v)!);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
return { buckets, zeroIdx, graph: fasGraph };
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const assignBucket = (buckets: List[], zeroIdx: number, entry: StateNode) => {
|
|
135
|
+
if (!entry.out) {
|
|
136
|
+
buckets[0].enqueue(entry);
|
|
137
|
+
} else if (!entry["in"]) {
|
|
138
|
+
buckets[buckets.length - 1].enqueue(entry);
|
|
139
|
+
} else {
|
|
140
|
+
buckets[entry.out - entry["in"] + zeroIdx].enqueue(entry);
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
export default greedyFAS;
|