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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/LICENSE +1 -1
  2. package/dist/core/graph-engine.d.ts +16 -7
  3. package/dist/core/graph-engine.d.ts.map +1 -1
  4. package/dist/core/graph-engine.js +13 -4
  5. package/dist/core/graph-layout.d.ts +69 -0
  6. package/dist/core/graph-layout.d.ts.map +1 -0
  7. package/dist/core/{base-layout.js → graph-layout.js} +63 -80
  8. package/dist/core/interaction-manager.d.ts +1 -1
  9. package/dist/core/interaction-manager.d.ts.map +1 -1
  10. package/dist/{core → graph}/edge.d.ts +18 -17
  11. package/dist/graph/edge.d.ts.map +1 -0
  12. package/dist/{core → graph}/edge.js +12 -15
  13. package/dist/{core → graph}/graph.d.ts +34 -31
  14. package/dist/graph/graph.d.ts.map +1 -0
  15. package/dist/{core → graph}/graph.js +43 -36
  16. package/dist/{core → graph}/node.d.ts +20 -20
  17. package/dist/graph/node.d.ts.map +1 -0
  18. package/dist/{core → graph}/node.js +16 -18
  19. package/dist/index.cjs +1181 -434
  20. package/dist/index.cjs.map +4 -4
  21. package/dist/index.d.ts +16 -14
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +19 -18
  24. package/dist/layers/graph-layer.d.ts +45 -5
  25. package/dist/layers/graph-layer.d.ts.map +1 -1
  26. package/dist/layers/graph-layer.js +80 -38
  27. package/dist/layers/node-layers/{path-rounded-rectange-layer.d.ts → path-rounded-rectangle-layer.d.ts} +1 -1
  28. package/dist/layers/node-layers/path-rounded-rectangle-layer.d.ts.map +1 -0
  29. package/dist/layers/node-layers/rounded-rectangle-layer-fragment.d.ts +1 -1
  30. package/dist/layers/node-layers/rounded-rectangle-layer-fragment.d.ts.map +1 -1
  31. package/dist/layers/node-layers/rounded-rectangle-layer-fragment.js +1 -3
  32. package/dist/layers/node-layers/rounded-rectangle-layer.d.ts +12 -3
  33. package/dist/layers/node-layers/rounded-rectangle-layer.d.ts.map +1 -1
  34. package/dist/layers/node-layers/rounded-rectangle-layer.js +25 -11
  35. package/dist/layouts/d3-force/d3-force-layout.d.ts +12 -3
  36. package/dist/layouts/d3-force/d3-force-layout.d.ts.map +1 -1
  37. package/dist/layouts/d3-force/d3-force-layout.js +11 -11
  38. package/dist/layouts/d3-force/worker.d.ts.map +1 -1
  39. package/dist/layouts/experimental/force-multi-graph-layout.d.ts +43 -0
  40. package/dist/layouts/experimental/force-multi-graph-layout.d.ts.map +1 -0
  41. package/dist/layouts/experimental/force-multi-graph-layout.js +226 -0
  42. package/dist/layouts/experimental/hive-plot-layout.d.ts +34 -0
  43. package/dist/layouts/experimental/hive-plot-layout.d.ts.map +1 -0
  44. package/dist/layouts/experimental/hive-plot-layout.js +142 -0
  45. package/dist/layouts/experimental/radial-layout.d.ts +28 -0
  46. package/dist/layouts/experimental/radial-layout.d.ts.map +1 -0
  47. package/dist/layouts/experimental/radial-layout.js +164 -0
  48. package/dist/layouts/gpu-force/gpu-force-layout.d.ts +15 -3
  49. package/dist/layouts/gpu-force/gpu-force-layout.d.ts.map +1 -1
  50. package/dist/layouts/gpu-force/gpu-force-layout.js +20 -18
  51. package/dist/layouts/gpu-force/worker.d.ts.map +1 -1
  52. package/dist/layouts/simple-layout.d.ts +42 -0
  53. package/dist/layouts/simple-layout.d.ts.map +1 -0
  54. package/dist/layouts/{simple-layout/simple-layout.js → simple-layout.js} +8 -7
  55. package/dist/loaders/create-graph.d.ts +13 -0
  56. package/dist/loaders/create-graph.d.ts.map +1 -0
  57. package/dist/{utils → loaders}/create-graph.js +9 -4
  58. package/dist/loaders/edge-parsers.d.ts +2 -6
  59. package/dist/loaders/edge-parsers.d.ts.map +1 -1
  60. package/dist/loaders/json-loader.js +1 -1
  61. package/dist/loaders/node-parsers.d.ts +2 -3
  62. package/dist/loaders/node-parsers.d.ts.map +1 -1
  63. package/dist/loaders/simple-json-graph-loader.d.ts +12 -0
  64. package/dist/loaders/simple-json-graph-loader.d.ts.map +1 -0
  65. package/dist/loaders/simple-json-graph-loader.js +20 -0
  66. package/dist/loaders/table-graph-loader.d.ts +17 -0
  67. package/dist/loaders/table-graph-loader.d.ts.map +1 -0
  68. package/dist/loaders/table-graph-loader.js +91 -0
  69. package/dist/utils/log.d.ts +1 -1
  70. package/dist/utils/log.d.ts.map +1 -1
  71. package/dist/utils/log.js +3 -3
  72. package/dist/widgets/long-press-button.d.ts +13 -0
  73. package/dist/widgets/long-press-button.d.ts.map +1 -0
  74. package/dist/widgets/long-press-button.js +31 -0
  75. package/dist/widgets/view-control-widget.d.ts +78 -0
  76. package/dist/widgets/view-control-widget.d.ts.map +1 -0
  77. package/dist/widgets/view-control-widget.js +194 -0
  78. package/package.json +8 -6
  79. package/src/core/graph-engine.ts +30 -10
  80. package/src/core/graph-layout.ts +146 -0
  81. package/src/core/interaction-manager.ts +2 -2
  82. package/src/{core → graph}/edge.ts +19 -17
  83. package/src/{core → graph}/graph.ts +51 -36
  84. package/src/{core → graph}/node.ts +21 -20
  85. package/src/index.ts +28 -28
  86. package/src/layers/graph-layer.ts +133 -46
  87. package/src/layers/node-layers/rounded-rectangle-layer-fragment.ts +1 -3
  88. package/src/layers/node-layers/rounded-rectangle-layer.ts +34 -10
  89. package/src/layouts/d3-force/d3-force-layout.ts +21 -11
  90. package/src/layouts/experimental/force-multi-graph-layout.ts +268 -0
  91. package/src/layouts/experimental/hive-plot-layout.ts +182 -0
  92. package/src/layouts/experimental/radial-layout.ts +210 -0
  93. package/src/layouts/gpu-force/gpu-force-layout.ts +32 -17
  94. package/src/layouts/{simple-layout/simple-layout.ts → simple-layout.ts} +34 -19
  95. package/src/{utils → loaders}/create-graph.ts +9 -4
  96. package/src/loaders/edge-parsers.ts +2 -1
  97. package/src/loaders/json-loader.ts +1 -1
  98. package/src/loaders/node-parsers.ts +2 -1
  99. package/src/loaders/simple-json-graph-loader.ts +28 -0
  100. package/src/loaders/table-graph-loader.ts +124 -0
  101. package/src/utils/log.ts +3 -3
  102. package/src/widgets/long-press-button.tsx +50 -0
  103. package/src/widgets/view-control-widget.tsx +337 -0
  104. package/dist/core/base-layout.d.ts +0 -72
  105. package/dist/core/base-layout.d.ts.map +0 -1
  106. package/dist/core/edge.d.ts.map +0 -1
  107. package/dist/core/graph.d.ts.map +0 -1
  108. package/dist/core/node.d.ts.map +0 -1
  109. package/dist/layers/node-layers/path-rounded-rectange-layer.d.ts.map +0 -1
  110. package/dist/layouts/simple-layout/simple-layout.d.ts +0 -23
  111. package/dist/layouts/simple-layout/simple-layout.d.ts.map +0 -1
  112. package/dist/utils/create-graph.d.ts +0 -9
  113. package/dist/utils/create-graph.d.ts.map +0 -1
  114. package/src/core/base-layout.ts +0 -154
  115. /package/dist/layers/node-layers/{path-rounded-rectange-layer.js → path-rounded-rectangle-layer.js} +0 -0
  116. /package/src/layers/node-layers/{path-rounded-rectange-layer.ts → path-rounded-rectangle-layer.ts} +0 -0
  117. /package/src/layouts/d3-force/{worker.ts → worker.js} +0 -0
  118. /package/src/layouts/gpu-force/{worker.ts → worker.js} +0 -0
@@ -0,0 +1,194 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "preact/jsx-runtime";
2
+ // deck.gl-community
3
+ // SPDX-License-Identifier: MIT
4
+ // Copyright (c) vis.gl contributors
5
+ import { Component, render } from 'preact';
6
+ import { LongPressButton } from "./long-press-button.js";
7
+ export const ViewControlWrapper = ({ children }) => (_jsxs("div", { style: {
8
+ alignItems: 'center',
9
+ display: 'flex',
10
+ flexDirection: 'column',
11
+ position: 'absolute',
12
+ zIndex: 99,
13
+ userSelect: 'none'
14
+ }, children: [' ', children, ' '] }));
15
+ export const NavigationButtonContainer = ({ children }) => (_jsxs("div", { style: {
16
+ background: '#f7f7f7',
17
+ borderRadius: '23px',
18
+ border: '0.5px solid #eaeaea',
19
+ boxShadow: 'inset 11px 11px 5px -7px rgba(230, 230, 230, 0.49)',
20
+ height: '46px',
21
+ width: '46px'
22
+ }, children: [' ', children, ' '] }));
23
+ export const NavigationButton = (props) => (_jsxs("div", { onClick: props.onClick, style: {
24
+ color: '#848484',
25
+ cursor: 'pointer',
26
+ position: 'absolute',
27
+ left: props.left,
28
+ top: props.top,
29
+ transform: `rotate(${props.rotate || 0}deg)`
30
+ // &:hover,
31
+ // &:active {
32
+ // color: #00ade6;
33
+ // }
34
+ }, children: [' ', props.children, ' '] }));
35
+ export const ZoomControlWrapper = ({ children }) => (_jsxs("div", { style: {
36
+ alignItems: 'center',
37
+ background: '#f7f7f7',
38
+ border: '0.5px solid #eaeaea',
39
+ display: 'flex',
40
+ flexDirection: 'column',
41
+ marginTop: '6px',
42
+ padding: '2px 0',
43
+ width: '18px'
44
+ }, children: [' ', children, ' '] }));
45
+ export const VerticalSlider = ({ children }) => (_jsxs("div", { style: {
46
+ display: 'inline-block',
47
+ height: '100px',
48
+ padding: '0',
49
+ width: '10px'
50
+ // > input[type='range'][orient='vertical'] {
51
+ // -webkit-appearance: slider-vertical;
52
+ // height: 100px;
53
+ // padding: 0;
54
+ // margin: 0;
55
+ // width: 10px;
56
+ // }
57
+ }, children: [' ', children, ' '] }));
58
+ export const ZoomControlButton = ({ children }) => (_jsxs("div", { style: {
59
+ cursor: 'pointer',
60
+ fontSize: '14px',
61
+ fontWeight: 500,
62
+ margin: '-4px'
63
+ // &:hover,
64
+ // &:active {
65
+ // color: #00ade6;
66
+ // }
67
+ }, children: [' ', children, ' '] }));
68
+ export class ViewControl extends Component {
69
+ static displayName = 'ViewControl';
70
+ static defaultProps = {
71
+ id: undefined,
72
+ viewId: undefined,
73
+ placement: 'top-left',
74
+ fitBounds: () => { },
75
+ panBy: () => { },
76
+ zoomBy: () => { },
77
+ zoomLevel: 1,
78
+ deltaPan: 10,
79
+ deltaZoom: 0.1,
80
+ minZoom: 0.1,
81
+ maxZoom: 1,
82
+ style: {},
83
+ className: ''
84
+ };
85
+ // pan actions
86
+ panUp = () => this.props.panBy(0, this.props.deltaPan);
87
+ panDown = () => this.props.panBy(0, -1 * this.props.deltaPan);
88
+ panLeft = () => this.props.panBy(this.props.deltaPan, 0);
89
+ panRight = () => this.props.panBy(-1 * this.props.deltaPan, 0);
90
+ // zoom actions
91
+ zoomIn = () => this.props.zoomBy(this.props.deltaZoom);
92
+ zoomOut = () => this.props.zoomBy(-1 * this.props.deltaZoom);
93
+ onChangeZoomLevel = (evt) => {
94
+ const delta = evt.target.value - this.props.zoomLevel;
95
+ this.props.zoomBy(delta);
96
+ };
97
+ render() {
98
+ const buttons = [
99
+ { top: -2, left: 14, rotate: 0, onClick: this.panUp, content: '▲', key: 'up' },
100
+ { top: 12, left: 0, rotate: -90, onClick: this.panLeft, content: '◀', key: 'left' },
101
+ { top: 12, left: 28, rotate: 90, onClick: this.panRight, content: '▶', key: 'right' },
102
+ { top: 25, left: 14, rotate: 180, onClick: this.panDown, content: '▼', key: 'down' }
103
+ ];
104
+ return (_jsxs(ViewControlWrapper, { children: [_jsxs(NavigationButtonContainer, { children: [buttons.map((b) => (_jsx(NavigationButton, { top: `${b.top}px`, left: `${b.left}px`, rotate: b.rotate, children: _jsx(LongPressButton, { onClick: b.onClick, children: b.content }) }, b.key))), _jsx(NavigationButton, { top: '12px', left: '16px', onClick: () => {
105
+ // console.log('on click fit bounds') || this.props.fitBounds;
106
+ }, children: '¤' })] }), _jsxs(ZoomControlWrapper, { children: [_jsx(ZoomControlButton, { children: _jsx(LongPressButton, { onClick: this.zoomIn, children: '+' }) }), _jsx(VerticalSlider, { children: _jsx("input", { type: "range", value: this.props.zoomLevel, min: this.props.minZoom, max: this.props.maxZoom, step: this.props.deltaZoom, onChange: this.onChangeZoomLevel,
107
+ /* @ts-expect-error TODO */
108
+ orient: "vertical" }) }), _jsx(ZoomControlButton, { children: _jsx(LongPressButton, { onClick: this.zoomOut, children: '-' }) })] })] }));
109
+ }
110
+ }
111
+ export class ViewControlWidget {
112
+ id = 'zoom';
113
+ props;
114
+ placement = 'top-left';
115
+ orientation = 'vertical';
116
+ viewId = null;
117
+ viewports = {};
118
+ deck;
119
+ element;
120
+ constructor(props) {
121
+ this.props = { ...ViewControl.defaultProps, ...props };
122
+ this.id = props.id || 'zoom';
123
+ this.viewId = props.viewId || null;
124
+ this.placement = props.placement || 'top-left';
125
+ // this.orientation = props.orientation || 'vertical';
126
+ // props.transitionDuration = props.transitionDuration || 200;
127
+ // props.zoomInLabel = props.zoomInLabel || 'Zoom In';
128
+ // props.zoomOutLabel = props.zoomOutLabel || 'Zoom Out';
129
+ props.style = props.style || {};
130
+ this.props = props;
131
+ }
132
+ onAdd({ deck }) {
133
+ this.deck = deck;
134
+ this.element = document.createElement('div');
135
+ const { style, className } = this.props;
136
+ this.element.classList.add('deck-widget', 'deck-widget-zoom');
137
+ if (className) {
138
+ this.element.classList.add(className);
139
+ }
140
+ if (style) {
141
+ Object.entries(style).map(([key, value]) => this.element.style.setProperty(key, value));
142
+ }
143
+ const ui = (_jsx(ViewControl, { ...this.props, zoomBy: this.handleDeltaZoom.bind(this), panBy: this.handlePanBy.bind(this) }));
144
+ render(ui, this.element);
145
+ return this.element;
146
+ }
147
+ onRemove() {
148
+ this.deck = undefined;
149
+ this.element = undefined;
150
+ }
151
+ setProps(props) {
152
+ Object.assign(this.props, props);
153
+ }
154
+ onViewportChange(viewport) {
155
+ this.viewports[viewport.id] = viewport;
156
+ }
157
+ handleDeltaZoom(deltaZoom) {
158
+ // console.log('Handle delta zoom');
159
+ for (const view of this.deck.getViewports()) {
160
+ this.handleZoomView(view, view.zoom + deltaZoom);
161
+ }
162
+ }
163
+ handlePanBy(deltaX, deltaY) {
164
+ // console.log('Handle panby', deltaX, deltaY);
165
+ for (const viewport of this.deck.getViewports()) {
166
+ this.handlePanViewport(viewport, deltaX, deltaY);
167
+ }
168
+ }
169
+ handleZoomView(viewport, nextZoom) {
170
+ const viewId = this.viewId || viewport?.id || 'default-view';
171
+ // @ts-expect-error TODO we lack a proper API for getting viewStates
172
+ const viewState = this.deck.viewManager.viewState || viewport;
173
+ const nextViewState = {
174
+ ...viewState,
175
+ zoom: nextZoom
176
+ // transitionDuration: this.props.transitionDuration,
177
+ // transitionInterpolator: new FlyToInterpolator()
178
+ };
179
+ // @ts-ignore Using private method temporary until there's a public one
180
+ this.deck._onViewStateChange({ viewId, viewState: nextViewState, interactionState: {} });
181
+ }
182
+ handlePanViewport(viewport, deltaX, deltaY) {
183
+ const viewId = this.viewId || viewport?.id || 'default-view';
184
+ // @ts-expect-error TODO we lack a proper API for getting viewStates
185
+ const viewState = this.deck.viewManager.viewState || viewport;
186
+ // console.log('Handle pan viewport', deltaX, deltaY, viewState);
187
+ const nextViewState = {
188
+ ...viewState,
189
+ position: [viewport.position[0] + deltaX, viewport.position[1] + deltaY]
190
+ };
191
+ // @ts-ignore Using private method temporary until there's a public one
192
+ this.deck._onViewStateChange({ viewId, viewState: nextViewState, interactionState: {} });
193
+ }
194
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deck.gl-community/graph-layers",
3
- "version": "9.0.2",
3
+ "version": "9.1.0-beta.2",
4
4
  "description": "WebGL2-Powered library for Graph Visualization",
5
5
  "keywords": [
6
6
  "graph",
@@ -31,9 +31,11 @@
31
31
  },
32
32
  "license": "MIT",
33
33
  "dependencies": {
34
- "@deck.gl/core": "^9.0.12",
35
- "@deck.gl/layers": "^9.0.12",
36
- "@luma.gl/core": "^9.0.12",
34
+ "@deck.gl/core": "^9.1.0",
35
+ "@deck.gl/layers": "^9.1.0",
36
+ "@deck.gl/widgets": "^9.1.0",
37
+ "@luma.gl/core": "^9.1.0",
38
+ "@probe.gl/log": "^4.0.4",
37
39
  "cardinal-spline-js": "^2.3.10",
38
40
  "color": "^4.2.3",
39
41
  "core-js": "^3.29.0",
@@ -45,11 +47,11 @@
45
47
  "global": "^4.4.0",
46
48
  "lodash.isequal": "^4.5.0",
47
49
  "lodash.pick": "^4.4.0",
48
- "probe.gl": "^3.6.0",
50
+ "preact": "^10.17.0",
49
51
  "raf": "^3.4.1"
50
52
  },
51
53
  "devDependencies": {
52
54
  "ngraph.generators": "^20.1.0"
53
55
  },
54
- "gitHead": "8955b0da47771f3524b65360243ee246abeb3660"
56
+ "gitHead": "80b6a3b1fafe0765f2070928ae360fc52bd57a46"
55
57
  }
@@ -2,23 +2,43 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- import {BaseLayout} from './base-layout';
5
+ import type {Node} from '../graph/node';
6
+ import {Edge} from '../graph/edge';
7
+ import {Graph} from '../graph/graph';
8
+ import {GraphLayout} from './graph-layout';
6
9
  import {Cache} from './cache';
7
- import {Edge} from './edge';
8
- import {Graph} from './graph';
9
10
 
10
- // Graph engine controls the graph data and layout calculation
11
+ export type GraphEngineProps = {
12
+ graph: Graph;
13
+ layout: GraphLayout;
14
+ };
15
+
16
+ /** Graph engine controls the graph data and layout calculation */
11
17
  export class GraphEngine extends EventTarget {
18
+ props: Readonly<Required<GraphEngineProps>>;
19
+
12
20
  private readonly _graph: Graph;
13
- private readonly _layout: BaseLayout;
21
+ private readonly _layout: GraphLayout;
14
22
  private readonly _cache = new Cache<'nodes' | 'edges', Node[] | Edge[]>();
15
23
  private _layoutDirty = false;
16
24
  private _transactionInProgress = false;
17
25
 
18
- constructor(graph: Graph, layout: BaseLayout) {
26
+ constructor(props: GraphEngineProps);
27
+ /** @deprecated Use props constructor: new GraphEngine(props) */
28
+ constructor(graph: Graph, layout: GraphLayout);
29
+
30
+ constructor(props: GraphEngineProps | Graph, layout?: GraphLayout) {
19
31
  super();
20
- this._graph = graph;
21
- this._layout = layout;
32
+ if (props instanceof Graph) {
33
+ props = {
34
+ graph: props,
35
+ layout
36
+ };
37
+ }
38
+
39
+ this.props = props;
40
+ this._graph = props.graph;
41
+ this._layout = props.layout;
22
42
  }
23
43
 
24
44
  /** Getters */
@@ -39,9 +59,9 @@ export class GraphEngine extends EventTarget {
39
59
  return this._cache.get('edges') as Edge[];
40
60
  };
41
61
 
42
- getNodePosition = (node) => this._layout.getNodePosition(node);
62
+ getNodePosition = (node: Node) => this._layout.getNodePosition(node);
43
63
 
44
- getEdgePosition = (edge) => this._layout.getEdgePosition(edge);
64
+ getEdgePosition = (edge: Edge) => this._layout.getEdgePosition(edge);
45
65
 
46
66
  getGraphVersion = () => this._graph.version;
47
67
 
@@ -0,0 +1,146 @@
1
+ // deck.gl-community
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import type {Graph} from '../graph/graph';
6
+ import type {Node} from '../graph/node';
7
+ import type {Edge} from '../graph/edge';
8
+
9
+ import isEqual from 'lodash.isequal';
10
+ import {EDGE_TYPE} from './constants';
11
+
12
+ // the status of the layout
13
+ export type GraphLayoutState = 'INIT' | 'START' | 'CALCULATING' | 'DONE' | 'ERROR';
14
+
15
+ export type GraphLayoutOptions = {};
16
+
17
+ /** All the layout classes are extended from this base layout class. */
18
+ export class GraphLayout<
19
+ OptionsT extends GraphLayoutOptions = GraphLayoutOptions
20
+ > extends EventTarget {
21
+ /** Name of the layout. */
22
+ protected readonly _name: string = 'GraphLayout';
23
+ /** Extra configuration options of the layout. */
24
+ protected _options: OptionsT;
25
+
26
+ public version = 0;
27
+ public state: GraphLayoutState = 'INIT';
28
+
29
+ /**
30
+ * Constructor of GraphLayout
31
+ * @param options extra configuration options of the layout
32
+ */
33
+ constructor(options: OptionsT) {
34
+ super();
35
+ this._options = options;
36
+ }
37
+
38
+ /**
39
+ * Check the equality of two layouts
40
+ * @param layout - The layout to be compared.
41
+ * @return - True if the layout is the same as itself.
42
+ */
43
+ equals(layout: GraphLayout): boolean {
44
+ if (!layout || !(layout instanceof GraphLayout)) {
45
+ return false;
46
+ }
47
+ return this._name === layout._name && isEqual(this._options, layout._options);
48
+ }
49
+
50
+ /** virtual functions: will be implemented in the child class */
51
+
52
+ /** first time to pass the graph data into this layout */
53
+ initializeGraph(graph: Graph) {}
54
+ /** update the existing graph */
55
+ updateGraph(graph: Graph) {}
56
+ /** start the layout calculation */
57
+ start() {}
58
+ /** update the layout calculation */
59
+ update() {}
60
+ /** resume the layout calculation */
61
+ resume() {}
62
+ /** stop the layout calculation */
63
+ stop() {}
64
+ /** access the position of the node in the layout */
65
+ getNodePosition(node: Node): [number, number] {
66
+ return [0, 0];
67
+ }
68
+ /** access the layout information of the edge */
69
+ getEdgePosition(edge: Edge) {
70
+ return {
71
+ type: EDGE_TYPE.LINE,
72
+ sourcePosition: [0, 0],
73
+ targetPosition: [0, 0],
74
+ controlPoints: []
75
+ };
76
+ }
77
+
78
+ /**
79
+ * Pin the node to a designated position, and the node won't move anymore
80
+ * @param node Node to be locked
81
+ * @param x x coordinate
82
+ * @param y y coordinate
83
+ */
84
+ lockNodePosition(node: Node, x: number, y: number) {}
85
+
86
+ /**
87
+ * Unlock the node, the node will be able to move freely.
88
+ * @param {Object} node Node to be unlocked
89
+ */
90
+ unlockNodePosition(node: Node) {}
91
+
92
+ // INTERNAL METHODS
93
+
94
+ protected _updateState(state) {
95
+ this.state = state;
96
+ this.version += 1;
97
+ }
98
+
99
+ /** @fires GraphLayout#onLayoutStart */
100
+ protected _onLayoutStart = (): void => {
101
+ this._updateState('CALCULATING');
102
+
103
+ /**
104
+ * Layout calculation start.
105
+ * @event GraphLayout#onLayoutChange
106
+ * @type {CustomEvent}
107
+ */
108
+ this.dispatchEvent(new CustomEvent('onLayoutStart'));
109
+ };
110
+
111
+ /** @fires GraphLayout#onLayoutChange */
112
+ protected _onLayoutChange = (): void => {
113
+ this._updateState('CALCULATING');
114
+
115
+ /**
116
+ * Layout calculation iteration.
117
+ * @event GraphLayout#onLayoutChange
118
+ * @type {CustomEvent}
119
+ */
120
+ this.dispatchEvent(new CustomEvent('onLayoutChange'));
121
+ };
122
+
123
+ /** @fires GraphLayout#onLayoutDone */
124
+ protected _onLayoutDone = (): void => {
125
+ this._updateState('DONE');
126
+
127
+ /**
128
+ * Layout calculation is done.
129
+ * @event GraphLayout#onLayoutDone
130
+ * @type {CustomEvent}
131
+ */
132
+ this.dispatchEvent(new CustomEvent('onLayoutDone'));
133
+ };
134
+
135
+ /** @fires GraphLayout#onLayoutError */
136
+ protected _onLayoutError = (): void => {
137
+ this._updateState('ERROR');
138
+
139
+ /**
140
+ * Layout calculation went wrong.
141
+ * @event GraphLayout#onLayoutError
142
+ * @type {CustomEvent}
143
+ */
144
+ this.dispatchEvent(new CustomEvent('onLayoutError'));
145
+ };
146
+ }
@@ -3,9 +3,9 @@
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
5
  import {EDGE_STATE, NODE_STATE, ValueOf} from './constants';
6
- import {Edge} from './edge';
6
+ import {Edge} from '../graph/edge';
7
+ import {Node} from '../graph/node';
7
8
  import {GraphEngine} from './graph-engine';
8
- import {Node} from './node';
9
9
 
10
10
  const NODE_TO_EDGE_STATE_MAP: Record<ValueOf<typeof NODE_STATE>, ValueOf<typeof EDGE_STATE>> = {
11
11
  [NODE_STATE.DEFAULT]: EDGE_STATE.DEFAULT,
@@ -3,17 +3,23 @@
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
5
  // Basic data structure of an edge
6
- import {EDGE_STATE} from './constants';
6
+ import {EDGE_STATE} from '../core/constants';
7
7
  import {Node} from './node';
8
8
 
9
- interface EdgeOptions {
9
+ export interface EdgeOptions {
10
+ /** the unique ID of the edge */
10
11
  id: string | number;
12
+ /** the ID of the source node */
11
13
  sourceId: string | number;
14
+ /** the ID of the target node */
12
15
  targetId: string | number;
16
+ /** whether the edge is directed or not */
13
17
  directed?: boolean;
14
- data: Record<string, unknown>;
18
+ /** origin data reference */
19
+ data?: Record<string, unknown>;
15
20
  }
16
21
 
22
+ /** Basic edge data structure */
17
23
  export class Edge {
18
24
  /** Unique uuid of the edge. */
19
25
  public id: string | number;
@@ -34,11 +40,7 @@ export class Edge {
34
40
 
35
41
  /**
36
42
  * The constructor
37
- * @param {String|Number} options.id - the unique ID of the edge
38
- * @param {String|Number} options.sourceId - the ID of the source node
39
- * @param {String|Number} options.targetId - the ID of the target node
40
- * @param {Boolean} options.directed - whether the edge is directed or not
41
- * @param {Record<string, unknown>} options.data - origin data reference
43
+ * @param options.id - information about the edge
42
44
  */
43
45
  constructor({id, sourceId, targetId, data, directed = false}: EdgeOptions) {
44
46
  this.id = id;
@@ -66,7 +68,7 @@ export class Edge {
66
68
 
67
69
  /**
68
70
  * Get the ID of the source node.
69
- * @return {String|Number} the ID of the source node.
71
+ * @return the ID of the source node.
70
72
  */
71
73
  getSourceNodeId(): string | number {
72
74
  return this._sourceId;
@@ -74,7 +76,7 @@ export class Edge {
74
76
 
75
77
  /**
76
78
  * Get the ID of the target node.
77
- * @return {String|Number} the ID of the target node.
79
+ * @return the ID of the target node.
78
80
  */
79
81
  getTargetNodeId(): string | number {
80
82
  return this._targetId;
@@ -82,8 +84,8 @@ export class Edge {
82
84
 
83
85
  /**
84
86
  * Return of the value of the selected property key.
85
- * @param {String} key - property key.
86
- * @return {Any} - the value of the property.
87
+ * @param key - property key.
88
+ * @return - the value of the property.
87
89
  */
88
90
  getPropertyValue(key: string): unknown {
89
91
  // try to search the key within this object
@@ -100,7 +102,7 @@ export class Edge {
100
102
 
101
103
  /**
102
104
  * Set the origin data as a reference.
103
- * @param {Object} data - the origin data.
105
+ * @param data - the origin data.
104
106
  */
105
107
  setData(data: Record<string, unknown>): void {
106
108
  this._data = data;
@@ -108,8 +110,8 @@ export class Edge {
108
110
 
109
111
  /**
110
112
  * Update a data property.
111
- * @param {String} key - the key of the property
112
- * @param {Any} value - the value of the property.
113
+ * @param key - the key of the property
114
+ * @param value - the value of the property.
113
115
  */
114
116
  setDataProperty(key: string, value: unknown): void {
115
117
  this._data[key] = value;
@@ -117,7 +119,7 @@ export class Edge {
117
119
 
118
120
  /**
119
121
  * Set edge state
120
- * @param {String} state - one of EDGE_STATE
122
+ * @param state - one of EDGE_STATE
121
123
  */
122
124
  setState(state: string): void {
123
125
  this.state = state;
@@ -125,7 +127,7 @@ export class Edge {
125
127
 
126
128
  /**
127
129
  * Get edge state
128
- * @returns {string} state - one of EDGE_STATE
130
+ * @returns state - one of EDGE_STATE
129
131
  */
130
132
  getState(): string {
131
133
  return this.state;