@antv/layout 0.2.0 → 0.2.3

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 (297) hide show
  1. package/dist/layout.min.js +1 -1
  2. package/dist/layout.min.js.LICENSE.txt +0 -9
  3. package/dist/layout.min.js.map +1 -1
  4. package/es/layout/circular.js.map +1 -1
  5. package/es/layout/comboCombined.js +3 -19
  6. package/es/layout/comboCombined.js.map +1 -1
  7. package/es/layout/concentric.js.map +1 -1
  8. package/es/layout/dagre/graph.d.ts +91 -0
  9. package/es/layout/dagre/graph.js +4 -0
  10. package/es/layout/dagre/graph.js.map +1 -0
  11. package/es/layout/dagre/index.d.ts +3 -4
  12. package/es/layout/dagre/index.js +0 -2
  13. package/es/layout/dagre/index.js.map +1 -1
  14. package/es/layout/dagre/src/acyclic.d.ts +1 -2
  15. package/es/layout/dagre/src/acyclic.js +7 -7
  16. package/es/layout/dagre/src/acyclic.js.map +1 -1
  17. package/es/layout/dagre/src/add-border-segments.d.ts +1 -2
  18. package/es/layout/dagre/src/add-border-segments.js +5 -5
  19. package/es/layout/dagre/src/add-border-segments.js.map +1 -1
  20. package/es/layout/dagre/src/coordinate-system.d.ts +1 -2
  21. package/es/layout/dagre/src/coordinate-system.js +15 -5
  22. package/es/layout/dagre/src/coordinate-system.js.map +1 -1
  23. package/es/layout/dagre/src/data/list.d.ts +9 -5
  24. package/es/layout/dagre/src/data/list.js +25 -27
  25. package/es/layout/dagre/src/data/list.js.map +1 -1
  26. package/es/layout/dagre/src/debug.d.ts +2 -3
  27. package/es/layout/dagre/src/debug.js +3 -5
  28. package/es/layout/dagre/src/debug.js.map +1 -1
  29. package/es/layout/dagre/src/greedy-fas.d.ts +2 -3
  30. package/es/layout/dagre/src/greedy-fas.js +16 -15
  31. package/es/layout/dagre/src/greedy-fas.js.map +1 -1
  32. package/es/layout/dagre/src/layout.d.ts +2 -3
  33. package/es/layout/dagre/src/layout.js +170 -91
  34. package/es/layout/dagre/src/layout.js.map +1 -1
  35. package/es/layout/dagre/src/nesting-graph.d.ts +1 -2
  36. package/es/layout/dagre/src/nesting-graph.js +15 -10
  37. package/es/layout/dagre/src/nesting-graph.js.map +1 -1
  38. package/es/layout/dagre/src/normalize.d.ts +1 -2
  39. package/es/layout/dagre/src/normalize.js +12 -11
  40. package/es/layout/dagre/src/normalize.js.map +1 -1
  41. package/es/layout/dagre/src/order/add-subgraph-constraints.d.ts +1 -2
  42. package/es/layout/dagre/src/order/add-subgraph-constraints.js.map +1 -1
  43. package/es/layout/dagre/src/order/barycenter.d.ts +1 -2
  44. package/es/layout/dagre/src/order/barycenter.js.map +1 -1
  45. package/es/layout/dagre/src/order/build-layer-graph.d.ts +2 -3
  46. package/es/layout/dagre/src/order/build-layer-graph.js +12 -8
  47. package/es/layout/dagre/src/order/build-layer-graph.js.map +1 -1
  48. package/es/layout/dagre/src/order/cross-count.d.ts +2 -3
  49. package/es/layout/dagre/src/order/cross-count.js +13 -12
  50. package/es/layout/dagre/src/order/cross-count.js.map +1 -1
  51. package/es/layout/dagre/src/order/index.d.ts +2 -3
  52. package/es/layout/dagre/src/order/index.js +17 -15
  53. package/es/layout/dagre/src/order/index.js.map +1 -1
  54. package/es/layout/dagre/src/order/init-data-order.d.ts +1 -2
  55. package/es/layout/dagre/src/order/init-data-order.js +3 -5
  56. package/es/layout/dagre/src/order/init-data-order.js.map +1 -1
  57. package/es/layout/dagre/src/order/init-order.d.ts +2 -3
  58. package/es/layout/dagre/src/order/init-order.js +1 -2
  59. package/es/layout/dagre/src/order/init-order.js.map +1 -1
  60. package/es/layout/dagre/src/order/resolve-conflicts.d.ts +18 -3
  61. package/es/layout/dagre/src/order/resolve-conflicts.js +9 -29
  62. package/es/layout/dagre/src/order/resolve-conflicts.js.map +1 -1
  63. package/es/layout/dagre/src/order/sort-subgraph.d.ts +6 -3
  64. package/es/layout/dagre/src/order/sort-subgraph.js +19 -14
  65. package/es/layout/dagre/src/order/sort-subgraph.js.map +1 -1
  66. package/es/layout/dagre/src/order/sort.d.ts +6 -1
  67. package/es/layout/dagre/src/order/sort.js +2 -2
  68. package/es/layout/dagre/src/order/sort.js.map +1 -1
  69. package/es/layout/dagre/src/parent-dummy-chains.d.ts +1 -2
  70. package/es/layout/dagre/src/parent-dummy-chains.js +47 -44
  71. package/es/layout/dagre/src/parent-dummy-chains.js.map +1 -1
  72. package/es/layout/dagre/src/position/bk.d.ts +22 -31
  73. package/es/layout/dagre/src/position/bk.js +49 -83
  74. package/es/layout/dagre/src/position/bk.js.map +1 -1
  75. package/es/layout/dagre/src/position/index.d.ts +1 -2
  76. package/es/layout/dagre/src/position/index.js +12 -14
  77. package/es/layout/dagre/src/position/index.js.map +1 -1
  78. package/es/layout/dagre/src/rank/feasible-tree.d.ts +5 -6
  79. package/es/layout/dagre/src/rank/feasible-tree.js +1 -2
  80. package/es/layout/dagre/src/rank/feasible-tree.js.map +1 -1
  81. package/es/layout/dagre/src/rank/index.d.ts +2 -3
  82. package/es/layout/dagre/src/rank/index.js.map +1 -1
  83. package/es/layout/dagre/src/rank/network-simplex.d.ts +8 -11
  84. package/es/layout/dagre/src/rank/network-simplex.js +18 -31
  85. package/es/layout/dagre/src/rank/network-simplex.js.map +1 -1
  86. package/es/layout/dagre/src/rank/util.d.ts +4 -5
  87. package/es/layout/dagre/src/rank/util.js +37 -20
  88. package/es/layout/dagre/src/rank/util.js.map +1 -1
  89. package/es/layout/dagre/src/util.d.ts +29 -48
  90. package/es/layout/dagre/src/util.js +91 -101
  91. package/es/layout/dagre/src/util.js.map +1 -1
  92. package/es/layout/dagre.d.ts +1 -1
  93. package/es/layout/dagre.js +28 -24
  94. package/es/layout/dagre.js.map +1 -1
  95. package/es/layout/fruchterman.js.map +1 -1
  96. package/es/layout/gForce.js +14 -6
  97. package/es/layout/gForce.js.map +1 -1
  98. package/lib/index.js +5 -1
  99. package/lib/index.js.map +1 -1
  100. package/lib/layout/circular.js.map +1 -1
  101. package/lib/layout/comboCombined.js +2 -18
  102. package/lib/layout/comboCombined.js.map +1 -1
  103. package/lib/layout/comboForce.js +5 -5
  104. package/lib/layout/comboForce.js.map +1 -1
  105. package/lib/layout/concentric.js.map +1 -1
  106. package/lib/layout/dagre/graph.d.ts +91 -0
  107. package/lib/layout/dagre/graph.js +28 -0
  108. package/lib/layout/dagre/graph.js.map +1 -0
  109. package/lib/layout/dagre/index.d.ts +3 -4
  110. package/lib/layout/dagre/index.js +0 -2
  111. package/lib/layout/dagre/index.js.map +1 -1
  112. package/lib/layout/dagre/src/acyclic.d.ts +1 -2
  113. package/lib/layout/dagre/src/acyclic.js +7 -7
  114. package/lib/layout/dagre/src/acyclic.js.map +1 -1
  115. package/lib/layout/dagre/src/add-border-segments.d.ts +1 -2
  116. package/lib/layout/dagre/src/add-border-segments.js +5 -8
  117. package/lib/layout/dagre/src/add-border-segments.js.map +1 -1
  118. package/lib/layout/dagre/src/coordinate-system.d.ts +1 -2
  119. package/lib/layout/dagre/src/coordinate-system.js +15 -5
  120. package/lib/layout/dagre/src/coordinate-system.js.map +1 -1
  121. package/lib/layout/dagre/src/data/list.d.ts +9 -5
  122. package/lib/layout/dagre/src/data/list.js +25 -26
  123. package/lib/layout/dagre/src/data/list.js.map +1 -1
  124. package/lib/layout/dagre/src/debug.d.ts +2 -3
  125. package/lib/layout/dagre/src/debug.js +6 -11
  126. package/lib/layout/dagre/src/debug.js.map +1 -1
  127. package/lib/layout/dagre/src/greedy-fas.d.ts +2 -3
  128. package/lib/layout/dagre/src/greedy-fas.js +41 -15
  129. package/lib/layout/dagre/src/greedy-fas.js.map +1 -1
  130. package/lib/layout/dagre/src/layout.d.ts +2 -3
  131. package/lib/layout/dagre/src/layout.js +171 -100
  132. package/lib/layout/dagre/src/layout.js.map +1 -1
  133. package/lib/layout/dagre/src/nesting-graph.d.ts +1 -2
  134. package/lib/layout/dagre/src/nesting-graph.js +15 -13
  135. package/lib/layout/dagre/src/nesting-graph.js.map +1 -1
  136. package/lib/layout/dagre/src/normalize.d.ts +1 -2
  137. package/lib/layout/dagre/src/normalize.js +12 -14
  138. package/lib/layout/dagre/src/normalize.js.map +1 -1
  139. package/lib/layout/dagre/src/order/add-subgraph-constraints.d.ts +1 -2
  140. package/lib/layout/dagre/src/order/add-subgraph-constraints.js.map +1 -1
  141. package/lib/layout/dagre/src/order/barycenter.d.ts +1 -2
  142. package/lib/layout/dagre/src/order/barycenter.js.map +1 -1
  143. package/lib/layout/dagre/src/order/build-layer-graph.d.ts +2 -3
  144. package/lib/layout/dagre/src/order/build-layer-graph.js +13 -12
  145. package/lib/layout/dagre/src/order/build-layer-graph.js.map +1 -1
  146. package/lib/layout/dagre/src/order/cross-count.d.ts +2 -3
  147. package/lib/layout/dagre/src/order/cross-count.js +14 -13
  148. package/lib/layout/dagre/src/order/cross-count.js.map +1 -1
  149. package/lib/layout/dagre/src/order/index.d.ts +2 -3
  150. package/lib/layout/dagre/src/order/index.js +15 -13
  151. package/lib/layout/dagre/src/order/index.js.map +1 -1
  152. package/lib/layout/dagre/src/order/init-data-order.d.ts +1 -2
  153. package/lib/layout/dagre/src/order/init-data-order.js +3 -5
  154. package/lib/layout/dagre/src/order/init-data-order.js.map +1 -1
  155. package/lib/layout/dagre/src/order/init-order.d.ts +2 -3
  156. package/lib/layout/dagre/src/order/init-order.js +1 -2
  157. package/lib/layout/dagre/src/order/init-order.js.map +1 -1
  158. package/lib/layout/dagre/src/order/resolve-conflicts.d.ts +18 -3
  159. package/lib/layout/dagre/src/order/resolve-conflicts.js +9 -29
  160. package/lib/layout/dagre/src/order/resolve-conflicts.js.map +1 -1
  161. package/lib/layout/dagre/src/order/sort-subgraph.d.ts +6 -3
  162. package/lib/layout/dagre/src/order/sort-subgraph.js +16 -11
  163. package/lib/layout/dagre/src/order/sort-subgraph.js.map +1 -1
  164. package/lib/layout/dagre/src/order/sort.d.ts +6 -1
  165. package/lib/layout/dagre/src/order/sort.js +2 -5
  166. package/lib/layout/dagre/src/order/sort.js.map +1 -1
  167. package/lib/layout/dagre/src/parent-dummy-chains.d.ts +1 -2
  168. package/lib/layout/dagre/src/parent-dummy-chains.js +47 -44
  169. package/lib/layout/dagre/src/parent-dummy-chains.js.map +1 -1
  170. package/lib/layout/dagre/src/position/bk.d.ts +22 -31
  171. package/lib/layout/dagre/src/position/bk.js +75 -85
  172. package/lib/layout/dagre/src/position/bk.js.map +1 -1
  173. package/lib/layout/dagre/src/position/index.d.ts +1 -2
  174. package/lib/layout/dagre/src/position/index.js +14 -17
  175. package/lib/layout/dagre/src/position/index.js.map +1 -1
  176. package/lib/layout/dagre/src/rank/feasible-tree.d.ts +5 -6
  177. package/lib/layout/dagre/src/rank/feasible-tree.js +3 -7
  178. package/lib/layout/dagre/src/rank/feasible-tree.js.map +1 -1
  179. package/lib/layout/dagre/src/rank/index.d.ts +2 -3
  180. package/lib/layout/dagre/src/rank/index.js.map +1 -1
  181. package/lib/layout/dagre/src/rank/network-simplex.d.ts +8 -11
  182. package/lib/layout/dagre/src/rank/network-simplex.js +27 -35
  183. package/lib/layout/dagre/src/rank/network-simplex.js.map +1 -1
  184. package/lib/layout/dagre/src/rank/util.d.ts +4 -5
  185. package/lib/layout/dagre/src/rank/util.js +36 -19
  186. package/lib/layout/dagre/src/rank/util.js.map +1 -1
  187. package/lib/layout/dagre/src/util.d.ts +29 -48
  188. package/lib/layout/dagre/src/util.js +80 -92
  189. package/lib/layout/dagre/src/util.js.map +1 -1
  190. package/lib/layout/dagre.d.ts +1 -1
  191. package/lib/layout/dagre.js +27 -23
  192. package/lib/layout/dagre.js.map +1 -1
  193. package/lib/layout/er/core.js +5 -1
  194. package/lib/layout/er/core.js.map +1 -1
  195. package/lib/layout/force/force-in-a-box.js +7 -3
  196. package/lib/layout/force/force-in-a-box.js.map +1 -1
  197. package/lib/layout/force/force.js +5 -1
  198. package/lib/layout/force/force.js.map +1 -1
  199. package/lib/layout/force/index.js +5 -1
  200. package/lib/layout/force/index.js.map +1 -1
  201. package/lib/layout/fruchterman.js.map +1 -1
  202. package/lib/layout/gForce.js +10 -2
  203. package/lib/layout/gForce.js.map +1 -1
  204. package/lib/layout/grid.js +2 -2
  205. package/lib/layout/grid.js.map +1 -1
  206. package/lib/layout/index.js +5 -1
  207. package/lib/layout/index.js.map +1 -1
  208. package/lib/layout/radial/index.js +5 -1
  209. package/lib/layout/radial/index.js.map +1 -1
  210. package/lib/registy/index.js +1 -1
  211. package/lib/registy/index.js.map +1 -1
  212. package/lib/util/index.js +5 -1
  213. package/lib/util/index.js.map +1 -1
  214. package/package.json +3 -2
  215. package/src/index.ts +7 -0
  216. package/src/layout/base.ts +54 -0
  217. package/src/layout/circular.ts +369 -0
  218. package/src/layout/comboCombined.ts +390 -0
  219. package/src/layout/comboForce.ts +873 -0
  220. package/src/layout/concentric.ts +289 -0
  221. package/src/layout/constants.ts +21 -0
  222. package/src/layout/dagre/graph.ts +104 -0
  223. package/src/layout/dagre/index.ts +31 -0
  224. package/src/layout/dagre/src/acyclic.ts +58 -0
  225. package/src/layout/dagre/src/add-border-segments.ts +47 -0
  226. package/src/layout/dagre/src/coordinate-system.ts +77 -0
  227. package/src/layout/dagre/src/data/list.ts +60 -0
  228. package/src/layout/dagre/src/debug.ts +30 -0
  229. package/src/layout/dagre/src/greedy-fas.ts +144 -0
  230. package/src/layout/dagre/src/layout.ts +580 -0
  231. package/src/layout/dagre/src/nesting-graph.ts +143 -0
  232. package/src/layout/dagre/src/normalize.ts +96 -0
  233. package/src/layout/dagre/src/order/add-subgraph-constraints.ts +29 -0
  234. package/src/layout/dagre/src/order/barycenter.ts +26 -0
  235. package/src/layout/dagre/src/order/build-layer-graph.ts +82 -0
  236. package/src/layout/dagre/src/order/cross-count.ts +77 -0
  237. package/src/layout/dagre/src/order/index.ts +105 -0
  238. package/src/layout/dagre/src/order/init-data-order.ts +27 -0
  239. package/src/layout/dagre/src/order/init-order.ts +56 -0
  240. package/src/layout/dagre/src/order/resolve-conflicts.ts +152 -0
  241. package/src/layout/dagre/src/order/sort-subgraph.ts +105 -0
  242. package/src/layout/dagre/src/order/sort.ts +76 -0
  243. package/src/layout/dagre/src/parent-dummy-chains.ts +102 -0
  244. package/src/layout/dagre/src/position/bk.ts +494 -0
  245. package/src/layout/dagre/src/position/index.ts +82 -0
  246. package/src/layout/dagre/src/rank/feasible-tree.ts +165 -0
  247. package/src/layout/dagre/src/rank/index.ts +54 -0
  248. package/src/layout/dagre/src/rank/network-simplex.ts +225 -0
  249. package/src/layout/dagre/src/rank/util.ts +157 -0
  250. package/src/layout/dagre/src/util.ts +308 -0
  251. package/src/layout/dagre.ts +423 -0
  252. package/src/layout/dagreCompound.ts +518 -0
  253. package/src/layout/er/core.ts +117 -0
  254. package/src/layout/er/forceGrid.ts +95 -0
  255. package/src/layout/er/grid.ts +185 -0
  256. package/src/layout/er/index.ts +68 -0
  257. package/src/layout/er/mysqlWorkbench.ts +345 -0
  258. package/src/layout/er/type.ts +39 -0
  259. package/src/layout/force/force-in-a-box.ts +400 -0
  260. package/src/layout/force/force.ts +391 -0
  261. package/src/layout/force/index.ts +1 -0
  262. package/src/layout/forceAtlas2/body.ts +115 -0
  263. package/src/layout/forceAtlas2/index.ts +556 -0
  264. package/src/layout/forceAtlas2/quad.ts +115 -0
  265. package/src/layout/forceAtlas2/quadTree.ts +107 -0
  266. package/src/layout/fruchterman.ts +361 -0
  267. package/src/layout/gForce.ts +487 -0
  268. package/src/layout/gpu/fruchterman.ts +314 -0
  269. package/src/layout/gpu/fruchtermanShader.ts +204 -0
  270. package/src/layout/gpu/gForce.ts +406 -0
  271. package/src/layout/gpu/gForceShader.ts +221 -0
  272. package/src/layout/grid.ts +391 -0
  273. package/src/layout/index.ts +45 -0
  274. package/src/layout/layout.ts +75 -0
  275. package/src/layout/mds.ts +140 -0
  276. package/src/layout/radial/index.ts +1 -0
  277. package/src/layout/radial/mds.ts +51 -0
  278. package/src/layout/radial/radial.ts +500 -0
  279. package/src/layout/radial/radialNonoverlapForce.ts +189 -0
  280. package/src/layout/random.ts +75 -0
  281. package/src/layout/types.ts +421 -0
  282. package/src/registy/index.ts +43 -0
  283. package/src/util/array.ts +1 -0
  284. package/src/util/function.ts +64 -0
  285. package/src/util/gpu.ts +254 -0
  286. package/src/util/index.ts +6 -0
  287. package/src/util/math.ts +158 -0
  288. package/src/util/number.ts +8 -0
  289. package/src/util/object.ts +28 -0
  290. package/src/util/string.ts +18 -0
  291. package/CHANGELOG.md +0 -78
  292. package/es/layout/dagre/src/graphlib.d.ts +0 -2
  293. package/es/layout/dagre/src/graphlib.js +0 -51
  294. package/es/layout/dagre/src/graphlib.js.map +0 -1
  295. package/lib/layout/dagre/src/graphlib.d.ts +0 -2
  296. package/lib/layout/dagre/src/graphlib.js +0 -56
  297. package/lib/layout/dagre/src/graphlib.js.map +0 -1
@@ -0,0 +1,390 @@
1
+ /**
2
+ * @fileOverview Combo force layout
3
+ * @author shiwu.wyy@antfin.com
4
+ */
5
+
6
+ import {
7
+ Edge,
8
+ Combo,
9
+ OutNode,
10
+ PointTuple,
11
+ ComboTree,
12
+ ComboCombinedLayoutOptions
13
+ } from "./types";
14
+ import { FORCE_LAYOUT_TYPE_MAP } from './constants';
15
+ import { Base } from "./base";
16
+ import { isArray, isNumber, isFunction, traverseTreeUp, isObject, findMinMaxNodeXY } from "../util";
17
+ import { CircularLayout, ConcentricLayout, GridLayout, RadialLayout, GForceLayout, MDSLayout } from ".";
18
+
19
+ type Node = OutNode & {
20
+ depth?: number;
21
+ itemType?: string;
22
+ comboId?: string;
23
+ fx?: number;
24
+ fy?: number;
25
+ mass?: number;
26
+ };
27
+
28
+ /**
29
+ * combined two layouts (inner and outer) for graph with combos
30
+ */
31
+ export class ComboCombinedLayout extends Base {
32
+
33
+ /** 布局中心 */
34
+ public center: PointTuple = [0, 0];
35
+
36
+ /** 内部计算参数 */
37
+ public nodes: Node[] = [];
38
+
39
+ public edges: Edge[] = [];
40
+
41
+ public combos: Combo[] = [];
42
+
43
+ public comboEdges: Edge[] = [];
44
+
45
+ /** 节点大小,用于防止节点之间的重叠 */
46
+ public nodeSize: number | number[] | ((d?: unknown) => number) | undefined;
47
+
48
+ /** 节点/combo最小间距,防止重叠时的间隙 */
49
+ public spacing: ((d?: unknown) => number) | number | undefined;
50
+
51
+ /** 最外层的布局算法,需要使用同步的布局算法,默认为 forceAtlas2 */
52
+ public outerLayout: any;
53
+
54
+ /** combo 内部的布局算法,默认为 concentric */
55
+ public innerLayout: ConcentricLayout | CircularLayout | GridLayout | RadialLayout;
56
+
57
+ /** Combo 内部的 padding */
58
+ public comboPadding:
59
+ | ((d?: unknown) => number)
60
+ | number
61
+ | number[]
62
+ | undefined = 10;
63
+
64
+ public comboTrees: ComboTree[] = [];
65
+
66
+ constructor(options?: ComboCombinedLayoutOptions) {
67
+ super();
68
+ this.updateCfg(options);
69
+ }
70
+
71
+ public getDefaultCfg() {
72
+ return {};
73
+ }
74
+
75
+ /**
76
+ * 执行布局
77
+ */
78
+ public execute() {
79
+ const self = this;
80
+ const nodes = self.nodes;
81
+ const center = self.center;
82
+
83
+ if (!nodes || nodes.length === 0) {
84
+ if (self.onLayoutEnd) self.onLayoutEnd();
85
+ return;
86
+ }
87
+ if (nodes.length === 1) {
88
+ nodes[0].x = center[0];
89
+ nodes[0].y = center[1];
90
+ if (self.onLayoutEnd) self.onLayoutEnd();
91
+ return;
92
+ }
93
+
94
+ self.initVals();
95
+
96
+ // layout
97
+ self.run();
98
+ if (self.onLayoutEnd) self.onLayoutEnd();
99
+ }
100
+
101
+ public run() {
102
+ const self = this;
103
+ const { nodes, edges, combos, comboEdges, center } = self;
104
+
105
+ const innerGraphs: any = self.getInnerGraphs();
106
+
107
+ const nodeMap: any = {};
108
+ nodes.forEach((node) => {
109
+ nodeMap[node.id] = node;
110
+ });
111
+ const comboMap: any = {};
112
+ combos.forEach((combo) => {
113
+ comboMap[combo.id] = combo;
114
+ });
115
+
116
+ // 每个 innerGraph 作为一个节点,带有大小,参与 force 计算
117
+ const outerNodeIds: string[] = [];
118
+ const outerNodes: Node[] = [];
119
+ const nodeAncestorIdMap: { [key: string]: string } = {};
120
+ let allHaveNoPosition = true;
121
+ this.comboTrees.forEach((cTree) => {
122
+ const innerNode = innerGraphs[cTree.id];
123
+ // 代表 combo 的节点
124
+ const oNode: Node = {
125
+ ...cTree,
126
+ x: innerNode.x || comboMap[cTree.id].x,
127
+ y: innerNode.y || comboMap[cTree.id].y,
128
+ fx: innerNode.fx || comboMap[cTree.id].fx,
129
+ fy: innerNode.fy || comboMap[cTree.id].fy,
130
+ mass: innerNode.mass || comboMap[cTree.id].mass,
131
+ size: innerNode.size
132
+ };
133
+ outerNodes.push(oNode);
134
+ if (!isNaN(oNode.x) && oNode.x !== 0 && !isNaN(oNode.y) && oNode.y !== 0) {
135
+ allHaveNoPosition = false;
136
+ } else {
137
+ oNode.x = Math.random() * 100;
138
+ oNode.y = Math.random() * 100;
139
+ }
140
+ outerNodeIds.push(cTree.id);
141
+ traverseTreeUp<ComboTree>(cTree, (child) => {
142
+ if (child.id !== cTree.id) nodeAncestorIdMap[child.id] = cTree.id;
143
+ return true;
144
+ });
145
+ });
146
+ nodes.forEach((node) => {
147
+ if (node.comboId && comboMap[node.comboId]) return;
148
+ // 代表节点的节点
149
+ const oNode: Node = { ...node };
150
+ outerNodes.push(oNode);
151
+ if (!isNaN(oNode.x) && oNode.x !== 0 && !isNaN(oNode.y) && oNode.y !== 0) {
152
+ allHaveNoPosition = false;
153
+ } else {
154
+ oNode.x = Math.random() * 100;
155
+ oNode.y = Math.random() * 100;
156
+ }
157
+ outerNodeIds.push(node.id);
158
+ });
159
+ const outerEdges: any = [];
160
+ edges.concat(comboEdges).forEach((edge) => {
161
+ const sourceAncestorId = nodeAncestorIdMap[edge.source] || edge.source;
162
+ const targetAncestorId = nodeAncestorIdMap[edge.target] || edge.target;
163
+ // 若两个点的祖先都在力导图的节点中,且是不同的节点,创建一条链接两个祖先的边到力导图的边中
164
+ if (sourceAncestorId !== targetAncestorId &&
165
+ outerNodeIds.includes(sourceAncestorId) &&
166
+ outerNodeIds.includes(targetAncestorId)) {
167
+ outerEdges.push({
168
+ source: sourceAncestorId,
169
+ target: targetAncestorId
170
+ });
171
+ }
172
+ });
173
+
174
+ // 若有需要最外层的 combo 或节点,则对最外层执行力导向
175
+ if (outerNodes?.length) {
176
+ if (outerNodes.length === 1) {
177
+ outerNodes[0].x = center[0];
178
+ outerNodes[0].y = center[1];
179
+ } else {
180
+ const outerData = {
181
+ nodes: outerNodes,
182
+ edges: outerEdges
183
+ };
184
+
185
+ // 需要使用一个同步的布局
186
+ // @ts-ignore
187
+ const outerLayout = this.outerLayout || new GForceLayout({
188
+ gravity: 1,
189
+ factor: 2,
190
+ linkDistance: (edge: any, source: any, target: any) => {
191
+ const nodeSize = ((source.size?.[0] || 30) + (target.size?.[0] || 30)) / 2;
192
+ return Math.min(nodeSize * 1.5, 700);
193
+ }
194
+ });
195
+ const outerLayoutType = outerLayout.getType?.();
196
+ outerLayout.updateCfg({
197
+ center,
198
+ kg: 5,
199
+ preventOverlap: true,
200
+ animate: false,
201
+ });
202
+ // 若所有 outerNodes 都没有位置,且 outerLayout 是力导家族的布局,则先执行 preset mds 或 grid
203
+ if (allHaveNoPosition && FORCE_LAYOUT_TYPE_MAP[outerLayoutType]) {
204
+ const outerLayoutPreset = outerNodes.length < 100 ? new MDSLayout() : new GridLayout();
205
+ outerLayoutPreset.layout(outerData);
206
+ }
207
+ outerLayout.layout(outerData);
208
+ }
209
+ // 根据外部布局结果,平移 innerGraphs 中的节点(第一层)
210
+ outerNodes.forEach((oNode) => {
211
+ const innerGraph = innerGraphs[oNode.id];
212
+ if (!innerGraph) {
213
+ const node = nodeMap[oNode.id];
214
+ if (node) {
215
+ node.x = oNode.x;
216
+ node.y = oNode.y;
217
+ }
218
+ return;
219
+ }
220
+ innerGraph.visited = true;
221
+ innerGraph.x = oNode.x;
222
+ innerGraph.y = oNode.y;
223
+ innerGraph.nodes.forEach((node: OutNode) => {
224
+ node.x += oNode.x;
225
+ node.y += oNode.y;
226
+ });
227
+ });
228
+ }
229
+
230
+ // 至上而下遍历树处理下面各层节点位置
231
+ const innerGraphIds = Object.keys(innerGraphs);
232
+ for (let i = innerGraphIds.length - 1; i >= 0; i--) {
233
+ const id = innerGraphIds[i];
234
+ const innerGraph = innerGraphs[id];
235
+ if (!innerGraph) continue;
236
+ innerGraph.nodes.forEach((node: OutNode) => {
237
+ if (!innerGraph.visited) {
238
+ node.x += (innerGraph.x || 0);
239
+ node.y += (innerGraph.y || 0);
240
+ }
241
+ if (nodeMap[node.id]) {
242
+ nodeMap[node.id].x = node.x;
243
+ nodeMap[node.id].y = node.y;
244
+ }
245
+ });
246
+ if (comboMap[id]) {
247
+ comboMap[id].x = innerGraph.x;
248
+ comboMap[id].y = innerGraph.y;
249
+ }
250
+ }
251
+ return { nodes, edges, combos, comboEdges };
252
+ }
253
+
254
+ private getInnerGraphs() {
255
+ const self = this;
256
+ const { comboTrees, nodeSize, edges, comboPadding, spacing } = self;
257
+ const innerGraphs: any = {};
258
+
259
+ // @ts-ignore
260
+ const innerGraphLayout: any = this.innerLayout || (new ConcentricLayout({ sortBy: 'id' }));
261
+ innerGraphLayout.center = [0, 0];
262
+ innerGraphLayout.preventOverlap = true;
263
+ innerGraphLayout.nodeSpacing = spacing;
264
+
265
+ (comboTrees || []).forEach((ctree: any) => {
266
+ traverseTreeUp<ComboTree>(ctree, (treeNode) => {
267
+ // @ts-ignore
268
+ let padding = comboPadding?.(treeNode) || 10; // 返回的最大值
269
+ if (isArray(padding)) padding = Math.max(...padding);
270
+ if (!treeNode.children?.length) {
271
+ // 空 combo
272
+ if (treeNode.itemType === 'combo') {
273
+ const treeNodeSize = padding ? [padding * 2, padding * 2] : [30, 30];
274
+ innerGraphs[treeNode.id] = {
275
+ id: treeNode.id,
276
+ nodes: [],
277
+ size: treeNodeSize
278
+ };
279
+ }
280
+ } else {
281
+ // 非空 combo
282
+ const innerGraphNodes = treeNode.children.map((child) => {
283
+ if (child.itemType === 'combo') return innerGraphs[child.id];
284
+ return {...child};
285
+ });
286
+ const innerGraphNodeIds = innerGraphNodes.map((node) => node.id);
287
+ const innerGraphData = {
288
+ nodes: innerGraphNodes,
289
+ edges: edges.filter((edge) => innerGraphNodeIds.includes(edge.source) && innerGraphNodeIds.includes(edge.target))
290
+ };
291
+ let minNodeSize = Infinity;
292
+ innerGraphNodes.forEach((node) => {
293
+ // @ts-ignore
294
+ if (!node.size) node.size = innerGraphs[node.id]?.size || nodeSize?.(node) || [30, 30];
295
+ if (isNumber(node.size)) node.size = [node.size, node.size];
296
+ if (minNodeSize > node.size[0]) minNodeSize = node.size[0];
297
+ if (minNodeSize > node.size[1]) minNodeSize = node.size[1];
298
+ });
299
+
300
+ // 根据节点数量、spacing,调整布局参数
301
+
302
+ innerGraphLayout.layout(innerGraphData);
303
+ const { minX, minY, maxX, maxY } = findMinMaxNodeXY(innerGraphNodes);
304
+ const innerGraphSize = Math.max(maxX - minX, maxY - minY, minNodeSize) + padding * 2;
305
+ innerGraphs[treeNode.id] = {
306
+ id: treeNode.id,
307
+ nodes: innerGraphNodes,
308
+ size: [innerGraphSize, innerGraphSize]
309
+ };
310
+ }
311
+ return true;
312
+ });
313
+ });
314
+ return innerGraphs;
315
+ }
316
+
317
+ private initVals() {
318
+ const self = this;
319
+
320
+ const nodeSize = self.nodeSize;
321
+ const spacing = self.spacing;
322
+ let nodeSizeFunc: (d: any) => number;
323
+ let spacingFunc: (d: any) => number;
324
+
325
+ // nodeSpacing to function
326
+ if (isNumber(spacing)) {
327
+ spacingFunc = () => spacing as any;
328
+ } else if (isFunction(spacing)) {
329
+ spacingFunc = spacing;
330
+ } else {
331
+ spacingFunc = () => 0;
332
+ }
333
+ this.spacing = spacingFunc;
334
+
335
+ // nodeSize to function
336
+ if (!nodeSize) {
337
+ nodeSizeFunc = (d) => {
338
+ const spacing = spacingFunc(d);
339
+ if (d.size) {
340
+ if (isArray(d.size)) {
341
+ const res = d.size[0] > d.size[1] ? d.size[0] : d.size[1];
342
+ return (res + spacing) / 2;
343
+ } if (isObject(d.size)) {
344
+ const res = d.size.width > d.size.height ? d.size.width : d.size.height;
345
+ return (res + spacing) / 2;
346
+ }
347
+ return (d.size + spacing) / 2;
348
+ }
349
+ return 10 + spacing / 2;
350
+ };
351
+ } else if (isFunction(nodeSize)) {
352
+ nodeSizeFunc = (d) => {
353
+ const size = nodeSize(d);
354
+ const spacing = spacingFunc(d);
355
+ if (isArray(d.size)) {
356
+ const res = d.size[0] > d.size[1] ? d.size[0] : d.size[1];
357
+ return (res + spacing) / 2;
358
+ }
359
+ return ((size || 10) + spacing) / 2;
360
+ };
361
+ } else if (isArray(nodeSize)) {
362
+ const larger = nodeSize[0] > nodeSize[1] ? nodeSize[0] : nodeSize[1];
363
+ const radius = larger / 2;
364
+ nodeSizeFunc = (d) => radius + spacingFunc(d) / 2;
365
+ } else {
366
+ // number type
367
+ const radius = nodeSize / 2;
368
+ nodeSizeFunc = (d) => radius + spacingFunc(d) / 2;
369
+ }
370
+ this.nodeSize = nodeSizeFunc;
371
+
372
+ // comboPadding to function
373
+ const comboPadding = self.comboPadding;
374
+ let comboPaddingFunc: (d: any) => number;
375
+ if (isNumber(comboPadding)) {
376
+ comboPaddingFunc = () => comboPadding as any;
377
+ } else if (isArray(comboPadding)) {
378
+ comboPaddingFunc = () => Math.max.apply(null, comboPadding);
379
+ } else if (isFunction(comboPadding)) {
380
+ comboPaddingFunc = comboPadding;
381
+ } else {
382
+ // null type
383
+ comboPaddingFunc = () => 0;
384
+ }
385
+ this.comboPadding = comboPaddingFunc;
386
+ }
387
+ public getType() {
388
+ return "comboCombined";
389
+ }
390
+ }