@deck.gl-community/graph-layers 9.0.0
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.
- package/LICENSE +20 -0
- package/README.md +7 -0
- package/dist/core/base-layout.d.ts +71 -0
- package/dist/core/base-layout.js +133 -0
- package/dist/core/cache.d.ts +14 -0
- package/dist/core/cache.js +26 -0
- package/dist/core/constants.d.ts +101 -0
- package/dist/core/constants.js +48 -0
- package/dist/core/edge.d.ts +86 -0
- package/dist/core/edge.js +121 -0
- package/dist/core/graph-engine.d.ts +54 -0
- package/dist/core/graph-engine.js +128 -0
- package/dist/core/graph.d.ts +155 -0
- package/dist/core/graph.js +301 -0
- package/dist/core/interaction-manager.d.ts +40 -0
- package/dist/core/interaction-manager.js +169 -0
- package/dist/core/node.d.ts +103 -0
- package/dist/core/node.js +177 -0
- package/dist/index.cjs +3540 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +28 -0
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer-fragment.glsl.d.ts +1 -0
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer-fragment.glsl.js +49 -0
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer-vertex-tf.glsl.d.ts +1 -0
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer-vertex-tf.glsl.js +14 -0
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer-vertex.glsl.d.ts +1 -0
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer-vertex.glsl.js +73 -0
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer.d.ts +20 -0
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer.js +133 -0
- package/dist/layers/common-layers/marker-layer/atlas-data-url.d.ts +3 -0
- package/dist/layers/common-layers/marker-layer/atlas-data-url.js +8 -0
- package/dist/layers/common-layers/marker-layer/marker-layer.d.ts +13 -0
- package/dist/layers/common-layers/marker-layer/marker-layer.js +29 -0
- package/dist/layers/common-layers/marker-layer/marker-list.d.ts +62 -0
- package/dist/layers/common-layers/marker-layer/marker-list.js +67 -0
- package/dist/layers/common-layers/marker-layer/marker-mapping.d.ts +422 -0
- package/dist/layers/common-layers/marker-layer/marker-mapping.js +427 -0
- package/dist/layers/common-layers/spline-layer/spline-layer.d.ts +24 -0
- package/dist/layers/common-layers/spline-layer/spline-layer.js +68 -0
- package/dist/layers/common-layers/zoomable-text-layer/zoomable-text-layer.d.ts +16 -0
- package/dist/layers/common-layers/zoomable-text-layer/zoomable-text-layer.js +65 -0
- package/dist/layers/edge-layer.d.ts +25 -0
- package/dist/layers/edge-layer.js +75 -0
- package/dist/layers/edge-layers/curved-edge-layer.d.ts +6 -0
- package/dist/layers/edge-layers/curved-edge-layer.js +69 -0
- package/dist/layers/edge-layers/edge-label-layer.d.ts +6 -0
- package/dist/layers/edge-layers/edge-label-layer.js +42 -0
- package/dist/layers/edge-layers/flow-layer.d.ts +6 -0
- package/dist/layers/edge-layers/flow-layer.js +28 -0
- package/dist/layers/edge-layers/path-edge-layer.d.ts +6 -0
- package/dist/layers/edge-layers/path-edge-layer.js +27 -0
- package/dist/layers/edge-layers/straight-line-edge-layer.d.ts +6 -0
- package/dist/layers/edge-layers/straight-line-edge-layer.js +26 -0
- package/dist/layers/graph-layer.d.ts +32 -0
- package/dist/layers/graph-layer.js +193 -0
- package/dist/layers/node-layers/circle-layer.d.ts +6 -0
- package/dist/layers/node-layers/circle-layer.js +23 -0
- package/dist/layers/node-layers/image-layer.d.ts +6 -0
- package/dist/layers/node-layers/image-layer.js +23 -0
- package/dist/layers/node-layers/label-layer.d.ts +6 -0
- package/dist/layers/node-layers/label-layer.js +23 -0
- package/dist/layers/node-layers/path-rounded-rectange-layer.d.ts +6 -0
- package/dist/layers/node-layers/path-rounded-rectange-layer.js +46 -0
- package/dist/layers/node-layers/rectangle-layer.d.ts +6 -0
- package/dist/layers/node-layers/rectangle-layer.js +49 -0
- package/dist/layers/node-layers/rounded-rectangle-layer-fragment.d.ts +1 -0
- package/dist/layers/node-layers/rounded-rectangle-layer-fragment.js +30 -0
- package/dist/layers/node-layers/rounded-rectangle-layer.d.ts +8 -0
- package/dist/layers/node-layers/rounded-rectangle-layer.js +28 -0
- package/dist/layers/node-layers/zoomable-marker-layer.d.ts +10 -0
- package/dist/layers/node-layers/zoomable-marker-layer.js +40 -0
- package/dist/layouts/d3-force/d3-force-layout.d.ts +24 -0
- package/dist/layouts/d3-force/d3-force-layout.js +116 -0
- package/dist/layouts/d3-force/worker.d.ts +0 -0
- package/dist/layouts/d3-force/worker.js +46 -0
- package/dist/layouts/gpu-force/gpu-force-layout.d.ts +30 -0
- package/dist/layouts/gpu-force/gpu-force-layout.js +232 -0
- package/dist/layouts/gpu-force/worker.d.ts +0 -0
- package/dist/layouts/gpu-force/worker.js +116 -0
- package/dist/layouts/simple-layout/simple-layout.d.ts +22 -0
- package/dist/layouts/simple-layout/simple-layout.js +64 -0
- package/dist/loaders/edge-parsers.d.ts +6 -0
- package/dist/loaders/edge-parsers.js +17 -0
- package/dist/loaders/json-loader.d.ts +7 -0
- package/dist/loaders/json-loader.js +16 -0
- package/dist/loaders/node-parsers.d.ts +3 -0
- package/dist/loaders/node-parsers.js +11 -0
- package/dist/style/style-property.d.ts +14 -0
- package/dist/style/style-property.js +195 -0
- package/dist/style/style-sheet.d.ts +10 -0
- package/dist/style/style-sheet.js +252 -0
- package/dist/utils/create-graph.d.ts +8 -0
- package/dist/utils/create-graph.js +33 -0
- package/dist/utils/layer-utils.d.ts +1 -0
- package/dist/utils/layer-utils.js +20 -0
- package/dist/utils/log.d.ts +2 -0
- package/dist/utils/log.js +6 -0
- package/dist/utils/polygon-calculations.d.ts +1 -0
- package/dist/utils/polygon-calculations.js +102 -0
- package/package.json +55 -0
- package/src/core/base-layout.ts +154 -0
- package/src/core/cache.ts +31 -0
- package/src/core/constants.ts +58 -0
- package/src/core/edge.ts +145 -0
- package/src/core/graph-engine.ts +170 -0
- package/src/core/graph.ts +342 -0
- package/src/core/interaction-manager.ts +225 -0
- package/src/core/node.ts +205 -0
- package/src/index.ts +42 -0
- package/src/layers/common-layers/flow-path-layer/flow-path-layer-fragment.glsl.ts +50 -0
- package/src/layers/common-layers/flow-path-layer/flow-path-layer-vertex-tf.glsl.ts +15 -0
- package/src/layers/common-layers/flow-path-layer/flow-path-layer-vertex.glsl.ts +74 -0
- package/src/layers/common-layers/flow-path-layer/flow-path-layer.ts +154 -0
- package/src/layers/common-layers/marker-layer/atlas-data-url.ts +10 -0
- package/src/layers/common-layers/marker-layer/marker-atlas.png +0 -0
- package/src/layers/common-layers/marker-layer/marker-layer.ts +36 -0
- package/src/layers/common-layers/marker-layer/marker-list.ts +68 -0
- package/src/layers/common-layers/marker-layer/marker-mapping.ts +428 -0
- package/src/layers/common-layers/marker-layer/markers/bell-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/bell.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/bookmark-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/bookmark.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/cd-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/cd.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/checkmark.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/circle-check-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/circle-check.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/circle-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/circle-i-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/circle-i.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/circle-minus-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/circle-minus.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/circle-plus-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/circle-plus.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/circle-questionmark-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/circle-questionmark.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/circle-slash-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/circle-slash.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/circle-x-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/circle-x.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/circle.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/diamond-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/diamond.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/flag-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/flag.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/gear.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/heart-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/heart.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/location-marker-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/location-marker.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/octagonal-star-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/octagonal-star.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/person-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/person.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/pin-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/pin.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/plus-small.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/plus.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/rectangle-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/rectangle.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/star-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/star.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/tag-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/tag.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/thumb-down-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/thumb-down.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/thumb-up.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/thumb_up-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/triangle-down-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/triangle-down.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/triangle-left-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/triangle-left.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/triangle-right-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/triangle-right.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/triangle-up-filled.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/triangle-up.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/x-small.png +0 -0
- package/src/layers/common-layers/marker-layer/markers/x.png +0 -0
- package/src/layers/common-layers/spline-layer/spline-layer.ts +83 -0
- package/src/layers/common-layers/zoomable-text-layer/zoomable-text-layer.ts +90 -0
- package/src/layers/edge-layer.ts +88 -0
- package/src/layers/edge-layers/curved-edge-layer.ts +88 -0
- package/src/layers/edge-layers/edge-label-layer.ts +48 -0
- package/src/layers/edge-layers/flow-layer.ts +34 -0
- package/src/layers/edge-layers/path-edge-layer.ts +39 -0
- package/src/layers/edge-layers/straight-line-edge-layer.ts +38 -0
- package/src/layers/graph-layer.ts +225 -0
- package/src/layers/node-layers/circle-layer.ts +29 -0
- package/src/layers/node-layers/image-layer.ts +29 -0
- package/src/layers/node-layers/label-layer.ts +29 -0
- package/src/layers/node-layers/path-rounded-rectange-layer.ts +56 -0
- package/src/layers/node-layers/rectangle-layer.ts +58 -0
- package/src/layers/node-layers/rounded-rectangle-layer-fragment.ts +31 -0
- package/src/layers/node-layers/rounded-rectangle-layer.ts +32 -0
- package/src/layers/node-layers/zoomable-marker-layer.ts +49 -0
- package/src/layouts/d3-force/d3-force-layout.ts +145 -0
- package/src/layouts/d3-force/worker.ts +61 -0
- package/src/layouts/gpu-force/gpu-force-layout.ts +249 -0
- package/src/layouts/gpu-force/worker.ts +137 -0
- package/src/layouts/simple-layout/simple-layout.ts +87 -0
- package/src/loaders/edge-parsers.ts +21 -0
- package/src/loaders/json-loader.ts +19 -0
- package/src/loaders/node-parsers.ts +13 -0
- package/src/style/style-property.ts +229 -0
- package/src/style/style-sheet.ts +277 -0
- package/src/utils/create-graph.ts +38 -0
- package/src/utils/layer-utils.ts +23 -0
- package/src/utils/log.ts +9 -0
- package/src/utils/polygon-calculations.ts +154 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// deck.gl-community
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
import { Cache } from './cache';
|
|
5
|
+
// Graph engine controls the graph data and layout calculation
|
|
6
|
+
export class GraphEngine extends EventTarget {
|
|
7
|
+
_graph;
|
|
8
|
+
_layout;
|
|
9
|
+
_cache = new Cache();
|
|
10
|
+
_layoutDirty = false;
|
|
11
|
+
_transactionInProgress = false;
|
|
12
|
+
constructor(graph, layout) {
|
|
13
|
+
super();
|
|
14
|
+
this._graph = graph;
|
|
15
|
+
this._layout = layout;
|
|
16
|
+
}
|
|
17
|
+
/** Getters */
|
|
18
|
+
getNodes = () => {
|
|
19
|
+
this._updateCache('nodes', () => this._graph.getNodes().filter((node) => this.getNodePosition(node)));
|
|
20
|
+
return this._cache.get('nodes');
|
|
21
|
+
};
|
|
22
|
+
getEdges = () => {
|
|
23
|
+
this._updateCache('edges', () => this._graph.getEdges().filter((edge) => this.getEdgePosition(edge)));
|
|
24
|
+
return this._cache.get('edges');
|
|
25
|
+
};
|
|
26
|
+
getNodePosition = (node) => this._layout.getNodePosition(node);
|
|
27
|
+
getEdgePosition = (edge) => this._layout.getEdgePosition(edge);
|
|
28
|
+
getGraphVersion = () => this._graph.version;
|
|
29
|
+
getLayoutLastUpdate = () => this._layout.version;
|
|
30
|
+
getLayoutState = () => this._layout.state;
|
|
31
|
+
/** Operations on the graph */
|
|
32
|
+
lockNodePosition = (node, x, y) => this._layout.lockNodePosition(node, x, y);
|
|
33
|
+
unlockNodePosition = (node) => this._layout.unlockNodePosition(node);
|
|
34
|
+
/**
|
|
35
|
+
* @fires GraphEngine#onLayoutStart
|
|
36
|
+
*/
|
|
37
|
+
_onLayoutStart = () => {
|
|
38
|
+
/**
|
|
39
|
+
* @event GraphEngine#onLayoutStart
|
|
40
|
+
* @type {CustomEvent}
|
|
41
|
+
*/
|
|
42
|
+
this.dispatchEvent(new CustomEvent('onLayoutStart'));
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* @fires GraphEngine#onLayoutChange
|
|
46
|
+
*/
|
|
47
|
+
_onLayoutChange = () => {
|
|
48
|
+
/**
|
|
49
|
+
* @event GraphEngine#onLayoutChange
|
|
50
|
+
* @type {CustomEvent}
|
|
51
|
+
*/
|
|
52
|
+
this.dispatchEvent(new CustomEvent('onLayoutChange'));
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* @fires GraphEngine#onLayoutDone
|
|
56
|
+
*/
|
|
57
|
+
_onLayoutDone = () => {
|
|
58
|
+
/**
|
|
59
|
+
* @event GraphEngine#onLayoutDone
|
|
60
|
+
* @type {CustomEvent}
|
|
61
|
+
*/
|
|
62
|
+
this.dispatchEvent(new CustomEvent('onLayoutDone'));
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* @fires GraphEngine#onLayoutError
|
|
66
|
+
*/
|
|
67
|
+
_onLayoutError = () => {
|
|
68
|
+
/**
|
|
69
|
+
* @event GraphEngine#onLayoutError
|
|
70
|
+
* @type {CustomEvent}
|
|
71
|
+
*/
|
|
72
|
+
this.dispatchEvent(new CustomEvent('onLayoutError'));
|
|
73
|
+
};
|
|
74
|
+
_onGraphStructureChanged = (entity) => {
|
|
75
|
+
this._layoutDirty = true;
|
|
76
|
+
this._graphChanged();
|
|
77
|
+
};
|
|
78
|
+
_onTransactionStart = () => {
|
|
79
|
+
this._transactionInProgress = true;
|
|
80
|
+
};
|
|
81
|
+
_onTransactionEnd = () => {
|
|
82
|
+
this._transactionInProgress = false;
|
|
83
|
+
this._graphChanged();
|
|
84
|
+
};
|
|
85
|
+
/** Layout calculations */
|
|
86
|
+
run = () => {
|
|
87
|
+
// TODO: throw if running on a cleared engine
|
|
88
|
+
this._graph.addEventListener('transactionStart', this._onTransactionStart);
|
|
89
|
+
this._graph.addEventListener('transactionEnd', this._onTransactionEnd);
|
|
90
|
+
this._graph.addEventListener('onNodeAdded', this._onGraphStructureChanged);
|
|
91
|
+
this._graph.addEventListener('onNodeRemoved', this._onGraphStructureChanged);
|
|
92
|
+
this._graph.addEventListener('onEdgeAdded', this._onGraphStructureChanged);
|
|
93
|
+
this._graph.addEventListener('onEdgeRemoved', this._onGraphStructureChanged);
|
|
94
|
+
this._layout.addEventListener('onLayoutStart', this._onLayoutStart);
|
|
95
|
+
this._layout.addEventListener('onLayoutChange', this._onLayoutChange);
|
|
96
|
+
this._layout.addEventListener('onLayoutDone', this._onLayoutDone);
|
|
97
|
+
this._layout.addEventListener('onLayoutError', this._onLayoutError);
|
|
98
|
+
this._layout.initializeGraph(this._graph);
|
|
99
|
+
this._layout.start();
|
|
100
|
+
};
|
|
101
|
+
clear = () => {
|
|
102
|
+
this._graph.removeEventListener('transactionStart', this._onTransactionStart);
|
|
103
|
+
this._graph.removeEventListener('transactionEnd', this._onTransactionEnd);
|
|
104
|
+
this._graph.removeEventListener('onNodeAdded', this._onGraphStructureChanged);
|
|
105
|
+
this._graph.removeEventListener('onNodeRemoved', this._onGraphStructureChanged);
|
|
106
|
+
this._graph.removeEventListener('onEdgeAdded', this._onGraphStructureChanged);
|
|
107
|
+
this._graph.removeEventListener('onEdgeRemoved', this._onGraphStructureChanged);
|
|
108
|
+
this._layout.removeEventListener('onLayoutStart', this._onLayoutStart);
|
|
109
|
+
this._layout.removeEventListener('onLayoutChange', this._onLayoutChange);
|
|
110
|
+
this._layout.removeEventListener('onLayoutDone', this._onLayoutDone);
|
|
111
|
+
this._layout.removeEventListener('onLayoutError', this._onLayoutError);
|
|
112
|
+
};
|
|
113
|
+
resume = () => this._layout.resume();
|
|
114
|
+
stop = () => this._layout.stop();
|
|
115
|
+
_graphChanged = () => {
|
|
116
|
+
if (this._layoutDirty && !this._transactionInProgress) {
|
|
117
|
+
this._updateLayout();
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
_updateLayout = () => {
|
|
121
|
+
this._layout.updateGraph(this._graph);
|
|
122
|
+
this._layout.update();
|
|
123
|
+
this._layoutDirty = false;
|
|
124
|
+
};
|
|
125
|
+
_updateCache(key, updateValue) {
|
|
126
|
+
this._cache.set(key, updateValue, this._graph.version + this._layout.version);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { Edge } from './edge';
|
|
2
|
+
import { Node } from './node';
|
|
3
|
+
export declare class Graph extends EventTarget {
|
|
4
|
+
/** List object of nodes. */
|
|
5
|
+
private _nodeMap;
|
|
6
|
+
/** List of object edges. */
|
|
7
|
+
private _edgeMap;
|
|
8
|
+
/**
|
|
9
|
+
* Identifies whether performing dirty check when streaming new data. If
|
|
10
|
+
* the name of the graph is not specified, will fall back to current time stamp.
|
|
11
|
+
*/
|
|
12
|
+
private _name;
|
|
13
|
+
/** Version the graph. A version is a number that is incremented every time the graph is updated. */
|
|
14
|
+
version: number;
|
|
15
|
+
/** Cached data: create array data from maps. */
|
|
16
|
+
private _cache;
|
|
17
|
+
/**
|
|
18
|
+
* The constructor of the Graph class.
|
|
19
|
+
* @param {Object} graph - copy the graph if this exists.
|
|
20
|
+
*/
|
|
21
|
+
constructor(graph?: Graph | null);
|
|
22
|
+
/**
|
|
23
|
+
* Set graph name
|
|
24
|
+
* @param {string} name
|
|
25
|
+
*/
|
|
26
|
+
setGraphName(name: string): void;
|
|
27
|
+
/** Get the name of the graph. Default value is the time stamp when creating this graph.
|
|
28
|
+
* @return {string} graph name.
|
|
29
|
+
*/
|
|
30
|
+
getGraphName(): string;
|
|
31
|
+
/**
|
|
32
|
+
* Perform a batch of operations defined by cb before indicating graph is updated
|
|
33
|
+
* @param {function} cb - a callback fuction containing the operations to perform
|
|
34
|
+
*/
|
|
35
|
+
transaction<T>(cb: (...args: unknown[]) => T): T;
|
|
36
|
+
/**
|
|
37
|
+
* Add a new node to the graph.
|
|
38
|
+
* @param {Node} node - expect a Node object to be added to the graph.
|
|
39
|
+
*/
|
|
40
|
+
addNode(node: Node): void;
|
|
41
|
+
/**
|
|
42
|
+
* Batch add nodes to the graph.
|
|
43
|
+
* @param {Node[]} nodes - a list of nodes to be added.
|
|
44
|
+
*/
|
|
45
|
+
batchAddNodes(nodes: Node[]): void;
|
|
46
|
+
/**
|
|
47
|
+
* Get all the nodes of the graph.
|
|
48
|
+
* @return {Node[]} - get all the nodes in the graph.
|
|
49
|
+
*/
|
|
50
|
+
getNodes(): Node[];
|
|
51
|
+
/**
|
|
52
|
+
* Get the node map of the graph. The key of the map is the ID of the nodes.
|
|
53
|
+
* @return {Object} - a map of nodes keyed by node IDs.
|
|
54
|
+
*/
|
|
55
|
+
getNodeMap(): Record<string | number, Node>;
|
|
56
|
+
/**
|
|
57
|
+
* Find a node by id
|
|
58
|
+
* @param {String} nodeId The id of the node
|
|
59
|
+
* @return {Object} Node
|
|
60
|
+
*/
|
|
61
|
+
findNode(nodeId: string | number): Node | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* Update the indicated node to the provided value
|
|
64
|
+
* @param {Node} node
|
|
65
|
+
*/
|
|
66
|
+
updateNode(node: Node): void;
|
|
67
|
+
/**
|
|
68
|
+
* Add a new edge to the graph.
|
|
69
|
+
* @param {Edge} edge - expect a Edge object to be added to the graph.
|
|
70
|
+
*/
|
|
71
|
+
addEdge(edge: Edge): void;
|
|
72
|
+
/**
|
|
73
|
+
* Batch add edges to the graph
|
|
74
|
+
* @param {Edge[]} edges - a list of edges to be added.
|
|
75
|
+
*/
|
|
76
|
+
batchAddEdges(edges: Edge[]): void;
|
|
77
|
+
/**
|
|
78
|
+
* Update the indicated edge to the provided value
|
|
79
|
+
* @param {Edge} edge
|
|
80
|
+
*/
|
|
81
|
+
updateEdge(edge: Edge): void;
|
|
82
|
+
/**
|
|
83
|
+
* Remove a node from the graph by node ID
|
|
84
|
+
* @param {String|Number} nodeId - the ID of the target node.
|
|
85
|
+
*/
|
|
86
|
+
removeNode(nodeId: string | number): void;
|
|
87
|
+
/**
|
|
88
|
+
* Get all the edges of the graph.
|
|
89
|
+
* @return {Edge[]} get all the edges in the graph.
|
|
90
|
+
*/
|
|
91
|
+
getEdges(): Edge[];
|
|
92
|
+
/**
|
|
93
|
+
* Get the edge map of the graph. The key of the map is the ID of the edges.
|
|
94
|
+
* @return {Object} - a map of edges keyed by edge IDs.
|
|
95
|
+
*/
|
|
96
|
+
getEdgeMap(): Record<string, Edge>;
|
|
97
|
+
/**
|
|
98
|
+
* Remove an edge from the graph by the edge ID
|
|
99
|
+
* @param {String|Number} edgeId - the target edge ID.
|
|
100
|
+
*/
|
|
101
|
+
removeEdge(edgeId: string | number): void;
|
|
102
|
+
/**
|
|
103
|
+
* Find the edge by edge ID.
|
|
104
|
+
* @param {String|Number} id - the target edge ID
|
|
105
|
+
* @return {Edge} - the target edge.
|
|
106
|
+
*/
|
|
107
|
+
findEdge(edgeId: string | number): Edge;
|
|
108
|
+
/**
|
|
109
|
+
* Return all the connected edges of a node by nodeID.
|
|
110
|
+
* @param {String|Number} nodeId - the target node ID
|
|
111
|
+
* @return {Edge[]} - an array of the connected edges.
|
|
112
|
+
*/
|
|
113
|
+
getConnectedEdges(nodeId: string | number): Edge[];
|
|
114
|
+
/**
|
|
115
|
+
* Return all the sibling nodes of a node by nodeID.
|
|
116
|
+
* @param {String|Number} nodeId - the target node ID
|
|
117
|
+
* @return {Node[]} - an array of the sibling nodes.
|
|
118
|
+
*/
|
|
119
|
+
getNodeSiblings(nodeId: string | number): Node[];
|
|
120
|
+
/**
|
|
121
|
+
* Get the degree of a node.
|
|
122
|
+
* @param {String|Number} nodeId - the target node ID.
|
|
123
|
+
* @return {Number} - the degree of the node.
|
|
124
|
+
*/
|
|
125
|
+
getDegree(nodeId: string | number): number;
|
|
126
|
+
/**
|
|
127
|
+
* Clean up all the nodes in the graph.
|
|
128
|
+
*/
|
|
129
|
+
resetNodes(): void;
|
|
130
|
+
/**
|
|
131
|
+
* Clean up all the edges in the graph.
|
|
132
|
+
*/
|
|
133
|
+
resetEdges(): void;
|
|
134
|
+
/**
|
|
135
|
+
* Clean up everything in the graph.
|
|
136
|
+
*/
|
|
137
|
+
reset(): void;
|
|
138
|
+
/**
|
|
139
|
+
* Trigger an update to the graph.
|
|
140
|
+
*/
|
|
141
|
+
triggerUpdate(): void;
|
|
142
|
+
/**
|
|
143
|
+
* Return true if the graph is empty.
|
|
144
|
+
* @return {Boolean} Return true if the graph is empty.
|
|
145
|
+
*/
|
|
146
|
+
isEmpty(): boolean;
|
|
147
|
+
/**
|
|
148
|
+
* Check the equality of two graphs data by checking last update time stamp
|
|
149
|
+
* @param {Object} g Another graph to be compared against itself
|
|
150
|
+
* @return {Bool} True if the graph is the same as itself.
|
|
151
|
+
*/
|
|
152
|
+
equals(g: Graph): boolean;
|
|
153
|
+
_bumpVersion(): void;
|
|
154
|
+
_updateCache(key: 'nodes' | 'edges', updateValue: unknown): void;
|
|
155
|
+
}
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
// deck.gl-community
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
import { log } from '../utils/log';
|
|
5
|
+
import { Cache } from './cache';
|
|
6
|
+
// Basic graph data structure
|
|
7
|
+
export class Graph extends EventTarget {
|
|
8
|
+
/** List object of nodes. */
|
|
9
|
+
_nodeMap = {};
|
|
10
|
+
/** List of object edges. */
|
|
11
|
+
_edgeMap = {};
|
|
12
|
+
/**
|
|
13
|
+
* Identifies whether performing dirty check when streaming new data. If
|
|
14
|
+
* the name of the graph is not specified, will fall back to current time stamp.
|
|
15
|
+
*/
|
|
16
|
+
_name = Date.now().toString();
|
|
17
|
+
/** Version the graph. A version is a number that is incremented every time the graph is updated. */
|
|
18
|
+
version = 0;
|
|
19
|
+
/** Cached data: create array data from maps. */
|
|
20
|
+
_cache = new Cache();
|
|
21
|
+
/**
|
|
22
|
+
* The constructor of the Graph class.
|
|
23
|
+
* @param {Object} graph - copy the graph if this exists.
|
|
24
|
+
*/
|
|
25
|
+
constructor(graph = null) {
|
|
26
|
+
super();
|
|
27
|
+
// copy the graph if it exists in the parameter
|
|
28
|
+
if (graph) {
|
|
29
|
+
// start copying the graph
|
|
30
|
+
this._nodeMap = graph._nodeMap;
|
|
31
|
+
this._edgeMap = graph._edgeMap;
|
|
32
|
+
this._name = graph && graph._name;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Set graph name
|
|
37
|
+
* @param {string} name
|
|
38
|
+
*/
|
|
39
|
+
setGraphName(name) {
|
|
40
|
+
this._name = name;
|
|
41
|
+
}
|
|
42
|
+
/** Get the name of the graph. Default value is the time stamp when creating this graph.
|
|
43
|
+
* @return {string} graph name.
|
|
44
|
+
*/
|
|
45
|
+
getGraphName() {
|
|
46
|
+
return this._name.toString();
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Perform a batch of operations defined by cb before indicating graph is updated
|
|
50
|
+
* @param {function} cb - a callback fuction containing the operations to perform
|
|
51
|
+
*/
|
|
52
|
+
transaction(cb) {
|
|
53
|
+
try {
|
|
54
|
+
this.dispatchEvent(new CustomEvent('transactionStart'));
|
|
55
|
+
return cb();
|
|
56
|
+
}
|
|
57
|
+
finally {
|
|
58
|
+
this.dispatchEvent(new CustomEvent('transactionEnd'));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Add a new node to the graph.
|
|
63
|
+
* @param {Node} node - expect a Node object to be added to the graph.
|
|
64
|
+
*/
|
|
65
|
+
addNode(node) {
|
|
66
|
+
// add it to the list and map
|
|
67
|
+
this._nodeMap[node.getId()] = node;
|
|
68
|
+
// update last update time stamp
|
|
69
|
+
this._bumpVersion();
|
|
70
|
+
this.dispatchEvent(new CustomEvent('onNodeAdded', { node }));
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Batch add nodes to the graph.
|
|
74
|
+
* @param {Node[]} nodes - a list of nodes to be added.
|
|
75
|
+
*/
|
|
76
|
+
batchAddNodes(nodes) {
|
|
77
|
+
// convert an array of objects to an object
|
|
78
|
+
this._nodeMap = nodes.reduce((res, node) => {
|
|
79
|
+
res[node.getId()] = node;
|
|
80
|
+
this.dispatchEvent(new CustomEvent('onNodeAdded', { node }));
|
|
81
|
+
return res;
|
|
82
|
+
}, { ...this._nodeMap });
|
|
83
|
+
this._bumpVersion();
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Get all the nodes of the graph.
|
|
87
|
+
* @return {Node[]} - get all the nodes in the graph.
|
|
88
|
+
*/
|
|
89
|
+
getNodes() {
|
|
90
|
+
this._updateCache('nodes', () => Object.values(this._nodeMap));
|
|
91
|
+
return this._cache.get('nodes');
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Get the node map of the graph. The key of the map is the ID of the nodes.
|
|
95
|
+
* @return {Object} - a map of nodes keyed by node IDs.
|
|
96
|
+
*/
|
|
97
|
+
getNodeMap() {
|
|
98
|
+
return this._nodeMap;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Find a node by id
|
|
102
|
+
* @param {String} nodeId The id of the node
|
|
103
|
+
* @return {Object} Node
|
|
104
|
+
*/
|
|
105
|
+
findNode(nodeId) {
|
|
106
|
+
return this._nodeMap[nodeId];
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Update the indicated node to the provided value
|
|
110
|
+
* @param {Node} node
|
|
111
|
+
*/
|
|
112
|
+
updateNode(node) {
|
|
113
|
+
this._nodeMap[node.getId()] = node;
|
|
114
|
+
this._bumpVersion();
|
|
115
|
+
this.dispatchEvent(new CustomEvent('onNodeUpdated', { node }));
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Add a new edge to the graph.
|
|
119
|
+
* @param {Edge} edge - expect a Edge object to be added to the graph.
|
|
120
|
+
*/
|
|
121
|
+
addEdge(edge) {
|
|
122
|
+
const sourceNode = this.findNode(edge.getSourceNodeId());
|
|
123
|
+
const targetNode = this.findNode(edge.getTargetNodeId());
|
|
124
|
+
if (!sourceNode || !targetNode) {
|
|
125
|
+
log.warn(`Unable to add edge ${edge.id}, source or target node is missing.`)();
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
this._edgeMap[edge.getId()] = edge;
|
|
129
|
+
sourceNode.addConnectedEdges(edge);
|
|
130
|
+
targetNode.addConnectedEdges(edge);
|
|
131
|
+
this._bumpVersion();
|
|
132
|
+
this.dispatchEvent(new CustomEvent('onEdgeAdded', { edge }));
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Batch add edges to the graph
|
|
136
|
+
* @param {Edge[]} edges - a list of edges to be added.
|
|
137
|
+
*/
|
|
138
|
+
batchAddEdges(edges) {
|
|
139
|
+
edges.forEach((edge) => this.addEdge(edge));
|
|
140
|
+
this._bumpVersion();
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Update the indicated edge to the provided value
|
|
144
|
+
* @param {Edge} edge
|
|
145
|
+
*/
|
|
146
|
+
updateEdge(edge) {
|
|
147
|
+
this._edgeMap[edge.getId()] = edge;
|
|
148
|
+
this._bumpVersion();
|
|
149
|
+
this.dispatchEvent(new CustomEvent('onEdgeUpdated', { edge }));
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Remove a node from the graph by node ID
|
|
153
|
+
* @param {String|Number} nodeId - the ID of the target node.
|
|
154
|
+
*/
|
|
155
|
+
removeNode(nodeId) {
|
|
156
|
+
const node = this.findNode(nodeId);
|
|
157
|
+
if (!node) {
|
|
158
|
+
log.warn(`Unable to remove node ${nodeId} - doesn't exist`)();
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
// remove all edges connect to this node from map
|
|
162
|
+
node.getConnectedEdges().forEach((e) => {
|
|
163
|
+
delete this._edgeMap[e.getId()];
|
|
164
|
+
});
|
|
165
|
+
// remove the node from map
|
|
166
|
+
delete this._nodeMap[nodeId];
|
|
167
|
+
this._bumpVersion();
|
|
168
|
+
this.dispatchEvent(new CustomEvent('onNodeRemoved', { node }));
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Get all the edges of the graph.
|
|
172
|
+
* @return {Edge[]} get all the edges in the graph.
|
|
173
|
+
*/
|
|
174
|
+
getEdges() {
|
|
175
|
+
this._updateCache('edges', () => Object.values(this._edgeMap));
|
|
176
|
+
return this._cache.get('edges');
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Get the edge map of the graph. The key of the map is the ID of the edges.
|
|
180
|
+
* @return {Object} - a map of edges keyed by edge IDs.
|
|
181
|
+
*/
|
|
182
|
+
getEdgeMap() {
|
|
183
|
+
return this._edgeMap;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Remove an edge from the graph by the edge ID
|
|
187
|
+
* @param {String|Number} edgeId - the target edge ID.
|
|
188
|
+
*/
|
|
189
|
+
removeEdge(edgeId) {
|
|
190
|
+
const edge = this.findEdge(edgeId);
|
|
191
|
+
if (!edge) {
|
|
192
|
+
log.warn(`Unable to remove edge ${edgeId} - doesn't exist`)();
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
const sourceNode = this.findNode(edge.getSourceNodeId());
|
|
196
|
+
const targetNode = this.findNode(edge.getTargetNodeId());
|
|
197
|
+
delete this._edgeMap[edgeId];
|
|
198
|
+
sourceNode.removeConnectedEdges(edge);
|
|
199
|
+
targetNode.removeConnectedEdges(edge);
|
|
200
|
+
this._bumpVersion();
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Find the edge by edge ID.
|
|
204
|
+
* @param {String|Number} id - the target edge ID
|
|
205
|
+
* @return {Edge} - the target edge.
|
|
206
|
+
*/
|
|
207
|
+
findEdge(edgeId) {
|
|
208
|
+
return this._edgeMap[edgeId];
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Return all the connected edges of a node by nodeID.
|
|
212
|
+
* @param {String|Number} nodeId - the target node ID
|
|
213
|
+
* @return {Edge[]} - an array of the connected edges.
|
|
214
|
+
*/
|
|
215
|
+
getConnectedEdges(nodeId) {
|
|
216
|
+
const node = this.findNode(nodeId);
|
|
217
|
+
if (!node) {
|
|
218
|
+
log.warn(`Unable to find node ${nodeId} - doesn't exist`)();
|
|
219
|
+
return [];
|
|
220
|
+
}
|
|
221
|
+
return node.getConnectedEdges();
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Return all the sibling nodes of a node by nodeID.
|
|
225
|
+
* @param {String|Number} nodeId - the target node ID
|
|
226
|
+
* @return {Node[]} - an array of the sibling nodes.
|
|
227
|
+
*/
|
|
228
|
+
getNodeSiblings(nodeId) {
|
|
229
|
+
const node = this.findNode(nodeId);
|
|
230
|
+
if (!node) {
|
|
231
|
+
log.warn(`Unable to find node ${nodeId} - doesn't exist`)();
|
|
232
|
+
return [];
|
|
233
|
+
}
|
|
234
|
+
return node.getSiblingIds().map((siblingNodeId) => this.findNode(siblingNodeId));
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Get the degree of a node.
|
|
238
|
+
* @param {String|Number} nodeId - the target node ID.
|
|
239
|
+
* @return {Number} - the degree of the node.
|
|
240
|
+
*/
|
|
241
|
+
getDegree(nodeId) {
|
|
242
|
+
const node = this.findNode(nodeId);
|
|
243
|
+
if (!node) {
|
|
244
|
+
log.warn(`Unable to find node ${nodeId} - doesn't exist`)();
|
|
245
|
+
return 0;
|
|
246
|
+
}
|
|
247
|
+
return node.getDegree();
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Clean up all the nodes in the graph.
|
|
251
|
+
*/
|
|
252
|
+
resetNodes() {
|
|
253
|
+
this._nodeMap = {};
|
|
254
|
+
this._bumpVersion();
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Clean up all the edges in the graph.
|
|
258
|
+
*/
|
|
259
|
+
resetEdges() {
|
|
260
|
+
this._edgeMap = {};
|
|
261
|
+
this._bumpVersion();
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Clean up everything in the graph.
|
|
265
|
+
*/
|
|
266
|
+
reset() {
|
|
267
|
+
this.resetNodes();
|
|
268
|
+
this.resetEdges();
|
|
269
|
+
this._bumpVersion();
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Trigger an update to the graph.
|
|
273
|
+
*/
|
|
274
|
+
triggerUpdate() {
|
|
275
|
+
this._bumpVersion();
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Return true if the graph is empty.
|
|
279
|
+
* @return {Boolean} Return true if the graph is empty.
|
|
280
|
+
*/
|
|
281
|
+
isEmpty() {
|
|
282
|
+
return Object.keys(this._nodeMap).length === 0;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Check the equality of two graphs data by checking last update time stamp
|
|
286
|
+
* @param {Object} g Another graph to be compared against itself
|
|
287
|
+
* @return {Bool} True if the graph is the same as itself.
|
|
288
|
+
*/
|
|
289
|
+
equals(g) {
|
|
290
|
+
if (!g || !(g instanceof Graph)) {
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
return this.version === g.version;
|
|
294
|
+
}
|
|
295
|
+
_bumpVersion() {
|
|
296
|
+
this.version += 1;
|
|
297
|
+
}
|
|
298
|
+
_updateCache(key, updateValue) {
|
|
299
|
+
this._cache.set(key, updateValue, this.version);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { GraphEngine } from './graph-engine';
|
|
2
|
+
import { Node } from './node';
|
|
3
|
+
interface EventMap {
|
|
4
|
+
onClick?: (info: unknown, event: Event) => void;
|
|
5
|
+
onHover?: (info: unknown) => void;
|
|
6
|
+
onMouseEnter?: (info: unknown) => void;
|
|
7
|
+
onMouseLeave?: (node: Node) => void;
|
|
8
|
+
onDragStart?: (info: unknown) => void;
|
|
9
|
+
onDrag?: (info: unknown) => void;
|
|
10
|
+
onDragEnd?: (info: unknown) => void;
|
|
11
|
+
}
|
|
12
|
+
export interface InteractionManagerProps {
|
|
13
|
+
nodeEvents?: EventMap;
|
|
14
|
+
edgeEvents?: EventMap;
|
|
15
|
+
engine: GraphEngine;
|
|
16
|
+
enableDragging: boolean;
|
|
17
|
+
resumeLayoutAfterDragging: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare class InteractionManager {
|
|
20
|
+
notifyCallback: Function;
|
|
21
|
+
private _lastInteraction;
|
|
22
|
+
private _lastHoveredNode;
|
|
23
|
+
private _lastSelectedNode;
|
|
24
|
+
nodeEvents: EventMap;
|
|
25
|
+
edgeEvents: EventMap;
|
|
26
|
+
engine: GraphEngine;
|
|
27
|
+
enableDragging: boolean;
|
|
28
|
+
resumeLayoutAfterDragging: boolean;
|
|
29
|
+
constructor(props: InteractionManagerProps, notifyCallback: Function);
|
|
30
|
+
updateProps({ nodeEvents, edgeEvents, engine, enableDragging, resumeLayoutAfterDragging }: InteractionManagerProps): void;
|
|
31
|
+
getLastInteraction(): number;
|
|
32
|
+
onClick(info: any, event: any): void;
|
|
33
|
+
_mouseLeaveNode(): void;
|
|
34
|
+
_mouseEnterNode(info: any): void;
|
|
35
|
+
onHover(info: any, event: any): void;
|
|
36
|
+
onDragStart(info: any, event: any): void;
|
|
37
|
+
onDrag(info: any, event: any): void;
|
|
38
|
+
onDragEnd(info: any, event: any): void;
|
|
39
|
+
}
|
|
40
|
+
export {};
|