@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,369 @@
1
+ /**
2
+ * @fileOverview random layout
3
+ * @author shiwu.wyy@antfin.com
4
+ */
5
+
6
+ import {
7
+ OutNode,
8
+ Edge,
9
+ PointTuple,
10
+ IndexMap,
11
+ CircularLayoutOptions
12
+ } from "./types";
13
+ import { Base } from "./base";
14
+ import { getDegree, clone, getEdgeTerminal, getFuncByUnknownType } from "../util";
15
+
16
+ type INode = OutNode & {
17
+ degree: number;
18
+ size: number | PointTuple;
19
+ weight: number;
20
+ children: string[];
21
+ parent: string[];
22
+ };
23
+
24
+ function initHierarchy(
25
+ nodes: INode[],
26
+ edges: Edge[],
27
+ nodeMap: IndexMap,
28
+ directed: boolean
29
+ ) {
30
+ nodes.forEach((_, i: number) => {
31
+ nodes[i].children = [];
32
+ nodes[i].parent = [];
33
+ });
34
+ if (directed) {
35
+ edges.forEach((e) => {
36
+ const source = getEdgeTerminal(e, 'source');
37
+ const target = getEdgeTerminal(e, 'target');
38
+ let sourceIdx = 0;
39
+ if (source) {
40
+ sourceIdx = nodeMap[source];
41
+ }
42
+ let targetIdx = 0;
43
+ if (target) {
44
+ targetIdx = nodeMap[target];
45
+ }
46
+ const child = nodes[sourceIdx].children!;
47
+ const parent = nodes[targetIdx].parent!;
48
+ child.push(nodes[targetIdx].id);
49
+ parent.push(nodes[sourceIdx].id);
50
+ });
51
+ } else {
52
+ edges.forEach((e) => {
53
+ const source = getEdgeTerminal(e, 'source');
54
+ const target = getEdgeTerminal(e, 'target');
55
+ let sourceIdx = 0;
56
+ if (source) {
57
+ sourceIdx = nodeMap[source];
58
+ }
59
+ let targetIdx = 0;
60
+ if (target) {
61
+ targetIdx = nodeMap[target];
62
+ }
63
+ const sourceChildren = nodes[sourceIdx].children!;
64
+ const targetChildren = nodes[targetIdx].children!;
65
+ sourceChildren.push(nodes[targetIdx].id);
66
+ targetChildren.push(nodes[sourceIdx].id);
67
+ });
68
+ }
69
+ }
70
+
71
+ function connect(a: INode, b: INode, edges: Edge[]) {
72
+ const m = edges.length;
73
+ for (let i = 0; i < m; i++) {
74
+ const source = getEdgeTerminal(edges[i], 'source');
75
+ const target = getEdgeTerminal(edges[i], 'target');
76
+ if (
77
+ (a.id === source && b.id === target) ||
78
+ (b.id === source && a.id === target)
79
+ ) {
80
+ return true;
81
+ }
82
+ }
83
+ return false;
84
+ }
85
+
86
+ function compareDegree(a: INode, b: INode) {
87
+ const aDegree = a.degree!;
88
+ const bDegree = b.degree!;
89
+ if (aDegree < bDegree) {
90
+ return -1;
91
+ }
92
+ if (aDegree > bDegree) {
93
+ return 1;
94
+ }
95
+ return 0;
96
+ }
97
+
98
+ /**
99
+ * 圆形布局
100
+ */
101
+ export class CircularLayout extends Base {
102
+ /** 布局中心 */
103
+ public center: PointTuple;
104
+
105
+ /** 固定半径,若设置了 radius,则 startRadius 与 endRadius 不起效 */
106
+ public radius: number | null = null;
107
+
108
+ /** 节点间距,若设置 nodeSpacing,则 radius 将被自动计算,即设置 radius 不生效 */
109
+ public nodeSpacing: ((d?: unknown) => number) | number | undefined;
110
+
111
+ /** 节点大小,配合 nodeSpacing,一起用于计算 radius。若不配置,节点大小默认为 30 */
112
+ public nodeSize: number | undefined = undefined;
113
+
114
+ /** 起始半径 */
115
+ public startRadius: number | null = null;
116
+
117
+ /** 终止半径 */
118
+ public endRadius: number | null = null;
119
+
120
+ /** 起始角度 */
121
+ public startAngle: number = 0;
122
+
123
+ /** 终止角度 */
124
+ public endAngle: number = 2 * Math.PI;
125
+
126
+ /** 是否顺时针 */
127
+ public clockwise: boolean = true;
128
+
129
+ /** 节点在环上分成段数(几个段将均匀分布),在 endRadius - startRadius != 0 时生效 */
130
+ public divisions: number = 1;
131
+
132
+ /** 节点在环上排序的依据,可选: 'topology', 'degree', 'null' */
133
+ public ordering: "topology" | "topology-directed" | "degree" | null = null;
134
+
135
+ /** how many 2*pi from first to last nodes */
136
+ public angleRatio = 1;
137
+
138
+ public nodes: INode[] = [];
139
+
140
+ public edges: Edge[] = [];
141
+
142
+ private nodeMap: IndexMap = {};
143
+
144
+ private degrees: number[] = [];
145
+
146
+ public width: number = 300;
147
+
148
+ public height: number = 300;
149
+
150
+ public onLayoutEnd: () => void;
151
+
152
+ constructor(options?: CircularLayoutOptions) {
153
+ super();
154
+ this.updateCfg(options);
155
+ }
156
+
157
+ public getDefaultCfg() {
158
+ return {
159
+ radius: null,
160
+ startRadius: null,
161
+ endRadius: null,
162
+ startAngle: 0,
163
+ endAngle: 2 * Math.PI,
164
+ clockwise: true,
165
+ divisions: 1,
166
+ ordering: null,
167
+ angleRatio: 1
168
+ };
169
+ }
170
+
171
+ /**
172
+ * 执行布局
173
+ */
174
+ public execute() {
175
+ const self = this;
176
+ const nodes = self.nodes;
177
+ const edges = self.edges;
178
+ const n = nodes.length;
179
+ if (n === 0) {
180
+ if (self.onLayoutEnd) self.onLayoutEnd();
181
+ return;
182
+ }
183
+
184
+ if (!self.width && typeof window !== "undefined") {
185
+ self.width = window.innerWidth;
186
+ }
187
+ if (!self.height && typeof window !== "undefined") {
188
+ self.height = window.innerHeight;
189
+ }
190
+ if (!self.center) {
191
+ self.center = [self.width / 2, self.height / 2];
192
+ }
193
+ const center = self.center;
194
+
195
+ if (n === 1) {
196
+ nodes[0].x = center[0];
197
+ nodes[0].y = center[1];
198
+ if (self.onLayoutEnd) self.onLayoutEnd();
199
+ return;
200
+ }
201
+
202
+ let { radius, startRadius, endRadius } = self;
203
+ const { divisions, startAngle, endAngle, angleRatio, ordering, clockwise, nodeSpacing: paramNodeSpacing, nodeSize: paramNodeSize } = self;
204
+ const angleStep = (endAngle - startAngle) / n;
205
+ // layout
206
+ const nodeMap: IndexMap = {};
207
+ nodes.forEach((node, i) => {
208
+ nodeMap[node.id] = i;
209
+ });
210
+ self.nodeMap = nodeMap;
211
+ const degrees = getDegree(nodes.length, nodeMap, edges);
212
+ self.degrees = degrees;
213
+ if (paramNodeSpacing) {
214
+ const nodeSpacing: Function = getFuncByUnknownType(10, paramNodeSpacing);
215
+ const nodeSize: Function = getFuncByUnknownType(10, paramNodeSize);
216
+ let maxNodeSize = -Infinity;
217
+ nodes.forEach((node) => {
218
+ const nSize = nodeSize(node);
219
+ if (maxNodeSize < nSize) maxNodeSize = nSize;
220
+ });
221
+ let length = 0;
222
+ nodes.forEach((node, i) => {
223
+ if (i === 0) length += (maxNodeSize || 10);
224
+ else length += (nodeSpacing(node) || 0) + (maxNodeSize || 10);
225
+ });
226
+ radius = length / (2 * Math.PI);
227
+ } else if (!radius && !startRadius && !endRadius) {
228
+ radius = self.height > self.width ? self.width / 2 : self.height / 2;
229
+ } else if (!startRadius && endRadius) {
230
+ startRadius = endRadius;
231
+ } else if (startRadius && !endRadius) {
232
+ endRadius = startRadius;
233
+ }
234
+ const astep = angleStep * angleRatio;
235
+
236
+ let layoutNodes = [];
237
+ if (ordering === "topology") {
238
+ // layout according to the topology
239
+ layoutNodes = self.topologyOrdering();
240
+ } else if (ordering === "topology-directed") {
241
+ // layout according to the topology
242
+ layoutNodes = self.topologyOrdering(true);
243
+ } else if (ordering === "degree") {
244
+ // layout according to the descent order of degrees
245
+ layoutNodes = self.degreeOrdering();
246
+ } else {
247
+ // layout according to the original order in the data.nodes
248
+ layoutNodes = nodes;
249
+ }
250
+
251
+ const divN = Math.ceil(n / divisions); // node number in each division
252
+ for (let i = 0; i < n; ++i) {
253
+ let r = radius;
254
+ if (!r && startRadius !== null && endRadius !== null) {
255
+ r = startRadius + (i * (endRadius - startRadius)) / (n - 1);
256
+ }
257
+ if (!r) {
258
+ r = 10 + (i * 100) / (n - 1);
259
+ }
260
+ let angle =
261
+ startAngle +
262
+ (i % divN) * astep +
263
+ ((2 * Math.PI) / divisions) * Math.floor(i / divN);
264
+ if (!clockwise) {
265
+ angle =
266
+ endAngle -
267
+ (i % divN) * astep -
268
+ ((2 * Math.PI) / divisions) * Math.floor(i / divN);
269
+ }
270
+ layoutNodes[i].x = center[0] + Math.cos(angle) * r;
271
+ layoutNodes[i].y = center[1] + Math.sin(angle) * r;
272
+ layoutNodes[i].weight = degrees[i];
273
+ }
274
+
275
+ self.onLayoutEnd?.();
276
+
277
+ return {
278
+ nodes: layoutNodes,
279
+ edges: this.edges
280
+ };
281
+ }
282
+
283
+ /**
284
+ * 根据节点的拓扑结构排序
285
+ * @return {array} orderedNodes 排序后的结果
286
+ */
287
+ public topologyOrdering(directed: boolean = false) {
288
+ const self = this;
289
+ const degrees = self.degrees;
290
+ const edges = self.edges;
291
+ const nodes = self.nodes;
292
+ const cnodes = clone(nodes);
293
+ const nodeMap = self.nodeMap;
294
+ const orderedCNodes = [cnodes[0]];
295
+ const resNodes = [nodes[0]];
296
+ const pickFlags: boolean[] = [];
297
+ const n = nodes.length;
298
+ pickFlags[0] = true;
299
+ initHierarchy(cnodes, edges, nodeMap, directed);
300
+ let k = 0;
301
+ cnodes.forEach((cnode, i) => {
302
+ if (i !== 0) {
303
+ if (
304
+ (i === n - 1 ||
305
+ degrees[i] !== degrees[i + 1] ||
306
+ connect(
307
+ orderedCNodes[k],
308
+ cnode,
309
+ edges
310
+ )) &&
311
+ !pickFlags[i]
312
+ ) {
313
+ orderedCNodes.push(cnode);
314
+ resNodes.push(nodes[nodeMap[cnode.id]]);
315
+ pickFlags[i] = true;
316
+ k++;
317
+ } else {
318
+ const children = orderedCNodes[k].children!;
319
+ let foundChild = false;
320
+ for (let j = 0; j < children.length; j++) {
321
+ const childIdx = nodeMap[children[j]];
322
+ if (degrees[childIdx] === degrees[i] && !pickFlags[childIdx]) {
323
+ orderedCNodes.push(cnodes[childIdx]);
324
+ resNodes.push(nodes[nodeMap[cnodes[childIdx].id]]);
325
+ pickFlags[childIdx] = true;
326
+ foundChild = true;
327
+ break;
328
+ }
329
+ }
330
+ let ii = 0;
331
+ while (!foundChild) {
332
+ if (!pickFlags[ii]) {
333
+ orderedCNodes.push(cnodes[ii]);
334
+ resNodes.push(nodes[nodeMap[cnodes[ii].id]]);
335
+ pickFlags[ii] = true;
336
+ foundChild = true;
337
+ }
338
+ ii++;
339
+ if (ii === n) {
340
+ break;
341
+ }
342
+ }
343
+ }
344
+ }
345
+ });
346
+ return resNodes;
347
+ }
348
+
349
+ /**
350
+ * 根据节点度数大小排序
351
+ * @return {array} orderedNodes 排序后的结果
352
+ */
353
+ public degreeOrdering(): INode[] {
354
+ const self = this;
355
+ const nodes = self.nodes;
356
+ const orderedNodes: INode[] = [];
357
+ const degrees = self.degrees;
358
+ nodes.forEach((node, i) => {
359
+ node.degree = degrees[i];
360
+ orderedNodes.push(node);
361
+ });
362
+ orderedNodes.sort(compareDegree);
363
+ return orderedNodes;
364
+ }
365
+
366
+ public getType() {
367
+ return "circular";
368
+ }
369
+ }