@deck.gl-community/graph-layers 9.2.0-beta.2 → 9.2.0-beta.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 (232) hide show
  1. package/dist/core/graph-engine.d.ts +63 -21
  2. package/dist/core/graph-engine.d.ts.map +1 -1
  3. package/dist/core/graph-engine.js +155 -75
  4. package/dist/core/graph-engine.js.map +1 -1
  5. package/dist/core/graph-layout.d.ts +22 -18
  6. package/dist/core/graph-layout.d.ts.map +1 -1
  7. package/dist/core/graph-layout.js +33 -18
  8. package/dist/core/graph-layout.js.map +1 -1
  9. package/dist/core/interaction-manager.d.ts +2 -2
  10. package/dist/core/interaction-manager.d.ts.map +1 -1
  11. package/dist/core/interaction-manager.js +7 -5
  12. package/dist/core/interaction-manager.js.map +1 -1
  13. package/dist/graph/arrow-graph.d.ts +69 -0
  14. package/dist/graph/arrow-graph.d.ts.map +1 -0
  15. package/dist/graph/arrow-graph.js +513 -0
  16. package/dist/graph/arrow-graph.js.map +1 -0
  17. package/dist/graph/classic-graph.d.ts +169 -0
  18. package/dist/graph/classic-graph.d.ts.map +1 -0
  19. package/dist/graph/classic-graph.js +390 -0
  20. package/dist/graph/classic-graph.js.map +1 -0
  21. package/dist/graph/edge.d.ts +6 -6
  22. package/dist/graph/edge.d.ts.map +1 -1
  23. package/dist/graph/edge.js.map +1 -1
  24. package/dist/graph/functions/arrow-utils.d.ts +6 -0
  25. package/dist/graph/functions/arrow-utils.d.ts.map +1 -0
  26. package/dist/graph/functions/arrow-utils.js +67 -0
  27. package/dist/graph/functions/arrow-utils.js.map +1 -0
  28. package/dist/graph/functions/create-graph-from-data.d.ts +3 -0
  29. package/dist/graph/functions/create-graph-from-data.d.ts.map +1 -0
  30. package/dist/graph/functions/create-graph-from-data.js +12 -0
  31. package/dist/graph/functions/create-graph-from-data.js.map +1 -0
  32. package/dist/graph/graph-normalization.d.ts +10 -0
  33. package/dist/graph/graph-normalization.d.ts.map +1 -0
  34. package/dist/graph/graph-normalization.js +65 -0
  35. package/dist/graph/graph-normalization.js.map +1 -0
  36. package/dist/graph/graph.d.ts +62 -155
  37. package/dist/graph/graph.d.ts.map +1 -1
  38. package/dist/graph/graph.js +11 -300
  39. package/dist/graph/graph.js.map +1 -1
  40. package/dist/graph/node.d.ts +6 -6
  41. package/dist/graph/node.d.ts.map +1 -1
  42. package/dist/graph/node.js +2 -2
  43. package/dist/graph/node.js.map +1 -1
  44. package/dist/graph-data/arrow-graph-data-builder.d.ts +21 -0
  45. package/dist/graph-data/arrow-graph-data-builder.d.ts.map +1 -0
  46. package/dist/graph-data/arrow-graph-data-builder.js +105 -0
  47. package/dist/graph-data/arrow-graph-data-builder.js.map +1 -0
  48. package/dist/graph-data/graph-data-builder.d.ts +6 -0
  49. package/dist/graph-data/graph-data-builder.d.ts.map +1 -0
  50. package/dist/graph-data/graph-data-builder.js +1 -0
  51. package/dist/graph-data/graph-data-builder.js.map +1 -0
  52. package/dist/graph-data/graph-data.d.ts +40 -0
  53. package/dist/graph-data/graph-data.d.ts.map +1 -0
  54. package/dist/graph-data/graph-data.js +11 -0
  55. package/dist/graph-data/graph-data.js.map +1 -0
  56. package/dist/graph-data/plain-graph-data-builder.d.ts +20 -0
  57. package/dist/graph-data/plain-graph-data-builder.d.ts.map +1 -0
  58. package/dist/graph-data/plain-graph-data-builder.js +105 -0
  59. package/dist/graph-data/plain-graph-data-builder.js.map +1 -0
  60. package/dist/graph-style-schema.cdn.js +1 -1
  61. package/dist/graph-style-schema.json +1 -1
  62. package/dist/index.cjs +6905 -4576
  63. package/dist/index.cjs.map +4 -4
  64. package/dist/index.d.ts +14 -7
  65. package/dist/index.d.ts.map +1 -1
  66. package/dist/index.js +24 -11
  67. package/dist/index.js.map +1 -1
  68. package/dist/layers/common-layers/flow-path-layer/flow-path-layer.d.ts.map +1 -1
  69. package/dist/layers/common-layers/flow-path-layer/flow-path-layer.js +1 -2
  70. package/dist/layers/common-layers/flow-path-layer/flow-path-layer.js.map +1 -1
  71. package/dist/layers/common-layers/grid-layer/grid-layer.d.ts +83 -0
  72. package/dist/layers/common-layers/grid-layer/grid-layer.d.ts.map +1 -0
  73. package/dist/layers/common-layers/grid-layer/grid-layer.js +133 -0
  74. package/dist/layers/common-layers/grid-layer/grid-layer.js.map +1 -0
  75. package/dist/layers/edge-attachment-helper.d.ts.map +1 -1
  76. package/dist/layers/edge-attachment-helper.js +1 -2
  77. package/dist/layers/edge-attachment-helper.js.map +1 -1
  78. package/dist/layers/graph-layer.d.ts +68 -11
  79. package/dist/layers/graph-layer.d.ts.map +1 -1
  80. package/dist/layers/graph-layer.js +435 -50
  81. package/dist/layers/graph-layer.js.map +1 -1
  82. package/dist/layouts/d3-dag/collapsable-d3-dag-layout.d.ts +24 -0
  83. package/dist/layouts/d3-dag/collapsable-d3-dag-layout.d.ts.map +1 -0
  84. package/dist/layouts/d3-dag/collapsable-d3-dag-layout.js +251 -0
  85. package/dist/layouts/d3-dag/collapsable-d3-dag-layout.js.map +1 -0
  86. package/dist/layouts/d3-dag/d3-dag-layout.d.ts +46 -61
  87. package/dist/layouts/d3-dag/d3-dag-layout.d.ts.map +1 -1
  88. package/dist/layouts/d3-dag/d3-dag-layout.js +85 -270
  89. package/dist/layouts/d3-dag/d3-dag-layout.js.map +1 -1
  90. package/dist/layouts/d3-force/d3-force-layout.d.ts +20 -8
  91. package/dist/layouts/d3-force/d3-force-layout.d.ts.map +1 -1
  92. package/dist/layouts/d3-force/d3-force-layout.js +39 -20
  93. package/dist/layouts/d3-force/d3-force-layout.js.map +1 -1
  94. package/dist/layouts/experimental/force-multi-graph-layout.d.ts +19 -15
  95. package/dist/layouts/experimental/force-multi-graph-layout.d.ts.map +1 -1
  96. package/dist/layouts/experimental/force-multi-graph-layout.js +47 -38
  97. package/dist/layouts/experimental/force-multi-graph-layout.js.map +1 -1
  98. package/dist/layouts/experimental/hive-plot-layout.d.ts +18 -15
  99. package/dist/layouts/experimental/hive-plot-layout.d.ts.map +1 -1
  100. package/dist/layouts/experimental/hive-plot-layout.js +33 -34
  101. package/dist/layouts/experimental/hive-plot-layout.js.map +1 -1
  102. package/dist/layouts/experimental/radial-layout.d.ts +12 -7
  103. package/dist/layouts/experimental/radial-layout.d.ts.map +1 -1
  104. package/dist/layouts/experimental/radial-layout.js +31 -14
  105. package/dist/layouts/experimental/radial-layout.js.map +1 -1
  106. package/dist/layouts/gpu-force/gpu-force-layout.d.ts +11 -8
  107. package/dist/layouts/gpu-force/gpu-force-layout.d.ts.map +1 -1
  108. package/dist/layouts/gpu-force/gpu-force-layout.js +59 -56
  109. package/dist/layouts/gpu-force/gpu-force-layout.js.map +1 -1
  110. package/dist/layouts/simple-layout.d.ts +8 -25
  111. package/dist/layouts/simple-layout.d.ts.map +1 -1
  112. package/dist/layouts/simple-layout.js +13 -17
  113. package/dist/layouts/simple-layout.js.map +1 -1
  114. package/dist/loaders/dot-graph-loader.d.ts +25 -0
  115. package/dist/loaders/dot-graph-loader.d.ts.map +1 -0
  116. package/dist/loaders/dot-graph-loader.js +668 -0
  117. package/dist/loaders/dot-graph-loader.js.map +1 -0
  118. package/dist/loaders/json-graph-loader.d.ts +6 -0
  119. package/dist/loaders/json-graph-loader.d.ts.map +1 -0
  120. package/dist/loaders/json-graph-loader.js +31 -0
  121. package/dist/loaders/json-graph-loader.js.map +1 -0
  122. package/dist/loaders/{edge-parsers.d.ts → parsers/edge-parsers.d.ts} +1 -1
  123. package/dist/loaders/parsers/edge-parsers.d.ts.map +1 -0
  124. package/dist/loaders/{edge-parsers.js → parsers/edge-parsers.js} +1 -1
  125. package/dist/loaders/parsers/edge-parsers.js.map +1 -0
  126. package/dist/loaders/{node-parsers.d.ts → parsers/node-parsers.d.ts} +1 -1
  127. package/dist/loaders/parsers/node-parsers.d.ts.map +1 -0
  128. package/dist/loaders/{node-parsers.js → parsers/node-parsers.js} +1 -1
  129. package/dist/loaders/parsers/node-parsers.js.map +1 -0
  130. package/dist/loaders/parsers/parse-json-graph.d.ts +29 -0
  131. package/dist/loaders/parsers/parse-json-graph.d.ts.map +1 -0
  132. package/dist/loaders/parsers/parse-json-graph.js +78 -0
  133. package/dist/loaders/parsers/parse-json-graph.js.map +1 -0
  134. package/dist/style/graph-style-engine.d.ts +4 -2
  135. package/dist/style/graph-style-engine.d.ts.map +1 -1
  136. package/dist/style/graph-style-engine.js +3 -2
  137. package/dist/style/graph-style-engine.js.map +1 -1
  138. package/dist/style/{style-engine.d.ts → stylesheet-engine.d.ts} +3 -3
  139. package/dist/style/stylesheet-engine.d.ts.map +1 -0
  140. package/dist/style/{style-engine.js → stylesheet-engine.js} +1 -1
  141. package/dist/style/stylesheet-engine.js.map +1 -0
  142. package/dist/utils/collapsed-chains.d.ts +8 -8
  143. package/dist/utils/collapsed-chains.d.ts.map +1 -1
  144. package/dist/utils/collapsed-chains.js +1 -6
  145. package/dist/utils/collapsed-chains.js.map +1 -1
  146. package/dist/utils/rank-grid.d.ts +30 -0
  147. package/dist/utils/rank-grid.d.ts.map +1 -0
  148. package/dist/utils/rank-grid.js +306 -0
  149. package/dist/utils/rank-grid.js.map +1 -0
  150. package/package.json +4 -8
  151. package/src/_disabled/arrow-graph-data.ts.disabled +18 -0
  152. package/src/_disabled/columnar-graph-data-builder.ts.disabled +250 -0
  153. package/src/_disabled/graph-runtime-layout.ts.disabled +29 -0
  154. package/src/core/graph-engine.ts +201 -84
  155. package/src/core/graph-layout.ts +52 -29
  156. package/src/core/interaction-manager.ts +20 -20
  157. package/src/graph/arrow-graph.ts +648 -0
  158. package/src/graph/classic-graph.ts +447 -0
  159. package/src/graph/edge.ts +7 -7
  160. package/src/graph/functions/arrow-utils.ts +72 -0
  161. package/src/graph/functions/convert-arrow-graph-to-classic-graph.ts.disabled +47 -0
  162. package/src/graph/functions/convert-plain-graph-to-arrow-graph.ts.disabled +119 -0
  163. package/src/graph/functions/create-graph-from-data.ts +16 -0
  164. package/src/graph/functions/create-plain-graph-from-data.ts.disabled +176 -0
  165. package/src/graph/graph-normalization.ts +87 -0
  166. package/src/graph/graph.ts +68 -339
  167. package/src/graph/node.ts +9 -9
  168. package/src/graph/tabular-graph.ts.disabled +761 -0
  169. package/src/graph-data/arrow-graph-data-builder.ts +165 -0
  170. package/src/graph-data/graph-data-builder.ts +7 -0
  171. package/src/graph-data/graph-data.ts +57 -0
  172. package/src/graph-data/plain-graph-data-builder.ts +132 -0
  173. package/src/index.ts +53 -13
  174. package/src/layers/common-layers/flow-path-layer/flow-path-layer.ts +1 -2
  175. package/src/layers/common-layers/grid-layer/grid-layer.ts +237 -0
  176. package/src/layers/edge-attachment-helper.ts +22 -16
  177. package/src/layers/graph-layer.ts +642 -62
  178. package/src/layouts/d3-dag/collapsable-d3-dag-layout.ts +330 -0
  179. package/src/layouts/d3-dag/d3-dag-layout.ts +166 -396
  180. package/src/layouts/d3-force/d3-force-layout.ts +52 -30
  181. package/src/layouts/experimental/force-multi-graph-layout.ts +55 -49
  182. package/src/layouts/experimental/hive-plot-layout.ts +41 -42
  183. package/src/layouts/experimental/radial-layout.ts +39 -20
  184. package/src/layouts/gpu-force/gpu-force-layout.ts +72 -70
  185. package/src/layouts/simple-layout.ts +20 -44
  186. package/src/loaders/{create-graph.ts → deprecated/create-graph.ts.disabled} +6 -6
  187. package/src/loaders/deprecated/json-classic-graph-loader.ts.disabled +33 -0
  188. package/src/loaders/{simple-json-graph-loader.ts → deprecated/simple-json-graph-loader.ts.disabled} +3 -3
  189. package/src/loaders/{table-graph-loader.ts → deprecated/table-graph-loader.ts.disabled} +8 -8
  190. package/src/loaders/dot-graph-loader.ts +860 -0
  191. package/src/loaders/json-graph-loader.ts +48 -0
  192. package/src/loaders/parsers/create-graph-data.ts.disabled +45 -0
  193. package/src/loaders/{edge-parsers.ts → parsers/edge-parsers.ts} +2 -2
  194. package/src/loaders/{node-parsers.ts → parsers/node-parsers.ts} +2 -2
  195. package/src/loaders/parsers/parse-json-graph.ts +134 -0
  196. package/src/style/graph-style-engine.ts +5 -2
  197. package/src/style/{style-engine.ts → stylesheet-engine.ts} +3 -3
  198. package/src/utils/collapsed-chains.ts +11 -17
  199. package/src/utils/rank-grid.ts +426 -0
  200. package/dist/loaders/create-graph.d.ts +0 -12
  201. package/dist/loaders/create-graph.d.ts.map +0 -1
  202. package/dist/loaders/create-graph.js +0 -38
  203. package/dist/loaders/create-graph.js.map +0 -1
  204. package/dist/loaders/edge-parsers.d.ts.map +0 -1
  205. package/dist/loaders/edge-parsers.js.map +0 -1
  206. package/dist/loaders/json-loader.d.ts +0 -7
  207. package/dist/loaders/json-loader.d.ts.map +0 -1
  208. package/dist/loaders/json-loader.js +0 -16
  209. package/dist/loaders/json-loader.js.map +0 -1
  210. package/dist/loaders/node-parsers.d.ts.map +0 -1
  211. package/dist/loaders/node-parsers.js.map +0 -1
  212. package/dist/loaders/simple-json-graph-loader.d.ts +0 -11
  213. package/dist/loaders/simple-json-graph-loader.d.ts.map +0 -1
  214. package/dist/loaders/simple-json-graph-loader.js +0 -20
  215. package/dist/loaders/simple-json-graph-loader.js.map +0 -1
  216. package/dist/loaders/table-graph-loader.d.ts +0 -16
  217. package/dist/loaders/table-graph-loader.d.ts.map +0 -1
  218. package/dist/loaders/table-graph-loader.js +0 -91
  219. package/dist/loaders/table-graph-loader.js.map +0 -1
  220. package/dist/style/style-engine.d.ts.map +0 -1
  221. package/dist/style/style-engine.js.map +0 -1
  222. package/dist/widgets/long-press-button.d.ts +0 -12
  223. package/dist/widgets/long-press-button.d.ts.map +0 -1
  224. package/dist/widgets/long-press-button.js +0 -31
  225. package/dist/widgets/long-press-button.js.map +0 -1
  226. package/dist/widgets/view-control-widget.d.ts +0 -77
  227. package/dist/widgets/view-control-widget.d.ts.map +0 -1
  228. package/dist/widgets/view-control-widget.js +0 -197
  229. package/dist/widgets/view-control-widget.js.map +0 -1
  230. package/src/loaders/json-loader.ts +0 -19
  231. package/src/widgets/long-press-button.tsx +0 -50
  232. package/src/widgets/view-control-widget.tsx +0 -339
@@ -0,0 +1,447 @@
1
+ // deck.gl-community
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import {warn} from '../utils/log';
6
+ import {Cache} from '../core/cache';
7
+ import {Edge} from './edge';
8
+ import {Node} from './node';
9
+ import type {EdgeInterface, NodeInterface, GraphProps} from './graph';
10
+ import {Graph} from './graph';
11
+ import type {PlainGraphData, GraphNodeData, GraphEdgeData} from '../graph-data/graph-data';
12
+ import {cloneRecord, normalizeEdgeState, normalizeNodeState, normalizeVersion} from './graph-normalization';
13
+
14
+ export type ClassicGraphProps = GraphProps & {
15
+ data: PlainGraphData;
16
+ };
17
+
18
+ /** Basic graph data structure */
19
+ export class ClassicGraph extends Graph {
20
+ /** List object of nodes. */
21
+ private _nodeMap: Record<string, Node> = {};
22
+ /** List of object edges. */
23
+ private _edgeMap: Record<string, Edge> = {};
24
+
25
+ /**
26
+ * Identifies whether performing dirty check when streaming new data. If
27
+ * the name of the graph is not specified, will fall back to current time stamp.
28
+ */
29
+ private _name: string = Date.now().toString();
30
+ /** Version the graph. A version is a number that is incremented every time the graph is updated. */
31
+ public version = 0;
32
+ /** Cached data: create array data from maps. */
33
+ private _cache = new Cache<'nodes' | 'edges', Node[] | Edge[]>();
34
+ private _suspendVersionUpdates = false;
35
+
36
+ /**
37
+ * The constructor of the graph class.
38
+ * @param props -
39
+ */
40
+ constructor(props: ClassicGraphProps) {
41
+ super(props);
42
+
43
+ const data = props.data;
44
+ const nodes = createNodesFromPlainGraphData(data?.nodes);
45
+ const edges = createEdgesFromPlainGraphData(data?.edges);
46
+
47
+ this._name = `unnamed-graph-${Date.now().toString()}`;
48
+ this._suspendVersionUpdates = true;
49
+ this.version = normalizeVersion(data?.version);
50
+ try {
51
+ this.batchAddNodes(nodes);
52
+ this.batchAddEdges(edges);
53
+ } finally {
54
+ this._suspendVersionUpdates = false;
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Set graph name
60
+ * @param name
61
+ */
62
+ setGraphName(name: string): void {
63
+ this._name = name;
64
+ }
65
+
66
+ /** Get the name of the graph. Default value is the time stamp when creating this graph.
67
+ * @return graph name.
68
+ */
69
+ getGraphName(): string {
70
+ return this._name.toString();
71
+ }
72
+
73
+ /**
74
+ * Perform a batch of operations defined by cb before indicating graph is updated
75
+ * @param {function} cb - a callback function containing the operations to perform
76
+ */
77
+ transaction<T>(cb: (...args: unknown[]) => T): T {
78
+ try {
79
+ this.props.onTransactionStart?.();
80
+ return cb();
81
+ } finally {
82
+ this.props.onTransactionEnd?.();
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Add a new node to the graph.
88
+ * @paramnode - expect a Node object to be added to the graph.
89
+ */
90
+ addNode(node: Node): void {
91
+ // add it to the list and map
92
+ this._nodeMap[node.getId()] = node;
93
+ // update last update time stamp
94
+ this._bumpVersion();
95
+ this.props.onNodeAdded?.(node);
96
+ }
97
+
98
+ /**
99
+ * Batch add nodes to the graph.
100
+ * @param nodes - a list of nodes to be added.
101
+ */
102
+ batchAddNodes(nodes: Node[]): void {
103
+ // convert an array of objects to an object
104
+ this._nodeMap = nodes.reduce(
105
+ (res, node) => {
106
+ res[node.getId()] = node;
107
+ this.props.onNodeAdded?.(node);
108
+ return res;
109
+ },
110
+ {...this._nodeMap}
111
+ );
112
+ this._bumpVersion();
113
+ }
114
+
115
+ /**
116
+ * Get all the nodes of the graph.
117
+ * @return {Node[]} - get all the nodes in the graph.
118
+ */
119
+ getNodes(): NodeInterface[] {
120
+ this._updateCache('nodes', () => Object.values(this._nodeMap));
121
+
122
+ return (this._cache.get('nodes') as Node[]) ?? [];
123
+ }
124
+
125
+ /**
126
+ * Get the node map of the graph. The key of the map is the ID of the nodes.
127
+ * @return - a map of nodes keyed by node IDs.
128
+ */
129
+ getNodeMap(): Record<string | number, Node> {
130
+ return this._nodeMap;
131
+ }
132
+
133
+ /**
134
+ * Find a node by id
135
+ * @param nodeId The id of the node
136
+ * @return Node
137
+ */
138
+ findNode(nodeId: string | number): Node | undefined {
139
+ return this._nodeMap[nodeId];
140
+ }
141
+
142
+ findNodeById(nodeId: string | number): NodeInterface | undefined {
143
+ return this.findNode(nodeId);
144
+ }
145
+
146
+ /**
147
+ * Update the indicated node to the provided value
148
+ * @param node
149
+ */
150
+ updateNode(node: Node): void {
151
+ this._nodeMap[node.getId()] = node;
152
+ this._bumpVersion();
153
+ this.props.onNodeUpdated?.(node);
154
+ }
155
+
156
+ /**
157
+ * Add a new edge to the graph.
158
+ * @param edge - expect a Edge object to be added to the graph.
159
+ */
160
+ addEdge(edge: Edge): void {
161
+ const sourceNode = this.findNode(edge.getSourceNodeId());
162
+ const targetNode = this.findNode(edge.getTargetNodeId());
163
+
164
+ if (!sourceNode || !targetNode) {
165
+ warn(`Unable to add edge ${edge.id}, source or target node is missing.`);
166
+ return;
167
+ }
168
+
169
+ this._edgeMap[edge.getId()] = edge;
170
+ sourceNode.addConnectedEdges(edge);
171
+ targetNode.addConnectedEdges(edge);
172
+ this._bumpVersion();
173
+ this.props.onEdgeAdded?.(edge);
174
+ }
175
+
176
+ /**
177
+ * Batch add edges to the graph
178
+ * @param edges - a list of edges to be added.
179
+ */
180
+ batchAddEdges(edges: Edge[]): void {
181
+ edges.forEach((edge) => this.addEdge(edge));
182
+ this._bumpVersion();
183
+ }
184
+
185
+ /**
186
+ * Update the indicated edge to the provided value
187
+ * @param edge
188
+ */
189
+ updateEdge(edge: Edge): void {
190
+ this._edgeMap[edge.getId()] = edge;
191
+ this._bumpVersion();
192
+ this.props.onEdgeUpdated?.(edge);
193
+ }
194
+
195
+ /**
196
+ * Remove a node from the graph by node ID
197
+ * @param nodeId - the ID of the target node.
198
+ */
199
+ removeNode(nodeId: string | number): void {
200
+ const node = this.findNode(nodeId);
201
+ if (!node) {
202
+ warn(`Unable to remove node ${nodeId} - doesn't exist`);
203
+ return;
204
+ }
205
+ // remove all edges connect to this node from map
206
+ node.getConnectedEdges().forEach((e) => {
207
+ delete this._edgeMap[e.getId()];
208
+ });
209
+ // remove the node from map
210
+ delete this._nodeMap[nodeId];
211
+ this._bumpVersion();
212
+ this.props.onNodeRemoved?.(node);
213
+ }
214
+
215
+ /**
216
+ * Get all the edges of the graph.
217
+ * @return get all the edges in the graph.
218
+ */
219
+ getEdges(): EdgeInterface[] {
220
+ this._updateCache('edges', () => Object.values(this._edgeMap));
221
+
222
+ return (this._cache.get('edges') as Edge[]) ?? [];
223
+ }
224
+
225
+ destroy(): void {
226
+ // No additional teardown required for the legacy graph implementation.
227
+ }
228
+
229
+ /**
230
+ * Get the edge map of the graph. The key of the map is the ID of the edges.
231
+ * @return - a map of edges keyed by edge IDs.
232
+ */
233
+ getEdgeMap(): Record<string, Edge> {
234
+ return this._edgeMap;
235
+ }
236
+
237
+ /**
238
+ * Remove an edge from the graph by the edge ID
239
+ * @param {String|Number} edgeId - the target edge ID.
240
+ */
241
+ removeEdge(edgeId: string | number): void {
242
+ const edge = this.findEdge(edgeId);
243
+ if (!edge) {
244
+ warn(`Unable to remove edge ${edgeId} - doesn't exist`);
245
+ return;
246
+ }
247
+ const sourceNode = this.findNode(edge.getSourceNodeId());
248
+ const targetNode = this.findNode(edge.getTargetNodeId());
249
+
250
+ delete this._edgeMap[edgeId];
251
+ sourceNode.removeConnectedEdges(edge);
252
+ targetNode.removeConnectedEdges(edge);
253
+ this._bumpVersion();
254
+ this.props.onEdgeRemoved?.(edge);
255
+ }
256
+
257
+ /**
258
+ * Find the edge by edge ID.
259
+ * @param id - the target edge ID
260
+ * @return - the target edge.
261
+ */
262
+ findEdge(edgeId: string | number): Edge {
263
+ return this._edgeMap[edgeId];
264
+ }
265
+
266
+ /**
267
+ * Return all the connected edges of a node by nodeID.
268
+ * @param nodeId - the target node ID
269
+ * @return - an array of the connected edges.
270
+ */
271
+ getConnectedEdges(nodeId: string | number): EdgeInterface[] {
272
+ const node = this.findNode(nodeId);
273
+ if (!node) {
274
+ warn(`Unable to find node ${nodeId} - doesn't exist`);
275
+ return [];
276
+ }
277
+ return node.getConnectedEdges();
278
+ }
279
+
280
+ /**
281
+ * Return all the sibling nodes of a node by nodeID.
282
+ * @param nodeId - the target node ID
283
+ * @return - an array of the sibling nodes.
284
+ */
285
+ getNodeSiblings(nodeId: string | number): Node[] {
286
+ const node = this.findNode(nodeId);
287
+ if (!node) {
288
+ warn(`Unable to find node ${nodeId} - doesn't exist`);
289
+ return [];
290
+ }
291
+ return node.getSiblingIds().map((siblingNodeId) => this.findNode(siblingNodeId));
292
+ }
293
+
294
+ /**
295
+ * Get the degree of a node.
296
+ * @param nodeId - the target node ID.
297
+ * @return - the degree of the node.
298
+ */
299
+ getDegree(nodeId: string | number): number {
300
+ const node = this.findNode(nodeId);
301
+ if (!node) {
302
+ warn(`Unable to find node ${nodeId} - doesn't exist`);
303
+ return 0;
304
+ }
305
+ return node.getDegree();
306
+ }
307
+
308
+ /**
309
+ * Clean up all the nodes in the graph.
310
+ */
311
+ resetNodes(): void {
312
+ this._nodeMap = {};
313
+ this._bumpVersion();
314
+ }
315
+
316
+ /**
317
+ * Clean up all the edges in the graph.
318
+ */
319
+ resetEdges(): void {
320
+ this._edgeMap = {};
321
+ this._bumpVersion();
322
+ }
323
+
324
+ /**
325
+ * Clean up everything in the graph.
326
+ */
327
+ reset(): void {
328
+ this.resetNodes();
329
+ this.resetEdges();
330
+ this._bumpVersion();
331
+ }
332
+
333
+ /**
334
+ * @deprecated Prefer interacting with this instance directly.
335
+ */
336
+ getClassicGraph(): ClassicGraph {
337
+ return this;
338
+ }
339
+
340
+ /**
341
+ * Trigger an update to the graph.
342
+ */
343
+ triggerUpdate(): void {
344
+ this._bumpVersion();
345
+ }
346
+
347
+ /**
348
+ * Return true if the graph is empty.
349
+ * @return {Boolean} Return true if the graph is empty.
350
+ */
351
+ isEmpty(): boolean {
352
+ return Object.keys(this._nodeMap).length === 0;
353
+ }
354
+
355
+ /**
356
+ * Check the equality of two graphs data by checking last update time stamp
357
+ * @param graph Another graph to be compared against itself
358
+ * @return true if the graph is the same as itself.
359
+ */
360
+ equals(graph: ClassicGraph): boolean {
361
+ if (!graph || !(graph instanceof ClassicGraph)) {
362
+ return false;
363
+ }
364
+ return this.version === graph.version;
365
+ }
366
+
367
+ _bumpVersion(): void {
368
+ if (this._suspendVersionUpdates) {
369
+ return;
370
+ }
371
+ this.version += 1;
372
+ }
373
+
374
+ _updateCache(key: 'nodes' | 'edges', updateValue: unknown): void {
375
+ this._cache.set(key, updateValue as any, this.version);
376
+ }
377
+ }
378
+
379
+ function createNodesFromPlainGraphData(nodes?: GraphNodeData[] | null): Node[] {
380
+ if (!nodes) {
381
+ return [];
382
+ }
383
+ return nodes.map((nodeData) => {
384
+ const nodeAttributes = createNodeAttributesFromPlainData(nodeData);
385
+ const selectable =
386
+ typeof nodeData.selectable === 'boolean'
387
+ ? nodeData.selectable
388
+ : Boolean(nodeAttributes.selectable);
389
+ const highlightConnectedEdges =
390
+ typeof nodeData.highlightConnectedEdges === 'boolean'
391
+ ? nodeData.highlightConnectedEdges
392
+ : Boolean(nodeAttributes.highlightConnectedEdges);
393
+
394
+ const node = new Node({
395
+ id: nodeData.id,
396
+ selectable,
397
+ highlightConnectedEdges,
398
+ data: nodeAttributes
399
+ });
400
+ node.setState(normalizeNodeState(nodeData.state));
401
+ return node;
402
+ });
403
+ }
404
+
405
+ function createEdgesFromPlainGraphData(edges?: GraphEdgeData[] | null): Edge[] {
406
+ if (!edges) {
407
+ return [];
408
+ }
409
+ return edges.map((edgeData) => {
410
+ const edgeAttributes = createEdgeAttributesFromPlainData(edgeData);
411
+ const directed =
412
+ typeof edgeData.directed === 'boolean'
413
+ ? edgeData.directed
414
+ : Boolean(edgeAttributes.directed);
415
+ const edge = new Edge({
416
+ id: edgeData.id,
417
+ sourceId: edgeData.sourceId,
418
+ targetId: edgeData.targetId,
419
+ directed,
420
+ data: edgeAttributes
421
+ });
422
+ edge.setState(normalizeEdgeState(edgeData.state));
423
+ return edge;
424
+ });
425
+ }
426
+
427
+ function createNodeAttributesFromPlainData(node: GraphNodeData): Record<string, unknown> {
428
+ const attributes = cloneRecord(node.attributes);
429
+ if (typeof node.label !== 'undefined') {
430
+ attributes.label = node.label;
431
+ }
432
+ if (typeof node.weight !== 'undefined') {
433
+ attributes.weight = node.weight;
434
+ }
435
+ return attributes;
436
+ }
437
+
438
+ function createEdgeAttributesFromPlainData(edge: GraphEdgeData): Record<string, unknown> {
439
+ const attributes = cloneRecord(edge.attributes);
440
+ if (typeof edge.label !== 'undefined') {
441
+ attributes.label = edge.label;
442
+ }
443
+ if (typeof edge.weight !== 'undefined') {
444
+ attributes.weight = edge.weight;
445
+ }
446
+ return attributes;
447
+ }
package/src/graph/edge.ts CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  // Basic data structure of an edge
6
6
  import type {EdgeState} from '../core/constants';
7
- import {Node} from './node';
7
+ import type {EdgeInterface, NodeInterface} from './graph';
8
8
 
9
9
  export interface EdgeOptions {
10
10
  /** the unique ID of the edge */
@@ -20,9 +20,9 @@ export interface EdgeOptions {
20
20
  }
21
21
 
22
22
  /** Basic edge data structure */
23
- export class Edge {
23
+ export class Edge implements EdgeInterface {
24
24
  /** Unique uuid of the edge. */
25
- public id: string | number;
25
+ public readonly id: string | number;
26
26
  /** ID of the source node. */
27
27
  private _sourceId: string | number;
28
28
  /** ID of the target node. */
@@ -34,7 +34,7 @@ export class Edge {
34
34
  /** Check the type of the object when picking engine gets it. */
35
35
  public readonly isEdge = true;
36
36
  /** Nodes at either end of this edge. */
37
- private readonly _connectedNodes: Record<string, Node> = {};
37
+ private readonly _connectedNodes: Record<string, NodeInterface> = {};
38
38
  /** Edge state. */
39
39
  public state: EdgeState = 'default';
40
40
 
@@ -133,15 +133,15 @@ export class Edge {
133
133
  return this.state;
134
134
  }
135
135
 
136
- addNode(node: Node): void {
136
+ addNode(node: NodeInterface): void {
137
137
  this._connectedNodes[node.getId()] = node;
138
138
  }
139
139
 
140
- removeNode(node: Node): void {
140
+ removeNode(node: NodeInterface): void {
141
141
  delete this._connectedNodes[node.getId()];
142
142
  }
143
143
 
144
- getConnectedNodes(): Node[] {
144
+ getConnectedNodes(): NodeInterface[] {
145
145
  return Object.values(this._connectedNodes);
146
146
  }
147
147
  }
@@ -0,0 +1,72 @@
1
+ // deck.gl-community
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import * as arrow from 'apache-arrow';
6
+
7
+ export function getVectorLength(vector: arrow.Vector | null): number {
8
+ return vector?.length ?? 0;
9
+ }
10
+
11
+ export function getVectorValue(vector: arrow.Vector | null, index: number): unknown {
12
+ return vector ? vector.get?.(index) ?? vector.toArray?.()[index] : undefined;
13
+ }
14
+
15
+ export function getColumnVector(table: arrow.Table, columnName: string): arrow.Vector | null {
16
+ const candidate = (table as arrow.Table & {getColumn?: (name: string) => arrow.Vector | null}).getColumn?.(columnName);
17
+ if (candidate) {
18
+ return candidate;
19
+ }
20
+ const childAccessor = (table as arrow.Table & {getChild?: (name: string) => arrow.Vector | null}).getChild;
21
+ if (typeof childAccessor === 'function') {
22
+ const vector = childAccessor.call(table, columnName);
23
+ if (vector) {
24
+ return vector;
25
+ }
26
+ }
27
+ const getChildAt = (table as arrow.Table & {getChildAt?: (index: number) => arrow.Vector | null}).getChildAt;
28
+ const schema = (table as arrow.Table & {schema?: {fields?: Array<{name: string}>}}).schema;
29
+ if (schema && Array.isArray(schema.fields) && typeof getChildAt === 'function') {
30
+ const index = schema.fields.findIndex((field) => field?.name === columnName);
31
+ if (index >= 0) {
32
+ return getChildAt.call(table, index) ?? null;
33
+ }
34
+ }
35
+ return null;
36
+ }
37
+
38
+ export function parseDataRecord(value: unknown): Record<string, unknown> {
39
+ if (typeof value === 'string') {
40
+ try {
41
+ const parsed = JSON.parse(value);
42
+ if (parsed && typeof parsed === 'object') {
43
+ return {...(parsed as Record<string, unknown>)};
44
+ }
45
+ } catch {
46
+ return {};
47
+ }
48
+ } else if (value && typeof value === 'object') {
49
+ return {...(value as Record<string, unknown>)};
50
+ }
51
+ return {};
52
+ }
53
+
54
+ export function coerceIdentifier(value: unknown): string | number {
55
+ if (typeof value === 'number') {
56
+ return value;
57
+ }
58
+ if (typeof value === 'string') {
59
+ const trimmed = value.trim();
60
+ if (trimmed !== '') {
61
+ const numeric = Number(trimmed);
62
+ if (!Number.isNaN(numeric) && String(numeric) === trimmed) {
63
+ return numeric;
64
+ }
65
+ }
66
+ return value;
67
+ }
68
+ if (value === null || typeof value === 'undefined') {
69
+ throw new Error('Arrow graph encountered an undefined identifier.');
70
+ }
71
+ return String(value);
72
+ }
@@ -0,0 +1,47 @@
1
+ import {ArrowGraph} from '../arrow-graph';
2
+ import {ClassicGraph} from '../classic-graph';
3
+ import {Node} from '../node';
4
+ import {Edge} from '../edge';
5
+
6
+ import {getVectorLength} from './arrow-utils'
7
+
8
+ export function convertArrowGraphToClassicGraph(graph: ArrowGraph): ClassicGraph {
9
+ // @ts-expect-error Accessing protected member
10
+ const nodeCount = getVectorLength(graph.nodeVectors.id);
11
+ // @ts-expect-error Accessing protected member
12
+ const edgeCount = getVectorLength(graph.edgeVectors.id);
13
+
14
+ const legacyNodes: Node[] = [];
15
+ for (let index = 0; index < nodeCount; index++) {
16
+ const node = new Node({
17
+ id: graph.getNodeIdByIndex(index),
18
+ selectable: graph.isNodeSelectableByIndex(index),
19
+ highlightConnectedEdges: graph.shouldHighlightConnectedEdgesByIndex(index),
20
+ data: graph.getNodeDataByIndex(index)
21
+ });
22
+ node.setState(graph.getNodeStateByIndex(index));
23
+ legacyNodes.push(node);
24
+ }
25
+
26
+ const legacyEdges: Edge[] = [];
27
+ for (let index = 0; index < edgeCount; index++) {
28
+ const edge = new Edge({
29
+ id: graph.getEdgeIdByIndex(index),
30
+ sourceId: graph.getEdgeSourceIdByIndex(index),
31
+ targetId: graph.getEdgeTargetIdByIndex(index),
32
+ directed: graph.isEdgeDirectedByIndex(index),
33
+ data: graph.getEdgeDataByIndex(index)
34
+ });
35
+ edge.setState(graph.getEdgeStateByIndex(index));
36
+ legacyEdges.push(edge);
37
+ }
38
+
39
+ const classicGraph = new ClassicGraph(graph.props);
40
+ if (legacyNodes.length > 0) {
41
+ classicGraph.batchAddNodes(legacyNodes);
42
+ }
43
+ if (legacyEdges.length > 0) {
44
+ classicGraph.batchAddEdges(legacyEdges);
45
+ }
46
+ return classicGraph;
47
+ }