Skip to content

Commit 2530739

Browse files
tonilastrecizlAlexIchenskiy
authored
New: Add new simulator (#56) (#57)
* New: Add new simulator (#56) * New: Add simulator scenarios for manual testing * New: Refactor simulator (WIP) * New: Add progress overlay, Update descriptions * Fix: Introduce new simulator event, Fix main-thread behavior * Fix: Rearrange class methods based on visibility * Fix: Improve naming * Chore(release): 0.2.0 * Fix: Tweak simulator, adjust API slightly * Fix: Temporarily patch some physics behavior * Fix: Adjust re-heating parameters * Fix: tweak physics behavior -> immediately stop sim when disabling * Chore: Remove the beta from release branches --------- Co-authored-by: dlozic <[email protected]> * New: Add zoom and recenter functions (#74) * New: Add zoom and recenter functions * Fix: Reduce excessive recentering (#75) * Fix: Remove excessive recenterings * Fix: Remove unused code * Fix: New simulator (#92) * Chore: Refactor naming * New: Add new events * Chore: Refactor code styling * Docs: Remove unused flags * Chore: Remove unused simulation functions * Chore: Refactor view render function calls * Chore: Add missing tests * New: Add removal functions (#96) * New: Add removal functions * Fix: Add missing callback data * Chore: Refactor remove return values * Chore: Refactor remove function type usage * Fix: Default settings for node placement (#98) * New: Add properties setters and getters (#93) * New: Add node properties setters * New: Add edge properties setters * New: Add properties getters * New: Add patch for nodes and edges * Fix: Make getters return copies * Fix: Edge factory listeners copying * Fix: Jest outdated tests * Fix: Github actions node version * Chore: Refactor observer interface * Chore: Refactor node/edge constructor settings * Chore: Refactor node/edge function grouping * Chore: Refactor node/edge function grouping * Fix: Listeners behaviour * Chore: Refactor property copying * Chore: Refactor subject implementation * Fix: Set position behaviour on node drag * Chore: Upgrade node version * Chore: Refactor function type check * Fix: Remove listener behaviour * Chore: Refactor util naming * Chore: Remove unused type assertion * Chore: Refactor position setter options * Chore: Refactor property patch function * Fix: Set map node position behaviour * Chore: Refactor simulator data patching * Chore: Change observers to callbacks * New: Add state setters with options (#95) * New: Add state setters with options * Chore: Remove leftover comments * Chore: Refactor state setter logic * Chore: Refactor state types * Fix: Rename merged function usage * Fix: Merged variable naming * Chore: Fix tests --------- Co-authored-by: dlozic <[email protected]> Co-authored-by: Oleksandr Ichenskyi <[email protected]> Co-authored-by: AlexIchenskiy <[email protected]>
1 parent cdb3a6d commit 2530739

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+5722
-12757
lines changed

.github/workflows/build.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
- uses: actions/checkout@v1
1010
- uses: actions/setup-node@v1
1111
with:
12-
node-version: "16.x"
12+
node-version: "18.x"
1313

1414
- name: 'Install'
1515
run: npm ci

.github/workflows/release.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
- uses: actions/checkout@v1
1313
- uses: actions/setup-node@v1
1414
with:
15-
node-version: "16.x"
15+
node-version: "18.x"
1616

1717
- name: 'Install'
1818
run: npm ci

.releaserc

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
}],
99
"@semantic-release/changelog",
1010
"@semantic-release/npm",
11-
'@semantic-release/github',
11+
"@semantic-release/github",
1212
["@semantic-release/git", {
1313
"assets": ["package.json", "CHANGELOG.md"],
1414
"message": "Chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
15-
}],
16-
],
15+
}]
16+
]
1717
}

README.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Orb is a graph visualization library. Read more about Orb in the following guide
2424
* [Styling nodes and edges](./docs/styles.md)
2525
* [Handling events](./docs/events.md)
2626
* Using different views
27-
* [Default view](./docs/view-default.md)
27+
* [Default view](./docs/view-default.md)
2828
* [Map view](./docs/view-map.md)
2929

3030
## Install
@@ -106,7 +106,7 @@ free to check other JavaScript examples in `examples/` directory.
106106
<div id="graph"></div>
107107
<script>
108108
const container = document.getElementById("graph");
109-
109+
110110
const nodes = [
111111
{ id: 1, label: "Orb" },
112112
{ id: 2, label: "Graph" },
@@ -116,13 +116,13 @@ free to check other JavaScript examples in `examples/` directory.
116116
{ id: 1, start: 1, end: 2, label: "DRAWS" },
117117
{ id: 2, start: 2, end: 3, label: "ON" },
118118
];
119-
120-
// First `Orb` is just a namespace of the JS package
119+
120+
// First `Orb` is just a namespace of the JS package
121121
const orb = new Orb.OrbView(container);
122-
122+
123123
// Initialize nodes and edges
124124
orb.data.setup({ nodes, edges });
125-
125+
126126
// Render and recenter the view
127127
orb.render(() => {
128128
orb.recenter();

docs/view-default.md

+20-15
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ interface IOrbViewSettings {
9191
zoomFitTransitionMs: number;
9292
isOutOfBoundsDragEnabled: boolean;
9393
areCoordinatesRounded: boolean;
94-
isSimulationAnimated: boolean;
94+
areCollapsedContainerDimensionsAllowed: boolean;
9595
}
9696
```
9797

@@ -164,7 +164,7 @@ const defaultSettings = {
164164
zoomFitTransitionMs: 200,
165165
isOutOfBoundsDragEnabled: false,
166166
areCoordinatesRounded: true,
167-
isSimulationAnimated: true,
167+
areCollapsedContainerDimensionsAllowed: false;
168168
}
169169
```
170170

@@ -295,22 +295,22 @@ Disabled by default (`false`).
295295

296296
The optional property `strategy` has two properties that you can enable/disable:
297297

298-
* `isDefaultSelectEnabled` - when `true`, the default selection strategy is used on mouse click:
299-
* If there is a node at the mouse click point, the node, its edges, and adjacent nodes will change
298+
- `isDefaultSelectEnabled` - when `true`, the default selection strategy is used on mouse click:
299+
- If there is a node at the mouse click point, the node, its edges, and adjacent nodes will change
300300
its state to `GraphObjectState.SELECTED`. Style properties that end with `...Selected` will be
301301
applied to all the selected objects (e.g. `borderColorSelected`).
302-
* If there is an edge at the mouse click point, the edge and its starting and ending nodes will change
302+
- If there is an edge at the mouse click point, the edge and its starting and ending nodes will change
303303
its state to `GraphObjectState.SELECTED`.
304-
* `isDefaultHoverEnabled` - when `true`, the default hover strategy is used on mouse move:
305-
* If there is a node at the mouse pointer, the node, its edges, and adjacent nodes will change its state to
304+
- `isDefaultHoverEnabled` - when `true`, the default hover strategy is used on mouse move:
305+
- If there is a node at the mouse pointer, the node, its edges, and adjacent nodes will change its state to
306306
`GraphObjectState.HOVERED`. Style properties that end with `...Hovered` will be applied to all the
307307
hovered objects (e.g. `borderColorHovered`).
308308

309309
With property `strategy` you can disable the above behavior and implement your select/hover strategy on
310310
top of events `OrbEventType.MOUSE_CLICK` and `OrbEventType.MOUSE_MOVE`, e.g:
311311

312312
```typescript
313-
import { isNode, OrbEventType, GraphObjectState } from '@memgraph/orb';
313+
import { isNode, OrbEventType, GraphObjectState } from "@memgraph/orb";
314314

315315
// Disable default select and hover strategy
316316
orb.setSettings({
@@ -335,7 +335,9 @@ orb.events.on(OrbEventType.MOUSE_CLICK, (event) => {
335335
// Clicked on unselected node
336336
if (event.subject && isNode(event.subject) && !event.subject.isSelected()) {
337337
// Deselect the previously selected nodes
338-
orb.data.getNodes((node) => node.isSelected()).forEach((node) => node.clearState());
338+
orb.data
339+
.getNodes((node) => node.isSelected())
340+
.forEach((node) => node.clearState());
339341
// Select the new node
340342
event.subject.state = GraphObjectState.SELECTED;
341343
orb.render();
@@ -347,9 +349,9 @@ orb.events.on(OrbEventType.MOUSE_CLICK, (event) => {
347349

348350
The optional property `interaction` has two properties that you can enable/disable:
349351

350-
* `isDragEnabled` - property controls the dragging behavior within the application. When it is set to `true`, dragging is enabled, allowing users to interact with nodes and edges by dragging them to different positions within the graph. On the other hand, when `isDragEnabled`` is set to false, dragging functionality is disabled, preventing users from moving or repositioning nodes and edges through dragging interactions.
352+
- `isDragEnabled` - property controls the dragging behavior within the application. When it is set to `true`, dragging is enabled, allowing users to interact with nodes and edges by dragging them to different positions within the graph. On the other hand, when `isDragEnabled`` is set to false, dragging functionality is disabled, preventing users from moving or repositioning nodes and edges through dragging interactions.
351353

352-
* `isZoomEnabled` - This property controls the zooming behavior within the application. Setting it to `true` enables zooming, allowing users to interactively zoom in and out of the graph. Setting it to `false` disables zooming, restricting the user's ability to change the zoom level.
354+
- `isZoomEnabled` - This property controls the zooming behavior within the application. Setting it to `true` enables zooming, allowing users to interactively zoom in and out of the graph. Setting it to `false` disables zooming, restricting the user's ability to change the zoom level.
353355

354356
These properties provide a straightforward way to enable or disable dragging and zooming features based on the needs and requirements of your application. By toggling the values of isDragEnabled and isZoomEnabled, you can easily control the interactivity options available to users. e.g:
355357

@@ -378,11 +380,14 @@ Disabled by default (`false`).
378380

379381
Rounds node coordinates to integer values. Slightly improves performance. Enabled by default (`true`).
380382

381-
### Property `isSimulationAnimated`
383+
### Property `areCollapsedContainerDimensionsAllowed`
382384

383-
Shows the process of simulation where the nodes are moved by the physics engine until they
384-
converge to a stable position. If disabled, the graph will suddenly appear in its final position.
385-
Enabled by default (`true`).
385+
Enables setting the dimensions of the Orb container element to zero.
386+
If the container element of Orb has collapsed dimensions (`width: 0;` or `height: 0;`),
387+
Orb will expand the container by setting the values to `100%`.
388+
If that doesn't work (the parent of the container also has collapsed dimensions),
389+
Orb will set an arbitrary fixed dimension to the container.
390+
Disabled by default (`false`).
386391

387392
## Settings
388393

examples/example-custom-styled-graph.html

+3-3
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,11 @@ <h1>Example 2 - Basic + Custom default style</h1>
5858
colorHover: '#e7644e',
5959
colorSelected: '#e7644e',
6060
fontSize: 3,
61-
label: node.data.label,
61+
label: node.getData().label,
6262
size: 6,
6363
};
6464

65-
if (node.data.label === 'Node A') {
65+
if (node.getData().label === 'Node A') {
6666
return {
6767
...basicStyle,
6868
size: 10,
@@ -84,7 +84,7 @@ <h1>Example 2 - Basic + Custom default style</h1>
8484
width: 0.3,
8585
widthHover: 0.9,
8686
widthSelected: 0.9,
87-
label: edge.data.label,
87+
label: edge.getData().label,
8888
};
8989
},
9090
});

examples/example-fixed-coordinates-graph.html

+3-3
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ <h1>Example 3 - Fixed coordinates</h1>
4343
];
4444

4545
const orb = new Orb.OrbView(container, {
46-
getPosition: (node) => ({ x: node.data.x, y: node.data.y })
46+
getPosition: (node) => ({ x: node.getData().x, y: node.getData().y })
4747
});
4848

4949
// Initialize nodes and edges
@@ -59,7 +59,7 @@ <h1>Example 3 - Fixed coordinates</h1>
5959
colorHover: '#e7644e',
6060
colorSelected: '#e7644e',
6161
fontSize: 3,
62-
label: node.data.label,
62+
label: node.getData().label,
6363
size: 6,
6464
};
6565
},
@@ -72,7 +72,7 @@ <h1>Example 3 - Fixed coordinates</h1>
7272
width: 0.3,
7373
widthHover: 0.9,
7474
widthSelected: 0.9,
75-
label: edge.data.label,
75+
label: edge.getData().label,
7676
};
7777
},
7878
});

examples/example-graph-data-changes.html

+4-4
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ <h1>Example 5 - Dynamics</h1>
5757
colorHover: '#e7644e',
5858
colorSelected: '#e7644e',
5959
fontSize: 3,
60-
label: node.data.label,
60+
label: node.getData().label,
6161
size: 6,
6262
};
6363
},
@@ -70,7 +70,7 @@ <h1>Example 5 - Dynamics</h1>
7070
width: 0.3,
7171
widthHover: 0.9,
7272
widthSelected: 0.9,
73-
label: edge.data.label,
73+
label: edge.getData().label,
7474
};
7575
},
7676
});
@@ -97,7 +97,7 @@ <h1>Example 5 - Dynamics</h1>
9797
if (currentNodes.length) {
9898
const newEdge = {
9999
id: n,
100-
start: currentNodes[Math.floor(Math.random() * currentNodes.length)].id,
100+
start: currentNodes[Math.floor(Math.random() * currentNodes.length)].getId(),
101101
end: n,
102102
label: `Edge ${n} (new)`
103103
};
@@ -115,7 +115,7 @@ <h1>Example 5 - Dynamics</h1>
115115

116116
orb.events.on(Orb.OrbEventType.NODE_CLICK, (event) => {
117117
console.log('Node clicked: ', event.node);
118-
orb.data.remove({ nodeIds: [event.node.id] });
118+
orb.data.remove({ nodeIds: [event.node.getId()] });
119119
orb.render();
120120
});
121121

examples/example-graph-events.html

+9-9
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ <h1>Example 4 - Events</h1>
6565
colorHover: '#e7644e',
6666
colorSelected: '#e7644e',
6767
fontSize: 3,
68-
label: node.data.label,
68+
label: node.getData().label,
6969
size: 6,
7070
};
7171
},
@@ -78,7 +78,7 @@ <h1>Example 4 - Events</h1>
7878
width: 0.3,
7979
widthHover: 0.9,
8080
widthSelected: 0.9,
81-
label: edge.data.label,
81+
label: edge.getData().label,
8282
};
8383
},
8484
});
@@ -103,27 +103,27 @@ <h1>Example 4 - Events</h1>
103103

104104
orb.events.on(Orb.OrbEventType.NODE_CLICK, (event) => {
105105
console.log('Event: node-click', event);
106-
output.innerHTML = `<b>${event.node.data.label}</b> clicked!`;
106+
output.innerHTML = `<b>${event.node.getData().label}</b> clicked!`;
107107
});
108108
orb.events.on(Orb.OrbEventType.NODE_HOVER, (event) => {
109109
console.log('Event: node-hover', event);
110-
output.innerHTML = `<b>${event.node.data.label}</b> hovered!`;
110+
output.innerHTML = `<b>${event.node.getData().label}</b> hovered!`;
111111
});
112112
orb.events.on(Orb.OrbEventType.EDGE_CLICK, (event) => {
113113
console.log('Event: edge-click', event);
114-
output.innerHTML = `Edge with id <b>${event.edge.data.id}</b> clicked!`;
114+
output.innerHTML = `Edge with id <b>${event.edge.getData().id}</b> clicked!`;
115115
});
116116

117117
orb.events.on(Orb.OrbEventType.NODE_RIGHT_CLICK, (data) => {
118118
data.event.preventDefault();
119119
console.log("Event: node-right-click", data);
120-
output.innerHTML = `<b>${data.node.data.label}</b> right clicked!`;
120+
output.innerHTML = `<b>${data.node.getData().label}</b> right clicked!`;
121121
})
122122

123123
orb.events.on(Orb.OrbEventType.EDGE_RIGHT_CLICK, (data) => {
124124
data.event.preventDefault();
125125
console.log("Event: edge-right-click", data);
126-
output.innerHTML = `Edge with id <b>${data.edge.data.id}</b> right clicked!`;
126+
output.innerHTML = `Edge with id <b>${data.edge.getData().id}</b> right clicked!`;
127127
})
128128

129129
orb.events.on(Orb.OrbEventType.MOUSE_RIGHT_CLICK, (data) => {
@@ -136,12 +136,12 @@ <h1>Example 4 - Events</h1>
136136

137137
orb.events.on(Orb.OrbEventType.NODE_DOUBLE_CLICK, (data) => {
138138
console.log("Event: node-double-click", data);
139-
output.innerHTML = `<b>${data.node.data.label}</b> double clicked!`;
139+
output.innerHTML = `<b>${data.node.getData().label}</b> double clicked!`;
140140
})
141141

142142
orb.events.on(Orb.OrbEventType.EDGE_DOUBLE_CLICK, (data) => {
143143
console.log("Event: edge-double-click", data);
144-
output.innerHTML = `Edge with id <b>${data.edge.data.id}</b> double clicked!`;
144+
output.innerHTML = `Edge with id <b>${data.edge.getData().id}</b> double clicked!`;
145145
})
146146

147147
orb.events.on(Orb.OrbEventType.MOUSE_DOUBLE_CLICK, (data) => {

examples/example-graph-on-map.html

+3-3
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ <h1>Example 6 - Map</h1>
4545
];
4646

4747
const orb = new Orb.OrbMapView(container, {
48-
getGeoPosition: (node) => ({ lat: node.data.lat, lng: node.data.lng, }),
48+
getGeoPosition: (node) => ({ lat: node.getData().lat, lng: node.getData().lng, }),
4949
});
5050

5151
// Assign a basic style
@@ -58,7 +58,7 @@ <h1>Example 6 - Map</h1>
5858
colorHover: '#e7644e',
5959
colorSelected: '#e7644e',
6060
fontSize: 10,
61-
label: node.data.label,
61+
label: node.getData().label,
6262
size: 6,
6363
};
6464
},
@@ -71,7 +71,7 @@ <h1>Example 6 - Map</h1>
7171
width: 1,
7272
widthHover: 0.9,
7373
widthSelected: 0.9,
74-
label: edge.data.label,
74+
label: edge.getData().label,
7575
};
7676
},
7777
});

examples/playground.html

+3-3
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
colorHover: '#e7644e',
4242
colorSelected: '#e7644e',
4343
fontSize: 3,
44-
label: node.data.labels[0],
44+
label: node.getData().labels[0],
4545
size: 6,
4646
};
4747
},
@@ -54,15 +54,15 @@
5454
width: 0.3,
5555
widthHover: 0.9,
5656
widthSelected: 0.9,
57-
label: edge.data.label,
57+
label: edge.getData().label,
5858
};
5959
},
6060
};
6161
};
6262

6363
const getOrbMapView = (container) => {
6464
const view = new Orb.OrbMapView(container, {
65-
getGeoPosition: (node) => ({ lat: node.data.lat, lng: node.data.lng, }),
65+
getGeoPosition: (node) => ({ lat: node.getData().lat, lng: node.getData().lng, }),
6666
});
6767

6868
// Assign a basic style

0 commit comments

Comments
 (0)