@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.
Files changed (90) hide show
  1. package/dist/layout.min.js +1 -1
  2. package/dist/layout.min.js.map +1 -1
  3. package/es/layout/comboCombined.js +6 -21
  4. package/es/layout/comboCombined.js.map +1 -1
  5. package/es/layout/grid.js +2 -0
  6. package/es/layout/grid.js.map +1 -1
  7. package/es/layout/types.d.ts +7 -3
  8. package/lib/layout/comboCombined.js +6 -21
  9. package/lib/layout/comboCombined.js.map +1 -1
  10. package/lib/layout/grid.js +2 -0
  11. package/lib/layout/grid.js.map +1 -1
  12. package/lib/layout/types.d.ts +7 -3
  13. package/package.json +2 -1
  14. package/src/index.ts +7 -0
  15. package/src/layout/base.ts +54 -0
  16. package/src/layout/circular.ts +369 -0
  17. package/src/layout/comboCombined.ts +391 -0
  18. package/src/layout/comboForce.ts +873 -0
  19. package/src/layout/concentric.ts +289 -0
  20. package/src/layout/constants.ts +21 -0
  21. package/src/layout/dagre/graph.ts +104 -0
  22. package/src/layout/dagre/index.ts +31 -0
  23. package/src/layout/dagre/src/acyclic.ts +58 -0
  24. package/src/layout/dagre/src/add-border-segments.ts +47 -0
  25. package/src/layout/dagre/src/coordinate-system.ts +77 -0
  26. package/src/layout/dagre/src/data/list.ts +60 -0
  27. package/src/layout/dagre/src/debug.ts +30 -0
  28. package/src/layout/dagre/src/greedy-fas.ts +144 -0
  29. package/src/layout/dagre/src/layout.ts +580 -0
  30. package/src/layout/dagre/src/nesting-graph.ts +143 -0
  31. package/src/layout/dagre/src/normalize.ts +96 -0
  32. package/src/layout/dagre/src/order/add-subgraph-constraints.ts +29 -0
  33. package/src/layout/dagre/src/order/barycenter.ts +26 -0
  34. package/src/layout/dagre/src/order/build-layer-graph.ts +82 -0
  35. package/src/layout/dagre/src/order/cross-count.ts +77 -0
  36. package/src/layout/dagre/src/order/index.ts +105 -0
  37. package/src/layout/dagre/src/order/init-data-order.ts +27 -0
  38. package/src/layout/dagre/src/order/init-order.ts +56 -0
  39. package/src/layout/dagre/src/order/resolve-conflicts.ts +152 -0
  40. package/src/layout/dagre/src/order/sort-subgraph.ts +105 -0
  41. package/src/layout/dagre/src/order/sort.ts +76 -0
  42. package/src/layout/dagre/src/parent-dummy-chains.ts +102 -0
  43. package/src/layout/dagre/src/position/bk.ts +494 -0
  44. package/src/layout/dagre/src/position/index.ts +82 -0
  45. package/src/layout/dagre/src/rank/feasible-tree.ts +165 -0
  46. package/src/layout/dagre/src/rank/index.ts +54 -0
  47. package/src/layout/dagre/src/rank/network-simplex.ts +225 -0
  48. package/src/layout/dagre/src/rank/util.ts +157 -0
  49. package/src/layout/dagre/src/util.ts +308 -0
  50. package/src/layout/dagre.ts +423 -0
  51. package/src/layout/dagreCompound.ts +518 -0
  52. package/src/layout/er/core.ts +117 -0
  53. package/src/layout/er/forceGrid.ts +95 -0
  54. package/src/layout/er/grid.ts +185 -0
  55. package/src/layout/er/index.ts +68 -0
  56. package/src/layout/er/mysqlWorkbench.ts +345 -0
  57. package/src/layout/er/type.ts +39 -0
  58. package/src/layout/force/force-in-a-box.ts +400 -0
  59. package/src/layout/force/force.ts +391 -0
  60. package/src/layout/force/index.ts +1 -0
  61. package/src/layout/forceAtlas2/body.ts +115 -0
  62. package/src/layout/forceAtlas2/index.ts +556 -0
  63. package/src/layout/forceAtlas2/quad.ts +115 -0
  64. package/src/layout/forceAtlas2/quadTree.ts +107 -0
  65. package/src/layout/fruchterman.ts +361 -0
  66. package/src/layout/gForce.ts +487 -0
  67. package/src/layout/gpu/fruchterman.ts +314 -0
  68. package/src/layout/gpu/fruchtermanShader.ts +204 -0
  69. package/src/layout/gpu/gForce.ts +406 -0
  70. package/src/layout/gpu/gForceShader.ts +221 -0
  71. package/src/layout/grid.ts +393 -0
  72. package/src/layout/index.ts +45 -0
  73. package/src/layout/layout.ts +75 -0
  74. package/src/layout/mds.ts +140 -0
  75. package/src/layout/radial/index.ts +1 -0
  76. package/src/layout/radial/mds.ts +51 -0
  77. package/src/layout/radial/radial.ts +500 -0
  78. package/src/layout/radial/radialNonoverlapForce.ts +189 -0
  79. package/src/layout/random.ts +75 -0
  80. package/src/layout/types.ts +425 -0
  81. package/src/registy/index.ts +43 -0
  82. package/src/util/array.ts +1 -0
  83. package/src/util/function.ts +64 -0
  84. package/src/util/gpu.ts +254 -0
  85. package/src/util/index.ts +6 -0
  86. package/src/util/math.ts +158 -0
  87. package/src/util/number.ts +8 -0
  88. package/src/util/object.ts +28 -0
  89. package/src/util/string.ts +18 -0
  90. package/CHANGELOG.md +0 -88
@@ -0,0 +1,105 @@
1
+ import { Graph } from "../../graph";
2
+ import barycenter from "./barycenter";
3
+ import resolveConflicts, { ConflictEntry } from "./resolve-conflicts";
4
+ import sort from "./sort";
5
+
6
+ const sortSubgraph = (
7
+ g: Graph,
8
+ v: string,
9
+ cg: Graph,
10
+ biasRight?: boolean,
11
+ usePrev?: boolean
12
+ ) => {
13
+ let movable = g.children(v);
14
+ // fixorder的点不参与排序(这个方案不合适,只排了新增节点,和原来的分离)
15
+ const node = g.node(v)!;
16
+ const bl = node ? node.borderLeft : undefined;
17
+ const br = node ? node.borderRight : undefined;
18
+ const subgraphs: Record<string, Partial<ConflictEntry>> = {};
19
+
20
+ if (bl) {
21
+ movable = movable?.filter((w) => {
22
+ return w !== bl && w !== br;
23
+ });
24
+ }
25
+
26
+ const barycenters = barycenter(g, movable || []);
27
+ barycenters?.forEach((entry) => {
28
+ if (g.children(entry.v)?.length) {
29
+ const subgraphResult = sortSubgraph(g, entry.v, cg, biasRight);
30
+ subgraphs[entry.v] = subgraphResult;
31
+ if (subgraphResult.hasOwnProperty("barycenter")) {
32
+ mergeBarycenters(entry, subgraphResult);
33
+ }
34
+ }
35
+ });
36
+
37
+ const entries = resolveConflicts(barycenters, cg);
38
+ expandSubgraphs(entries, subgraphs);
39
+
40
+ // 添加fixorder信息到entries里边
41
+ // TODO: 不考虑复合情况,只用第一个点的fixorder信息,后续考虑更完备的实现
42
+ entries
43
+ .filter((e) => e.vs.length > 0)
44
+ ?.forEach((e) => {
45
+ const node = g.node(e.vs[0])!;
46
+ if (node) {
47
+ e.fixorder = node.fixorder;
48
+ e.order = node.order;
49
+ }
50
+ });
51
+
52
+ const result = sort(entries, biasRight, usePrev);
53
+
54
+ if (bl) {
55
+ result.vs = [bl, result.vs, br].flat();
56
+ if (g.predecessors(bl)?.length) {
57
+ const blPred = g.node(g.predecessors(bl)?.[0] || "")!;
58
+ const brPred = g.node(g.predecessors(br)?.[0] || "")!;
59
+ if (!result.hasOwnProperty("barycenter")) {
60
+ result.barycenter = 0;
61
+ result.weight = 0;
62
+ }
63
+ result.barycenter =
64
+ (result.barycenter! * result.weight! +
65
+ (blPred.order as number) +
66
+ (brPred.order as number)) /
67
+ (result.weight! + 2);
68
+ result.weight! += 2;
69
+ }
70
+ }
71
+
72
+ return result;
73
+ };
74
+
75
+ const expandSubgraphs = (
76
+ entries: ConflictEntry[],
77
+ subgraphs: Record<string, Partial<ConflictEntry>>
78
+ ) => {
79
+ entries?.forEach((entry) => {
80
+ const vss = entry.vs?.map((v: string) => {
81
+ if (subgraphs[v]) {
82
+ return subgraphs[v].vs!;
83
+ }
84
+ return v;
85
+ });
86
+ entry.vs = vss.flat();
87
+ });
88
+ };
89
+
90
+ const mergeBarycenters = (
91
+ target: { weight?: number; barycenter?: number },
92
+ other: { weight?: number; barycenter?: number }
93
+ ) => {
94
+ if (target.barycenter !== undefined) {
95
+ target.barycenter =
96
+ (target.barycenter * target.weight! + other.barycenter! * other.weight!) /
97
+ (target.weight! + other.weight!);
98
+ target.weight! += other.weight!;
99
+ } else {
100
+ target.barycenter = other.barycenter;
101
+ target.weight = other.weight;
102
+ }
103
+ };
104
+
105
+ export default sortSubgraph;
@@ -0,0 +1,76 @@
1
+ import { partition } from "../util";
2
+ import { ConflictEntry } from "./resolve-conflicts";
3
+
4
+ const sort = (entries: ConflictEntry[], biasRight?: boolean, usePrev?: boolean) => {
5
+ const parts = partition(entries, (entry) => {
6
+ // NOTE: 有fixorder的也可以排
7
+ return (entry.hasOwnProperty("fixorder") && !isNaN(entry.fixorder!)) || entry.hasOwnProperty("barycenter");
8
+ });
9
+ const sortable = parts.lhs;
10
+ const unsortable = parts.rhs.sort((a, b) => -a.i - (-b.i));
11
+ const vs: string[][] = [];
12
+ let sum = 0;
13
+ let weight = 0;
14
+ let vsIndex = 0;
15
+
16
+ sortable?.sort(compareWithBias(!!biasRight, !!usePrev));
17
+
18
+ vsIndex = consumeUnsortable(vs, unsortable, vsIndex);
19
+
20
+ sortable?.forEach((entry) => {
21
+ vsIndex += entry.vs?.length;
22
+ vs.push(entry.vs);
23
+ sum += entry.barycenter! * entry.weight!;
24
+ weight += entry.weight!;
25
+ vsIndex = consumeUnsortable(vs, unsortable, vsIndex);
26
+ });
27
+
28
+ const result: { vs: string[], barycenter?: number, weight?: number } = { vs: vs.flat() };
29
+ if (weight) {
30
+ result.barycenter = sum / weight;
31
+ result.weight = weight;
32
+ }
33
+ return result;
34
+ };
35
+
36
+ const consumeUnsortable = (vs: string[][], unsortable: ConflictEntry[], index: number) => {
37
+ let iindex = index;
38
+ let last;
39
+ while (unsortable.length && (last = unsortable[unsortable.length - 1]).i <= iindex) {
40
+ unsortable.pop();
41
+ vs?.push(last.vs);
42
+ iindex++;
43
+ }
44
+ return iindex;
45
+ };
46
+
47
+ /**
48
+ * 配置是否考虑使用之前的布局结果
49
+ */
50
+ const compareWithBias = (bias: boolean, usePrev: boolean) => {
51
+ return (entryV: ConflictEntry, entryW: ConflictEntry) => {
52
+ // 排序的时候先判断fixorder,不行再判断重心
53
+ if (entryV.fixorder !== undefined && entryW.fixorder !== undefined) {
54
+ return entryV.fixorder - entryW.fixorder;
55
+ }
56
+ if (entryV.barycenter! < entryW.barycenter!) {
57
+ return -1;
58
+ }
59
+ if (entryV.barycenter! > entryW.barycenter!) {
60
+ return 1;
61
+ }
62
+ // 重心相同,考虑之前排好的顺序
63
+ if (usePrev && entryV.order !== undefined && entryW.order !== undefined) {
64
+ if (entryV.order < entryW.order) {
65
+ return -1;
66
+ }
67
+ if (entryV.order > entryW.order) {
68
+ return 1;
69
+ }
70
+ }
71
+
72
+ return !bias ? entryV.i - entryW.i : entryW.i - entryV.i;
73
+ };
74
+ };
75
+
76
+ export default sort;
@@ -0,0 +1,102 @@
1
+ import { Graph } from "../graph";
2
+
3
+ type OrderItem = { low: number; lim: number };
4
+
5
+ // deep first search with both order low for pre, lim for post
6
+ const dfsBothOrder = (g: Graph) => {
7
+ const result: Record<string, OrderItem> = {};
8
+ let lim = 0;
9
+
10
+ const dfs = (v: string) => {
11
+ const low = lim;
12
+ g.children(v)?.forEach(dfs);
13
+ result[v] = { low, lim: lim++ };
14
+ };
15
+ g.children()?.forEach(dfs);
16
+
17
+ return result;
18
+ };
19
+
20
+ // Find a path from v to w through the lowest common ancestor (LCA). Return the
21
+ // full path and the LCA.
22
+ const findPath = (
23
+ g: Graph,
24
+ postorderNums: Record<string, OrderItem>,
25
+ v: string,
26
+ w: string
27
+ ) => {
28
+ const vPath = [];
29
+ const wPath = [];
30
+ const low = Math.min(postorderNums[v].low, postorderNums[w].low);
31
+ const lim = Math.max(postorderNums[v].lim, postorderNums[w].lim);
32
+ let parent: string | undefined;
33
+ let lca: string | undefined;
34
+
35
+ // Traverse up from v to find the LCA
36
+ parent = v;
37
+ do {
38
+ parent = g.parent(parent);
39
+ vPath.push(parent);
40
+ } while (
41
+ parent &&
42
+ (postorderNums[parent].low > low || lim > postorderNums[parent].lim)
43
+ );
44
+ lca = parent;
45
+
46
+ // Traverse from w to LCA
47
+ parent = w;
48
+ while (parent && parent !== lca) {
49
+ wPath.push(parent);
50
+ parent = g.parent(parent);
51
+ }
52
+
53
+ return { lca, path: vPath.concat(wPath.reverse()) };
54
+ };
55
+
56
+ const parentDummyChains = (g: Graph) => {
57
+ const postorderNums = dfsBothOrder(g);
58
+
59
+ g.graph().dummyChains?.forEach((startV) => {
60
+ let v = startV;
61
+ let node = g.node(v)!;
62
+ const edgeObj = node.edgeObj;
63
+ if (!edgeObj) return;
64
+ const pathData = findPath(g, postorderNums, edgeObj.v, edgeObj.w);
65
+ const path = pathData.path;
66
+ const lca = pathData.lca;
67
+ let pathIdx = 0;
68
+ let pathV = path[pathIdx]!;
69
+ let ascending = true;
70
+
71
+ while (v !== edgeObj.w) {
72
+ node = g.node(v)!;
73
+
74
+ if (ascending) {
75
+ while (pathV !== lca && g.node(pathV)?.maxRank! < node.rank!) {
76
+ pathIdx++;
77
+ pathV = path[pathIdx]!;
78
+ }
79
+
80
+ if (pathV === lca) {
81
+ ascending = false;
82
+ }
83
+ }
84
+
85
+ if (!ascending) {
86
+ while (
87
+ pathIdx < path.length - 1 &&
88
+ (g.node(path[pathIdx + 1]!)?.minRank as number) <=
89
+ (node.rank as number)
90
+ ) {
91
+ pathIdx++;
92
+ }
93
+ pathV = path[pathIdx]!;
94
+ }
95
+
96
+ g.setParent(v, pathV);
97
+ v = g.successors(v)![0];
98
+ }
99
+ });
100
+ };
101
+
102
+ export default parentDummyChains;