@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,252 @@
|
|
|
1
|
+
// deck.gl-community
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
import { StyleProperty } from './style-property';
|
|
5
|
+
import { NODE_TYPE, EDGE_DECORATOR_TYPE } from '../core/constants';
|
|
6
|
+
import { log } from '../utils/log';
|
|
7
|
+
const COMMON_DECKGL_PROPS = {
|
|
8
|
+
getOffset: 'offset',
|
|
9
|
+
opacity: 'opacity'
|
|
10
|
+
};
|
|
11
|
+
const DECKGL_ACCESSOR_MAP = {
|
|
12
|
+
[NODE_TYPE.CIRCLE]: {
|
|
13
|
+
...COMMON_DECKGL_PROPS,
|
|
14
|
+
getFillColor: 'fill',
|
|
15
|
+
getLineColor: 'stroke',
|
|
16
|
+
getLineWidth: 'strokeWidth',
|
|
17
|
+
getRadius: 'radius'
|
|
18
|
+
},
|
|
19
|
+
[NODE_TYPE.RECTANGLE]: {
|
|
20
|
+
...COMMON_DECKGL_PROPS,
|
|
21
|
+
getWidth: 'width',
|
|
22
|
+
getHeight: 'height',
|
|
23
|
+
getFillColor: 'fill',
|
|
24
|
+
getLineColor: 'stroke',
|
|
25
|
+
getLineWidth: 'strokeWidth'
|
|
26
|
+
},
|
|
27
|
+
[NODE_TYPE.ROUNDED_RECTANGLE]: {
|
|
28
|
+
...COMMON_DECKGL_PROPS,
|
|
29
|
+
getCornerRadius: 'cornerRadius',
|
|
30
|
+
getRadius: 'radius',
|
|
31
|
+
getWidth: 'width',
|
|
32
|
+
getHeight: 'height',
|
|
33
|
+
getFillColor: 'fill',
|
|
34
|
+
getLineColor: 'stroke',
|
|
35
|
+
getLineWidth: 'strokeWidth'
|
|
36
|
+
},
|
|
37
|
+
[NODE_TYPE.PATH_ROUNDED_RECTANGLE]: {
|
|
38
|
+
...COMMON_DECKGL_PROPS,
|
|
39
|
+
getWidth: 'width',
|
|
40
|
+
getHeight: 'height',
|
|
41
|
+
getFillColor: 'fill',
|
|
42
|
+
getLineColor: 'stroke',
|
|
43
|
+
getLineWidth: 'strokeWidth',
|
|
44
|
+
getCornerRadius: 'cornerRadius'
|
|
45
|
+
},
|
|
46
|
+
[NODE_TYPE.LABEL]: {
|
|
47
|
+
...COMMON_DECKGL_PROPS,
|
|
48
|
+
getColor: 'color',
|
|
49
|
+
getText: 'text',
|
|
50
|
+
getSize: 'fontSize',
|
|
51
|
+
getTextAnchor: 'textAnchor',
|
|
52
|
+
getAlignmentBaseline: 'alignmentBaseline',
|
|
53
|
+
getAngle: 'angle',
|
|
54
|
+
scaleWithZoom: 'scaleWithZoom',
|
|
55
|
+
textMaxWidth: 'textMaxWidth',
|
|
56
|
+
textWordBreak: 'textWordBreak',
|
|
57
|
+
textSizeMinPixels: 'textSizeMinPixels'
|
|
58
|
+
},
|
|
59
|
+
[NODE_TYPE.MARKER]: {
|
|
60
|
+
...COMMON_DECKGL_PROPS,
|
|
61
|
+
getColor: 'fill',
|
|
62
|
+
getSize: 'size',
|
|
63
|
+
getMarker: 'marker',
|
|
64
|
+
scaleWithZoom: 'scaleWithZoom'
|
|
65
|
+
},
|
|
66
|
+
// --------- Edge related ---------
|
|
67
|
+
Edge: {
|
|
68
|
+
getColor: 'stroke',
|
|
69
|
+
getWidth: 'strokeWidth'
|
|
70
|
+
},
|
|
71
|
+
[EDGE_DECORATOR_TYPE.LABEL]: {
|
|
72
|
+
getColor: 'color',
|
|
73
|
+
getText: 'text',
|
|
74
|
+
getSize: 'fontSize',
|
|
75
|
+
getTextAnchor: 'textAnchor',
|
|
76
|
+
getAlignmentBaseline: 'alignmentBaseline',
|
|
77
|
+
scaleWithZoom: 'scaleWithZoom',
|
|
78
|
+
textMaxWidth: 'textMaxWidth',
|
|
79
|
+
textWordBreak: 'textWordBreak',
|
|
80
|
+
textSizeMinPixels: 'textSizeMinPixels'
|
|
81
|
+
},
|
|
82
|
+
[EDGE_DECORATOR_TYPE.FLOW]: {
|
|
83
|
+
getColor: 'color',
|
|
84
|
+
getWidth: 'width',
|
|
85
|
+
getSpeed: 'speed',
|
|
86
|
+
getTailLength: 'tailLength'
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
const DECKGL_UPDATE_TRIGGERS = {
|
|
90
|
+
[NODE_TYPE.CIRCLE]: ['getFillColor', 'getRadius', 'getLineColor', 'getLineWidth'],
|
|
91
|
+
[NODE_TYPE.RECTANGLE]: ['getFillColor', 'getLineColor', 'getLineWidth'],
|
|
92
|
+
[NODE_TYPE.ROUNDED_RECTANGLE]: [
|
|
93
|
+
'getFillColor',
|
|
94
|
+
'getLineColor',
|
|
95
|
+
'getLineWidth',
|
|
96
|
+
'getCornerRadius'
|
|
97
|
+
],
|
|
98
|
+
[NODE_TYPE.PATH_ROUNDED_RECTANGLE]: [
|
|
99
|
+
'getFillColor',
|
|
100
|
+
'getLineColor',
|
|
101
|
+
'getLineWidth',
|
|
102
|
+
'getCornerRadius'
|
|
103
|
+
],
|
|
104
|
+
[NODE_TYPE.LABEL]: [
|
|
105
|
+
'getColor',
|
|
106
|
+
'getText',
|
|
107
|
+
'getSize',
|
|
108
|
+
'getTextAnchor',
|
|
109
|
+
'getAlignmentBaseline',
|
|
110
|
+
'getAngle'
|
|
111
|
+
],
|
|
112
|
+
[NODE_TYPE.MARKER]: ['getColor', 'getSize', 'getMarker'],
|
|
113
|
+
Edge: ['getColor', 'getWidth'],
|
|
114
|
+
[EDGE_DECORATOR_TYPE.LABEL]: [
|
|
115
|
+
'getColor',
|
|
116
|
+
'getText',
|
|
117
|
+
'getSize',
|
|
118
|
+
'getTextAnchor',
|
|
119
|
+
'getAlignmentBaseline'
|
|
120
|
+
],
|
|
121
|
+
[EDGE_DECORATOR_TYPE.FLOW]: ['getColor', 'getWidth', 'getSpeed', 'getTailLength']
|
|
122
|
+
};
|
|
123
|
+
export class Stylesheet {
|
|
124
|
+
type;
|
|
125
|
+
properties;
|
|
126
|
+
constructor(style, updateTriggers) {
|
|
127
|
+
const { type: layerType, ...restStyle } = style;
|
|
128
|
+
if (!layerType || !(layerType in DECKGL_ACCESSOR_MAP)) {
|
|
129
|
+
throw new Error(`illegal type: ${layerType}`);
|
|
130
|
+
}
|
|
131
|
+
this.type = layerType;
|
|
132
|
+
// style = {
|
|
133
|
+
// type: 'circle',
|
|
134
|
+
// fill: 'red'
|
|
135
|
+
// radius: 5,
|
|
136
|
+
//
|
|
137
|
+
// ':hover': {
|
|
138
|
+
// fill: 'blue',
|
|
139
|
+
// stroke: 'red'
|
|
140
|
+
// }
|
|
141
|
+
// };
|
|
142
|
+
// step 1: extract 'rules': default, hover
|
|
143
|
+
// default: {fill: 'red', radius: 5};
|
|
144
|
+
// hover: {fill: 'blue', stroke: 'red'};
|
|
145
|
+
const rules = Object.keys(restStyle).reduce((res, key) => {
|
|
146
|
+
const isSelector = key.startsWith(':');
|
|
147
|
+
if (isSelector) {
|
|
148
|
+
const state = key.substring(1);
|
|
149
|
+
res[state] = restStyle[key];
|
|
150
|
+
return res;
|
|
151
|
+
}
|
|
152
|
+
res.default[key] = restStyle[key];
|
|
153
|
+
return res;
|
|
154
|
+
}, {
|
|
155
|
+
default: {}
|
|
156
|
+
});
|
|
157
|
+
// step 2: extract all unique attributes from rules
|
|
158
|
+
// attributes: ['fill', 'radius', 'stroke']
|
|
159
|
+
const attributes = Object.values(rules).reduce((res, rule) => {
|
|
160
|
+
const attrs = Object.keys(rule);
|
|
161
|
+
const set = new Set([...res, ...attrs]);
|
|
162
|
+
return Array.from(set);
|
|
163
|
+
}, []);
|
|
164
|
+
// step 3: create a attribute map as:
|
|
165
|
+
// attrMap = {
|
|
166
|
+
// fill: {default: 'red', hover: 'blue'},
|
|
167
|
+
// radius: {default: 5},
|
|
168
|
+
// stroke: {hover: 'red'},
|
|
169
|
+
// }
|
|
170
|
+
const attrMap = attributes.reduce((res, attr) => {
|
|
171
|
+
res[attr] = Object.entries(rules).reduce((acc, entry) => {
|
|
172
|
+
const [state, rule] = entry;
|
|
173
|
+
if (typeof rule[attr] !== 'undefined') {
|
|
174
|
+
acc[state] = rule[attr];
|
|
175
|
+
}
|
|
176
|
+
return acc;
|
|
177
|
+
}, {});
|
|
178
|
+
return res;
|
|
179
|
+
}, {});
|
|
180
|
+
// step 4: simplify the attribute map if only default exists for the attribute
|
|
181
|
+
// simplifiedStyleMap = {
|
|
182
|
+
// fill: {default: 'red', hover: 'blue'},
|
|
183
|
+
// radius: 5,
|
|
184
|
+
// stroke: {hover: 'red'},
|
|
185
|
+
// }
|
|
186
|
+
const simplifiedStyleMap = Object.entries(attrMap).reduce((res, entry) => {
|
|
187
|
+
const [attr, valueMap] = entry;
|
|
188
|
+
const onlyDefault = Object.keys(valueMap).length === 1 && valueMap.default !== undefined;
|
|
189
|
+
if (onlyDefault) {
|
|
190
|
+
res[attr] = valueMap.default;
|
|
191
|
+
return res;
|
|
192
|
+
}
|
|
193
|
+
res[attr] = valueMap;
|
|
194
|
+
return res;
|
|
195
|
+
}, {});
|
|
196
|
+
// step 5: create style property
|
|
197
|
+
// if the propety only maps to default state => return value only
|
|
198
|
+
// if the property maps to other states => return accessor function
|
|
199
|
+
// start to parse properties
|
|
200
|
+
this.properties = {};
|
|
201
|
+
for (const key in simplifiedStyleMap) {
|
|
202
|
+
this.properties[key] = new StyleProperty({
|
|
203
|
+
key,
|
|
204
|
+
value: simplifiedStyleMap[key],
|
|
205
|
+
updateTrigger: updateTriggers.stateUpdateTrigger
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
_getProperty(deckglAccessor) {
|
|
210
|
+
const map = DECKGL_ACCESSOR_MAP[this.type];
|
|
211
|
+
if (!map) {
|
|
212
|
+
throw new Error(`illegal type: ${this.type}`);
|
|
213
|
+
}
|
|
214
|
+
const styleProp = map[deckglAccessor];
|
|
215
|
+
if (!styleProp) {
|
|
216
|
+
log.error(`Invalid DeckGL accessor: ${deckglAccessor}`)();
|
|
217
|
+
throw new Error(`Invalid DeckGL accessor: ${deckglAccessor}`);
|
|
218
|
+
}
|
|
219
|
+
return this.properties[styleProp];
|
|
220
|
+
}
|
|
221
|
+
getDeckGLAccessor(deckglAccessor) {
|
|
222
|
+
const property = this._getProperty(deckglAccessor);
|
|
223
|
+
// get the value
|
|
224
|
+
if (property) {
|
|
225
|
+
return property.getValue();
|
|
226
|
+
}
|
|
227
|
+
// return default value
|
|
228
|
+
const styleProp = DECKGL_ACCESSOR_MAP[this.type][deckglAccessor];
|
|
229
|
+
return StyleProperty.getDefault(styleProp);
|
|
230
|
+
}
|
|
231
|
+
getDeckGLAccessorUpdateTrigger(deckglAccessor) {
|
|
232
|
+
const property = this._getProperty(deckglAccessor);
|
|
233
|
+
// get the value
|
|
234
|
+
if (property) {
|
|
235
|
+
return property.getUpdateTrigger();
|
|
236
|
+
}
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
getDeckGLAccessors() {
|
|
240
|
+
const accessorMap = DECKGL_ACCESSOR_MAP[this.type];
|
|
241
|
+
return Object.keys(accessorMap).reduce((res, accessor) => {
|
|
242
|
+
res[accessor] = this.getDeckGLAccessor(accessor);
|
|
243
|
+
return res;
|
|
244
|
+
}, {});
|
|
245
|
+
}
|
|
246
|
+
getDeckGLUpdateTriggers() {
|
|
247
|
+
return DECKGL_UPDATE_TRIGGERS[this.type].reduce((res, accessor) => {
|
|
248
|
+
res[accessor] = this.getDeckGLAccessorUpdateTrigger(accessor);
|
|
249
|
+
return res;
|
|
250
|
+
}, {});
|
|
251
|
+
}
|
|
252
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// deck.gl-community
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
import { Edge } from '../core/edge';
|
|
5
|
+
import { Node } from '../core/node';
|
|
6
|
+
import { Graph } from '../core/graph';
|
|
7
|
+
export function createGraph({ name, nodes, edges, nodeParser, edgeParser }) {
|
|
8
|
+
// create a new empty graph
|
|
9
|
+
const graph = new Graph();
|
|
10
|
+
const graphName = name || Date.now();
|
|
11
|
+
graph.setGraphName(graphName);
|
|
12
|
+
// add nodes
|
|
13
|
+
const glNodes = nodes.map((node) => {
|
|
14
|
+
const { id } = nodeParser(node);
|
|
15
|
+
return new Node({
|
|
16
|
+
id,
|
|
17
|
+
data: node
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
graph.batchAddNodes(glNodes);
|
|
21
|
+
const glEdges = edges.map((edge) => {
|
|
22
|
+
const { id, sourceId, targetId, directed } = edgeParser(edge);
|
|
23
|
+
return new Edge({
|
|
24
|
+
id,
|
|
25
|
+
sourceId,
|
|
26
|
+
targetId,
|
|
27
|
+
directed,
|
|
28
|
+
data: edge
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
graph.batchAddEdges(glEdges);
|
|
32
|
+
return graph;
|
|
33
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const mixedGetPosition: (getPosition: any, getOffset: any) => any;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// deck.gl-community
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
export const mixedGetPosition = (getPosition, getOffset) => {
|
|
5
|
+
if (!getOffset) {
|
|
6
|
+
return getPosition;
|
|
7
|
+
}
|
|
8
|
+
if (typeof getOffset === 'function') {
|
|
9
|
+
return (d) => {
|
|
10
|
+
const [x, y] = getPosition(d);
|
|
11
|
+
const [offX, offY] = getOffset(d);
|
|
12
|
+
return [x + offX, y + offY];
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
const [offX, offY] = getOffset;
|
|
16
|
+
return (d) => {
|
|
17
|
+
const [x, y] = getPosition(d);
|
|
18
|
+
return [x + offX, y + offY];
|
|
19
|
+
};
|
|
20
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// deck.gl-community
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
import { Log, COLOR } from 'probe.gl';
|
|
5
|
+
export const log = new Log({ id: 'react-graph-layers' }).enable();
|
|
6
|
+
log.log({ color: COLOR.CYAN }, 'Initialize react-graph-layers logger.')();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function generateRoundedCorners(pos: any, width: any, height: any, radius: any, factor?: number): any[];
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// deck.gl-community
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
export function generateRoundedCorners(pos, width, height, radius, factor = 20) {
|
|
5
|
+
const halfWidth = width / 2;
|
|
6
|
+
const halfHeight = height / 2;
|
|
7
|
+
const bottomLeft = { X: pos[0] - halfWidth, Y: pos[1] - halfHeight };
|
|
8
|
+
const topLeft = { X: pos[0] - halfWidth, Y: pos[1] + halfHeight };
|
|
9
|
+
const bottomRight = { X: pos[0] + halfWidth, Y: pos[1] - halfHeight };
|
|
10
|
+
const topRight = { X: pos[0] + halfWidth, Y: pos[1] + halfHeight };
|
|
11
|
+
const roundedPointsForBottomLeft = getRoundedCorner(bottomLeft, topLeft, bottomRight, radius, factor);
|
|
12
|
+
const roundedPointsForTopLeft = getRoundedCorner(topLeft, topRight, bottomLeft, radius, factor).reverse();
|
|
13
|
+
const roundedPointsForTopRight = getRoundedCorner(topRight, bottomRight, topLeft, radius, factor).reverse();
|
|
14
|
+
const roundedPointsForBottomRight = getRoundedCorner(bottomRight, bottomLeft, topRight, radius, factor).reverse();
|
|
15
|
+
const result = [
|
|
16
|
+
...roundedPointsForBottomLeft,
|
|
17
|
+
...roundedPointsForTopLeft,
|
|
18
|
+
...roundedPointsForTopRight,
|
|
19
|
+
...roundedPointsForBottomRight
|
|
20
|
+
];
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
*
|
|
25
|
+
* @param {*} angularPoint = corner point
|
|
26
|
+
* @param {*} p1 = edge one
|
|
27
|
+
* @param {*} p2 = edge two
|
|
28
|
+
* @param {*} radius = corner radius
|
|
29
|
+
* @param {*} factor = affects the points used for curve
|
|
30
|
+
* reference: https://stackoverflow.com/questions/24771828/how-to-calculate-rounded-corners-for-a-polygon
|
|
31
|
+
*/
|
|
32
|
+
// eslint-disable-next-line max-statements
|
|
33
|
+
function getRoundedCorner(angularPoint, p1, p2, radius, factor) {
|
|
34
|
+
// Vector 1
|
|
35
|
+
const dx1 = angularPoint.X - p1.X;
|
|
36
|
+
const dy1 = angularPoint.Y - p1.Y;
|
|
37
|
+
// Vector 2
|
|
38
|
+
const dx2 = angularPoint.X - p2.X;
|
|
39
|
+
const dy2 = angularPoint.Y - p2.Y;
|
|
40
|
+
// Angle between vector 1 and vector 2 divided by 2
|
|
41
|
+
const angle = (Math.atan2(dy1, dx1) - Math.atan2(dy2, dx2)) / 2;
|
|
42
|
+
// The length of segment between angular point and the
|
|
43
|
+
// points of intersection with the circle of a given radius
|
|
44
|
+
const tan = Math.abs(Math.tan(angle));
|
|
45
|
+
let segment = radius / tan;
|
|
46
|
+
// var segment = 2;
|
|
47
|
+
// Check the segment
|
|
48
|
+
const length1 = getLength(dx1, dy1);
|
|
49
|
+
const length2 = getLength(dx2, dy2);
|
|
50
|
+
const length = Math.min(length1, length2);
|
|
51
|
+
if (segment > length) {
|
|
52
|
+
segment = length;
|
|
53
|
+
radius = length * tan;
|
|
54
|
+
}
|
|
55
|
+
// Points of intersection are calculated by the proportion between
|
|
56
|
+
// the coordinates of the vector, length of vector and the length of the segment.
|
|
57
|
+
const p1Cross = getProportionPoint(angularPoint, segment, length1, dx1, dy1);
|
|
58
|
+
const p2Cross = getProportionPoint(angularPoint, segment, length2, dx2, dy2);
|
|
59
|
+
// Calculation of the coordinates of the circle
|
|
60
|
+
// center by the addition of angular vectors.
|
|
61
|
+
const dx = angularPoint.X * 2 - p1Cross.X - p2Cross.X;
|
|
62
|
+
const dy = angularPoint.Y * 2 - p1Cross.Y - p2Cross.Y;
|
|
63
|
+
const L = getLength(dx, dy);
|
|
64
|
+
const d = getLength(segment, radius);
|
|
65
|
+
const circlePoint = getProportionPoint(angularPoint, d, L, dx, dy);
|
|
66
|
+
// StartAngle and EndAngle of arc
|
|
67
|
+
let startAngle = Math.atan2(p1Cross.Y - circlePoint.Y, p1Cross.X - circlePoint.X);
|
|
68
|
+
const endAngle = Math.atan2(p2Cross.Y - circlePoint.Y, p2Cross.X - circlePoint.X);
|
|
69
|
+
// Sweep angle
|
|
70
|
+
let sweepAngle = endAngle - startAngle;
|
|
71
|
+
// Some additional checks
|
|
72
|
+
if (sweepAngle < 0) {
|
|
73
|
+
startAngle = endAngle;
|
|
74
|
+
sweepAngle = -sweepAngle;
|
|
75
|
+
}
|
|
76
|
+
if (sweepAngle > Math.PI)
|
|
77
|
+
sweepAngle = Math.PI - sweepAngle;
|
|
78
|
+
const degreeFactor = factor / Math.PI;
|
|
79
|
+
return getPointsForArc(sweepAngle, degreeFactor, startAngle, circlePoint, radius);
|
|
80
|
+
}
|
|
81
|
+
function getLength(dx, dy) {
|
|
82
|
+
return Math.sqrt(dx * dx + dy * dy);
|
|
83
|
+
}
|
|
84
|
+
function getProportionPoint(point, segment, length, dx, dy) {
|
|
85
|
+
const factor = segment / length;
|
|
86
|
+
return {
|
|
87
|
+
X: point.X - dx * factor,
|
|
88
|
+
Y: point.Y - dy * factor
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function getPointsForArc(sweepAngle, degreeFactor, startAngle, circlePoint, radius) {
|
|
92
|
+
const pointsCount = Math.abs(sweepAngle * degreeFactor);
|
|
93
|
+
const sign = Math.sign(sweepAngle);
|
|
94
|
+
const points = [];
|
|
95
|
+
for (let i = 0; i < pointsCount; ++i) {
|
|
96
|
+
const pointX = circlePoint.X + Math.cos(startAngle + (sign * i) / degreeFactor) * radius;
|
|
97
|
+
const pointY = circlePoint.Y + Math.sin(startAngle + (sign * i) / degreeFactor) * radius;
|
|
98
|
+
const point = [pointX, pointY];
|
|
99
|
+
points.push(point);
|
|
100
|
+
}
|
|
101
|
+
return points;
|
|
102
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@deck.gl-community/graph-layers",
|
|
3
|
+
"version": "9.0.0",
|
|
4
|
+
"description": "WebGL2-Powered library for Graph Visualization",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"graph",
|
|
7
|
+
"visualization",
|
|
8
|
+
"force-directed layout",
|
|
9
|
+
"gpu",
|
|
10
|
+
"deck.gl"
|
|
11
|
+
],
|
|
12
|
+
"type": "module",
|
|
13
|
+
"sideEffects": false,
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"main": "./dist/index.cjs",
|
|
16
|
+
"module": "./dist/index.js",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"require": "./dist/index.cjs",
|
|
21
|
+
"import": "./dist/index.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist",
|
|
26
|
+
"src"
|
|
27
|
+
],
|
|
28
|
+
"scripts": {
|
|
29
|
+
"test": "vitest run",
|
|
30
|
+
"test-watch": "vitest"
|
|
31
|
+
},
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@deck.gl/core": "^9.0.12",
|
|
35
|
+
"@deck.gl/layers": "^9.0.12",
|
|
36
|
+
"@luma.gl/core": "^9.0.12",
|
|
37
|
+
"cardinal-spline-js": "^2.3.10",
|
|
38
|
+
"color": "^4.2.3",
|
|
39
|
+
"core-js": "^3.29.0",
|
|
40
|
+
"d3": "^7.8.2",
|
|
41
|
+
"d3-array": "^3.2.2",
|
|
42
|
+
"d3-force": "^3.0.0",
|
|
43
|
+
"d3-format": "^3.1.0",
|
|
44
|
+
"d3-scale": "^4.0.2",
|
|
45
|
+
"global": "^4.4.0",
|
|
46
|
+
"gpu.js": "^2.16.0",
|
|
47
|
+
"lodash.isequal": "^4.5.0",
|
|
48
|
+
"lodash.pick": "^4.4.0",
|
|
49
|
+
"probe.gl": "^3.6.0",
|
|
50
|
+
"raf": "^3.4.1"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"ngraph.generators": "^20.1.0"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// deck.gl-community
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import isEqual from 'lodash.isequal';
|
|
6
|
+
import {EDGE_TYPE, LAYOUT_STATE} from './constants';
|
|
7
|
+
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
9
|
+
export interface BaseLayoutOptions {}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* All the layout classes are extended from this base layout class.
|
|
13
|
+
*/
|
|
14
|
+
export class BaseLayout extends EventTarget {
|
|
15
|
+
/** Name of the layout. */
|
|
16
|
+
protected readonly _name: string = 'BaseLayout';
|
|
17
|
+
/** Extra configuration options of the layout. */
|
|
18
|
+
protected _options: BaseLayoutOptions;
|
|
19
|
+
|
|
20
|
+
public version = 0;
|
|
21
|
+
public state = LAYOUT_STATE.INIT;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Constructor of BaseLayout
|
|
25
|
+
* @param {Object} options extra configuration options of the layout
|
|
26
|
+
*/
|
|
27
|
+
constructor(options: BaseLayoutOptions = {}) {
|
|
28
|
+
super();
|
|
29
|
+
this._options = options;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @fires BaseLayout#onLayoutStart
|
|
34
|
+
* @protected
|
|
35
|
+
*/
|
|
36
|
+
_onLayoutStart(): void {
|
|
37
|
+
this._updateState(LAYOUT_STATE.CALCULATING);
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Layout calculation start.
|
|
41
|
+
*
|
|
42
|
+
* @event BaseLayout#onLayoutChange
|
|
43
|
+
* @type {CustomEvent}
|
|
44
|
+
*/
|
|
45
|
+
this.dispatchEvent(new CustomEvent('onLayoutStart'));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @fires BaseLayout#onLayoutChange
|
|
50
|
+
* @protected
|
|
51
|
+
*/
|
|
52
|
+
_onLayoutChange(): void {
|
|
53
|
+
this._updateState(LAYOUT_STATE.CALCULATING);
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Layout calculation iteration.
|
|
57
|
+
*
|
|
58
|
+
* @event BaseLayout#onLayoutChange
|
|
59
|
+
* @type {CustomEvent}
|
|
60
|
+
*/
|
|
61
|
+
this.dispatchEvent(new CustomEvent('onLayoutChange'));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @fires BaseLayout#onLayoutDone
|
|
66
|
+
* @protected
|
|
67
|
+
*/
|
|
68
|
+
_onLayoutDone(): void {
|
|
69
|
+
this._updateState(LAYOUT_STATE.DONE);
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Layout calculation is done.
|
|
73
|
+
*
|
|
74
|
+
* @event BaseLayout#onLayoutDone
|
|
75
|
+
* @type {CustomEvent}
|
|
76
|
+
*/
|
|
77
|
+
this.dispatchEvent(new CustomEvent('onLayoutDone'));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* @fires BaseLayout#onLayoutError
|
|
82
|
+
* @protected
|
|
83
|
+
*/
|
|
84
|
+
_onLayoutError(): void {
|
|
85
|
+
this._updateState(LAYOUT_STATE.ERROR);
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Layout calculation went wrong.
|
|
89
|
+
*
|
|
90
|
+
* @event BaseLayout#onLayoutError
|
|
91
|
+
* @type {CustomEvent}
|
|
92
|
+
*/
|
|
93
|
+
this.dispatchEvent(new CustomEvent('onLayoutError'));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Check the equality of two layouts
|
|
98
|
+
* @param {Object} layout The layout to be compared.
|
|
99
|
+
* @return {Bool} True if the layout is the same as itself.
|
|
100
|
+
*/
|
|
101
|
+
equals(layout: BaseLayout): boolean {
|
|
102
|
+
if (!layout || !(layout instanceof BaseLayout)) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
return this._name === layout._name && isEqual(this._options, layout._options);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** virtual functions: will be implemented in the child class */
|
|
109
|
+
|
|
110
|
+
// first time to pass the graph data into this layout
|
|
111
|
+
initializeGraph(graph) {}
|
|
112
|
+
// update the existing graph
|
|
113
|
+
updateGraph(graph) {}
|
|
114
|
+
// start the layout calculation
|
|
115
|
+
start() {}
|
|
116
|
+
// update the layout calculation
|
|
117
|
+
update() {}
|
|
118
|
+
// resume the layout calculation
|
|
119
|
+
resume() {}
|
|
120
|
+
// stop the layout calculation
|
|
121
|
+
stop() {}
|
|
122
|
+
// access the position of the node in the layout
|
|
123
|
+
getNodePosition(node: Node): [number, number] {
|
|
124
|
+
return [0, 0];
|
|
125
|
+
}
|
|
126
|
+
// access the layout information of the edge
|
|
127
|
+
getEdgePosition(edge) {
|
|
128
|
+
return {
|
|
129
|
+
type: EDGE_TYPE.LINE,
|
|
130
|
+
sourcePosition: [0, 0],
|
|
131
|
+
targetPosition: [0, 0],
|
|
132
|
+
controlPoints: []
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Pin the node to a designated position, and the node won't move anymore
|
|
138
|
+
* @param {Object} node Node to be locked
|
|
139
|
+
* @param {Number} x x coordinate
|
|
140
|
+
* @param {Number} y y coordinate
|
|
141
|
+
*/
|
|
142
|
+
lockNodePosition(node, x, y) {}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Unlock the node, the node will be able to move freely.
|
|
146
|
+
* @param {Object} node Node to be unlocked
|
|
147
|
+
*/
|
|
148
|
+
unlockNodePosition(node) {}
|
|
149
|
+
|
|
150
|
+
_updateState(state) {
|
|
151
|
+
this.state = state;
|
|
152
|
+
this.version += 1;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// deck.gl-community
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
export class Cache<K, V> {
|
|
6
|
+
private readonly _keys = new Map<K, {value: V; version: number}>();
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param key The key of the cache
|
|
10
|
+
* @returns {*} The value of the cache as set by the `set` method.
|
|
11
|
+
*/
|
|
12
|
+
get(key: K): V | undefined {
|
|
13
|
+
return this._keys.get(key)?.value;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param key The key of the cache
|
|
18
|
+
* @param createValue A callback to create the value of the cache if it is needed.
|
|
19
|
+
* @param version The version of the cache. If the version is smaller than the current version, the cache will not be updated.
|
|
20
|
+
*/
|
|
21
|
+
set(key: K, createValue: (...args: unknown[]) => V, version: number): void {
|
|
22
|
+
const cached = this._keys.get(key);
|
|
23
|
+
|
|
24
|
+
const keyUpdated = cached === undefined || version > cached.version;
|
|
25
|
+
if (!keyUpdated) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
this._keys.set(key, {version, value: createValue()});
|
|
30
|
+
}
|
|
31
|
+
}
|