@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,225 @@
1
+ // deck.gl-community
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import {EDGE_STATE, NODE_STATE, ValueOf} from './constants';
6
+ import {Edge} from './edge';
7
+ import {GraphEngine} from './graph-engine';
8
+ import {Node} from './node';
9
+
10
+ const NODE_TO_EDGE_STATE_MAP: Record<ValueOf<typeof NODE_STATE>, ValueOf<typeof EDGE_STATE>> = {
11
+ [NODE_STATE.DEFAULT]: EDGE_STATE.DEFAULT,
12
+ [NODE_STATE.HOVER]: EDGE_STATE.HOVER,
13
+ [NODE_STATE.DRAGGING]: EDGE_STATE.DRAGGING,
14
+ [NODE_STATE.SELECTED]: EDGE_STATE.SELECTED
15
+ };
16
+
17
+ function shouldEdgeBeSelected(edge: Edge): boolean {
18
+ return edge
19
+ .getConnectedNodes()
20
+ .some(
21
+ (node) => node.getState() === NODE_STATE.SELECTED && node.shouldHighlightConnectedEdges()
22
+ );
23
+ }
24
+
25
+ function setNodeState(node: Node, state: ValueOf<typeof NODE_STATE>) {
26
+ node.setState(state);
27
+ if (node.shouldHighlightConnectedEdges()) {
28
+ node.getConnectedEdges().forEach((edge) => {
29
+ let newEdgeState = NODE_TO_EDGE_STATE_MAP[state];
30
+ if (shouldEdgeBeSelected(edge)) {
31
+ newEdgeState = EDGE_STATE.SELECTED;
32
+ }
33
+ edge.setState(newEdgeState);
34
+ });
35
+ }
36
+ }
37
+
38
+ interface EventMap {
39
+ onClick?: (info: unknown, event: Event) => void;
40
+ onHover?: (info: unknown) => void;
41
+ onMouseEnter?: (info: unknown) => void;
42
+ onMouseLeave?: (node: Node) => void;
43
+ onDragStart?: (info: unknown) => void;
44
+ onDrag?: (info: unknown) => void;
45
+ onDragEnd?: (info: unknown) => void;
46
+ }
47
+
48
+ export interface InteractionManagerProps {
49
+ nodeEvents?: EventMap;
50
+ edgeEvents?: EventMap;
51
+ engine: GraphEngine;
52
+ enableDragging: boolean;
53
+ resumeLayoutAfterDragging: boolean;
54
+ }
55
+
56
+ export class InteractionManager {
57
+ public notifyCallback: Function;
58
+ private _lastInteraction = 0;
59
+ private _lastHoveredNode: Node | null = null;
60
+ private _lastSelectedNode: Node | null = null;
61
+
62
+ public nodeEvents: EventMap = undefined!;
63
+ public edgeEvents: EventMap = undefined!;
64
+ public engine: GraphEngine = undefined!;
65
+ public enableDragging: boolean = undefined!;
66
+ public resumeLayoutAfterDragging: boolean = undefined!;
67
+
68
+ constructor(props: InteractionManagerProps, notifyCallback: Function) {
69
+ this.updateProps(props);
70
+ this.notifyCallback = notifyCallback;
71
+
72
+ // internal state
73
+ this._lastInteraction = 0;
74
+ this._lastHoveredNode = null;
75
+ this._lastSelectedNode = null;
76
+ }
77
+
78
+ updateProps({
79
+ nodeEvents = {},
80
+ edgeEvents = {},
81
+ engine,
82
+ enableDragging,
83
+ resumeLayoutAfterDragging
84
+ }: InteractionManagerProps): void {
85
+ this.nodeEvents = nodeEvents;
86
+ this.edgeEvents = edgeEvents;
87
+ this.engine = engine;
88
+ this.enableDragging = enableDragging;
89
+ this.resumeLayoutAfterDragging = resumeLayoutAfterDragging;
90
+ }
91
+
92
+ getLastInteraction(): number {
93
+ return this._lastInteraction;
94
+ }
95
+
96
+ onClick(info, event): void {
97
+ const {object} = info;
98
+
99
+ if (!object) {
100
+ return;
101
+ }
102
+
103
+ if (object.isNode) {
104
+ if ((object as Node).isSelectable()) {
105
+ if (this._lastSelectedNode) {
106
+ setNodeState(this._lastSelectedNode, NODE_STATE.DEFAULT);
107
+ }
108
+ setNodeState(object, NODE_STATE.SELECTED);
109
+ this._lastSelectedNode = object as Node;
110
+ this._lastInteraction = Date.now();
111
+ this.notifyCallback();
112
+ }
113
+
114
+ if (this.nodeEvents.onClick) {
115
+ this.nodeEvents.onClick(info, event);
116
+ }
117
+ }
118
+
119
+ if (object.isEdge && this.edgeEvents.onClick) {
120
+ this.edgeEvents.onClick(info, event);
121
+ }
122
+ }
123
+
124
+ _mouseLeaveNode(): void {
125
+ const lastHoveredNode = this._lastHoveredNode;
126
+
127
+ if (!(lastHoveredNode.isSelectable() && lastHoveredNode.getState() === NODE_STATE.SELECTED)) {
128
+ // reset the last hovered node's state
129
+ const newState =
130
+ this._lastSelectedNode !== null && this._lastSelectedNode.id === this._lastHoveredNode?.id
131
+ ? NODE_STATE.SELECTED
132
+ : NODE_STATE.DEFAULT;
133
+ setNodeState(lastHoveredNode, newState);
134
+ }
135
+ // trigger the callback if exists
136
+ if (this.nodeEvents.onMouseLeave) {
137
+ this.nodeEvents.onMouseLeave(lastHoveredNode);
138
+ }
139
+ }
140
+
141
+ _mouseEnterNode(info): void {
142
+ // set the node's state to hover
143
+ setNodeState(info.object as Node, NODE_STATE.HOVER);
144
+ // trigger the callback if exists
145
+ if (this.nodeEvents.onMouseEnter) {
146
+ this.nodeEvents.onMouseEnter(info);
147
+ }
148
+ if (this.nodeEvents.onHover) {
149
+ this.nodeEvents.onHover(info);
150
+ }
151
+ }
152
+
153
+ onHover(info, event) {
154
+ if (!info.object) {
155
+ if (this._lastHoveredNode) {
156
+ this._mouseLeaveNode();
157
+ this._lastInteraction = Date.now();
158
+ this._lastHoveredNode = null;
159
+ this.notifyCallback();
160
+ }
161
+ return;
162
+ }
163
+
164
+ // hover over on a node
165
+ if (info.object.isNode) {
166
+ const isSameNode = this._lastHoveredNode && this._lastHoveredNode.id === info.object.id;
167
+ // stay in the same node
168
+ if (isSameNode) {
169
+ return;
170
+ }
171
+ if (this._lastHoveredNode) {
172
+ // reset the previous hovered node's state if not the same node
173
+ this._mouseLeaveNode();
174
+ }
175
+ // enter new node
176
+ this._mouseEnterNode(info);
177
+ this._lastInteraction = Date.now();
178
+ this._lastHoveredNode = info.object;
179
+ this.notifyCallback();
180
+ }
181
+ if (info.object.isEdge && this.edgeEvents.onHover) {
182
+ this.edgeEvents.onHover(info);
183
+ }
184
+ }
185
+
186
+ onDragStart(info, event) {
187
+ if (this.nodeEvents.onDragStart) {
188
+ this.nodeEvents.onDragStart(info);
189
+ }
190
+ }
191
+
192
+ onDrag(info, event) {
193
+ if (!info.object.isNode || !this.enableDragging) {
194
+ return;
195
+ }
196
+ event.stopImmediatePropagation();
197
+
198
+ // info.viewport is undefined when the object is offscreen, so we use viewport from onDragStart
199
+ const coordinates = info.layer.context.viewport.unproject([info.x, info.y]);
200
+
201
+ // limit the node position to be within bounds of the viewport
202
+ const bounds = info.layer.context.viewport.getBounds(); // [minX, minY, maxX, maxY]
203
+ const x = Math.min(Math.max(coordinates[0], bounds[0]), bounds[2]);
204
+ const y = Math.min(Math.max(coordinates[1], bounds[1]), bounds[3]);
205
+ this.engine.lockNodePosition(info.object, x, y);
206
+
207
+ setNodeState(info.object, NODE_STATE.DRAGGING);
208
+ this._lastInteraction = Date.now();
209
+ this.notifyCallback();
210
+ if (this.nodeEvents.onDrag) {
211
+ this.nodeEvents.onDrag(info);
212
+ }
213
+ }
214
+
215
+ onDragEnd(info, event) {
216
+ if (!info.object.isNode || !this.enableDragging) {
217
+ return;
218
+ }
219
+ if (this.resumeLayoutAfterDragging) {
220
+ this.engine.resume();
221
+ }
222
+ setNodeState(info.object, NODE_STATE.DEFAULT);
223
+ this.engine.unlockNodePosition(info.object);
224
+ }
225
+ }
@@ -0,0 +1,205 @@
1
+ // deck.gl-community
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import {NODE_STATE, ValueOf} from './constants';
6
+ import {Edge} from './edge';
7
+
8
+ interface NodeOptions {
9
+ id: number | string;
10
+ selectable?: boolean;
11
+ highlightConnectedEdges?: boolean;
12
+ data: Record<string, unknown>;
13
+ }
14
+
15
+ // Basic data structure of a node
16
+ export class Node {
17
+ public id: string | number;
18
+ /** Keep a reference to origin data. */
19
+ private _data: Record<string, unknown>;
20
+ /** List edges. */
21
+ private _connectedEdges: Record<string, Edge> = {};
22
+ /** Interaction state of the node. */
23
+ public state: ValueOf<typeof NODE_STATE> = NODE_STATE.DEFAULT;
24
+ /** Can the node be selected? */
25
+ private _selectable: boolean;
26
+ /** Should the state of this node affect the state of the connected edges? */
27
+ private _highlightConnectedEdges: boolean;
28
+ /** Check the type of the object when picking engine gets it. */
29
+ public readonly isNode = true;
30
+ /**
31
+ * The constructor of a node
32
+ * @param {String|Number} options.id - the unique ID of the node
33
+ * @param {Record<string, unknown>} options.data - origin data reference
34
+ */
35
+ constructor({id, selectable = false, highlightConnectedEdges = false, data = {}}: NodeOptions) {
36
+ this.id = id;
37
+ this._data = data;
38
+ this._selectable = selectable;
39
+ this._highlightConnectedEdges = highlightConnectedEdges;
40
+ }
41
+
42
+ /**
43
+ * Return the ID of the node
44
+ * @return {String|Number} - the ID of the node.
45
+ */
46
+ getId(): string | number {
47
+ return this.id;
48
+ }
49
+
50
+ /**
51
+ * Return the degree of the node -- includes in-degree and out-degree
52
+ * @return {Number} - the degree of the node.
53
+ */
54
+ getDegree(): number {
55
+ return Object.keys(this._connectedEdges).length;
56
+ }
57
+
58
+ /**
59
+ * Return the in-degree of the node.
60
+ * @return {Number} - the in-degree of the node.
61
+ */
62
+ getInDegree(): number {
63
+ const nodeId = this.getId();
64
+ return this.getConnectedEdges().reduce((count, e) => {
65
+ const isDirected = e.isDirected();
66
+ if (isDirected && e.getTargetNodeId() === nodeId) {
67
+ count += 1;
68
+ }
69
+ return count;
70
+ }, 0);
71
+ }
72
+
73
+ /**
74
+ * Return the out-degree of the node.
75
+ * @return {Number} - the out-degree of the node.
76
+ */
77
+ getOutDegree(): number {
78
+ const nodeId = this.getId();
79
+ return this.getConnectedEdges().reduce((count, e) => {
80
+ const isDirected = e.isDirected();
81
+ if (isDirected && e.getSourceNodeId() === nodeId) {
82
+ count += 1;
83
+ }
84
+ return count;
85
+ }, 0);
86
+ }
87
+
88
+ /**
89
+ * Return all the IDs of the sibling nodes.
90
+ * @return {String[]} [description]
91
+ */
92
+ getSiblingIds(): (string | number)[] {
93
+ const nodeId = this.getId();
94
+ return this.getConnectedEdges().reduce(
95
+ (siblings, e) => {
96
+ if (e.getTargetNodeId() === nodeId) {
97
+ siblings.push(e.getSourceNodeId());
98
+ } else {
99
+ siblings.push(e.getTargetNodeId());
100
+ }
101
+ return siblings;
102
+ },
103
+ [] as (string | number)[]
104
+ );
105
+ }
106
+
107
+ /**
108
+ * Return all the connected edges.
109
+ * @return {Object[]} - an array of the connected edges.
110
+ */
111
+ getConnectedEdges(): Edge[] {
112
+ return Object.values(this._connectedEdges);
113
+ }
114
+
115
+ /**
116
+ * Return of the value of the selected property key.
117
+ * @param {String} key - property key.
118
+ * @return {Any} - the value of the property or undefined (not found).
119
+ */
120
+ getPropertyValue(key: string): unknown {
121
+ // try to search the key within this object
122
+ if (this.hasOwnProperty(key)) {
123
+ return this[key];
124
+ }
125
+ // try to search the key in the original data reference
126
+ else if (this._data.hasOwnProperty(key)) {
127
+ return this._data[key];
128
+ }
129
+ // otherwise, not found
130
+ return undefined;
131
+ }
132
+
133
+ /**
134
+ * Set the new node data.
135
+ * @param {Record<string, unknown>} data - the new data of the node
136
+ */
137
+ setData(data: Record<string, unknown>): void {
138
+ this._data = data;
139
+ }
140
+
141
+ /**
142
+ * Update a data property.
143
+ * @param {String} key - the key of the property
144
+ * @param {Any} value - the value of the property.
145
+ */
146
+ setDataProperty(key: string, value: unknown): void {
147
+ this._data[key] = value;
148
+ }
149
+
150
+ /**
151
+ * Set node state
152
+ * @param {String} state - one of NODE_STATE
153
+ */
154
+ setState(state: ValueOf<typeof NODE_STATE>): void {
155
+ this.state = state;
156
+ }
157
+
158
+ /**
159
+ * Get node state
160
+ * @returns {string} state - one of NODE_STATE
161
+ */
162
+ getState(): ValueOf<typeof NODE_STATE> {
163
+ return this.state;
164
+ }
165
+
166
+ /**
167
+ * Add connected edges to the node
168
+ * @param {Edge || Edge[]} edge an edge or an array of edges to be added to this._connectedEdges
169
+ */
170
+ addConnectedEdges(edge: Edge | Edge[]): void {
171
+ const iterableEdges = Array.isArray(edge) ? edge : [edge];
172
+ iterableEdges.forEach((e) => {
173
+ this._connectedEdges[e.id] = e;
174
+ e.addNode(this);
175
+ });
176
+ }
177
+
178
+ /**
179
+ * Remove edges from this._connectedEdges
180
+ * @param {Edge | Edge[]} edge an edge or an array of edges to be removed from this._connectedEdges
181
+ */
182
+ removeConnectedEdges(edge: Edge | Edge[]): void {
183
+ const iterableEdges = Array.isArray(edge) ? edge : [edge];
184
+ iterableEdges.forEach((e) => {
185
+ e.removeNode(this);
186
+ delete this._connectedEdges[e.id];
187
+ });
188
+ }
189
+
190
+ /**
191
+ * Clear this._connectedEdges
192
+ */
193
+ clearConnectedEdges(): void {
194
+ Object.values(this._connectedEdges).forEach((e) => e.removeNode(this));
195
+ this._connectedEdges = {};
196
+ }
197
+
198
+ isSelectable(): boolean {
199
+ return this._selectable;
200
+ }
201
+
202
+ shouldHighlightConnectedEdges(): boolean {
203
+ return this._highlightConnectedEdges;
204
+ }
205
+ }
package/src/index.ts ADDED
@@ -0,0 +1,42 @@
1
+ // deck.gl-community
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ // react-graph-layers core
6
+ export {GraphEngine} from './core/graph-engine';
7
+ export {Graph} from './core/graph';
8
+ export {Node} from './core/node';
9
+ export {Edge} from './core/edge';
10
+ export {
11
+ NODE_STATE,
12
+ NODE_TYPE,
13
+ EDGE_TYPE,
14
+ EDGE_DECORATOR_TYPE,
15
+ LAYOUT_STATE,
16
+ MARKER_TYPE
17
+ } from './core/constants';
18
+
19
+ // react-graph-layers layouts
20
+ export {BaseLayout} from './core/base-layout';
21
+ export {D3ForceLayout} from './layouts/d3-force/d3-force-layout';
22
+ export {GPUForceLayout} from './layouts/gpu-force/gpu-force-layout';
23
+ export {SimpleLayout} from './layouts/simple-layout/simple-layout';
24
+
25
+ // react-graph-layers loaders
26
+ export {JSONLoader} from './loaders/json-loader';
27
+ export {basicNodeParser} from './loaders/node-parsers';
28
+ export {basicEdgeParser} from './loaders/edge-parsers';
29
+
30
+ // react-graph-layers utils
31
+ export {createGraph} from './utils/create-graph';
32
+ export * from './utils/layer-utils';
33
+ export * from './utils/log';
34
+
35
+ // deck.gl components
36
+ export {GraphLayer} from './layers/graph-layer';
37
+ export {EdgeLayer} from './layers/edge-layer';
38
+
39
+ // DEPRECATED
40
+
41
+ /** @deprecated Use EdgeLayer */
42
+ export {EdgeLayer as CompositeEdgeLayer} from './layers/edge-layer';
@@ -0,0 +1,50 @@
1
+ // deck.gl-community
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ export const fs = /* glsl */ `\
6
+ #define SHADER_NAME flow-path-layer-fragment-shader
7
+
8
+ precision highp float;
9
+
10
+ varying vec4 vColor;
11
+ varying float segmentIndex;
12
+ varying float speed;
13
+ varying float offset;
14
+ varying float pathLength;
15
+ varying float tailLength;
16
+
17
+ void main(void) {
18
+ gl_FragColor = vColor;
19
+
20
+ // use highlight color if this fragment belongs to the selected object.
21
+ gl_FragColor = picking_filterHighlightColor(gl_FragColor);
22
+
23
+ // use picking color if rendering to picking FBO.
24
+ gl_FragColor = picking_filterPickingColor(gl_FragColor);
25
+
26
+ if (speed == 0.0) {
27
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
28
+ } else {
29
+ // the portion of the visible segment (0 to 1) , ex: 0.3
30
+ // edge cases: pathLength = 0 or tailLength > pathLength
31
+ float segFragment = 0.0;
32
+ if (pathLength != 0.0) {
33
+ segFragment = tailLength / pathLength;
34
+ }
35
+ if (tailLength > pathLength) {
36
+ segFragment = 1.0;
37
+ }
38
+ float startSegmentIndex = mod(offset, 60.0) / 60.0;
39
+ // the end offset, cap to 1.0 (end of the line)
40
+ float endSegmentIndex = min(startSegmentIndex + segFragment, 1.0);
41
+ if (segmentIndex < startSegmentIndex || segmentIndex > endSegmentIndex) {
42
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
43
+ } else {
44
+ // fading tail
45
+ float portion = (segmentIndex - startSegmentIndex) / segFragment;
46
+ gl_FragColor[3] = portion;
47
+ }
48
+ }
49
+ }
50
+ `;
@@ -0,0 +1,15 @@
1
+ // deck.gl-community
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ export const tfvs = /* glsl */ `\
6
+ #define SHADER_NAME flow-path-layer-vertex-tf-shader
7
+
8
+ attribute float a_offset;
9
+ attribute float a_speed;
10
+ varying float v_offset;
11
+
12
+ void main(void) {
13
+ v_offset = a_offset + a_speed;
14
+ }
15
+ `;
@@ -0,0 +1,74 @@
1
+ // deck.gl-community
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ export const vs = /* glsl */ `\
6
+ #define SHADER_NAME flow-path-layer-vertex-shader
7
+
8
+ attribute vec3 positions;
9
+ attribute vec3 instanceSourcePositions;
10
+ attribute vec3 instanceTargetPositions;
11
+ attribute vec4 instanceSourceTargetPositions64xyLow;
12
+ attribute vec4 instanceColors;
13
+ attribute vec3 instancePickingColors;
14
+ attribute float instanceWidths;
15
+ attribute float instanceSpeeds;
16
+ attribute float instanceOffsets;
17
+ attribute float instanceTailLengths;
18
+
19
+ uniform float opacity;
20
+ uniform float widthScale;
21
+ uniform float widthMinPixels;
22
+ uniform float widthMaxPixels;
23
+
24
+ varying vec4 vColor;
25
+ varying float segmentIndex;
26
+ varying float speed;
27
+ varying float pathLength;
28
+ varying float tailLength;
29
+ varying float offset;
30
+
31
+ // offset vector by strokeWidth pixels
32
+ // offset_direction is -1 (left) or 1 (right)
33
+ vec2 getExtrusionOffset(vec2 line_clipspace, float offset_direction, float width) {
34
+ // normalized direction of the line
35
+ vec2 dir_screenspace = normalize(line_clipspace * project_uViewportSize);
36
+ // rotate by 90 degrees
37
+ dir_screenspace = vec2(-dir_screenspace.y, dir_screenspace.x);
38
+
39
+ vec2 offset_screenspace = dir_screenspace * offset_direction * width / 2.0;
40
+ vec2 offset_clipspace = project_pixel_size_to_clipspace(offset_screenspace);
41
+
42
+ return offset_clipspace;
43
+ }
44
+
45
+ void main(void) {
46
+ // Position
47
+ vec4 source = project_position_to_clipspace(instanceSourcePositions, instanceSourceTargetPositions64xyLow.xy, vec3(0.));
48
+ vec4 target = project_position_to_clipspace(instanceTargetPositions, instanceSourceTargetPositions64xyLow.zw, vec3(0.));
49
+
50
+ // Multiply out width and clamp to limits
51
+ float widthPixels = clamp(
52
+ project_size_to_pixel(instanceWidths * widthScale),
53
+ widthMinPixels, widthMaxPixels
54
+ );
55
+
56
+ // linear interpolation of source & target to pick right coord
57
+ segmentIndex = positions.x;
58
+ speed = instanceSpeeds;
59
+ tailLength = project_size_to_pixel(instanceTailLengths * widthScale);
60
+ offset = instanceOffsets;
61
+ pathLength = distance(instanceSourcePositions, instanceTargetPositions);
62
+ vec4 p = mix(source, target, segmentIndex);
63
+
64
+ // extrude
65
+ vec2 offset = getExtrusionOffset(target.xy - source.xy, positions.y, widthPixels);
66
+ gl_Position = p + vec4(offset, 0.0, 0.0);
67
+
68
+ // Color
69
+ vColor = vec4(instanceColors.rgb, instanceColors.a * opacity) / 255.;
70
+
71
+ // Set color to be rendered to picking fbo (also used to check for selection highlight).
72
+ picking_setPickingColor(instancePickingColors);
73
+ }
74
+ `;