New: Add state setters with options - #95
Conversation
| if (data.type === 'node' && data.options.isSingle) { | ||
| const nodes = this._nodes.getAll(); | ||
|
|
||
| for (let i = 0; i < nodes.length; i++) { |
There was a problem hiding this comment.
I feel like these iterations through all nodes/edges can be slow. Any ideas? And do we want to clear the state of all nodes/edges or only the adjusting ones?
There was a problem hiding this comment.
How about using hash maps? Obviously, this would require a lot of code change. Just starting a discussion, I don't think it's doable right now.
For the second question, I would say only the ones that are being adjusted.
There was a problem hiding this comment.
Or maybe to supplement this nodes array we can keep an index where nodeIndex[node.id] === nodes.findIndex((el) => el.id === node.id)
There was a problem hiding this comment.
Are you suggesting storing nodes in a hashmap? As far as I know, retrieving elements from an array by a known index is O(1) complexity, so iterating through an array vs a hashmap (which also has O(1) complexity for retrieving element by key) may not make a big difference here. I might have misunderstood your point, or perhaps I missed something, so feel free to clarify it further :)
There was a problem hiding this comment.
If all nodes are in state X, and you want to clear them up if they are not node with ID 1, you still need to to N - 1 updates. So hash maps or any other structure won't help there, you already have the fastest structure, an array.
But, you can do this and increase the memory footprint: I am not sure if it makes sense to go into this right now, but this would be the plan:
- Graph keeps a structure of nodes/edges by state, so each state has a structure of nodes and edges (probably just id) - a set of a map.
- States in nodes and edges are just views, readonly
- When state is updated in node, edge it is just updated in the graph
This way, if you have isSingle: true, graph, as an owner of the data can then literally take all selected nodes from a set or a map, clear those states and set the new node as single selected. This would improve the speed, but it would worse the memory footprint and code simplitiy because owner of the state becomes the graph, not graph objects (node/edge).
I would keep this as is and fix only if we see that it hurts performance.
There was a problem hiding this comment.
Sorry, I misunderstood the functionality. I saw === instead of !==. I thought you were trying to clear the state of anode with a specific id.
| if (options && options.isToggle) { | ||
| this._toggleState(result.state); | ||
| } else { | ||
| this._state = result.state; | ||
| } |
There was a problem hiding this comment.
Either have this._state = <function that handles options in general>(results.state) where function doesn't mutate the state, but returns what the new state should be, or keep this as is, but still change the toggleState to not mutate the this._state because I don't see a reason why it should. The best functions are the clean ones, which do not mutate state (if it is possible to make them).
| if (typeof result === 'number') { | ||
| this._state = result; | ||
| } else if (typeof result === 'object') { | ||
| const options = result.options; |
There was a problem hiding this comment.
For these checks, please use utils/type.utils.ts because of:
- cleaner code,
isNumbervs `typeof x === 'number' - handles edge cases,
isPlainObjectvstypeof result === 'object'(edge case is:typeof nullwill return'object').
| result = arg; | ||
| } | ||
|
|
||
| if (typeof result === 'number') { |
There was a problem hiding this comment.
Same comments as for edges.
| export interface IGraphObjectStateOptions { | ||
| isToggle?: boolean; | ||
| isSingle?: boolean; | ||
| } |
There was a problem hiding this comment.
In these cases, when it is options, it would be best not to have optionals here, but where you use it, line 17: Partial<IGraphObjectStateOptions> where options can also be optional, e.g. options?: Partial<...>.
If you move external logic (having optional params) too deep into the type, it is harder to handle that in some other cases. E.g. if you wish to create default params, you could then just say: const default: IGraphObjectStateOptions = { ... } and you would be forced to define both. If you would use options from Parameters you would see that this object is optional here with all its children. The context of when is something optional, when it isn't is being kept.
| if (data.type === 'node' && data.options.isSingle) { | ||
| const nodes = this._nodes.getAll(); | ||
|
|
||
| for (let i = 0; i < nodes.length; i++) { |
There was a problem hiding this comment.
If all nodes are in state X, and you want to clear them up if they are not node with ID 1, you still need to to N - 1 updates. So hash maps or any other structure won't help there, you already have the fastest structure, an array.
But, you can do this and increase the memory footprint: I am not sure if it makes sense to go into this right now, but this would be the plan:
- Graph keeps a structure of nodes/edges by state, so each state has a structure of nodes and edges (probably just id) - a set of a map.
- States in nodes and edges are just views, readonly
- When state is updated in node, edge it is just updated in the graph
This way, if you have isSingle: true, graph, as an owner of the data can then literally take all selected nodes from a set or a map, clear those states and set the new node as single selected. This would improve the speed, but it would worse the memory footprint and code simplitiy because owner of the state becomes the graph, not graph objects (node/edge).
I would keep this as is and fix only if we see that it hurts performance.
| if (data && 'type' in data && 'options' in data && 'isSingle' in data.options) { | ||
| if (data.type === 'node' && data.options.isSingle) { |
There was a problem hiding this comment.
Can you maybe simplify this to if (data && data.options?.isSingle && data.type === 'node')?
There was a problem hiding this comment.
I believe it could be possible, but only after reworking IObserverDataPayload into a more generic solution as you mentioned here. Currently, I am using some sort of custom type guard because of the interfaces used in that payload
| this.notifyListeners(); | ||
| } | ||
|
|
||
| private _handleState(state: number, options?: Partial<IGraphObjectStateOptions>): number { |
There was a problem hiding this comment.
It is nitpicking really, but maybe getNextState would be a better name.
* 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
* 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 <davidlozic@gmail.com> * 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 <davidlozic@gmail.com> Co-authored-by: Oleksandr Ichenskyi <55350107+AlexIchenskiy@users.noreply.github.com> Co-authored-by: AlexIchenskiy <aichenskiy@gmail.com>
… tooling * Fix: Fix multiple maps issue (#33) * Chore: Update package.json version * New: Change the API to handle OrbView and OrbMapView (#34) * New: Change the API to handle OrbView and OrbMapView * New: Change the API for select/hover strategies * Chore: Release/1.0.0 * New: Add support to get selected/hovered nodes and edges (#61) * New: Added support to get selected nodes and edges * New: Added support to get hovered nodes and edges --------- Co-authored-by: Abhinav Singh Parmar <abhinavparmar147@gmail.com> * New: Add support for enabling and disabling dragging of nodes (fixes #62) (#69) * New: Add feature to enable/disable node dragging (fixes #62) * New: Added support to modify interaction from setSettings * New: Updated documentation for interaction property * New: Add feature to enable/disable zoom (fixes #62) * NEW: Updated documentation for interaction property * NEW: Updated documentation to include isDragEnabled * New: Add support for custom edge line style (#77) * New Added support for custom edges * Refactor: Streamline edge rendering code and optimize line style handling * New: Add support for handling device pixel ratio (#45) * Chore: Move container and canvas creation from the view to the renderer * New: Add devicePixelRatio render property and handler * Fix: Add default DPR for older browsers * Chore: Remove useless check for automatic DPR * 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 <davidlozic@gmail.com> * 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 <davidlozic@gmail.com> Co-authored-by: Oleksandr Ichenskyi <55350107+AlexIchenskiy@users.noreply.github.com> Co-authored-by: AlexIchenskiy <aichenskiy@gmail.com> * New: Add zoom in and out functions (#100) * Fix: Skip unnecessary listener notify on set style * Fix: remove unnecessary rerender on state change * Chore: Update documentation * Fix: Node/edge getter performance issue * Chore: Add data change docs example * Fix: Docs typos * Fix: Disable source map generation (#105) * New: Add tree layout (#107) * New: Add new layouts * New: Add layout options * Chore: Make layout dynamically changeable * Chore: Update docs * Fix: Naming typo * Chore: Refactor layouts * New: Enable layout node add/remove * Chore: Improve behavior for recurrent nodes * Chore: Move some simulator settings to layout * Chore: Refactor code quality and performance * Fix: Layout behavior on change * Chore: Add recenter on layout change * Fix: Layout change behavior * Fix: Simulation behavior on data deletion * Chore: Add recenter on layout change * Fix: Change layout engine logic (#108) * Fix: Change layout engine logic * New: Add simulation cancellation logic * Chore: Remove leftover code * Fix: Hierarchical layout recenter logic * Chore: Refactor package versions and code logic * Fix: Refactor function types * New: Add multiselect (#110) * New: Add multiselect * Chore: Simplify logic * Chore: Update package.json * New: Add SVG export (#111) * New: Add SVG export * Chore: Refactor code quality * New: Add WebGL renderer (#109) * New: Add WebGL renderer * New: Add naive WebGL force layout computation * New: Add WebGL improved node/shape geometry options * New: Add labels and node images * Fix: GPU drag behavior * Chore: Remove leftover comments * Fix: WebGL renderer style invalidating * Chore: Refactor code quality * Chore: Add WebGL example and docs * New: Add docs page (#112) * New: Add docs page * New: Add more docs examples * Update .github/workflows/docs.yml --------- Co-authored-by: Toni <toni.lastre@memgraph.io> * Chore: Finish up the release process * Chore: Fix sync between package.json files * Chore: Add new package-lock.json --------- Co-authored-by: David <davidlozic@gmail.com> Co-authored-by: Abhinv Singh Parmar <abhi171b010@gmail.com> Co-authored-by: Abhinav Singh Parmar <abhinavparmar147@gmail.com> Co-authored-by: Abhinv Singh Parmar <abhinav.parmar@infosys.com> Co-authored-by: Oleksandr Ichenskyi <55350107+AlexIchenskiy@users.noreply.github.com> Co-authored-by: AlexIchenskiy <aichenskiy@gmail.com>
Resolves #68
As an enhancement to the freshly implemented getters and setters, this PR introduces a new way to set the state of nodes and edges using objects that specify state with additional parameters such as
isSingleandisToggle. Now, it is possible to use both the regular setter:and the new setter:
and so on. This provides more customization flexibility to the user, with default values for these parameters set to
false. It should be easily extendable for adding even more options.