memgraph / orb

Graph visualization library
Apache License 2.0
350 stars 17 forks source link

Focusing a node to the middle of the canvas #52

Closed shashankshukla96 closed 1 year ago

shashankshukla96 commented 1 year ago

Is there any way in which a node can be focused, i.e. if it can be moved to the center of the node dynamically?

For example, there are a bunch of nodes on the screen and after some event, I want to move one of the nodes to the center of the canvas. Is it possible with the current implementation of Orb?

Also, one more point, can we select a node or an edge without clicking or hovering over it?

I have seen a few functions, selectNode and selectEdge in src/models/strategy.ts, but I don't think these are exposed to be used. Let me know if I am missing anything.

cizl commented 1 year ago

In your example, when you move one of the nodes to the center of the canvas (programmatically), would the other nodes stay in place or move with the focused node?

In other words: 1) Would the screen center towards one node? 2) Would the node go to the center of the screen? If this is the case, would the other nodes rearrange around the focused node or would they stay in their previous positions?

shashankshukla96 commented 1 year ago

Ideally, all the nodes should stay in their own place but the origin of the canvas should be moved to the center of the node to which I want to focus on. What do you think ? is it feasible?

tonilastre commented 1 year ago

I think you can do that with the current implementation and by accessing private variables of the OrbView. Maybe try something along the way:

To recap, access the private view._renderer so you can use https://github.com/memgraph/orb/blob/main/src/renderer/canvas/canvas-renderer.ts#L261 and once you have a transform object (d3-zoom.ZoomTransform), you can call the same code that recenter uses with d3 and view._canvas.

shashankshukla96 commented 1 year ago

great, thanks!

Also, can we select a node or an edge without clicking or hovering over it? @tonilastre

tonilastre commented 1 year ago

Good question, just checked the docs and I am seeing that we are missing that :)

You can do that yep, you can change the state of each node and/or edge with node.state = GraphObjectState.SELECTED or edge.state = GraphObjectState.HOVERED. There are also functions to know if it is selected or hovered and to clear the state, e.g. https://github.com/memgraph/orb/blob/main/src/models/node.ts#L235-L245

Btw GraphObjectState is not an enum because we wanted to make it in such a way so you can have your custom states on top of it: https://github.com/memgraph/orb/blob/main/src/models/state.ts

This means you can have node.state = 900 where 900 means something to you when you will be styling a node or interacting with it. This is also the reason why mouse click/hover events that are handling selection/hover state of nodes/edges have a strategy because if you want to have a custom strategy and what state node/edge should be in, you can implement a new strategy class, and give it to the view. This is if you want to have 100% customization :)

shashankshukla96 commented 1 year ago

Awesome, thanks!

josiahbryan commented 3 months ago

Thanks @tonilastre for the hints! For anyone else coming here, like I commented on in #103, I've crafted this function which does just what you're talking about I think - you just have to call it with the selected node:

https://gist.github.com/josiahbryan/354a0357dd52e43b14b3df4022267b9f

I use it like this in my app:

const nodeIdForFocus = 'aidgno_ticss4ego8hzw5tx3ov9sdz9b';

const orbNode = orb.data
    .getNodes()
    .find((x) => x.id === nodeIdForFocus);

if (orbNode) {
    orbFocusOnNode(orb, orbNode);
}