@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.
Files changed (210) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +7 -0
  3. package/dist/core/base-layout.d.ts +71 -0
  4. package/dist/core/base-layout.js +133 -0
  5. package/dist/core/cache.d.ts +14 -0
  6. package/dist/core/cache.js +26 -0
  7. package/dist/core/constants.d.ts +101 -0
  8. package/dist/core/constants.js +48 -0
  9. package/dist/core/edge.d.ts +86 -0
  10. package/dist/core/edge.js +121 -0
  11. package/dist/core/graph-engine.d.ts +54 -0
  12. package/dist/core/graph-engine.js +128 -0
  13. package/dist/core/graph.d.ts +155 -0
  14. package/dist/core/graph.js +301 -0
  15. package/dist/core/interaction-manager.d.ts +40 -0
  16. package/dist/core/interaction-manager.js +169 -0
  17. package/dist/core/node.d.ts +103 -0
  18. package/dist/core/node.js +177 -0
  19. package/dist/index.cjs +3540 -0
  20. package/dist/index.cjs.map +7 -0
  21. package/dist/index.d.ts +19 -0
  22. package/dist/index.js +28 -0
  23. package/dist/layers/common-layers/flow-path-layer/flow-path-layer-fragment.glsl.d.ts +1 -0
  24. package/dist/layers/common-layers/flow-path-layer/flow-path-layer-fragment.glsl.js +49 -0
  25. package/dist/layers/common-layers/flow-path-layer/flow-path-layer-vertex-tf.glsl.d.ts +1 -0
  26. package/dist/layers/common-layers/flow-path-layer/flow-path-layer-vertex-tf.glsl.js +14 -0
  27. package/dist/layers/common-layers/flow-path-layer/flow-path-layer-vertex.glsl.d.ts +1 -0
  28. package/dist/layers/common-layers/flow-path-layer/flow-path-layer-vertex.glsl.js +73 -0
  29. package/dist/layers/common-layers/flow-path-layer/flow-path-layer.d.ts +20 -0
  30. package/dist/layers/common-layers/flow-path-layer/flow-path-layer.js +133 -0
  31. package/dist/layers/common-layers/marker-layer/atlas-data-url.d.ts +3 -0
  32. package/dist/layers/common-layers/marker-layer/atlas-data-url.js +8 -0
  33. package/dist/layers/common-layers/marker-layer/marker-layer.d.ts +13 -0
  34. package/dist/layers/common-layers/marker-layer/marker-layer.js +29 -0
  35. package/dist/layers/common-layers/marker-layer/marker-list.d.ts +62 -0
  36. package/dist/layers/common-layers/marker-layer/marker-list.js +67 -0
  37. package/dist/layers/common-layers/marker-layer/marker-mapping.d.ts +422 -0
  38. package/dist/layers/common-layers/marker-layer/marker-mapping.js +427 -0
  39. package/dist/layers/common-layers/spline-layer/spline-layer.d.ts +24 -0
  40. package/dist/layers/common-layers/spline-layer/spline-layer.js +68 -0
  41. package/dist/layers/common-layers/zoomable-text-layer/zoomable-text-layer.d.ts +16 -0
  42. package/dist/layers/common-layers/zoomable-text-layer/zoomable-text-layer.js +65 -0
  43. package/dist/layers/edge-layer.d.ts +25 -0
  44. package/dist/layers/edge-layer.js +75 -0
  45. package/dist/layers/edge-layers/curved-edge-layer.d.ts +6 -0
  46. package/dist/layers/edge-layers/curved-edge-layer.js +69 -0
  47. package/dist/layers/edge-layers/edge-label-layer.d.ts +6 -0
  48. package/dist/layers/edge-layers/edge-label-layer.js +42 -0
  49. package/dist/layers/edge-layers/flow-layer.d.ts +6 -0
  50. package/dist/layers/edge-layers/flow-layer.js +28 -0
  51. package/dist/layers/edge-layers/path-edge-layer.d.ts +6 -0
  52. package/dist/layers/edge-layers/path-edge-layer.js +27 -0
  53. package/dist/layers/edge-layers/straight-line-edge-layer.d.ts +6 -0
  54. package/dist/layers/edge-layers/straight-line-edge-layer.js +26 -0
  55. package/dist/layers/graph-layer.d.ts +32 -0
  56. package/dist/layers/graph-layer.js +193 -0
  57. package/dist/layers/node-layers/circle-layer.d.ts +6 -0
  58. package/dist/layers/node-layers/circle-layer.js +23 -0
  59. package/dist/layers/node-layers/image-layer.d.ts +6 -0
  60. package/dist/layers/node-layers/image-layer.js +23 -0
  61. package/dist/layers/node-layers/label-layer.d.ts +6 -0
  62. package/dist/layers/node-layers/label-layer.js +23 -0
  63. package/dist/layers/node-layers/path-rounded-rectange-layer.d.ts +6 -0
  64. package/dist/layers/node-layers/path-rounded-rectange-layer.js +46 -0
  65. package/dist/layers/node-layers/rectangle-layer.d.ts +6 -0
  66. package/dist/layers/node-layers/rectangle-layer.js +49 -0
  67. package/dist/layers/node-layers/rounded-rectangle-layer-fragment.d.ts +1 -0
  68. package/dist/layers/node-layers/rounded-rectangle-layer-fragment.js +30 -0
  69. package/dist/layers/node-layers/rounded-rectangle-layer.d.ts +8 -0
  70. package/dist/layers/node-layers/rounded-rectangle-layer.js +28 -0
  71. package/dist/layers/node-layers/zoomable-marker-layer.d.ts +10 -0
  72. package/dist/layers/node-layers/zoomable-marker-layer.js +40 -0
  73. package/dist/layouts/d3-force/d3-force-layout.d.ts +24 -0
  74. package/dist/layouts/d3-force/d3-force-layout.js +116 -0
  75. package/dist/layouts/d3-force/worker.d.ts +0 -0
  76. package/dist/layouts/d3-force/worker.js +46 -0
  77. package/dist/layouts/gpu-force/gpu-force-layout.d.ts +30 -0
  78. package/dist/layouts/gpu-force/gpu-force-layout.js +232 -0
  79. package/dist/layouts/gpu-force/worker.d.ts +0 -0
  80. package/dist/layouts/gpu-force/worker.js +116 -0
  81. package/dist/layouts/simple-layout/simple-layout.d.ts +22 -0
  82. package/dist/layouts/simple-layout/simple-layout.js +64 -0
  83. package/dist/loaders/edge-parsers.d.ts +6 -0
  84. package/dist/loaders/edge-parsers.js +17 -0
  85. package/dist/loaders/json-loader.d.ts +7 -0
  86. package/dist/loaders/json-loader.js +16 -0
  87. package/dist/loaders/node-parsers.d.ts +3 -0
  88. package/dist/loaders/node-parsers.js +11 -0
  89. package/dist/style/style-property.d.ts +14 -0
  90. package/dist/style/style-property.js +195 -0
  91. package/dist/style/style-sheet.d.ts +10 -0
  92. package/dist/style/style-sheet.js +252 -0
  93. package/dist/utils/create-graph.d.ts +8 -0
  94. package/dist/utils/create-graph.js +33 -0
  95. package/dist/utils/layer-utils.d.ts +1 -0
  96. package/dist/utils/layer-utils.js +20 -0
  97. package/dist/utils/log.d.ts +2 -0
  98. package/dist/utils/log.js +6 -0
  99. package/dist/utils/polygon-calculations.d.ts +1 -0
  100. package/dist/utils/polygon-calculations.js +102 -0
  101. package/package.json +55 -0
  102. package/src/core/base-layout.ts +154 -0
  103. package/src/core/cache.ts +31 -0
  104. package/src/core/constants.ts +58 -0
  105. package/src/core/edge.ts +145 -0
  106. package/src/core/graph-engine.ts +170 -0
  107. package/src/core/graph.ts +342 -0
  108. package/src/core/interaction-manager.ts +225 -0
  109. package/src/core/node.ts +205 -0
  110. package/src/index.ts +42 -0
  111. package/src/layers/common-layers/flow-path-layer/flow-path-layer-fragment.glsl.ts +50 -0
  112. package/src/layers/common-layers/flow-path-layer/flow-path-layer-vertex-tf.glsl.ts +15 -0
  113. package/src/layers/common-layers/flow-path-layer/flow-path-layer-vertex.glsl.ts +74 -0
  114. package/src/layers/common-layers/flow-path-layer/flow-path-layer.ts +154 -0
  115. package/src/layers/common-layers/marker-layer/atlas-data-url.ts +10 -0
  116. package/src/layers/common-layers/marker-layer/marker-atlas.png +0 -0
  117. package/src/layers/common-layers/marker-layer/marker-layer.ts +36 -0
  118. package/src/layers/common-layers/marker-layer/marker-list.ts +68 -0
  119. package/src/layers/common-layers/marker-layer/marker-mapping.ts +428 -0
  120. package/src/layers/common-layers/marker-layer/markers/bell-filled.png +0 -0
  121. package/src/layers/common-layers/marker-layer/markers/bell.png +0 -0
  122. package/src/layers/common-layers/marker-layer/markers/bookmark-filled.png +0 -0
  123. package/src/layers/common-layers/marker-layer/markers/bookmark.png +0 -0
  124. package/src/layers/common-layers/marker-layer/markers/cd-filled.png +0 -0
  125. package/src/layers/common-layers/marker-layer/markers/cd.png +0 -0
  126. package/src/layers/common-layers/marker-layer/markers/checkmark.png +0 -0
  127. package/src/layers/common-layers/marker-layer/markers/circle-check-filled.png +0 -0
  128. package/src/layers/common-layers/marker-layer/markers/circle-check.png +0 -0
  129. package/src/layers/common-layers/marker-layer/markers/circle-filled.png +0 -0
  130. package/src/layers/common-layers/marker-layer/markers/circle-i-filled.png +0 -0
  131. package/src/layers/common-layers/marker-layer/markers/circle-i.png +0 -0
  132. package/src/layers/common-layers/marker-layer/markers/circle-minus-filled.png +0 -0
  133. package/src/layers/common-layers/marker-layer/markers/circle-minus.png +0 -0
  134. package/src/layers/common-layers/marker-layer/markers/circle-plus-filled.png +0 -0
  135. package/src/layers/common-layers/marker-layer/markers/circle-plus.png +0 -0
  136. package/src/layers/common-layers/marker-layer/markers/circle-questionmark-filled.png +0 -0
  137. package/src/layers/common-layers/marker-layer/markers/circle-questionmark.png +0 -0
  138. package/src/layers/common-layers/marker-layer/markers/circle-slash-filled.png +0 -0
  139. package/src/layers/common-layers/marker-layer/markers/circle-slash.png +0 -0
  140. package/src/layers/common-layers/marker-layer/markers/circle-x-filled.png +0 -0
  141. package/src/layers/common-layers/marker-layer/markers/circle-x.png +0 -0
  142. package/src/layers/common-layers/marker-layer/markers/circle.png +0 -0
  143. package/src/layers/common-layers/marker-layer/markers/diamond-filled.png +0 -0
  144. package/src/layers/common-layers/marker-layer/markers/diamond.png +0 -0
  145. package/src/layers/common-layers/marker-layer/markers/flag-filled.png +0 -0
  146. package/src/layers/common-layers/marker-layer/markers/flag.png +0 -0
  147. package/src/layers/common-layers/marker-layer/markers/gear.png +0 -0
  148. package/src/layers/common-layers/marker-layer/markers/heart-filled.png +0 -0
  149. package/src/layers/common-layers/marker-layer/markers/heart.png +0 -0
  150. package/src/layers/common-layers/marker-layer/markers/location-marker-filled.png +0 -0
  151. package/src/layers/common-layers/marker-layer/markers/location-marker.png +0 -0
  152. package/src/layers/common-layers/marker-layer/markers/octagonal-star-filled.png +0 -0
  153. package/src/layers/common-layers/marker-layer/markers/octagonal-star.png +0 -0
  154. package/src/layers/common-layers/marker-layer/markers/person-filled.png +0 -0
  155. package/src/layers/common-layers/marker-layer/markers/person.png +0 -0
  156. package/src/layers/common-layers/marker-layer/markers/pin-filled.png +0 -0
  157. package/src/layers/common-layers/marker-layer/markers/pin.png +0 -0
  158. package/src/layers/common-layers/marker-layer/markers/plus-small.png +0 -0
  159. package/src/layers/common-layers/marker-layer/markers/plus.png +0 -0
  160. package/src/layers/common-layers/marker-layer/markers/rectangle-filled.png +0 -0
  161. package/src/layers/common-layers/marker-layer/markers/rectangle.png +0 -0
  162. package/src/layers/common-layers/marker-layer/markers/star-filled.png +0 -0
  163. package/src/layers/common-layers/marker-layer/markers/star.png +0 -0
  164. package/src/layers/common-layers/marker-layer/markers/tag-filled.png +0 -0
  165. package/src/layers/common-layers/marker-layer/markers/tag.png +0 -0
  166. package/src/layers/common-layers/marker-layer/markers/thumb-down-filled.png +0 -0
  167. package/src/layers/common-layers/marker-layer/markers/thumb-down.png +0 -0
  168. package/src/layers/common-layers/marker-layer/markers/thumb-up.png +0 -0
  169. package/src/layers/common-layers/marker-layer/markers/thumb_up-filled.png +0 -0
  170. package/src/layers/common-layers/marker-layer/markers/triangle-down-filled.png +0 -0
  171. package/src/layers/common-layers/marker-layer/markers/triangle-down.png +0 -0
  172. package/src/layers/common-layers/marker-layer/markers/triangle-left-filled.png +0 -0
  173. package/src/layers/common-layers/marker-layer/markers/triangle-left.png +0 -0
  174. package/src/layers/common-layers/marker-layer/markers/triangle-right-filled.png +0 -0
  175. package/src/layers/common-layers/marker-layer/markers/triangle-right.png +0 -0
  176. package/src/layers/common-layers/marker-layer/markers/triangle-up-filled.png +0 -0
  177. package/src/layers/common-layers/marker-layer/markers/triangle-up.png +0 -0
  178. package/src/layers/common-layers/marker-layer/markers/x-small.png +0 -0
  179. package/src/layers/common-layers/marker-layer/markers/x.png +0 -0
  180. package/src/layers/common-layers/spline-layer/spline-layer.ts +83 -0
  181. package/src/layers/common-layers/zoomable-text-layer/zoomable-text-layer.ts +90 -0
  182. package/src/layers/edge-layer.ts +88 -0
  183. package/src/layers/edge-layers/curved-edge-layer.ts +88 -0
  184. package/src/layers/edge-layers/edge-label-layer.ts +48 -0
  185. package/src/layers/edge-layers/flow-layer.ts +34 -0
  186. package/src/layers/edge-layers/path-edge-layer.ts +39 -0
  187. package/src/layers/edge-layers/straight-line-edge-layer.ts +38 -0
  188. package/src/layers/graph-layer.ts +225 -0
  189. package/src/layers/node-layers/circle-layer.ts +29 -0
  190. package/src/layers/node-layers/image-layer.ts +29 -0
  191. package/src/layers/node-layers/label-layer.ts +29 -0
  192. package/src/layers/node-layers/path-rounded-rectange-layer.ts +56 -0
  193. package/src/layers/node-layers/rectangle-layer.ts +58 -0
  194. package/src/layers/node-layers/rounded-rectangle-layer-fragment.ts +31 -0
  195. package/src/layers/node-layers/rounded-rectangle-layer.ts +32 -0
  196. package/src/layers/node-layers/zoomable-marker-layer.ts +49 -0
  197. package/src/layouts/d3-force/d3-force-layout.ts +145 -0
  198. package/src/layouts/d3-force/worker.ts +61 -0
  199. package/src/layouts/gpu-force/gpu-force-layout.ts +249 -0
  200. package/src/layouts/gpu-force/worker.ts +137 -0
  201. package/src/layouts/simple-layout/simple-layout.ts +87 -0
  202. package/src/loaders/edge-parsers.ts +21 -0
  203. package/src/loaders/json-loader.ts +19 -0
  204. package/src/loaders/node-parsers.ts +13 -0
  205. package/src/style/style-property.ts +229 -0
  206. package/src/style/style-sheet.ts +277 -0
  207. package/src/utils/create-graph.ts +38 -0
  208. package/src/utils/layer-utils.ts +23 -0
  209. package/src/utils/log.ts +9 -0
  210. 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,8 @@
1
+ import { Graph } from '../core/graph';
2
+ export declare function createGraph({ name, nodes, edges, nodeParser, edgeParser }: {
3
+ name: any;
4
+ nodes: any;
5
+ edges: any;
6
+ nodeParser: any;
7
+ edgeParser: any;
8
+ }): Graph;
@@ -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,2 @@
1
+ import { Log } from 'probe.gl';
2
+ export declare const log: Log;
@@ -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
+ }