@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,289 @@
1
+ /**
2
+ * @fileOverview concentric layout
3
+ * @author shiwu.wyy@antfin.com
4
+ * this algorithm refers to <cytoscape.js> - https://github.com/cytoscape/cytoscape.js/
5
+ */
6
+
7
+ import {
8
+ OutNode,
9
+ Edge,
10
+ PointTuple,
11
+ Size,
12
+ IndexMap,
13
+ ConcentricLayoutOptions
14
+ } from "./types";
15
+ import { isString, isArray, isNumber, getDegree, isObject, isFunction } from "../util";
16
+ import { Base } from "./base";
17
+
18
+ type INode = OutNode & {
19
+ degree: number;
20
+ size: number | PointTuple | Size;
21
+ };
22
+
23
+ type NodeMap = {
24
+ [key: string]: INode;
25
+ };
26
+
27
+ /**
28
+ * 同心圆布局
29
+ */
30
+ export class ConcentricLayout extends Base {
31
+ /** 布局中心 */
32
+ public center: PointTuple;
33
+
34
+ public nodeSize: number | PointTuple = 30;
35
+
36
+ /** min spacing between outside of nodes (used for radius adjustment) */
37
+ public minNodeSpacing: number = 10;
38
+
39
+ /** same as minNodeSpacing. min spacing between outside of nodes (used for radius adjustment) */
40
+ public nodeSpacing: number | number[] | ((d?: unknown) => number) | undefined = 10;
41
+
42
+ /** prevents node overlap, may overflow boundingBox if not enough space */
43
+ public preventOverlap: boolean = false;
44
+
45
+ /** how many radians should be between the first and last node (defaults to full circle) */
46
+ public sweep: number | undefined;
47
+
48
+ /** whether levels have an equal radial distance betwen them, may cause bounding box overflow */
49
+ public equidistant: boolean = false;
50
+
51
+ /** where nodes start in radians */
52
+ public startAngle: number = (3 / 2) * Math.PI;
53
+
54
+ /** whether the layout should go clockwise (true) or counterclockwise/anticlockwise (false) */
55
+ public clockwise: boolean = true;
56
+
57
+ /** the letiation of concentric values in each level */
58
+ public maxLevelDiff: undefined | number;
59
+
60
+ /** 根据 sortBy 指定的属性进行排布,数值高的放在中心,如果是 sortBy 则会计算节点度数,度数最高的放在中心 */
61
+ public sortBy: string = "degree";
62
+
63
+ public nodes: INode[] = [];
64
+
65
+ public edges: Edge[] = [];
66
+
67
+ public width: number = 300;
68
+
69
+ public height: number = 300;
70
+
71
+ /** 迭代结束的回调函数 */
72
+ public onLayoutEnd: () => void = () => {};
73
+
74
+ private maxValueNode: INode | undefined;
75
+
76
+ private counterclockwise: boolean | undefined;
77
+
78
+ constructor(options?: ConcentricLayoutOptions) {
79
+ super();
80
+ this.updateCfg(options);
81
+ }
82
+
83
+ public getDefaultCfg() {
84
+ return {
85
+ nodeSize: 30,
86
+ minNodeSpacing: 10,
87
+ nodeSpacing: 10,
88
+ preventOverlap: false,
89
+ sweep: undefined,
90
+ equidistant: false,
91
+ startAngle: (3 / 2) * Math.PI,
92
+ clockwise: true,
93
+ maxLevelDiff: undefined,
94
+ sortBy: "degree"
95
+ };
96
+ }
97
+
98
+ /**
99
+ * 执行布局
100
+ */
101
+ public execute() {
102
+ const self = this;
103
+ const { nodes, edges } = self;
104
+ const n = nodes.length;
105
+ if (n === 0) {
106
+ self.onLayoutEnd?.();
107
+ return;
108
+ }
109
+
110
+ if (!self.width && typeof window !== "undefined") {
111
+ self.width = window.innerWidth;
112
+ }
113
+ if (!self.height && typeof window !== "undefined") {
114
+ self.height = window.innerHeight;
115
+ }
116
+ if (!self.center) {
117
+ self.center = [self.width / 2, self.height / 2];
118
+ }
119
+ const center = self.center;
120
+
121
+ if (n === 1) {
122
+ nodes[0].x = center[0];
123
+ nodes[0].y = center[1];
124
+ self.onLayoutEnd?.();
125
+ return;
126
+ }
127
+
128
+ const { nodeSize, nodeSpacing } = self;
129
+
130
+ const layoutNodes: INode[] = [];
131
+ let maxNodeSize: number;
132
+ let maxNodeSpacing: number = 0;
133
+ if (isArray(nodeSize)) {
134
+ maxNodeSize = Math.max(nodeSize[0], nodeSize[1]);
135
+ } else {
136
+ maxNodeSize = nodeSize;
137
+ }
138
+ if (isArray(nodeSpacing)) {
139
+ maxNodeSpacing = Math.max(nodeSpacing[0], nodeSpacing[1]);
140
+ } else if (isNumber(nodeSpacing)) {
141
+ maxNodeSpacing = nodeSpacing;
142
+ }
143
+ nodes.forEach((node) => {
144
+ layoutNodes.push(node);
145
+ let nodeSize: number = maxNodeSize;
146
+ if (isArray(node.size)) {
147
+ nodeSize = Math.max(node.size[0], node.size[1]);
148
+ } else if (isNumber(node.size)) {
149
+ nodeSize = node.size;
150
+ } else if (isObject(node.size)) {
151
+ nodeSize = Math.max((node.size as any).width, (node.size as any).height);
152
+ }
153
+ maxNodeSize = Math.max(maxNodeSize, nodeSize);
154
+
155
+ if (isFunction(nodeSpacing)) {
156
+ maxNodeSpacing = Math.max(nodeSpacing(node), maxNodeSpacing);
157
+ }
158
+ });
159
+
160
+ self.clockwise =
161
+ self.counterclockwise !== undefined
162
+ ? !self.counterclockwise
163
+ : self.clockwise;
164
+
165
+ // layout
166
+ const nodeMap: NodeMap = {};
167
+ const indexMap: IndexMap = {};
168
+ layoutNodes.forEach((node, i) => {
169
+ nodeMap[node.id] = node;
170
+ indexMap[node.id] = i;
171
+ });
172
+
173
+ // get the node degrees
174
+ if (
175
+ self.sortBy === "degree" ||
176
+ !isString(self.sortBy) ||
177
+ (layoutNodes[0] as any)[self.sortBy] === undefined
178
+ ) {
179
+ self.sortBy = "degree";
180
+ if (!isNumber(nodes[0].degree)) {
181
+ const values = getDegree(nodes.length, indexMap, edges);
182
+ layoutNodes.forEach((node, i) => {
183
+ node.degree = values[i];
184
+ });
185
+ }
186
+ }
187
+ // sort nodes by value
188
+ layoutNodes.sort(
189
+ (n1: INode, n2: INode) =>
190
+ (n2 as any)[self.sortBy] - (n1 as any)[self.sortBy]
191
+ );
192
+
193
+ self.maxValueNode = layoutNodes[0];
194
+
195
+ self.maxLevelDiff =
196
+ self.maxLevelDiff || (self.maxValueNode as any)[self.sortBy] / 4;
197
+
198
+ // put the values into levels
199
+ const levels: any[] = [[]];
200
+ let currentLevel = levels[0];
201
+ layoutNodes.forEach((node) => {
202
+ if (currentLevel.length > 0) {
203
+ const diff = Math.abs(
204
+ currentLevel[0][self.sortBy] - (node as any)[self.sortBy]
205
+ );
206
+ if (self.maxLevelDiff && diff >= self.maxLevelDiff) {
207
+ currentLevel = [];
208
+ levels.push(currentLevel);
209
+ }
210
+ }
211
+ currentLevel.push(node);
212
+ });
213
+
214
+ // create positions for levels
215
+ let minDist = maxNodeSize + (maxNodeSpacing || self.minNodeSpacing); // min dist between nodes
216
+ if (!self.preventOverlap) {
217
+ // then strictly constrain to bb
218
+ const firstLvlHasMulti = levels.length > 0 && levels[0].length > 1;
219
+ const maxR = Math.min(self.width, self.height) / 2 - minDist;
220
+ const rStep = maxR / (levels.length + (firstLvlHasMulti ? 1 : 0));
221
+
222
+ minDist = Math.min(minDist, rStep);
223
+ }
224
+
225
+ // find the metrics for each level
226
+ let r = 0;
227
+ levels.forEach((level) => {
228
+ let sweep = self.sweep;
229
+ if (sweep === undefined) {
230
+ sweep = 2 * Math.PI - (2 * Math.PI) / level.length;
231
+ }
232
+ const dTheta = (level.dTheta = sweep / Math.max(1, level.length - 1));
233
+
234
+ // calculate the radius
235
+ if (level.length > 1 && self.preventOverlap) {
236
+ // but only if more than one node (can't overlap)
237
+ const dcos = Math.cos(dTheta) - Math.cos(0);
238
+ const dsin = Math.sin(dTheta) - Math.sin(0);
239
+ const rMin = Math.sqrt(
240
+ (minDist * minDist) / (dcos * dcos + dsin * dsin)
241
+ ); // s.t. no nodes overlapping
242
+
243
+ r = Math.max(rMin, r);
244
+ }
245
+ level.r = r;
246
+ r += minDist;
247
+ });
248
+
249
+ if (self.equidistant) {
250
+ let rDeltaMax = 0;
251
+ let rr = 0;
252
+ for (let i = 0; i < levels.length; i++) {
253
+ const level = levels[i];
254
+ const rDelta = level.r - rr;
255
+ rDeltaMax = Math.max(rDeltaMax, rDelta);
256
+ }
257
+ rr = 0;
258
+ levels.forEach((level, i) => {
259
+ if (i === 0) {
260
+ rr = level.r;
261
+ }
262
+ level.r = rr;
263
+ rr += rDeltaMax;
264
+ });
265
+ }
266
+
267
+ // calculate the node positions
268
+ levels.forEach((level) => {
269
+ const dTheta = level.dTheta;
270
+ const rr = level.r;
271
+ level.forEach((node: INode, j: number) => {
272
+ const theta = self.startAngle + (self.clockwise ? 1 : -1) * dTheta * j;
273
+ node.x = center[0] + rr * Math.cos(theta);
274
+ node.y = center[1] + rr * Math.sin(theta);
275
+ });
276
+ });
277
+
278
+ if (self.onLayoutEnd) self.onLayoutEnd();
279
+
280
+ return {
281
+ nodes,
282
+ edges
283
+ };
284
+ }
285
+
286
+ public getType() {
287
+ return "concentric";
288
+ }
289
+ }
@@ -0,0 +1,21 @@
1
+ /** layout message type */
2
+ export const LAYOUT_MESSAGE = {
3
+ // run layout
4
+ RUN: "LAYOUT_RUN",
5
+ // layout ended with success
6
+ END: "LAYOUT_END",
7
+ // layout error
8
+ ERROR: "LAYOUT_ERROR",
9
+ // layout tick, used in force directed layout
10
+ TICK: "LAYOUT_TICK",
11
+ GPURUN: "GPU_LAYOUT_RUN",
12
+ GPUEND: "GPU_LAYOUT_END"
13
+ };
14
+
15
+ export const FORCE_LAYOUT_TYPE_MAP: { [key: string]: boolean } = {
16
+ 'gForce': true,
17
+ 'fruchterman': true,
18
+ 'forceAtlas2': true,
19
+ 'force': true,
20
+ 'graphin-force': true,
21
+ };
@@ -0,0 +1,104 @@
1
+ import { Graph as RawGraph } from "@antv/graphlib";
2
+
3
+ export class Graph extends RawGraph<
4
+ string,
5
+ Node<Record<string, any>> & NodeConfig,
6
+ Partial<EdgeConfig & Edge & GraphEdge>,
7
+ Partial<GraphLabel>
8
+ > {}
9
+
10
+ export interface GraphLabel {
11
+ width?: number | undefined;
12
+ height?: number | undefined;
13
+ compound?: boolean | undefined;
14
+ rankdir?: string | undefined;
15
+ align?: string | undefined;
16
+ nodesep?: number | undefined;
17
+ edgesep?: number | undefined;
18
+ ranksep?: number | undefined;
19
+ marginx?: number | undefined;
20
+ marginy?: number | undefined;
21
+ acyclicer?: string | undefined;
22
+ ranker?: string | undefined;
23
+ maxRank?: number;
24
+ nestingRoot?: string;
25
+ nodeRankFactor?: number;
26
+ dummyChains?: string[];
27
+ root?: string;
28
+ }
29
+
30
+ export interface NodeConfig {
31
+ width?: number | undefined;
32
+ height?: number | undefined;
33
+ }
34
+
35
+ export interface EdgeConfig {
36
+ minlen?: number | undefined;
37
+ weight?: number | undefined;
38
+ width?: number | undefined;
39
+ height?: number | undefined;
40
+ lablepos?: "l" | "c" | "r" | undefined;
41
+ labeloffest?: number | undefined;
42
+ }
43
+
44
+ export interface CustomConfig {
45
+ edgeLabelSpace?: boolean | undefined;
46
+ keepNodeOrder?: boolean | undefined;
47
+ nodeOrder?: string[] | undefined;
48
+ prevGraph?: Graph | undefined;
49
+ }
50
+
51
+ export type layout = (
52
+ graph: Graph,
53
+ layout?: GraphLabel & NodeConfig & EdgeConfig & CustomConfig
54
+ ) => void;
55
+
56
+ export interface Edge {
57
+ v: string;
58
+ w: string;
59
+ name?: string | undefined;
60
+ label?: any;
61
+ e?: any;
62
+ }
63
+
64
+ export interface GraphEdge {
65
+ points: { x: number; y: number }[];
66
+ [key: string]: any;
67
+ }
68
+
69
+ export type Node<T = {}> = T & {
70
+ x?: number;
71
+ y?: number;
72
+ width?: number;
73
+ height?: number;
74
+ class?: string | undefined;
75
+ label?: any;
76
+ padding?: number | undefined;
77
+ paddingX?: number | undefined;
78
+ paddingY?: number | undefined;
79
+ rx?: number | undefined;
80
+ ry?: number | undefined;
81
+ shape?: string | undefined;
82
+ order?: number;
83
+ rank?: number;
84
+ in?: number;
85
+ out?: number;
86
+ fixorder?: number;
87
+ _order?: number;
88
+ _rank?: number;
89
+ dummy?: string;
90
+ selfEdges?: any;
91
+ borderTop?: any;
92
+ borderBottom?: any;
93
+ borderLeft?: any;
94
+ borderRight?: any;
95
+ minRank?: number;
96
+ maxRank?: number;
97
+ layer?: number;
98
+ edgeLabel?: any;
99
+ edgeObj?: Edge;
100
+ borderType?: string;
101
+ labelpos?: string;
102
+ parent?: string;
103
+ lim?: number;
104
+ };
@@ -0,0 +1,31 @@
1
+ /*
2
+ Copyright (c) 2012-2014 Chris Pettitt
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in
12
+ all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
21
+ */
22
+ import layout from './src/layout';
23
+ import { time, notime } from './src/util';
24
+
25
+ export default {
26
+ layout,
27
+ util: {
28
+ time,
29
+ notime
30
+ },
31
+ };
@@ -0,0 +1,58 @@
1
+ import { Edge, Graph } from "../graph";
2
+ import greedyFAS from "./greedy-fas";
3
+
4
+ const run = (g: Graph) => {
5
+ const weightFn = (g: Graph) => {
6
+ return (e: Edge) => g.edge(e)?.weight || 1;
7
+ };
8
+ const fas =
9
+ g.graph().acyclicer === "greedy" ? greedyFAS(g, weightFn(g)) : dfsFAS(g);
10
+ fas?.forEach((e: Edge) => {
11
+ const label = g.edge(e)!;
12
+ g.removeEdgeObj(e);
13
+ label.forwardName = e.name;
14
+ label.reversed = true;
15
+ g.setEdge(e.w, e.v, label, `rev-${Math.random()}`);
16
+ });
17
+ };
18
+
19
+ const dfsFAS = (g: Graph) => {
20
+ const fas: Edge[] = [];
21
+ const stack: Record<string, boolean> = {};
22
+ const visited: Record<string, boolean> = {};
23
+
24
+ const dfs = (v: string) => {
25
+ if (visited[v]) {
26
+ return;
27
+ }
28
+ visited[v] = true;
29
+ stack[v] = true;
30
+ g.outEdges(v)?.forEach((e) => {
31
+ if (stack[e.w]) {
32
+ fas.push(e);
33
+ } else {
34
+ dfs(e.w);
35
+ }
36
+ });
37
+ delete stack[v];
38
+ };
39
+
40
+ g.nodes().forEach(dfs);
41
+ return fas;
42
+ };
43
+
44
+ const undo = (g: Graph) => {
45
+ g.edges().forEach((e) => {
46
+ const label = g.edge(e)!;
47
+ if (label.reversed) {
48
+ g.removeEdgeObj(e);
49
+
50
+ const forwardName = label.forwardName;
51
+ delete label.reversed;
52
+ delete label.forwardName;
53
+ g.setEdge(e.w, e.v, label, forwardName);
54
+ }
55
+ });
56
+ };
57
+
58
+ export default { run, undo };
@@ -0,0 +1,47 @@
1
+ import { Graph, Node } from "../graph";
2
+ import { addDummyNode } from "./util";
3
+
4
+ const addBorderSegments = (g: Graph) => {
5
+ const dfs = (v: string) => {
6
+ const children = g.children(v);
7
+ const node = g.node(v)!;
8
+ if (children?.length) {
9
+ children.forEach((child) => dfs(child));
10
+ }
11
+
12
+ if (node.hasOwnProperty("minRank")) {
13
+ node.borderLeft = [];
14
+ node.borderRight = [];
15
+ for (
16
+ let rank = node.minRank!, maxRank = node.maxRank! + 1;
17
+ rank < maxRank;
18
+ rank += 1
19
+ ) {
20
+ addBorderNode(g, "borderLeft", "_bl", v, node, rank);
21
+ addBorderNode(g, "borderRight", "_br", v, node, rank);
22
+ }
23
+ }
24
+ };
25
+
26
+ g.children()?.forEach((child) => dfs(child));
27
+ };
28
+
29
+ const addBorderNode = (
30
+ g: Graph,
31
+ prop: string,
32
+ prefix: string,
33
+ sg: string,
34
+ sgNode: Node<Record<string, any>>,
35
+ rank: number
36
+ ) => {
37
+ const label = { rank, borderType: prop, width: 0, height: 0 };
38
+ const prev = sgNode[prop][rank - 1];
39
+ const curr = addDummyNode(g, "border", label, prefix);
40
+ sgNode[prop][rank] = curr;
41
+ g.setParent(curr, sg);
42
+ if (prev) {
43
+ g.setEdge(prev, curr, { weight: 1 });
44
+ }
45
+ };
46
+
47
+ export default addBorderSegments;
@@ -0,0 +1,77 @@
1
+ import { Graph } from "../graph";
2
+
3
+ const adjust = (g: Graph) => {
4
+ const rankDir = g.graph().rankdir?.toLowerCase();
5
+ if (rankDir === "lr" || rankDir === "rl") {
6
+ swapWidthHeight(g);
7
+ }
8
+ };
9
+
10
+ const undo = (g: Graph) => {
11
+ const rankDir = g.graph().rankdir?.toLowerCase();
12
+ if (rankDir === "bt" || rankDir === "rl") {
13
+ reverseY(g);
14
+ }
15
+
16
+ if (rankDir === "lr" || rankDir === "rl") {
17
+ swapXY(g);
18
+ swapWidthHeight(g);
19
+ }
20
+ };
21
+
22
+ const swapWidthHeight = (g: Graph) => {
23
+ g.nodes().forEach((v) => {
24
+ swapWidthHeightOne(g.node(v)!);
25
+ });
26
+ g.edges().forEach((e) => {
27
+ swapWidthHeightOne(g.edge(e)!);
28
+ });
29
+ };
30
+
31
+ const swapWidthHeightOne = (attrs: { width?: number; height?: number }) => {
32
+ const w = attrs.width;
33
+ attrs.width = attrs.height;
34
+ attrs.height = w;
35
+ };
36
+
37
+ const reverseY = (g: Graph) => {
38
+ g.nodes().forEach((v) => {
39
+ reverseYOne(g.node(v)!);
40
+ });
41
+
42
+ g.edges().forEach((e) => {
43
+ const edge = g.edge(e)!;
44
+ edge.points?.forEach((point) => reverseYOne(point));
45
+ if (edge.hasOwnProperty("y")) {
46
+ reverseYOne(edge as { y: number });
47
+ }
48
+ });
49
+ };
50
+
51
+ const reverseYOne = (attrs: { y?: number }) => {
52
+ if (attrs?.y) {
53
+ attrs.y = -attrs.y;
54
+ }
55
+ };
56
+
57
+ const swapXY = (g: Graph) => {
58
+ g.nodes().forEach((v) => {
59
+ swapXYOne(g.node(v));
60
+ });
61
+
62
+ g.edges().forEach((e) => {
63
+ const edge = g.edge(e)!;
64
+ edge.points?.forEach((point) => swapXYOne(point));
65
+ if (edge.hasOwnProperty("x")) {
66
+ swapXYOne(edge);
67
+ }
68
+ });
69
+ };
70
+
71
+ const swapXYOne = (attrs: any) => {
72
+ const x = attrs.x;
73
+ attrs.x = attrs.y;
74
+ attrs.y = x;
75
+ };
76
+
77
+ export default { adjust, undo };
@@ -0,0 +1,60 @@
1
+ const filterOutLinks = (k: string, v: string) => {
2
+ if (k !== "next" && k !== "prev") {
3
+ return v;
4
+ }
5
+ };
6
+
7
+ type LinkedNode<T> = {
8
+ prev?: LinkedNode<T>;
9
+ next?: LinkedNode<T>;
10
+ } & T;
11
+
12
+ const unlink = <T>(entry: LinkedNode<T>) => {
13
+ entry.prev!.next = entry.next;
14
+ entry.next!.prev = entry.prev;
15
+ delete entry.next;
16
+ delete entry.prev;
17
+ };
18
+
19
+ export default class List<T> {
20
+ // a shortcut that next is head and prev is tail
21
+ public shortcut: LinkedNode<T>;
22
+
23
+ constructor() {
24
+ const shortcut: LinkedNode<any> = {};
25
+ shortcut.prev = shortcut;
26
+ shortcut.next = shortcut.prev;
27
+ this.shortcut = shortcut;
28
+ }
29
+
30
+ public dequeue() {
31
+ const shortcut = this.shortcut;
32
+ const entry = shortcut.prev;
33
+ if (entry && entry !== shortcut) {
34
+ unlink(entry);
35
+ return entry;
36
+ }
37
+ }
38
+
39
+ public enqueue(entry: LinkedNode<T>) {
40
+ const shortcut = this.shortcut;
41
+ if (entry.prev && entry.next) {
42
+ unlink(entry);
43
+ }
44
+ entry.next = shortcut.next;
45
+ shortcut.next!.prev = entry;
46
+ shortcut.next = entry;
47
+ entry.prev = shortcut;
48
+ }
49
+
50
+ public toString() {
51
+ const strs = [];
52
+ const sentinel = this.shortcut;
53
+ let curr = sentinel.prev;
54
+ while (curr !== sentinel) {
55
+ strs.push(JSON.stringify(curr, filterOutLinks));
56
+ curr = curr?.prev;
57
+ }
58
+ return `[${strs.join(", ")}]`;
59
+ }
60
+ }