@deck.gl-community/graph-layers 9.0.2 → 9.1.0-beta.2

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 (118) hide show
  1. package/LICENSE +1 -1
  2. package/dist/core/graph-engine.d.ts +16 -7
  3. package/dist/core/graph-engine.d.ts.map +1 -1
  4. package/dist/core/graph-engine.js +13 -4
  5. package/dist/core/graph-layout.d.ts +69 -0
  6. package/dist/core/graph-layout.d.ts.map +1 -0
  7. package/dist/core/{base-layout.js → graph-layout.js} +63 -80
  8. package/dist/core/interaction-manager.d.ts +1 -1
  9. package/dist/core/interaction-manager.d.ts.map +1 -1
  10. package/dist/{core → graph}/edge.d.ts +18 -17
  11. package/dist/graph/edge.d.ts.map +1 -0
  12. package/dist/{core → graph}/edge.js +12 -15
  13. package/dist/{core → graph}/graph.d.ts +34 -31
  14. package/dist/graph/graph.d.ts.map +1 -0
  15. package/dist/{core → graph}/graph.js +43 -36
  16. package/dist/{core → graph}/node.d.ts +20 -20
  17. package/dist/graph/node.d.ts.map +1 -0
  18. package/dist/{core → graph}/node.js +16 -18
  19. package/dist/index.cjs +1181 -434
  20. package/dist/index.cjs.map +4 -4
  21. package/dist/index.d.ts +16 -14
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +19 -18
  24. package/dist/layers/graph-layer.d.ts +45 -5
  25. package/dist/layers/graph-layer.d.ts.map +1 -1
  26. package/dist/layers/graph-layer.js +80 -38
  27. package/dist/layers/node-layers/{path-rounded-rectange-layer.d.ts → path-rounded-rectangle-layer.d.ts} +1 -1
  28. package/dist/layers/node-layers/path-rounded-rectangle-layer.d.ts.map +1 -0
  29. package/dist/layers/node-layers/rounded-rectangle-layer-fragment.d.ts +1 -1
  30. package/dist/layers/node-layers/rounded-rectangle-layer-fragment.d.ts.map +1 -1
  31. package/dist/layers/node-layers/rounded-rectangle-layer-fragment.js +1 -3
  32. package/dist/layers/node-layers/rounded-rectangle-layer.d.ts +12 -3
  33. package/dist/layers/node-layers/rounded-rectangle-layer.d.ts.map +1 -1
  34. package/dist/layers/node-layers/rounded-rectangle-layer.js +25 -11
  35. package/dist/layouts/d3-force/d3-force-layout.d.ts +12 -3
  36. package/dist/layouts/d3-force/d3-force-layout.d.ts.map +1 -1
  37. package/dist/layouts/d3-force/d3-force-layout.js +11 -11
  38. package/dist/layouts/d3-force/worker.d.ts.map +1 -1
  39. package/dist/layouts/experimental/force-multi-graph-layout.d.ts +43 -0
  40. package/dist/layouts/experimental/force-multi-graph-layout.d.ts.map +1 -0
  41. package/dist/layouts/experimental/force-multi-graph-layout.js +226 -0
  42. package/dist/layouts/experimental/hive-plot-layout.d.ts +34 -0
  43. package/dist/layouts/experimental/hive-plot-layout.d.ts.map +1 -0
  44. package/dist/layouts/experimental/hive-plot-layout.js +142 -0
  45. package/dist/layouts/experimental/radial-layout.d.ts +28 -0
  46. package/dist/layouts/experimental/radial-layout.d.ts.map +1 -0
  47. package/dist/layouts/experimental/radial-layout.js +164 -0
  48. package/dist/layouts/gpu-force/gpu-force-layout.d.ts +15 -3
  49. package/dist/layouts/gpu-force/gpu-force-layout.d.ts.map +1 -1
  50. package/dist/layouts/gpu-force/gpu-force-layout.js +20 -18
  51. package/dist/layouts/gpu-force/worker.d.ts.map +1 -1
  52. package/dist/layouts/simple-layout.d.ts +42 -0
  53. package/dist/layouts/simple-layout.d.ts.map +1 -0
  54. package/dist/layouts/{simple-layout/simple-layout.js → simple-layout.js} +8 -7
  55. package/dist/loaders/create-graph.d.ts +13 -0
  56. package/dist/loaders/create-graph.d.ts.map +1 -0
  57. package/dist/{utils → loaders}/create-graph.js +9 -4
  58. package/dist/loaders/edge-parsers.d.ts +2 -6
  59. package/dist/loaders/edge-parsers.d.ts.map +1 -1
  60. package/dist/loaders/json-loader.js +1 -1
  61. package/dist/loaders/node-parsers.d.ts +2 -3
  62. package/dist/loaders/node-parsers.d.ts.map +1 -1
  63. package/dist/loaders/simple-json-graph-loader.d.ts +12 -0
  64. package/dist/loaders/simple-json-graph-loader.d.ts.map +1 -0
  65. package/dist/loaders/simple-json-graph-loader.js +20 -0
  66. package/dist/loaders/table-graph-loader.d.ts +17 -0
  67. package/dist/loaders/table-graph-loader.d.ts.map +1 -0
  68. package/dist/loaders/table-graph-loader.js +91 -0
  69. package/dist/utils/log.d.ts +1 -1
  70. package/dist/utils/log.d.ts.map +1 -1
  71. package/dist/utils/log.js +3 -3
  72. package/dist/widgets/long-press-button.d.ts +13 -0
  73. package/dist/widgets/long-press-button.d.ts.map +1 -0
  74. package/dist/widgets/long-press-button.js +31 -0
  75. package/dist/widgets/view-control-widget.d.ts +78 -0
  76. package/dist/widgets/view-control-widget.d.ts.map +1 -0
  77. package/dist/widgets/view-control-widget.js +194 -0
  78. package/package.json +8 -6
  79. package/src/core/graph-engine.ts +30 -10
  80. package/src/core/graph-layout.ts +146 -0
  81. package/src/core/interaction-manager.ts +2 -2
  82. package/src/{core → graph}/edge.ts +19 -17
  83. package/src/{core → graph}/graph.ts +51 -36
  84. package/src/{core → graph}/node.ts +21 -20
  85. package/src/index.ts +28 -28
  86. package/src/layers/graph-layer.ts +133 -46
  87. package/src/layers/node-layers/rounded-rectangle-layer-fragment.ts +1 -3
  88. package/src/layers/node-layers/rounded-rectangle-layer.ts +34 -10
  89. package/src/layouts/d3-force/d3-force-layout.ts +21 -11
  90. package/src/layouts/experimental/force-multi-graph-layout.ts +268 -0
  91. package/src/layouts/experimental/hive-plot-layout.ts +182 -0
  92. package/src/layouts/experimental/radial-layout.ts +210 -0
  93. package/src/layouts/gpu-force/gpu-force-layout.ts +32 -17
  94. package/src/layouts/{simple-layout/simple-layout.ts → simple-layout.ts} +34 -19
  95. package/src/{utils → loaders}/create-graph.ts +9 -4
  96. package/src/loaders/edge-parsers.ts +2 -1
  97. package/src/loaders/json-loader.ts +1 -1
  98. package/src/loaders/node-parsers.ts +2 -1
  99. package/src/loaders/simple-json-graph-loader.ts +28 -0
  100. package/src/loaders/table-graph-loader.ts +124 -0
  101. package/src/utils/log.ts +3 -3
  102. package/src/widgets/long-press-button.tsx +50 -0
  103. package/src/widgets/view-control-widget.tsx +337 -0
  104. package/dist/core/base-layout.d.ts +0 -72
  105. package/dist/core/base-layout.d.ts.map +0 -1
  106. package/dist/core/edge.d.ts.map +0 -1
  107. package/dist/core/graph.d.ts.map +0 -1
  108. package/dist/core/node.d.ts.map +0 -1
  109. package/dist/layers/node-layers/path-rounded-rectange-layer.d.ts.map +0 -1
  110. package/dist/layouts/simple-layout/simple-layout.d.ts +0 -23
  111. package/dist/layouts/simple-layout/simple-layout.d.ts.map +0 -1
  112. package/dist/utils/create-graph.d.ts +0 -9
  113. package/dist/utils/create-graph.d.ts.map +0 -1
  114. package/src/core/base-layout.ts +0 -154
  115. /package/dist/layers/node-layers/{path-rounded-rectange-layer.js → path-rounded-rectangle-layer.js} +0 -0
  116. /package/src/layers/node-layers/{path-rounded-rectange-layer.ts → path-rounded-rectangle-layer.ts} +0 -0
  117. /package/src/layouts/d3-force/{worker.ts → worker.js} +0 -0
  118. /package/src/layouts/gpu-force/{worker.ts → worker.js} +0 -0
package/dist/index.cjs CHANGED
@@ -34,8 +34,6 @@ var __publicField = (obj, key, value) => {
34
34
  // dist/index.js
35
35
  var dist_exports = {};
36
36
  __export(dist_exports, {
37
- BaseLayout: () => BaseLayout,
38
- CompositeEdgeLayer: () => EdgeLayer,
39
37
  D3ForceLayout: () => D3ForceLayout,
40
38
  EDGE_DECORATOR_TYPE: () => EDGE_DECORATOR_TYPE,
41
39
  EDGE_TYPE: () => EDGE_TYPE,
@@ -45,21 +43,29 @@ __export(dist_exports, {
45
43
  Graph: () => Graph,
46
44
  GraphEngine: () => GraphEngine,
47
45
  GraphLayer: () => GraphLayer,
48
- JSONLoader: () => JSONLoader,
49
- LAYOUT_STATE: () => LAYOUT_STATE,
46
+ GraphLayout: () => GraphLayout,
47
+ JSONLoader: () => JSONLoader2,
50
48
  MARKER_TYPE: () => MARKER_TYPE,
51
49
  NODE_STATE: () => NODE_STATE,
52
50
  NODE_TYPE: () => NODE_TYPE,
53
51
  Node: () => Node,
54
52
  SimpleLayout: () => SimpleLayout,
55
- basicEdgeParser: () => basicEdgeParser,
56
- basicNodeParser: () => basicNodeParser,
53
+ ViewControlWidget: () => ViewControlWidget,
54
+ _HivePlotLayout: () => HivePlotLayout,
55
+ _MultigraphLayout: () => ForceMultiGraphLayout,
56
+ _RadialLayout: () => RadialLayout,
57
57
  createGraph: () => createGraph,
58
+ loadSimpleJSONGraph: () => loadSimpleJSONGraph,
58
59
  log: () => log,
59
60
  mixedGetPosition: () => mixedGetPosition
60
61
  });
61
62
  module.exports = __toCommonJS(dist_exports);
62
63
 
64
+ // dist/utils/log.js
65
+ var import_log = require("@probe.gl/log");
66
+ var log = new import_log.Log({ id: "graph-layers" }).enable();
67
+ log.log({ color: import_log.COLOR.CYAN }, "Initialize graph-layers logger.")();
68
+
63
69
  // dist/core/cache.js
64
70
  var Cache = class {
65
71
  _keys = /* @__PURE__ */ new Map();
@@ -86,120 +92,7 @@ var Cache = class {
86
92
  }
87
93
  };
88
94
 
89
- // dist/core/graph-engine.js
90
- var GraphEngine = class extends EventTarget {
91
- _graph;
92
- _layout;
93
- _cache = new Cache();
94
- _layoutDirty = false;
95
- _transactionInProgress = false;
96
- constructor(graph, layout) {
97
- super();
98
- this._graph = graph;
99
- this._layout = layout;
100
- }
101
- /** Getters */
102
- getNodes = () => {
103
- this._updateCache("nodes", () => this._graph.getNodes().filter((node) => this.getNodePosition(node)));
104
- return this._cache.get("nodes");
105
- };
106
- getEdges = () => {
107
- this._updateCache("edges", () => this._graph.getEdges().filter((edge) => this.getEdgePosition(edge)));
108
- return this._cache.get("edges");
109
- };
110
- getNodePosition = (node) => this._layout.getNodePosition(node);
111
- getEdgePosition = (edge) => this._layout.getEdgePosition(edge);
112
- getGraphVersion = () => this._graph.version;
113
- getLayoutLastUpdate = () => this._layout.version;
114
- getLayoutState = () => this._layout.state;
115
- /** Operations on the graph */
116
- lockNodePosition = (node, x, y) => this._layout.lockNodePosition(node, x, y);
117
- unlockNodePosition = (node) => this._layout.unlockNodePosition(node);
118
- /**
119
- * @fires GraphEngine#onLayoutStart
120
- */
121
- _onLayoutStart = () => {
122
- this.dispatchEvent(new CustomEvent("onLayoutStart"));
123
- };
124
- /**
125
- * @fires GraphEngine#onLayoutChange
126
- */
127
- _onLayoutChange = () => {
128
- this.dispatchEvent(new CustomEvent("onLayoutChange"));
129
- };
130
- /**
131
- * @fires GraphEngine#onLayoutDone
132
- */
133
- _onLayoutDone = () => {
134
- this.dispatchEvent(new CustomEvent("onLayoutDone"));
135
- };
136
- /**
137
- * @fires GraphEngine#onLayoutError
138
- */
139
- _onLayoutError = () => {
140
- this.dispatchEvent(new CustomEvent("onLayoutError"));
141
- };
142
- _onGraphStructureChanged = (entity) => {
143
- this._layoutDirty = true;
144
- this._graphChanged();
145
- };
146
- _onTransactionStart = () => {
147
- this._transactionInProgress = true;
148
- };
149
- _onTransactionEnd = () => {
150
- this._transactionInProgress = false;
151
- this._graphChanged();
152
- };
153
- /** Layout calculations */
154
- run = () => {
155
- this._graph.addEventListener("transactionStart", this._onTransactionStart);
156
- this._graph.addEventListener("transactionEnd", this._onTransactionEnd);
157
- this._graph.addEventListener("onNodeAdded", this._onGraphStructureChanged);
158
- this._graph.addEventListener("onNodeRemoved", this._onGraphStructureChanged);
159
- this._graph.addEventListener("onEdgeAdded", this._onGraphStructureChanged);
160
- this._graph.addEventListener("onEdgeRemoved", this._onGraphStructureChanged);
161
- this._layout.addEventListener("onLayoutStart", this._onLayoutStart);
162
- this._layout.addEventListener("onLayoutChange", this._onLayoutChange);
163
- this._layout.addEventListener("onLayoutDone", this._onLayoutDone);
164
- this._layout.addEventListener("onLayoutError", this._onLayoutError);
165
- this._layout.initializeGraph(this._graph);
166
- this._layout.start();
167
- };
168
- clear = () => {
169
- this._graph.removeEventListener("transactionStart", this._onTransactionStart);
170
- this._graph.removeEventListener("transactionEnd", this._onTransactionEnd);
171
- this._graph.removeEventListener("onNodeAdded", this._onGraphStructureChanged);
172
- this._graph.removeEventListener("onNodeRemoved", this._onGraphStructureChanged);
173
- this._graph.removeEventListener("onEdgeAdded", this._onGraphStructureChanged);
174
- this._graph.removeEventListener("onEdgeRemoved", this._onGraphStructureChanged);
175
- this._layout.removeEventListener("onLayoutStart", this._onLayoutStart);
176
- this._layout.removeEventListener("onLayoutChange", this._onLayoutChange);
177
- this._layout.removeEventListener("onLayoutDone", this._onLayoutDone);
178
- this._layout.removeEventListener("onLayoutError", this._onLayoutError);
179
- };
180
- resume = () => this._layout.resume();
181
- stop = () => this._layout.stop();
182
- _graphChanged = () => {
183
- if (this._layoutDirty && !this._transactionInProgress) {
184
- this._updateLayout();
185
- }
186
- };
187
- _updateLayout = () => {
188
- this._layout.updateGraph(this._graph);
189
- this._layout.update();
190
- this._layoutDirty = false;
191
- };
192
- _updateCache(key, updateValue) {
193
- this._cache.set(key, updateValue, this._graph.version + this._layout.version);
194
- }
195
- };
196
-
197
- // dist/utils/log.js
198
- var import_probe = require("probe.gl");
199
- var log = new import_probe.Log({ id: "react-graph-layers" }).enable();
200
- log.log({ color: import_probe.COLOR.CYAN }, "Initialize react-graph-layers logger.")();
201
-
202
- // dist/core/graph.js
95
+ // dist/graph/graph.js
203
96
  var Graph = class extends EventTarget {
204
97
  /** List object of nodes. */
205
98
  _nodeMap = {};
@@ -216,32 +109,38 @@ var Graph = class extends EventTarget {
216
109
  _cache = new Cache();
217
110
  /**
218
111
  * The constructor of the Graph class.
219
- * @param {Object} graph - copy the graph if this exists.
112
+ * @param graph - copy the graph if this exists.
220
113
  */
221
- constructor(graph = null) {
114
+ constructor(propsOrGraph) {
222
115
  super();
223
- if (graph) {
116
+ if (propsOrGraph instanceof Graph) {
117
+ const graph = propsOrGraph;
118
+ this._name = (graph == null ? void 0 : graph._name) || this._name;
224
119
  this._nodeMap = graph._nodeMap;
225
120
  this._edgeMap = graph._edgeMap;
226
- this._name = graph && graph._name;
121
+ } else {
122
+ const props = propsOrGraph;
123
+ this._name = (props == null ? void 0 : props.name) || this._name;
124
+ this.batchAddNodes((props == null ? void 0 : props.nodes) || []);
125
+ this.batchAddEdges((props == null ? void 0 : props.edges) || []);
227
126
  }
228
127
  }
229
128
  /**
230
129
  * Set graph name
231
- * @param {string} name
130
+ * @param name
232
131
  */
233
132
  setGraphName(name) {
234
133
  this._name = name;
235
134
  }
236
135
  /** Get the name of the graph. Default value is the time stamp when creating this graph.
237
- * @return {string} graph name.
136
+ * @return graph name.
238
137
  */
239
138
  getGraphName() {
240
139
  return this._name.toString();
241
140
  }
242
141
  /**
243
142
  * Perform a batch of operations defined by cb before indicating graph is updated
244
- * @param {function} cb - a callback fuction containing the operations to perform
143
+ * @param {function} cb - a callback function containing the operations to perform
245
144
  */
246
145
  transaction(cb) {
247
146
  try {
@@ -253,7 +152,7 @@ var Graph = class extends EventTarget {
253
152
  }
254
153
  /**
255
154
  * Add a new node to the graph.
256
- * @param {Node} node - expect a Node object to be added to the graph.
155
+ * @paramnode - expect a Node object to be added to the graph.
257
156
  */
258
157
  addNode(node) {
259
158
  this._nodeMap[node.getId()] = node;
@@ -262,7 +161,7 @@ var Graph = class extends EventTarget {
262
161
  }
263
162
  /**
264
163
  * Batch add nodes to the graph.
265
- * @param {Node[]} nodes - a list of nodes to be added.
164
+ * @param nodes - a list of nodes to be added.
266
165
  */
267
166
  batchAddNodes(nodes) {
268
167
  this._nodeMap = nodes.reduce((res, node) => {
@@ -282,22 +181,22 @@ var Graph = class extends EventTarget {
282
181
  }
283
182
  /**
284
183
  * Get the node map of the graph. The key of the map is the ID of the nodes.
285
- * @return {Object} - a map of nodes keyed by node IDs.
184
+ * @return - a map of nodes keyed by node IDs.
286
185
  */
287
186
  getNodeMap() {
288
187
  return this._nodeMap;
289
188
  }
290
189
  /**
291
190
  * Find a node by id
292
- * @param {String} nodeId The id of the node
293
- * @return {Object} Node
191
+ * @param nodeId The id of the node
192
+ * @return Node
294
193
  */
295
194
  findNode(nodeId) {
296
195
  return this._nodeMap[nodeId];
297
196
  }
298
197
  /**
299
198
  * Update the indicated node to the provided value
300
- * @param {Node} node
199
+ * @param node
301
200
  */
302
201
  updateNode(node) {
303
202
  this._nodeMap[node.getId()] = node;
@@ -306,7 +205,7 @@ var Graph = class extends EventTarget {
306
205
  }
307
206
  /**
308
207
  * Add a new edge to the graph.
309
- * @param {Edge} edge - expect a Edge object to be added to the graph.
208
+ * @param edge - expect a Edge object to be added to the graph.
310
209
  */
311
210
  addEdge(edge) {
312
211
  const sourceNode = this.findNode(edge.getSourceNodeId());
@@ -323,7 +222,7 @@ var Graph = class extends EventTarget {
323
222
  }
324
223
  /**
325
224
  * Batch add edges to the graph
326
- * @param {Edge[]} edges - a list of edges to be added.
225
+ * @param edges - a list of edges to be added.
327
226
  */
328
227
  batchAddEdges(edges) {
329
228
  edges.forEach((edge) => this.addEdge(edge));
@@ -331,7 +230,7 @@ var Graph = class extends EventTarget {
331
230
  }
332
231
  /**
333
232
  * Update the indicated edge to the provided value
334
- * @param {Edge} edge
233
+ * @param edge
335
234
  */
336
235
  updateEdge(edge) {
337
236
  this._edgeMap[edge.getId()] = edge;
@@ -340,7 +239,7 @@ var Graph = class extends EventTarget {
340
239
  }
341
240
  /**
342
241
  * Remove a node from the graph by node ID
343
- * @param {String|Number} nodeId - the ID of the target node.
242
+ * @param nodeId - the ID of the target node.
344
243
  */
345
244
  removeNode(nodeId) {
346
245
  const node = this.findNode(nodeId);
@@ -357,7 +256,7 @@ var Graph = class extends EventTarget {
357
256
  }
358
257
  /**
359
258
  * Get all the edges of the graph.
360
- * @return {Edge[]} get all the edges in the graph.
259
+ * @return get all the edges in the graph.
361
260
  */
362
261
  getEdges() {
363
262
  this._updateCache("edges", () => Object.values(this._edgeMap));
@@ -365,7 +264,7 @@ var Graph = class extends EventTarget {
365
264
  }
366
265
  /**
367
266
  * Get the edge map of the graph. The key of the map is the ID of the edges.
368
- * @return {Object} - a map of edges keyed by edge IDs.
267
+ * @return - a map of edges keyed by edge IDs.
369
268
  */
370
269
  getEdgeMap() {
371
270
  return this._edgeMap;
@@ -389,16 +288,16 @@ var Graph = class extends EventTarget {
389
288
  }
390
289
  /**
391
290
  * Find the edge by edge ID.
392
- * @param {String|Number} id - the target edge ID
393
- * @return {Edge} - the target edge.
291
+ * @param id - the target edge ID
292
+ * @return - the target edge.
394
293
  */
395
294
  findEdge(edgeId) {
396
295
  return this._edgeMap[edgeId];
397
296
  }
398
297
  /**
399
298
  * Return all the connected edges of a node by nodeID.
400
- * @param {String|Number} nodeId - the target node ID
401
- * @return {Edge[]} - an array of the connected edges.
299
+ * @param nodeId - the target node ID
300
+ * @return - an array of the connected edges.
402
301
  */
403
302
  getConnectedEdges(nodeId) {
404
303
  const node = this.findNode(nodeId);
@@ -410,8 +309,8 @@ var Graph = class extends EventTarget {
410
309
  }
411
310
  /**
412
311
  * Return all the sibling nodes of a node by nodeID.
413
- * @param {String|Number} nodeId - the target node ID
414
- * @return {Node[]} - an array of the sibling nodes.
312
+ * @param nodeId - the target node ID
313
+ * @return - an array of the sibling nodes.
415
314
  */
416
315
  getNodeSiblings(nodeId) {
417
316
  const node = this.findNode(nodeId);
@@ -423,8 +322,8 @@ var Graph = class extends EventTarget {
423
322
  }
424
323
  /**
425
324
  * Get the degree of a node.
426
- * @param {String|Number} nodeId - the target node ID.
427
- * @return {Number} - the degree of the node.
325
+ * @param nodeId - the target node ID.
326
+ * @return - the degree of the node.
428
327
  */
429
328
  getDegree(nodeId) {
430
329
  const node = this.findNode(nodeId);
@@ -471,14 +370,14 @@ var Graph = class extends EventTarget {
471
370
  }
472
371
  /**
473
372
  * Check the equality of two graphs data by checking last update time stamp
474
- * @param {Object} g Another graph to be compared against itself
475
- * @return {Bool} True if the graph is the same as itself.
373
+ * @param graph Another graph to be compared against itself
374
+ * @return true if the graph is the same as itself.
476
375
  */
477
- equals(g) {
478
- if (!g || !(g instanceof Graph)) {
376
+ equals(graph) {
377
+ if (!graph || !(graph instanceof Graph)) {
479
378
  return false;
480
379
  }
481
- return this.version === g.version;
380
+ return this.version === graph.version;
482
381
  }
483
382
  _bumpVersion() {
484
383
  this.version += 1;
@@ -584,15 +483,8 @@ var EDGE_DECORATOR_TYPE = {
584
483
  LABEL: "EDGE_LABEL",
585
484
  FLOW: "FLOW"
586
485
  };
587
- var LAYOUT_STATE = {
588
- INIT: "INIT",
589
- START: "START",
590
- CALCULATING: "CALCULATING",
591
- DONE: "DONE",
592
- ERROR: "ERROR"
593
- };
594
486
 
595
- // dist/core/node.js
487
+ // dist/graph/node.js
596
488
  var Node = class {
597
489
  id;
598
490
  /** Keep a reference to origin data. */
@@ -609,8 +501,6 @@ var Node = class {
609
501
  isNode = true;
610
502
  /**
611
503
  * The constructor of a node
612
- * @param {String|Number} options.id - the unique ID of the node
613
- * @param {Record<string, unknown>} options.data - origin data reference
614
504
  */
615
505
  constructor({ id, selectable = false, highlightConnectedEdges = false, data = {} }) {
616
506
  this.id = id;
@@ -620,7 +510,7 @@ var Node = class {
620
510
  }
621
511
  /**
622
512
  * Return the ID of the node
623
- * @return {String|Number} - the ID of the node.
513
+ * @return - the ID of the node.
624
514
  */
625
515
  getId() {
626
516
  return this.id;
@@ -634,7 +524,7 @@ var Node = class {
634
524
  }
635
525
  /**
636
526
  * Return the in-degree of the node.
637
- * @return {Number} - the in-degree of the node.
527
+ * @return - the in-degree of the node.
638
528
  */
639
529
  getInDegree() {
640
530
  const nodeId = this.getId();
@@ -648,7 +538,7 @@ var Node = class {
648
538
  }
649
539
  /**
650
540
  * Return the out-degree of the node.
651
- * @return {Number} - the out-degree of the node.
541
+ * @return - the out-degree of the node.
652
542
  */
653
543
  getOutDegree() {
654
544
  const nodeId = this.getId();
@@ -662,7 +552,7 @@ var Node = class {
662
552
  }
663
553
  /**
664
554
  * Return all the IDs of the sibling nodes.
665
- * @return {String[]} [description]
555
+ * @return [description]
666
556
  */
667
557
  getSiblingIds() {
668
558
  const nodeId = this.getId();
@@ -677,15 +567,15 @@ var Node = class {
677
567
  }
678
568
  /**
679
569
  * Return all the connected edges.
680
- * @return {Object[]} - an array of the connected edges.
570
+ * @return - an array of the connected edges.
681
571
  */
682
572
  getConnectedEdges() {
683
573
  return Object.values(this._connectedEdges);
684
574
  }
685
575
  /**
686
576
  * Return of the value of the selected property key.
687
- * @param {String} key - property key.
688
- * @return {Any} - the value of the property or undefined (not found).
577
+ * @param key - property key.
578
+ * @return - the value of the property or undefined (not found).
689
579
  */
690
580
  getPropertyValue(key) {
691
581
  if (this.hasOwnProperty(key)) {
@@ -697,36 +587,36 @@ var Node = class {
697
587
  }
698
588
  /**
699
589
  * Set the new node data.
700
- * @param {Record<string, unknown>} data - the new data of the node
590
+ * @param data - the new data of the node
701
591
  */
702
592
  setData(data) {
703
593
  this._data = data;
704
594
  }
705
595
  /**
706
596
  * Update a data property.
707
- * @param {String} key - the key of the property
708
- * @param {Any} value - the value of the property.
597
+ * @param key - the key of the property
598
+ * @param value - the value of the property.
709
599
  */
710
600
  setDataProperty(key, value) {
711
601
  this._data[key] = value;
712
602
  }
713
603
  /**
714
604
  * Set node state
715
- * @param {String} state - one of NODE_STATE
605
+ * @param state - one of NODE_STATE
716
606
  */
717
607
  setState(state) {
718
608
  this.state = state;
719
609
  }
720
610
  /**
721
611
  * Get node state
722
- * @returns {string} state - one of NODE_STATE
612
+ * @returns state - one of NODE_STATE
723
613
  */
724
614
  getState() {
725
615
  return this.state;
726
616
  }
727
617
  /**
728
618
  * Add connected edges to the node
729
- * @param {Edge || Edge[]} edge an edge or an array of edges to be added to this._connectedEdges
619
+ * @param edge an edge or an array of edges to be added to this._connectedEdges
730
620
  */
731
621
  addConnectedEdges(edge) {
732
622
  const iterableEdges = Array.isArray(edge) ? edge : [edge];
@@ -737,7 +627,7 @@ var Node = class {
737
627
  }
738
628
  /**
739
629
  * Remove edges from this._connectedEdges
740
- * @param {Edge | Edge[]} edge an edge or an array of edges to be removed from this._connectedEdges
630
+ * @param edge an edge or an array of edges to be removed from this._connectedEdges
741
631
  */
742
632
  removeConnectedEdges(edge) {
743
633
  const iterableEdges = Array.isArray(edge) ? edge : [edge];
@@ -761,7 +651,7 @@ var Node = class {
761
651
  }
762
652
  };
763
653
 
764
- // dist/core/edge.js
654
+ // dist/graph/edge.js
765
655
  var Edge = class {
766
656
  /** Unique uuid of the edge. */
767
657
  id;
@@ -781,11 +671,7 @@ var Edge = class {
781
671
  state = EDGE_STATE.DEFAULT;
782
672
  /**
783
673
  * The constructor
784
- * @param {String|Number} options.id - the unique ID of the edge
785
- * @param {String|Number} options.sourceId - the ID of the source node
786
- * @param {String|Number} options.targetId - the ID of the target node
787
- * @param {Boolean} options.directed - whether the edge is directed or not
788
- * @param {Record<string, unknown>} options.data - origin data reference
674
+ * @param options.id - information about the edge
789
675
  */
790
676
  constructor({ id, sourceId, targetId, data, directed = false }) {
791
677
  this.id = id;
@@ -810,22 +696,22 @@ var Edge = class {
810
696
  }
811
697
  /**
812
698
  * Get the ID of the source node.
813
- * @return {String|Number} the ID of the source node.
699
+ * @return the ID of the source node.
814
700
  */
815
701
  getSourceNodeId() {
816
702
  return this._sourceId;
817
703
  }
818
704
  /**
819
705
  * Get the ID of the target node.
820
- * @return {String|Number} the ID of the target node.
706
+ * @return the ID of the target node.
821
707
  */
822
708
  getTargetNodeId() {
823
709
  return this._targetId;
824
710
  }
825
711
  /**
826
712
  * Return of the value of the selected property key.
827
- * @param {String} key - property key.
828
- * @return {Any} - the value of the property.
713
+ * @param key - property key.
714
+ * @return - the value of the property.
829
715
  */
830
716
  getPropertyValue(key) {
831
717
  if (this.hasOwnProperty(key)) {
@@ -837,29 +723,29 @@ var Edge = class {
837
723
  }
838
724
  /**
839
725
  * Set the origin data as a reference.
840
- * @param {Object} data - the origin data.
726
+ * @param data - the origin data.
841
727
  */
842
728
  setData(data) {
843
729
  this._data = data;
844
730
  }
845
731
  /**
846
732
  * Update a data property.
847
- * @param {String} key - the key of the property
848
- * @param {Any} value - the value of the property.
733
+ * @param key - the key of the property
734
+ * @param value - the value of the property.
849
735
  */
850
736
  setDataProperty(key, value) {
851
737
  this._data[key] = value;
852
738
  }
853
739
  /**
854
740
  * Set edge state
855
- * @param {String} state - one of EDGE_STATE
741
+ * @param state - one of EDGE_STATE
856
742
  */
857
743
  setState(state) {
858
744
  this.state = state;
859
745
  }
860
746
  /**
861
747
  * Get edge state
862
- * @returns {string} state - one of EDGE_STATE
748
+ * @returns state - one of EDGE_STATE
863
749
  */
864
750
  getState() {
865
751
  return this.state;
@@ -875,90 +761,174 @@ var Edge = class {
875
761
  }
876
762
  };
877
763
 
878
- // dist/core/base-layout.js
879
- var import_lodash = __toESM(require("lodash.isequal"), 1);
880
- var BaseLayout = class extends EventTarget {
881
- /** Name of the layout. */
882
- _name = "BaseLayout";
883
- /** Extra configuration options of the layout. */
884
- _options;
885
- version = 0;
886
- state = LAYOUT_STATE.INIT;
887
- /**
888
- * Constructor of BaseLayout
889
- * @param {Object} options extra configuration options of the layout
890
- */
891
- constructor(options = {}) {
764
+ // dist/core/graph-engine.js
765
+ var GraphEngine = class extends EventTarget {
766
+ props;
767
+ _graph;
768
+ _layout;
769
+ _cache = new Cache();
770
+ _layoutDirty = false;
771
+ _transactionInProgress = false;
772
+ constructor(props, layout) {
892
773
  super();
893
- this._options = options;
774
+ if (props instanceof Graph) {
775
+ props = {
776
+ graph: props,
777
+ layout
778
+ };
779
+ }
780
+ this.props = props;
781
+ this._graph = props.graph;
782
+ this._layout = props.layout;
894
783
  }
784
+ /** Getters */
785
+ getNodes = () => {
786
+ this._updateCache("nodes", () => this._graph.getNodes().filter((node) => this.getNodePosition(node)));
787
+ return this._cache.get("nodes");
788
+ };
789
+ getEdges = () => {
790
+ this._updateCache("edges", () => this._graph.getEdges().filter((edge) => this.getEdgePosition(edge)));
791
+ return this._cache.get("edges");
792
+ };
793
+ getNodePosition = (node) => this._layout.getNodePosition(node);
794
+ getEdgePosition = (edge) => this._layout.getEdgePosition(edge);
795
+ getGraphVersion = () => this._graph.version;
796
+ getLayoutLastUpdate = () => this._layout.version;
797
+ getLayoutState = () => this._layout.state;
798
+ /** Operations on the graph */
799
+ lockNodePosition = (node, x, y) => this._layout.lockNodePosition(node, x, y);
800
+ unlockNodePosition = (node) => this._layout.unlockNodePosition(node);
895
801
  /**
896
- * @fires BaseLayout#onLayoutStart
897
- * @protected
802
+ * @fires GraphEngine#onLayoutStart
898
803
  */
899
- _onLayoutStart() {
900
- this._updateState(LAYOUT_STATE.CALCULATING);
804
+ _onLayoutStart = () => {
901
805
  this.dispatchEvent(new CustomEvent("onLayoutStart"));
902
- }
806
+ };
903
807
  /**
904
- * @fires BaseLayout#onLayoutChange
905
- * @protected
808
+ * @fires GraphEngine#onLayoutChange
906
809
  */
907
- _onLayoutChange() {
908
- this._updateState(LAYOUT_STATE.CALCULATING);
810
+ _onLayoutChange = () => {
909
811
  this.dispatchEvent(new CustomEvent("onLayoutChange"));
910
- }
812
+ };
911
813
  /**
912
- * @fires BaseLayout#onLayoutDone
913
- * @protected
814
+ * @fires GraphEngine#onLayoutDone
914
815
  */
915
- _onLayoutDone() {
916
- this._updateState(LAYOUT_STATE.DONE);
816
+ _onLayoutDone = () => {
917
817
  this.dispatchEvent(new CustomEvent("onLayoutDone"));
918
- }
818
+ };
919
819
  /**
920
- * @fires BaseLayout#onLayoutError
921
- * @protected
820
+ * @fires GraphEngine#onLayoutError
922
821
  */
923
- _onLayoutError() {
924
- this._updateState(LAYOUT_STATE.ERROR);
822
+ _onLayoutError = () => {
925
823
  this.dispatchEvent(new CustomEvent("onLayoutError"));
824
+ };
825
+ _onGraphStructureChanged = (entity) => {
826
+ this._layoutDirty = true;
827
+ this._graphChanged();
828
+ };
829
+ _onTransactionStart = () => {
830
+ this._transactionInProgress = true;
831
+ };
832
+ _onTransactionEnd = () => {
833
+ this._transactionInProgress = false;
834
+ this._graphChanged();
835
+ };
836
+ /** Layout calculations */
837
+ run = () => {
838
+ this._graph.addEventListener("transactionStart", this._onTransactionStart);
839
+ this._graph.addEventListener("transactionEnd", this._onTransactionEnd);
840
+ this._graph.addEventListener("onNodeAdded", this._onGraphStructureChanged);
841
+ this._graph.addEventListener("onNodeRemoved", this._onGraphStructureChanged);
842
+ this._graph.addEventListener("onEdgeAdded", this._onGraphStructureChanged);
843
+ this._graph.addEventListener("onEdgeRemoved", this._onGraphStructureChanged);
844
+ this._layout.addEventListener("onLayoutStart", this._onLayoutStart);
845
+ this._layout.addEventListener("onLayoutChange", this._onLayoutChange);
846
+ this._layout.addEventListener("onLayoutDone", this._onLayoutDone);
847
+ this._layout.addEventListener("onLayoutError", this._onLayoutError);
848
+ this._layout.initializeGraph(this._graph);
849
+ this._layout.start();
850
+ };
851
+ clear = () => {
852
+ this._graph.removeEventListener("transactionStart", this._onTransactionStart);
853
+ this._graph.removeEventListener("transactionEnd", this._onTransactionEnd);
854
+ this._graph.removeEventListener("onNodeAdded", this._onGraphStructureChanged);
855
+ this._graph.removeEventListener("onNodeRemoved", this._onGraphStructureChanged);
856
+ this._graph.removeEventListener("onEdgeAdded", this._onGraphStructureChanged);
857
+ this._graph.removeEventListener("onEdgeRemoved", this._onGraphStructureChanged);
858
+ this._layout.removeEventListener("onLayoutStart", this._onLayoutStart);
859
+ this._layout.removeEventListener("onLayoutChange", this._onLayoutChange);
860
+ this._layout.removeEventListener("onLayoutDone", this._onLayoutDone);
861
+ this._layout.removeEventListener("onLayoutError", this._onLayoutError);
862
+ };
863
+ resume = () => this._layout.resume();
864
+ stop = () => this._layout.stop();
865
+ _graphChanged = () => {
866
+ if (this._layoutDirty && !this._transactionInProgress) {
867
+ this._updateLayout();
868
+ }
869
+ };
870
+ _updateLayout = () => {
871
+ this._layout.updateGraph(this._graph);
872
+ this._layout.update();
873
+ this._layoutDirty = false;
874
+ };
875
+ _updateCache(key, updateValue) {
876
+ this._cache.set(key, updateValue, this._graph.version + this._layout.version);
877
+ }
878
+ };
879
+
880
+ // dist/core/graph-layout.js
881
+ var import_lodash = __toESM(require("lodash.isequal"), 1);
882
+ var GraphLayout = class extends EventTarget {
883
+ /** Name of the layout. */
884
+ _name = "GraphLayout";
885
+ /** Extra configuration options of the layout. */
886
+ _options;
887
+ version = 0;
888
+ state = "INIT";
889
+ /**
890
+ * Constructor of GraphLayout
891
+ * @param options extra configuration options of the layout
892
+ */
893
+ constructor(options) {
894
+ super();
895
+ this._options = options;
926
896
  }
927
897
  /**
928
898
  * Check the equality of two layouts
929
- * @param {Object} layout The layout to be compared.
930
- * @return {Bool} True if the layout is the same as itself.
899
+ * @param layout - The layout to be compared.
900
+ * @return - True if the layout is the same as itself.
931
901
  */
932
902
  equals(layout) {
933
- if (!layout || !(layout instanceof BaseLayout)) {
903
+ if (!layout || !(layout instanceof GraphLayout)) {
934
904
  return false;
935
905
  }
936
906
  return this._name === layout._name && (0, import_lodash.default)(this._options, layout._options);
937
907
  }
938
908
  /** virtual functions: will be implemented in the child class */
939
- // first time to pass the graph data into this layout
909
+ /** first time to pass the graph data into this layout */
940
910
  initializeGraph(graph) {
941
911
  }
942
- // update the existing graph
912
+ /** update the existing graph */
943
913
  updateGraph(graph) {
944
914
  }
945
- // start the layout calculation
915
+ /** start the layout calculation */
946
916
  start() {
947
917
  }
948
- // update the layout calculation
918
+ /** update the layout calculation */
949
919
  update() {
950
920
  }
951
- // resume the layout calculation
921
+ /** resume the layout calculation */
952
922
  resume() {
953
923
  }
954
- // stop the layout calculation
924
+ /** stop the layout calculation */
955
925
  stop() {
956
926
  }
957
- // access the position of the node in the layout
927
+ /** access the position of the node in the layout */
958
928
  getNodePosition(node) {
959
929
  return [0, 0];
960
930
  }
961
- // access the layout information of the edge
931
+ /** access the layout information of the edge */
962
932
  getEdgePosition(edge) {
963
933
  return {
964
934
  type: EDGE_TYPE.LINE,
@@ -969,9 +939,9 @@ var BaseLayout = class extends EventTarget {
969
939
  }
970
940
  /**
971
941
  * Pin the node to a designated position, and the node won't move anymore
972
- * @param {Object} node Node to be locked
973
- * @param {Number} x x coordinate
974
- * @param {Number} y y coordinate
942
+ * @param node Node to be locked
943
+ * @param x x coordinate
944
+ * @param y y coordinate
975
945
  */
976
946
  lockNodePosition(node, x, y) {
977
947
  }
@@ -981,31 +951,106 @@ var BaseLayout = class extends EventTarget {
981
951
  */
982
952
  unlockNodePosition(node) {
983
953
  }
954
+ // INTERNAL METHODS
984
955
  _updateState(state) {
985
956
  this.state = state;
986
957
  this.version += 1;
987
958
  }
959
+ /** @fires GraphLayout#onLayoutStart */
960
+ _onLayoutStart = () => {
961
+ this._updateState("CALCULATING");
962
+ this.dispatchEvent(new CustomEvent("onLayoutStart"));
963
+ };
964
+ /** @fires GraphLayout#onLayoutChange */
965
+ _onLayoutChange = () => {
966
+ this._updateState("CALCULATING");
967
+ this.dispatchEvent(new CustomEvent("onLayoutChange"));
968
+ };
969
+ /** @fires GraphLayout#onLayoutDone */
970
+ _onLayoutDone = () => {
971
+ this._updateState("DONE");
972
+ this.dispatchEvent(new CustomEvent("onLayoutDone"));
973
+ };
974
+ /** @fires GraphLayout#onLayoutError */
975
+ _onLayoutError = () => {
976
+ this._updateState("ERROR");
977
+ this.dispatchEvent(new CustomEvent("onLayoutError"));
978
+ };
988
979
  };
989
980
 
990
- // dist/layouts/d3-force/d3-force-layout.js
991
- var import_meta = {};
992
- var defaultOptions = {
993
- alpha: 0.3,
994
- resumeAlpha: 0.1,
995
- nBodyStrength: -900,
996
- nBodyDistanceMin: 100,
997
- nBodyDistanceMax: 400,
998
- getCollisionRadius: 0
999
- };
1000
- var D3ForceLayout = class extends BaseLayout {
1001
- _name = "D3";
1002
- _positionsByNodeId = /* @__PURE__ */ new Map();
1003
- _graph;
1004
- _worker;
1005
- constructor(options) {
1006
- super(options);
1007
- this._options = {
1008
- ...defaultOptions,
981
+ // dist/layouts/simple-layout.js
982
+ var _SimpleLayout = class extends GraphLayout {
983
+ _name = "SimpleLayout";
984
+ _graph = null;
985
+ _nodeMap = {};
986
+ _nodePositionMap = {};
987
+ constructor(options = {}) {
988
+ super({ ..._SimpleLayout.defaultOptions, ...options });
989
+ }
990
+ initializeGraph(graph) {
991
+ this.updateGraph(graph);
992
+ }
993
+ _notifyLayoutComplete() {
994
+ this._onLayoutStart();
995
+ this._onLayoutChange();
996
+ this._onLayoutDone();
997
+ }
998
+ start() {
999
+ this._notifyLayoutComplete();
1000
+ }
1001
+ update() {
1002
+ this._notifyLayoutComplete();
1003
+ }
1004
+ resume() {
1005
+ this._notifyLayoutComplete();
1006
+ }
1007
+ updateGraph(graph) {
1008
+ this._graph = graph;
1009
+ this._nodeMap = graph.getNodes().reduce((res, node) => {
1010
+ res[node.getId()] = node;
1011
+ return res;
1012
+ }, {});
1013
+ this._nodePositionMap = graph.getNodes().reduce((res, node) => {
1014
+ res[node.getId()] = this._options.nodePositionAccessor(node);
1015
+ return res;
1016
+ }, {});
1017
+ }
1018
+ setNodePositionAccessor = (accessor) => {
1019
+ this._options.nodePositionAccessor = accessor;
1020
+ };
1021
+ getNodePosition = (node) => this._nodePositionMap[node.getId()];
1022
+ getEdgePosition = (edge) => {
1023
+ const sourcePos = this._nodePositionMap[edge.getSourceNodeId()];
1024
+ const targetPos = this._nodePositionMap[edge.getTargetNodeId()];
1025
+ return {
1026
+ type: EDGE_TYPE.LINE,
1027
+ sourcePosition: sourcePos,
1028
+ targetPosition: targetPos,
1029
+ controlPoints: []
1030
+ };
1031
+ };
1032
+ lockNodePosition = (node, x, y) => {
1033
+ this._nodePositionMap[node.getId()] = [x, y];
1034
+ this._onLayoutChange();
1035
+ this._onLayoutDone();
1036
+ };
1037
+ };
1038
+ var SimpleLayout = _SimpleLayout;
1039
+ __publicField(SimpleLayout, "defaultOptions", {
1040
+ nodePositionAccessor: (node) => [node.getPropertyValue("x"), node.getPropertyValue("y")]
1041
+ });
1042
+
1043
+ // dist/layouts/d3-force/d3-force-layout.js
1044
+ var import_meta = {};
1045
+ var _D3ForceLayout = class extends GraphLayout {
1046
+ _name = "D3";
1047
+ _positionsByNodeId = /* @__PURE__ */ new Map();
1048
+ _graph;
1049
+ _worker;
1050
+ constructor(options) {
1051
+ super(options);
1052
+ this._options = {
1053
+ ..._D3ForceLayout.defaultOptions,
1009
1054
  ...options
1010
1055
  };
1011
1056
  }
@@ -1045,10 +1090,10 @@ var D3ForceLayout = class extends BaseLayout {
1045
1090
  if (event.data.type !== "end") {
1046
1091
  return;
1047
1092
  }
1048
- event.data.nodes.forEach(({ id, ...d3 }) => this._positionsByNodeId.set(id, {
1049
- ...d3,
1093
+ event.data.nodes.forEach(({ id, ...d32 }) => this._positionsByNodeId.set(id, {
1094
+ ...d32,
1050
1095
  // precompute so that when we return the node position we do not need to do the conversion
1051
- coordinates: [d3.x, d3.y]
1096
+ coordinates: [d32.x, d32.y]
1052
1097
  }));
1053
1098
  this._onLayoutChange();
1054
1099
  this._onLayoutDone();
@@ -1099,18 +1144,19 @@ var D3ForceLayout = class extends BaseLayout {
1099
1144
  d3Node.fy = null;
1100
1145
  };
1101
1146
  };
1102
-
1103
- // dist/layouts/gpu-force/gpu-force-layout.js
1104
- var import_meta2 = {};
1105
- var defaultOptions2 = {
1147
+ var D3ForceLayout = _D3ForceLayout;
1148
+ __publicField(D3ForceLayout, "defaultOptions", {
1106
1149
  alpha: 0.3,
1107
1150
  resumeAlpha: 0.1,
1108
1151
  nBodyStrength: -900,
1109
1152
  nBodyDistanceMin: 100,
1110
1153
  nBodyDistanceMax: 400,
1111
1154
  getCollisionRadius: 0
1112
- };
1113
- var GPUForceLayout = class extends BaseLayout {
1155
+ });
1156
+
1157
+ // dist/layouts/gpu-force/gpu-force-layout.js
1158
+ var import_meta2 = {};
1159
+ var _GPUForceLayout = class extends GraphLayout {
1114
1160
  _name = "GPU";
1115
1161
  _d3Graph;
1116
1162
  _nodeMap;
@@ -1118,13 +1164,14 @@ var GPUForceLayout = class extends BaseLayout {
1118
1164
  _graph;
1119
1165
  _worker;
1120
1166
  _callbacks;
1121
- constructor(options) {
1122
- super(options);
1123
- this._name = "GPU";
1124
- this._options = {
1125
- ...defaultOptions2,
1167
+ constructor(options = {}) {
1168
+ const _options = {
1169
+ ..._GPUForceLayout.defaultOptions,
1126
1170
  ...options
1127
1171
  };
1172
+ super(_options);
1173
+ this._name = "GPU";
1174
+ this._options = _options;
1128
1175
  this._d3Graph = { nodes: [], edges: [] };
1129
1176
  this._nodeMap = {};
1130
1177
  this._edgeMap = {};
@@ -1316,148 +1363,483 @@ var GPUForceLayout = class extends BaseLayout {
1316
1363
  d3Node.fy = null;
1317
1364
  };
1318
1365
  };
1366
+ var GPUForceLayout = _GPUForceLayout;
1367
+ __publicField(GPUForceLayout, "defaultOptions", {
1368
+ alpha: 0.3,
1369
+ resumeAlpha: 0.1,
1370
+ nBodyStrength: -900,
1371
+ nBodyDistanceMin: 100,
1372
+ nBodyDistanceMax: 400,
1373
+ getCollisionRadius: 0
1374
+ });
1319
1375
 
1320
- // dist/layouts/simple-layout/simple-layout.js
1321
- var defaultOptions3 = {
1322
- nodePositionAccessor: (node) => [node.getPropertyValue("x"), node.getPropertyValue("y")]
1376
+ // dist/layouts/experimental/radial-layout.js
1377
+ var traverseTree = (nodeId, nodeMap) => {
1378
+ const node = nodeMap[nodeId];
1379
+ if (node.isLeaf) {
1380
+ return node;
1381
+ }
1382
+ return {
1383
+ ...node,
1384
+ children: node.children.map((nid) => traverseTree(nid, nodeMap))
1385
+ };
1323
1386
  };
1324
- var SimpleLayout = class extends BaseLayout {
1325
- _name = "SimpleLayout";
1387
+ var getLeafNodeCount = (node, count) => {
1388
+ if (!node.children || node.children.length === 0) {
1389
+ return count + 1;
1390
+ }
1391
+ const sum = node.children.reduce((res, c) => {
1392
+ return res + getLeafNodeCount(c, 0);
1393
+ }, 0);
1394
+ return count + sum;
1395
+ };
1396
+ var getTreeDepth = (node, depth = 0) => {
1397
+ if (node.isLeaf) {
1398
+ return depth;
1399
+ }
1400
+ return getTreeDepth(node.children[0], depth + 1);
1401
+ };
1402
+ var getPath = (node, targetId, path) => {
1403
+ if (node.id === targetId) {
1404
+ path.push(node.id);
1405
+ return true;
1406
+ }
1407
+ const inChildren = node.children && node.children.some((c) => getPath(c, targetId, path));
1408
+ if (inChildren) {
1409
+ path.push(node.id);
1410
+ return true;
1411
+ }
1412
+ return false;
1413
+ };
1414
+ var _RadialLayout = class extends GraphLayout {
1415
+ _name = "RadialLayout";
1326
1416
  _graph = null;
1327
- _nodeMap = {};
1328
- _nodePositionMap = {};
1417
+ // custom layout data structure
1418
+ _hierarchicalPoints = {};
1419
+ nestedTree;
1329
1420
  constructor(options = {}) {
1330
- super({ ...defaultOptions3, ...options });
1421
+ super(options);
1422
+ this._options = {
1423
+ ..._RadialLayout.defaultOptions,
1424
+ ...options
1425
+ };
1331
1426
  }
1332
1427
  initializeGraph(graph) {
1333
1428
  this.updateGraph(graph);
1334
1429
  }
1335
- _notifyLayoutComplete() {
1336
- this._onLayoutStart();
1430
+ updateGraph(graph) {
1431
+ this._graph = graph;
1432
+ }
1433
+ start() {
1434
+ const nodeCount = this._graph.getNodes().length;
1435
+ if (nodeCount === 0) {
1436
+ return;
1437
+ }
1438
+ const { tree } = this._options;
1439
+ if (!tree || tree.length === 0) {
1440
+ return;
1441
+ }
1442
+ const { radius } = this._options;
1443
+ const unitAngle = 360 / nodeCount;
1444
+ const rootNode = tree[0];
1445
+ const nodeMap = tree.reduce((res, node) => {
1446
+ res[node.id] = {
1447
+ ...node,
1448
+ isLeaf: !node.children || node.children.length === 0
1449
+ };
1450
+ return res;
1451
+ }, {});
1452
+ this.nestedTree = traverseTree(rootNode.id, nodeMap);
1453
+ const totalLevels = getTreeDepth(this.nestedTree, 0);
1454
+ const distanceBetweenLevels = radius / (totalLevels - 1);
1455
+ const calculatePosition = (node, level, startAngle, positionMap) => {
1456
+ const isRoot = node.id === rootNode.id;
1457
+ if (node.children && node.children.length !== 0) {
1458
+ const groupSize = getLeafNodeCount(node, 0);
1459
+ positionMap[node.id] = isRoot ? [0, 0] : rotate(0, 0, 0, distanceBetweenLevels * (level + 1), startAngle + unitAngle * (groupSize / 2));
1460
+ let tempAngle = startAngle;
1461
+ node.children.forEach((n) => {
1462
+ calculatePosition(n, level + 1, tempAngle, positionMap);
1463
+ tempAngle += getLeafNodeCount(n, 0) * unitAngle;
1464
+ });
1465
+ } else {
1466
+ positionMap[node.id] = rotate(0, 0, 0, distanceBetweenLevels * (level + 1), startAngle + unitAngle);
1467
+ }
1468
+ };
1469
+ this._hierarchicalPoints = {};
1470
+ calculatePosition(this.nestedTree, 0, 0, this._hierarchicalPoints);
1337
1471
  this._onLayoutChange();
1338
1472
  this._onLayoutDone();
1339
1473
  }
1340
- start() {
1341
- this._notifyLayoutComplete();
1474
+ getNodePosition = (node) => {
1475
+ return this._hierarchicalPoints[node.id];
1476
+ };
1477
+ // spline curve version
1478
+ getEdgePosition = (edge) => {
1479
+ const sourceNodeId = edge.getSourceNodeId();
1480
+ const targetNodeId = edge.getTargetNodeId();
1481
+ const sourceNodePos = this._hierarchicalPoints[sourceNodeId];
1482
+ const targetNodePos = this._hierarchicalPoints[targetNodeId];
1483
+ const sourcePath = [];
1484
+ getPath(this.nestedTree, sourceNodeId, sourcePath);
1485
+ const targetPath = [];
1486
+ getPath(this.nestedTree, targetNodeId, targetPath);
1487
+ const totalLevels = sourcePath.length;
1488
+ let commonAncestorLevel = totalLevels - 1;
1489
+ for (let i = 0; i < totalLevels; i++) {
1490
+ if (sourcePath[i] === targetPath[i]) {
1491
+ commonAncestorLevel = i;
1492
+ break;
1493
+ }
1494
+ }
1495
+ const wayPoints = [];
1496
+ for (let i = 1; i <= commonAncestorLevel; i++) {
1497
+ const nodeId = sourcePath[i];
1498
+ wayPoints.push(this._hierarchicalPoints[nodeId]);
1499
+ }
1500
+ for (let i = commonAncestorLevel - 1; i > 0; i--) {
1501
+ const nodeId = targetPath[i];
1502
+ wayPoints.push(this._hierarchicalPoints[nodeId]);
1503
+ }
1504
+ return {
1505
+ type: EDGE_TYPE.SPLINE_CURVE,
1506
+ sourcePosition: sourceNodePos,
1507
+ targetPosition: targetNodePos,
1508
+ controlPoints: wayPoints
1509
+ };
1510
+ };
1511
+ lockNodePosition = (node, x, y) => {
1512
+ this._hierarchicalPoints[node.id] = [x, y];
1513
+ this._onLayoutChange();
1514
+ this._onLayoutDone();
1515
+ };
1516
+ };
1517
+ var RadialLayout = _RadialLayout;
1518
+ __publicField(RadialLayout, "defaultOptions", {
1519
+ radius: 500
1520
+ });
1521
+ function rotate(cx, cy, x, y, angle) {
1522
+ const radians = Math.PI / 180 * angle;
1523
+ const cos = Math.cos(radians);
1524
+ const sin = Math.sin(radians);
1525
+ const nx = cos * (x - cx) + sin * (y - cy) + cx;
1526
+ const ny = cos * (y - cy) - sin * (x - cx) + cy;
1527
+ return [nx, ny];
1528
+ }
1529
+
1530
+ // dist/layouts/experimental/force-multi-graph-layout.js
1531
+ var d3 = __toESM(require("d3-force"), 1);
1532
+ var _ForceMultiGraphLayout = class extends GraphLayout {
1533
+ _name = "ForceMultiGraphLayout";
1534
+ _graph;
1535
+ // d3 part
1536
+ // custom graph data
1537
+ _d3Graph = { nodes: [], edges: [] };
1538
+ _nodeMap = {};
1539
+ _edgeMap = {};
1540
+ _simulator;
1541
+ constructor(options = {}) {
1542
+ super(options);
1543
+ this._options = {
1544
+ ..._ForceMultiGraphLayout.defaultOptions,
1545
+ ...options
1546
+ };
1342
1547
  }
1343
- update() {
1344
- this._notifyLayoutComplete();
1548
+ initializeGraph(graph) {
1549
+ this.updateGraph(graph);
1550
+ }
1551
+ _strength = (d3Edge) => {
1552
+ if (d3Edge.isVirtual) {
1553
+ return 1 / d3Edge.edgeCount;
1554
+ }
1555
+ const sourceDegree = this._graph.getDegree(d3Edge.source.id);
1556
+ const targetDegree = this._graph.getDegree(d3Edge.target.id);
1557
+ return 1 / Math.min(sourceDegree, targetDegree);
1558
+ };
1559
+ _generateSimulator() {
1560
+ if (this._simulator) {
1561
+ this._simulator.on("tick", null).on("end", null);
1562
+ this._simulator = null;
1563
+ }
1564
+ const { alpha, nBodyStrength, nBodyDistanceMin, nBodyDistanceMax } = this._options;
1565
+ const g = this._d3Graph;
1566
+ this._simulator = d3.forceSimulation(g.nodes).force("edge", d3.forceLink(g.edges).id((n) => n.id).strength(this._strength)).force("charge", d3.forceManyBody().strength(nBodyStrength).distanceMin(nBodyDistanceMin).distanceMax(nBodyDistanceMax)).force("center", d3.forceCenter()).alpha(alpha);
1567
+ this._simulator.on("tick", this._onLayoutChange).on("end", this._onLayoutDone);
1568
+ }
1569
+ start() {
1570
+ this._generateSimulator();
1571
+ this._simulator.restart();
1345
1572
  }
1346
1573
  resume() {
1347
- this._notifyLayoutComplete();
1574
+ this._simulator.restart();
1575
+ }
1576
+ stop() {
1577
+ this._simulator.stop();
1348
1578
  }
1349
1579
  updateGraph(graph) {
1350
1580
  this._graph = graph;
1351
- this._nodeMap = graph.getNodes().reduce((res, node) => {
1352
- res[node.getId()] = node;
1353
- return res;
1354
- }, {});
1355
- this._nodePositionMap = graph.getNodes().reduce((res, node) => {
1356
- res[node.getId()] = this._options.nodePositionAccessor(node);
1581
+ const newNodeMap = {};
1582
+ const newD3Nodes = graph.getNodes().map((node) => {
1583
+ const oldD3Node = this._nodeMap[node.id];
1584
+ const newD3Node = oldD3Node ? oldD3Node : { id: node.id };
1585
+ newNodeMap[node.id] = newD3Node;
1586
+ return newD3Node;
1587
+ });
1588
+ const nodePairs = graph.getEdges().reduce((res, edge) => {
1589
+ const nodes = [edge.getSourceNodeId(), edge.getTargetNodeId()];
1590
+ const pairId = nodes.sort().toString();
1591
+ if (!res[pairId]) {
1592
+ res[pairId] = [edge];
1593
+ } else {
1594
+ res[pairId].push(edge);
1595
+ }
1357
1596
  return res;
1358
1597
  }, {});
1598
+ const newD3Edges = [];
1599
+ const newEdgeMap = {};
1600
+ Object.keys(nodePairs).forEach((pairId) => {
1601
+ const betweenEdges = nodePairs[pairId];
1602
+ const firstEdge = betweenEdges[0];
1603
+ if (betweenEdges.length === 1) {
1604
+ const newD3Edge2 = {
1605
+ type: EDGE_TYPE.LINE,
1606
+ id: firstEdge.getId(),
1607
+ source: newNodeMap[firstEdge.getSourceNodeId()],
1608
+ target: newNodeMap[firstEdge.getTargetNodeId()],
1609
+ isVirtual: false
1610
+ };
1611
+ newEdgeMap[firstEdge.getId()] = newD3Edge2;
1612
+ newD3Edges.push(newD3Edge2);
1613
+ return;
1614
+ }
1615
+ const newD3Edge = {
1616
+ type: EDGE_TYPE.LINE,
1617
+ id: pairId,
1618
+ source: newNodeMap[firstEdge.getSourceNodeId()],
1619
+ target: newNodeMap[firstEdge.getTargetNodeId()],
1620
+ isVirtual: true,
1621
+ edgeCount: betweenEdges.length
1622
+ };
1623
+ newEdgeMap[pairId] = newD3Edge;
1624
+ newD3Edges.push(newD3Edge);
1625
+ betweenEdges.forEach((e, idx) => {
1626
+ newEdgeMap[e.id] = {
1627
+ type: EDGE_TYPE.SPLINE_CURVE,
1628
+ id: e.id,
1629
+ source: newNodeMap[e.getSourceNodeId()],
1630
+ target: newNodeMap[e.getTargetNodeId()],
1631
+ virtualEdgeId: pairId,
1632
+ isVirtual: true,
1633
+ index: idx
1634
+ };
1635
+ });
1636
+ });
1637
+ this._nodeMap = newNodeMap;
1638
+ this._d3Graph.nodes = newD3Nodes;
1639
+ this._edgeMap = newEdgeMap;
1640
+ this._d3Graph.edges = newD3Edges;
1359
1641
  }
1360
- setNodePositionAccessor = (accessor) => {
1361
- this._options.nodePositionAccessor = accessor;
1642
+ getNodePosition = (node) => {
1643
+ const d3Node = this._nodeMap[node.id];
1644
+ if (d3Node) {
1645
+ return [d3Node.x, d3Node.y];
1646
+ }
1647
+ return [0, 0];
1362
1648
  };
1363
- getNodePosition = (node) => this._nodePositionMap[node.getId()];
1364
1649
  getEdgePosition = (edge) => {
1365
- const sourcePos = this._nodePositionMap[edge.getSourceNodeId()];
1366
- const targetPos = this._nodePositionMap[edge.getTargetNodeId()];
1650
+ const d3Edge = this._edgeMap[edge.id];
1651
+ if (d3Edge) {
1652
+ if (!d3Edge.isVirtual) {
1653
+ return {
1654
+ type: EDGE_TYPE.LINE,
1655
+ sourcePosition: [d3Edge.source.x, d3Edge.source.y],
1656
+ targetPosition: [d3Edge.target.x, d3Edge.target.y],
1657
+ controlPoints: []
1658
+ };
1659
+ }
1660
+ const virtualEdge = this._edgeMap[d3Edge.virtualEdgeId];
1661
+ const edgeCount = virtualEdge.edgeCount;
1662
+ const sourcePosition = [virtualEdge.source.x, virtualEdge.source.y];
1663
+ const targetPosition = [virtualEdge.target.x, virtualEdge.target.y];
1664
+ const distance = Math.hypot(sourcePosition[0] - targetPosition[0], sourcePosition[1] - targetPosition[1]);
1665
+ const index = d3Edge.index;
1666
+ const direction = index % 2 ? 1 : -1;
1667
+ const symmetricShape = edgeCount % 2 === 0;
1668
+ const offset = Math.max(distance / 10, 5) * (symmetricShape ? Math.floor(index / 2 + 1) : Math.ceil(index / 2));
1669
+ const controlPoint = computeControlPoint(sourcePosition, targetPosition, direction, offset);
1670
+ return {
1671
+ type: EDGE_TYPE.SPLINE_CURVE,
1672
+ sourcePosition,
1673
+ targetPosition,
1674
+ controlPoints: [controlPoint]
1675
+ };
1676
+ }
1367
1677
  return {
1368
1678
  type: EDGE_TYPE.LINE,
1369
- sourcePosition: sourcePos,
1370
- targetPosition: targetPos,
1679
+ sourcePosition: [0, 0],
1680
+ targetPosition: [0, 0],
1371
1681
  controlPoints: []
1372
1682
  };
1373
1683
  };
1374
1684
  lockNodePosition = (node, x, y) => {
1375
- this._nodePositionMap[node.getId()] = [x, y];
1685
+ const d3Node = this._nodeMap[node.id];
1686
+ d3Node.x = x;
1687
+ d3Node.y = y;
1376
1688
  this._onLayoutChange();
1377
1689
  this._onLayoutDone();
1378
1690
  };
1379
1691
  };
1692
+ var ForceMultiGraphLayout = _ForceMultiGraphLayout;
1693
+ __publicField(ForceMultiGraphLayout, "defaultOptions", {
1694
+ alpha: 3,
1695
+ nBodyStrength: -1200,
1696
+ nBodyDistanceMin: 100,
1697
+ nBodyDistanceMax: 1400
1698
+ });
1699
+ function computeControlPoint(source, target, direction, offset) {
1700
+ const midPoint = [(source[0] + target[0]) / 2, (source[1] + target[1]) / 2];
1701
+ const dx = target[0] - source[0];
1702
+ const dy = target[1] - source[1];
1703
+ const normal = [dy, -dx];
1704
+ const length = Math.sqrt(Math.pow(normal[0], 2) + Math.pow(normal[1], 2));
1705
+ const normalized = [normal[0] / length, normal[1] / length];
1706
+ return [
1707
+ midPoint[0] + normalized[0] * offset * direction,
1708
+ midPoint[1] + normalized[1] * offset * direction
1709
+ ];
1710
+ }
1380
1711
 
1381
- // dist/utils/create-graph.js
1382
- function createGraph({ name, nodes, edges, nodeParser, edgeParser }) {
1383
- const graph = new Graph();
1384
- const graphName = name || Date.now();
1385
- graph.setGraphName(graphName);
1386
- const glNodes = nodes.map((node) => {
1387
- const { id } = nodeParser(node);
1388
- return new Node({
1389
- id,
1390
- data: node
1391
- });
1392
- });
1393
- graph.batchAddNodes(glNodes);
1394
- const glEdges = edges.map((edge) => {
1395
- const { id, sourceId, targetId, directed } = edgeParser(edge);
1396
- return new Edge({
1397
- id,
1398
- sourceId,
1399
- targetId,
1400
- directed,
1401
- data: edge
1402
- });
1403
- });
1404
- graph.batchAddEdges(glEdges);
1405
- return graph;
1406
- }
1407
-
1408
- // dist/loaders/node-parsers.js
1409
- function basicNodeParser(node) {
1410
- if (node.id === void 0) {
1411
- log.error("Invalid node: id is missing.")();
1412
- return null;
1413
- }
1414
- return { id: node.id };
1415
- }
1416
-
1417
- // dist/loaders/edge-parsers.js
1418
- function basicEdgeParser(edge) {
1419
- const { id, directed, sourceId, targetId } = edge;
1420
- if (sourceId === void 0 || targetId === void 0) {
1421
- log.error("Invalid edge: sourceId or targetId is missing.")();
1422
- return null;
1423
- }
1424
- return {
1425
- id,
1426
- directed: directed || false,
1427
- sourceId,
1428
- targetId
1429
- };
1430
- }
1431
-
1432
- // dist/loaders/json-loader.js
1433
- var JSONLoader = ({ json, nodeParser = basicNodeParser, edgeParser = basicEdgeParser }) => {
1434
- const { name = "default", nodes, edges } = json;
1435
- if (!nodes) {
1436
- log.error("Invalid graph: nodes is missing.")();
1437
- return null;
1438
- }
1439
- const graph = createGraph({ name, nodes, edges, nodeParser, edgeParser });
1440
- return graph;
1441
- };
1442
-
1443
- // dist/utils/layer-utils.js
1444
- var mixedGetPosition = (getPosition, getOffset2) => {
1445
- if (!getOffset2) {
1446
- return getPosition;
1447
- }
1448
- if (typeof getOffset2 === "function") {
1449
- return (d) => {
1450
- const [x, y] = getPosition(d);
1451
- const [offX2, offY2] = getOffset2(d);
1452
- return [x + offX2, y + offY2];
1712
+ // dist/layouts/experimental/hive-plot-layout.js
1713
+ var _HivePlotLayout = class extends GraphLayout {
1714
+ _name = "HivePlot";
1715
+ _graph;
1716
+ _totalAxis;
1717
+ _axis;
1718
+ _nodeMap = {};
1719
+ _nodePositionMap = {};
1720
+ constructor(options = {}) {
1721
+ super(options);
1722
+ this._options = {
1723
+ ..._HivePlotLayout.defaultOptions,
1724
+ ...options
1453
1725
  };
1454
1726
  }
1455
- const [offX, offY] = getOffset2;
1456
- return (d) => {
1457
- const [x, y] = getPosition(d);
1458
- return [x + offX, y + offY];
1727
+ initializeGraph(graph) {
1728
+ this.updateGraph(graph);
1729
+ }
1730
+ updateGraph(graph) {
1731
+ const { getNodeAxis, innerRadius, outerRadius } = this._options;
1732
+ this._graph = graph;
1733
+ this._nodeMap = graph.getNodes().reduce((res, node) => {
1734
+ res[node.getId()] = node;
1735
+ return res;
1736
+ }, {});
1737
+ this._axis = graph.getNodes().reduce((res, node) => {
1738
+ const axis = getNodeAxis(node);
1739
+ if (!res[axis]) {
1740
+ res[axis] = [];
1741
+ }
1742
+ res[axis].push(node);
1743
+ return res;
1744
+ }, {});
1745
+ this._axis = Object.keys(this._axis).reduce((res, axis) => {
1746
+ const bucketedNodes = this._axis[axis];
1747
+ const sortedNodes = bucketedNodes.sort((a, b) => {
1748
+ if (a.getDegree() > b.getDegree()) {
1749
+ return 1;
1750
+ }
1751
+ if (a.getDegree() === b.getDegree()) {
1752
+ return 0;
1753
+ }
1754
+ return -1;
1755
+ });
1756
+ res[axis] = sortedNodes;
1757
+ return res;
1758
+ }, {});
1759
+ this._totalAxis = Object.keys(this._axis).length;
1760
+ const center = [0, 0];
1761
+ const angleInterval = 360 / Object.keys(this._axis).length;
1762
+ this._nodePositionMap = Object.keys(this._axis).reduce((res, axis, axisIdx) => {
1763
+ const axisAngle = angleInterval * axisIdx;
1764
+ const bucketedNodes = this._axis[axis];
1765
+ const interval = (outerRadius - innerRadius) / bucketedNodes.length;
1766
+ bucketedNodes.forEach((node, idx) => {
1767
+ const radius = innerRadius + idx * interval;
1768
+ const x = Math.cos(axisAngle / 180 * Math.PI) * radius + center[0];
1769
+ const y = Math.sin(axisAngle / 180 * Math.PI) * radius + center[1];
1770
+ res[node.getId()] = [x, y];
1771
+ });
1772
+ return res;
1773
+ }, {});
1774
+ }
1775
+ start() {
1776
+ this._onLayoutChange();
1777
+ this._onLayoutDone();
1778
+ }
1779
+ getNodePosition = (node) => this._nodePositionMap[node.getId()];
1780
+ getEdgePosition = (edge) => {
1781
+ const { getNodeAxis } = this._options;
1782
+ const sourceNodeId = edge.getSourceNodeId();
1783
+ const targetNodeId = edge.getTargetNodeId();
1784
+ const sourcePosition = this._nodePositionMap[sourceNodeId];
1785
+ const targetPosition = this._nodePositionMap[targetNodeId];
1786
+ const sourceNode = this._nodeMap[sourceNodeId];
1787
+ const targetNode = this._nodeMap[targetNodeId];
1788
+ const sourceNodeAxis = getNodeAxis(sourceNode);
1789
+ const targetNodeAxis = getNodeAxis(targetNode);
1790
+ if (sourceNodeAxis === targetNodeAxis) {
1791
+ return {
1792
+ type: EDGE_TYPE.LINE,
1793
+ sourcePosition,
1794
+ targetPosition,
1795
+ controlPoints: []
1796
+ };
1797
+ }
1798
+ const controlPoint = computeControlPoint2({
1799
+ sourcePosition,
1800
+ sourceNodeAxis,
1801
+ targetPosition,
1802
+ targetNodeAxis,
1803
+ totalAxis: this._totalAxis
1804
+ });
1805
+ return {
1806
+ type: EDGE_TYPE.SPLINE_CURVE,
1807
+ sourcePosition,
1808
+ targetPosition,
1809
+ controlPoints: [controlPoint]
1810
+ };
1811
+ };
1812
+ lockNodePosition = (node, x, y) => {
1813
+ this._nodePositionMap[node.id] = [x, y];
1814
+ this._onLayoutChange();
1815
+ this._onLayoutDone();
1459
1816
  };
1460
1817
  };
1818
+ var HivePlotLayout = _HivePlotLayout;
1819
+ __publicField(HivePlotLayout, "defaultOptions", {
1820
+ innerRadius: 100,
1821
+ outerRadius: 500,
1822
+ getNodeAxis: (node) => node.getPropertyValue("group")
1823
+ });
1824
+ function computeControlPoint2({ sourcePosition, sourceNodeAxis, targetPosition, targetNodeAxis, totalAxis }) {
1825
+ const halfAxis = (totalAxis - 1) / 2;
1826
+ const sameSide = sourceNodeAxis <= halfAxis && targetNodeAxis <= halfAxis || sourceNodeAxis > halfAxis && targetNodeAxis > halfAxis;
1827
+ const direction = sameSide && sourceNodeAxis <= halfAxis && targetNodeAxis <= halfAxis ? 1 : -1;
1828
+ const source = sourceNodeAxis < targetNodeAxis && sameSide ? sourcePosition : targetPosition;
1829
+ const target = sourceNodeAxis < targetNodeAxis && sameSide ? targetPosition : sourcePosition;
1830
+ const distance = Math.hypot(source[0] - target[0], source[1] - target[1]);
1831
+ const offset = distance * 0.2;
1832
+ const midPoint = [(source[0] + target[0]) / 2, (source[1] + target[1]) / 2];
1833
+ const dx = target[0] - source[0];
1834
+ const dy = target[1] - source[1];
1835
+ const normal = [dy, -dx];
1836
+ const length = Math.hypot(dy, -dx);
1837
+ const normalized = [normal[0] / length, normal[1] / length];
1838
+ return [
1839
+ midPoint[0] + normalized[0] * offset * direction,
1840
+ midPoint[1] + normalized[1] * offset * direction
1841
+ ];
1842
+ }
1461
1843
 
1462
1844
  // dist/layers/graph-layer.js
1463
1845
  var import_core16 = require("@deck.gl/core");
@@ -1845,6 +2227,25 @@ var Stylesheet = class {
1845
2227
  }
1846
2228
  };
1847
2229
 
2230
+ // dist/utils/layer-utils.js
2231
+ var mixedGetPosition = (getPosition, getOffset2) => {
2232
+ if (!getOffset2) {
2233
+ return getPosition;
2234
+ }
2235
+ if (typeof getOffset2 === "function") {
2236
+ return (d) => {
2237
+ const [x, y] = getPosition(d);
2238
+ const [offX2, offY2] = getOffset2(d);
2239
+ return [x + offX2, y + offY2];
2240
+ };
2241
+ }
2242
+ const [offX, offY] = getOffset2;
2243
+ return (d) => {
2244
+ const [x, y] = getPosition(d);
2245
+ return [x + offX, y + offY];
2246
+ };
2247
+ };
2248
+
1848
2249
  // dist/core/interaction-manager.js
1849
2250
  var NODE_TO_EDGE_STATE_MAP = {
1850
2251
  [NODE_STATE.DEFAULT]: EDGE_STATE.DEFAULT,
@@ -2182,8 +2583,6 @@ var fs = (
2182
2583
 
2183
2584
  precision highp float;
2184
2585
 
2185
- uniform float cornerRadius;
2186
-
2187
2586
  varying vec4 vFillColor;
2188
2587
  varying vec2 unitPosition;
2189
2588
 
@@ -2192,7 +2591,7 @@ void main(void) {
2192
2591
  float distToCenter = length(unitPosition);
2193
2592
 
2194
2593
  /* Calculate the cutoff radius for the rounded corners */
2195
- float threshold = sqrt(2.0) * (1.0 - cornerRadius) + 1.0 * cornerRadius;
2594
+ float threshold = sqrt(2.0) * (1.0 - roundedRectangle.cornerRadius) + 1.0 * roundedRectangle.cornerRadius;
2196
2595
  if (distToCenter <= threshold) {
2197
2596
  gl_FragColor = vFillColor;
2198
2597
  } else {
@@ -2207,19 +2606,33 @@ void main(void) {
2207
2606
  );
2208
2607
 
2209
2608
  // dist/layers/node-layers/rounded-rectangle-layer.js
2609
+ var uniformBlock = `uniform roundedRectangleUniforms {
2610
+ float cornerRadius;
2611
+ } roundedRectangle;
2612
+ `;
2613
+ var roundedRectangleUniforms = {
2614
+ name: "roundedRectangle",
2615
+ vs: uniformBlock,
2616
+ fs: uniformBlock,
2617
+ uniformTypes: {
2618
+ cornerRadius: "f32"
2619
+ }
2620
+ };
2210
2621
  var RoundedRectangleLayer = class extends RectangleLayer {
2211
- draw({ uniforms }) {
2212
- super.draw({
2213
- uniforms: {
2214
- ...uniforms,
2215
- cornerRadius: this.props.cornerRadius
2216
- }
2217
- });
2622
+ draw(props) {
2623
+ const { cornerRadius } = this.props;
2624
+ const roundedRectangleProps = { cornerRadius };
2625
+ const model = this.state.model;
2626
+ model.shaderInputs.setProps({ roundedRectangle: roundedRectangleProps });
2627
+ super.draw(props);
2218
2628
  }
2219
2629
  getShaders() {
2220
- return Object.assign({}, super.getShaders(void 0), {
2221
- fs
2222
- });
2630
+ const shaders = super.getShaders(void 0);
2631
+ return {
2632
+ ...shaders,
2633
+ fs,
2634
+ modules: [...shaders.modules, roundedRectangleUniforms]
2635
+ };
2223
2636
  }
2224
2637
  };
2225
2638
  __publicField(RoundedRectangleLayer, "layerName", "RoundedRectangleLayer");
@@ -2229,7 +2642,7 @@ RoundedRectangleLayer.defaultProps = {
2229
2642
  cornerRadius: 0.1
2230
2643
  };
2231
2644
 
2232
- // dist/layers/node-layers/path-rounded-rectange-layer.js
2645
+ // dist/layers/node-layers/path-rounded-rectangle-layer.js
2233
2646
  var import_core6 = require("@deck.gl/core");
2234
2647
  var import_layers5 = require("@deck.gl/layers");
2235
2648
 
@@ -2310,7 +2723,7 @@ function getPointsForArc(sweepAngle, degreeFactor, startAngle, circlePoint, radi
2310
2723
  return points;
2311
2724
  }
2312
2725
 
2313
- // dist/layers/node-layers/path-rounded-rectange-layer.js
2726
+ // dist/layers/node-layers/path-rounded-rectangle-layer.js
2314
2727
  var generateRoundedRectangle = (node, { getWidth, getHeight, getPosition, getCornerRadius }) => {
2315
2728
  const pos = getPosition(node);
2316
2729
  const width = typeof getWidth === "function" ? getWidth(node) : getWidth;
@@ -3360,6 +3773,69 @@ var FlowLayer = class extends import_core15.CompositeLayer {
3360
3773
  };
3361
3774
  __publicField(FlowLayer, "layerName", "FlowLayer");
3362
3775
 
3776
+ // dist/loaders/create-graph.js
3777
+ function createGraph(props) {
3778
+ const { name, nodes, edges, nodeParser, edgeParser } = props;
3779
+ const graph = new Graph();
3780
+ const graphName = name || Date.now();
3781
+ graph.setGraphName(graphName);
3782
+ const glNodes = nodes.map((node) => {
3783
+ const { id } = nodeParser(node);
3784
+ return new Node({
3785
+ id,
3786
+ data: node
3787
+ });
3788
+ });
3789
+ graph.batchAddNodes(glNodes);
3790
+ const glEdges = edges.map((edge) => {
3791
+ const { id, sourceId, targetId, directed } = edgeParser(edge);
3792
+ return new Edge({
3793
+ id,
3794
+ sourceId,
3795
+ targetId,
3796
+ directed,
3797
+ data: edge
3798
+ });
3799
+ });
3800
+ graph.batchAddEdges(glEdges);
3801
+ return graph;
3802
+ }
3803
+
3804
+ // dist/loaders/node-parsers.js
3805
+ function basicNodeParser(node) {
3806
+ if (node.id === void 0) {
3807
+ log.error("Invalid node: id is missing.")();
3808
+ return null;
3809
+ }
3810
+ return { id: node.id };
3811
+ }
3812
+
3813
+ // dist/loaders/edge-parsers.js
3814
+ function basicEdgeParser(edge) {
3815
+ const { id, directed, sourceId, targetId } = edge;
3816
+ if (sourceId === void 0 || targetId === void 0) {
3817
+ log.error("Invalid edge: sourceId or targetId is missing.")();
3818
+ return null;
3819
+ }
3820
+ return {
3821
+ id,
3822
+ directed: directed || false,
3823
+ sourceId,
3824
+ targetId
3825
+ };
3826
+ }
3827
+
3828
+ // dist/loaders/json-loader.js
3829
+ var JSONLoader = ({ json, nodeParser = basicNodeParser, edgeParser = basicEdgeParser }) => {
3830
+ const { name = "default", nodes, edges } = json;
3831
+ if (!nodes) {
3832
+ log.error("Invalid graph: nodes is missing.")();
3833
+ return null;
3834
+ }
3835
+ const graph = createGraph({ name, nodes, edges, nodeParser, edgeParser });
3836
+ return graph;
3837
+ };
3838
+
3363
3839
  // dist/layers/graph-layer.js
3364
3840
  var NODE_LAYER_MAP = {
3365
3841
  [NODE_TYPE.RECTANGLE]: RectangleLayer,
@@ -3380,36 +3856,9 @@ var SHARED_LAYER_PROPS = {
3380
3856
  depthTest: false
3381
3857
  }
3382
3858
  };
3383
- var defaultProps3 = {
3384
- // an array of styles for layers
3385
- nodeStyle: [],
3386
- nodeEvents: {
3387
- onMouseLeave: () => {
3388
- },
3389
- onHover: () => {
3390
- },
3391
- onMouseEnter: () => {
3392
- },
3393
- onClick: () => {
3394
- },
3395
- onDrag: () => {
3396
- }
3397
- },
3398
- edgeStyle: {
3399
- color: "black",
3400
- strokeWidth: 1,
3401
- // an array of styles for layers
3402
- decorators: []
3403
- },
3404
- edgeEvents: {
3405
- onClick: () => {
3406
- },
3407
- onHover: () => {
3408
- }
3409
- },
3410
- enableDragging: false
3411
- };
3412
3859
  var GraphLayer = class extends import_core16.CompositeLayer {
3860
+ // @ts-expect-error Some typescript confusion due to override of base class state
3861
+ state;
3413
3862
  forceUpdate = () => {
3414
3863
  if (this.context && this.context.layerManager) {
3415
3864
  this.setNeedsUpdate();
@@ -3418,24 +3867,57 @@ var GraphLayer = class extends import_core16.CompositeLayer {
3418
3867
  };
3419
3868
  constructor(props) {
3420
3869
  super(props);
3421
- props.engine.addEventListener("onLayoutChange", this.forceUpdate);
3422
3870
  }
3423
3871
  initializeState() {
3424
- const interactionManager = new InteractionManager(this.props, () => this.forceUpdate());
3425
- this.state = { interactionManager };
3872
+ this.state = {
3873
+ interactionManager: new InteractionManager(this.props, () => this.forceUpdate())
3874
+ };
3875
+ const engine = this.props.engine;
3876
+ this._setGraphEngine(engine);
3426
3877
  }
3427
3878
  shouldUpdateState({ changeFlags }) {
3428
3879
  return changeFlags.dataChanged || changeFlags.propsChanged;
3429
3880
  }
3430
- updateState({ props }) {
3431
- this.state.interactionManager.updateProps(props);
3881
+ updateState({ props, oldProps, changeFlags }) {
3882
+ if (changeFlags.dataChanged && props.data && !(Array.isArray(props.data) && props.data.length === 0)) {
3883
+ const graph = this.props.graphLoader({ json: props.data });
3884
+ const layout = this.props.layout;
3885
+ const graphEngine = new GraphEngine({ graph, layout });
3886
+ this._setGraphEngine(graphEngine);
3887
+ this.state.interactionManager.updateProps(props);
3888
+ this.forceUpdate();
3889
+ } else if (changeFlags.propsChanged && props.graph !== oldProps.graph) {
3890
+ const graphEngine = new GraphEngine({ graph: props.graph, layout: props.layout });
3891
+ this._setGraphEngine(graphEngine);
3892
+ this.state.interactionManager.updateProps(props);
3893
+ this.forceUpdate();
3894
+ }
3432
3895
  }
3433
3896
  finalize() {
3434
- this.props.engine.removeEventListener("onLayoutChange", this.forceUpdate);
3897
+ this._removeGraphEngine();
3898
+ }
3899
+ _setGraphEngine(graphEngine) {
3900
+ if (graphEngine === this.state.graphEngine) {
3901
+ return;
3902
+ }
3903
+ this._removeGraphEngine();
3904
+ if (graphEngine) {
3905
+ this.state.graphEngine = graphEngine;
3906
+ this.state.graphEngine.run();
3907
+ this.state.graphEngine.addEventListener("onLayoutChange", this.forceUpdate);
3908
+ }
3909
+ }
3910
+ _removeGraphEngine() {
3911
+ if (this.state.graphEngine) {
3912
+ this.state.graphEngine.removeEventListener("onLayoutChange", this.forceUpdate);
3913
+ this.state.graphEngine.clear();
3914
+ this.state.graphEngine = null;
3915
+ }
3435
3916
  }
3436
3917
  createNodeLayers() {
3437
- const { engine, nodeStyle } = this.props;
3438
- if (!nodeStyle || !Array.isArray(nodeStyle) || nodeStyle.length === 0) {
3918
+ const engine = this.state.graphEngine;
3919
+ const { nodeStyle } = this.props;
3920
+ if (!engine || !nodeStyle || !Array.isArray(nodeStyle) || nodeStyle.length === 0) {
3439
3921
  return [];
3440
3922
  }
3441
3923
  return nodeStyle.filter(Boolean).map((style, idx) => {
@@ -3466,8 +3948,9 @@ var GraphLayer = class extends import_core16.CompositeLayer {
3466
3948
  });
3467
3949
  }
3468
3950
  createEdgeLayers() {
3469
- const { edgeStyle, engine } = this.props;
3470
- if (!edgeStyle) {
3951
+ const engine = this.state.graphEngine;
3952
+ const { edgeStyle } = this.props;
3953
+ if (!engine || !edgeStyle) {
3471
3954
  return [];
3472
3955
  }
3473
3956
  return (Array.isArray(edgeStyle) ? edgeStyle : [edgeStyle]).filter(Boolean).flatMap((style, idx) => {
@@ -3532,9 +4015,273 @@ var GraphLayer = class extends import_core16.CompositeLayer {
3532
4015
  return [this.createEdgeLayers(), this.createNodeLayers()];
3533
4016
  }
3534
4017
  };
4018
+ __publicField(GraphLayer, "layerName", "GraphLayer");
3535
4019
  __publicField(GraphLayer, "defaultProps", {
3536
- pickable: true
4020
+ // Composite layer props
4021
+ // @ts-expect-error composite layer props
4022
+ pickable: true,
4023
+ // Graph props
4024
+ graphLoader: JSONLoader,
4025
+ nodeStyle: [],
4026
+ nodeEvents: {
4027
+ onMouseLeave: () => {
4028
+ },
4029
+ onHover: () => {
4030
+ },
4031
+ onMouseEnter: () => {
4032
+ },
4033
+ onClick: () => {
4034
+ },
4035
+ onDrag: () => {
4036
+ }
4037
+ },
4038
+ edgeStyle: {
4039
+ stroke: "black",
4040
+ strokeWidth: 1,
4041
+ // an array of styles for layers
4042
+ decorators: []
4043
+ },
4044
+ edgeEvents: {
4045
+ onClick: () => {
4046
+ },
4047
+ onHover: () => {
4048
+ }
4049
+ },
4050
+ enableDragging: false
4051
+ });
4052
+
4053
+ // dist/widgets/view-control-widget.js
4054
+ var import_jsx_runtime2 = require("preact/jsx-runtime");
4055
+ var import_preact2 = require("preact");
4056
+
4057
+ // dist/widgets/long-press-button.js
4058
+ var import_jsx_runtime = require("preact/jsx-runtime");
4059
+ var import_preact = require("preact");
4060
+ var LongPressButton = class extends import_preact.Component {
4061
+ buttonPressTimer = null;
4062
+ _repeat = () => {
4063
+ if (this.buttonPressTimer) {
4064
+ this.props.onClick();
4065
+ this.buttonPressTimer = setTimeout(this._repeat, 100);
4066
+ }
4067
+ };
4068
+ _handleButtonPress = () => {
4069
+ this.buttonPressTimer = setTimeout(this._repeat, 100);
4070
+ };
4071
+ _handleButtonRelease = () => {
4072
+ if (this.buttonPressTimer) {
4073
+ clearTimeout(this.buttonPressTimer);
4074
+ }
4075
+ this.buttonPressTimer = null;
4076
+ };
4077
+ render() {
4078
+ return (0, import_jsx_runtime.jsx)("div", { className: "deck-widget-button", children: (0, import_jsx_runtime.jsx)("div", { style: {
4079
+ pointerEvents: "auto"
4080
+ }, onMouseDown: (event) => {
4081
+ this._handleButtonPress();
4082
+ document.addEventListener("mouseup", this._handleButtonRelease, { once: true });
4083
+ }, children: this.props.children }) });
4084
+ }
4085
+ };
4086
+
4087
+ // dist/widgets/view-control-widget.js
4088
+ var ViewControlWrapper = ({ children }) => (0, import_jsx_runtime2.jsxs)("div", { style: {
4089
+ alignItems: "center",
4090
+ display: "flex",
4091
+ flexDirection: "column",
4092
+ position: "absolute",
4093
+ zIndex: 99,
4094
+ userSelect: "none"
4095
+ }, children: [" ", children, " "] });
4096
+ var NavigationButtonContainer = ({ children }) => (0, import_jsx_runtime2.jsxs)("div", { style: {
4097
+ background: "#f7f7f7",
4098
+ borderRadius: "23px",
4099
+ border: "0.5px solid #eaeaea",
4100
+ boxShadow: "inset 11px 11px 5px -7px rgba(230, 230, 230, 0.49)",
4101
+ height: "46px",
4102
+ width: "46px"
4103
+ }, children: [" ", children, " "] });
4104
+ var NavigationButton = (props) => (0, import_jsx_runtime2.jsxs)("div", { onClick: props.onClick, style: {
4105
+ color: "#848484",
4106
+ cursor: "pointer",
4107
+ position: "absolute",
4108
+ left: props.left,
4109
+ top: props.top,
4110
+ transform: `rotate(${props.rotate || 0}deg)`
4111
+ // &:hover,
4112
+ // &:active {
4113
+ // color: #00ade6;
4114
+ // }
4115
+ }, children: [" ", props.children, " "] });
4116
+ var ZoomControlWrapper = ({ children }) => (0, import_jsx_runtime2.jsxs)("div", { style: {
4117
+ alignItems: "center",
4118
+ background: "#f7f7f7",
4119
+ border: "0.5px solid #eaeaea",
4120
+ display: "flex",
4121
+ flexDirection: "column",
4122
+ marginTop: "6px",
4123
+ padding: "2px 0",
4124
+ width: "18px"
4125
+ }, children: [" ", children, " "] });
4126
+ var VerticalSlider = ({ children }) => (0, import_jsx_runtime2.jsxs)("div", { style: {
4127
+ display: "inline-block",
4128
+ height: "100px",
4129
+ padding: "0",
4130
+ width: "10px"
4131
+ // > input[type='range'][orient='vertical'] {
4132
+ // -webkit-appearance: slider-vertical;
4133
+ // height: 100px;
4134
+ // padding: 0;
4135
+ // margin: 0;
4136
+ // width: 10px;
4137
+ // }
4138
+ }, children: [" ", children, " "] });
4139
+ var ZoomControlButton = ({ children }) => (0, import_jsx_runtime2.jsxs)("div", { style: {
4140
+ cursor: "pointer",
4141
+ fontSize: "14px",
4142
+ fontWeight: 500,
4143
+ margin: "-4px"
4144
+ // &:hover,
4145
+ // &:active {
4146
+ // color: #00ade6;
4147
+ // }
4148
+ }, children: [" ", children, " "] });
4149
+ var ViewControl = class extends import_preact2.Component {
4150
+ // pan actions
4151
+ panUp = () => this.props.panBy(0, this.props.deltaPan);
4152
+ panDown = () => this.props.panBy(0, -1 * this.props.deltaPan);
4153
+ panLeft = () => this.props.panBy(this.props.deltaPan, 0);
4154
+ panRight = () => this.props.panBy(-1 * this.props.deltaPan, 0);
4155
+ // zoom actions
4156
+ zoomIn = () => this.props.zoomBy(this.props.deltaZoom);
4157
+ zoomOut = () => this.props.zoomBy(-1 * this.props.deltaZoom);
4158
+ onChangeZoomLevel = (evt) => {
4159
+ const delta = evt.target.value - this.props.zoomLevel;
4160
+ this.props.zoomBy(delta);
4161
+ };
4162
+ render() {
4163
+ const buttons = [
4164
+ { top: -2, left: 14, rotate: 0, onClick: this.panUp, content: "\u25B2", key: "up" },
4165
+ { top: 12, left: 0, rotate: -90, onClick: this.panLeft, content: "\u25C0", key: "left" },
4166
+ { top: 12, left: 28, rotate: 90, onClick: this.panRight, content: "\u25B6", key: "right" },
4167
+ { top: 25, left: 14, rotate: 180, onClick: this.panDown, content: "\u25BC", key: "down" }
4168
+ ];
4169
+ return (0, import_jsx_runtime2.jsxs)(ViewControlWrapper, { children: [(0, import_jsx_runtime2.jsxs)(NavigationButtonContainer, { children: [buttons.map((b) => (0, import_jsx_runtime2.jsx)(NavigationButton, { top: `${b.top}px`, left: `${b.left}px`, rotate: b.rotate, children: (0, import_jsx_runtime2.jsx)(LongPressButton, { onClick: b.onClick, children: b.content }) }, b.key)), (0, import_jsx_runtime2.jsx)(NavigationButton, { top: "12px", left: "16px", onClick: () => {
4170
+ }, children: "\xA4" })] }), (0, import_jsx_runtime2.jsxs)(ZoomControlWrapper, { children: [(0, import_jsx_runtime2.jsx)(ZoomControlButton, { children: (0, import_jsx_runtime2.jsx)(LongPressButton, { onClick: this.zoomIn, children: "+" }) }), (0, import_jsx_runtime2.jsx)(VerticalSlider, { children: (0, import_jsx_runtime2.jsx)("input", {
4171
+ type: "range",
4172
+ value: this.props.zoomLevel,
4173
+ min: this.props.minZoom,
4174
+ max: this.props.maxZoom,
4175
+ step: this.props.deltaZoom,
4176
+ onChange: this.onChangeZoomLevel,
4177
+ /* @ts-expect-error TODO */
4178
+ orient: "vertical"
4179
+ }) }), (0, import_jsx_runtime2.jsx)(ZoomControlButton, { children: (0, import_jsx_runtime2.jsx)(LongPressButton, { onClick: this.zoomOut, children: "-" }) })] })] });
4180
+ }
4181
+ };
4182
+ __publicField(ViewControl, "displayName", "ViewControl");
4183
+ __publicField(ViewControl, "defaultProps", {
4184
+ id: void 0,
4185
+ viewId: void 0,
4186
+ placement: "top-left",
4187
+ fitBounds: () => {
4188
+ },
4189
+ panBy: () => {
4190
+ },
4191
+ zoomBy: () => {
4192
+ },
4193
+ zoomLevel: 1,
4194
+ deltaPan: 10,
4195
+ deltaZoom: 0.1,
4196
+ minZoom: 0.1,
4197
+ maxZoom: 1,
4198
+ style: {},
4199
+ className: ""
3537
4200
  });
3538
- GraphLayer.layerName = "GraphLayer";
3539
- GraphLayer.defaultProps = defaultProps3;
4201
+ var ViewControlWidget = class {
4202
+ id = "zoom";
4203
+ props;
4204
+ placement = "top-left";
4205
+ orientation = "vertical";
4206
+ viewId = null;
4207
+ viewports = {};
4208
+ deck;
4209
+ element;
4210
+ constructor(props) {
4211
+ this.props = { ...ViewControl.defaultProps, ...props };
4212
+ this.id = props.id || "zoom";
4213
+ this.viewId = props.viewId || null;
4214
+ this.placement = props.placement || "top-left";
4215
+ props.style = props.style || {};
4216
+ this.props = props;
4217
+ }
4218
+ onAdd({ deck }) {
4219
+ this.deck = deck;
4220
+ this.element = document.createElement("div");
4221
+ const { style, className } = this.props;
4222
+ this.element.classList.add("deck-widget", "deck-widget-zoom");
4223
+ if (className) {
4224
+ this.element.classList.add(className);
4225
+ }
4226
+ if (style) {
4227
+ Object.entries(style).map(([key, value]) => this.element.style.setProperty(key, value));
4228
+ }
4229
+ const ui = (0, import_jsx_runtime2.jsx)(ViewControl, { ...this.props, zoomBy: this.handleDeltaZoom.bind(this), panBy: this.handlePanBy.bind(this) });
4230
+ (0, import_preact2.render)(ui, this.element);
4231
+ return this.element;
4232
+ }
4233
+ onRemove() {
4234
+ this.deck = void 0;
4235
+ this.element = void 0;
4236
+ }
4237
+ setProps(props) {
4238
+ Object.assign(this.props, props);
4239
+ }
4240
+ onViewportChange(viewport) {
4241
+ this.viewports[viewport.id] = viewport;
4242
+ }
4243
+ handleDeltaZoom(deltaZoom) {
4244
+ for (const view of this.deck.getViewports()) {
4245
+ this.handleZoomView(view, view.zoom + deltaZoom);
4246
+ }
4247
+ }
4248
+ handlePanBy(deltaX, deltaY) {
4249
+ for (const viewport of this.deck.getViewports()) {
4250
+ this.handlePanViewport(viewport, deltaX, deltaY);
4251
+ }
4252
+ }
4253
+ handleZoomView(viewport, nextZoom) {
4254
+ const viewId = this.viewId || (viewport == null ? void 0 : viewport.id) || "default-view";
4255
+ const viewState = this.deck.viewManager.viewState || viewport;
4256
+ const nextViewState = {
4257
+ ...viewState,
4258
+ zoom: nextZoom
4259
+ // transitionDuration: this.props.transitionDuration,
4260
+ // transitionInterpolator: new FlyToInterpolator()
4261
+ };
4262
+ this.deck._onViewStateChange({ viewId, viewState: nextViewState, interactionState: {} });
4263
+ }
4264
+ handlePanViewport(viewport, deltaX, deltaY) {
4265
+ const viewId = this.viewId || (viewport == null ? void 0 : viewport.id) || "default-view";
4266
+ const viewState = this.deck.viewManager.viewState || viewport;
4267
+ const nextViewState = {
4268
+ ...viewState,
4269
+ position: [viewport.position[0] + deltaX, viewport.position[1] + deltaY]
4270
+ };
4271
+ this.deck._onViewStateChange({ viewId, viewState: nextViewState, interactionState: {} });
4272
+ }
4273
+ };
4274
+
4275
+ // dist/loaders/simple-json-graph-loader.js
4276
+ var JSONLoader2 = ({ json, nodeParser, edgeParser }) => loadSimpleJSONGraph(json, { nodeParser, edgeParser });
4277
+ function loadSimpleJSONGraph(json, options) {
4278
+ const { nodeParser = basicNodeParser, edgeParser = basicEdgeParser } = options;
4279
+ const { name = "default", nodes, edges } = json;
4280
+ if (!nodes) {
4281
+ log.error("Invalid graph: nodes is missing.")();
4282
+ return null;
4283
+ }
4284
+ const graph = createGraph({ name, nodes, edges, nodeParser, edgeParser });
4285
+ return graph;
4286
+ }
3540
4287
  //# sourceMappingURL=index.cjs.map