Comments (15)
@vasturiano Thanks for your comments!
I'm happy to offer some bigger, more worked out examples for others, that also include vue and vuetify so others can see how your awesome package can be applied in those contexts. One nice thing of the vuetify docs is that they have a codepen for all the examples, which is especially nice if you want to play around with the code and experiment. If you want I can help in setting up a bunch of them for your package based on your existing code examples.
With respect to the ctx
canvas context, previously I was not aware the requestAnimationFrame
loop keeps running at all times unless you explicitly tell it not to via pauseAnimation
.
Especially if you don't use the edge particles and you have largely unchanging data there is little need to keep the event loop running after the simulation freezes. For instance, currently on a graph of e.g. 200 nodes, even after the simulation freezes, the nodeCanvasObject
callback will be executed approximately 200 * 60 = 12.000 per second, even when the data and the layout, i.e. the visual, do not change.
It's a bit unfortunate that currently when you apply pauseAnimation
all event propagation always stops. I can see that in the generic scenario that needs to be done. However, in the above scenario, instead of wiping the canvas, it would be nice to be able to keep it alive after the layout freezes. That way you can still get the colors from the canvas to be able to generate hover events. When applying a drag move one could then quickly call resumeAnimation
to facilitate the drag move and automatically call pauseAnimation
after the layout stabilizes. Doing so will be less taxing for the browser, which helps in making additional transitions less choppy, especially when there are a lot of nodes in the network.
from force-graph.
@vasturiano I think it would be really helpful to decouple the pointer interaction events from the pauseAnimation
and resumeAnimation
functionality. I was thinking, wouldn't it be possible to use a mousedown
event or say an invisible svg element at the location of the mouse cursor to signal the start of a drag move in case the rendering cycle of the component is paused?
from force-graph.
@klaraseitz if your overall intent is to improve the graph performance by bypassing rerenders after the simulation engine has stopped, note that there's been a flag added on v1.38.0
that addresses exactly this.
The option is autoPauseRedraw
and it's enabled by default, so you should be automatically getting the performance improvement, if you upgrade your component version.
More details about it in this issue.
from force-graph.
@vasturiano Oh perfect!! I saw that option but thought my current version already had that. Now that I upgraded it works really smoothly. Thanks so much, Great library!
from force-graph.
Thanks for reaching out! Using the latest version (1.15.0
) you can simply do myGraph.refresh()
to reheat the force simulation engine.
As for the other configuration parameters, there are exposed properties that lets you manipulate this, such as d3AlphaDecay
, d3VelocityDecay
, d3Force
, warmupTicks
and cooldownTicks
. If there's somehow an operation you're not able to control using these methods, please let me know and I'll consider adding additional support for.
from force-graph.
Hi,
thanks for the update, much appreciated! I had a few more questions if you don't mind :-)
With respect to the simulation, it would be nice to be able to manually control the tick function e.g. to say simulation.tick(20)
. Is there currently a good way to do that?
Furthermore, it would be handy to be able to manually- redraw - the canvas, e.g. because you've changed the color for a node. Currently I do this by using a function inside nodeCanvasObject
that itself depends on a settings object. Of note, I need nodeCanvasObject
because I draw more complex shapes as well. Hence if I change the settings object, the function changes the color. This is just an example of course, but in general it would be nice to be able to tell the graph object to re-render itself.
In that scenario, what would be the best way to redraw the canvas (without changing node positions etc.)?
Finally, it would also be handy to be able to have direct access to the ctx
object, outside of nodeCanvasObject
in order to control the canvas element by another process / function. For instance, I do some additional manipulations to ctx
after the force engine has done its thing.
Clearly you could assign ctx
to some variable from inside of nodeCanvasObject
and then use that variable later, but it's a bit awkward to do it that way.
PS: I'm using your package in vue.js, which works quite well. No fancy binding, inside a component after mount I just create an instance of ForceGraph
and define a few helper methods on the vue object that essentially call a few methods on a ForceGraph
instance. For instance, now there is no zoom to fit function that zooms the canvas such that all nodes are inside the view port, so I created my own. A function like that would be useful to others as well I guess.
Anyways, thanks for you help, much appreciated! :-)
from force-graph.
PS: I'm using your package in vue.js, which works quite well. No fancy binding, inside a component after mount I just create an instance of
ForceGraph
and define a few helper methods on the vue object that essentially call a few methods on aForceGraph
instance. For instance, now there is no zoom to fit function that zooms the canvas such that all nodes are inside the view port, so I created my own. A function like that would be useful to others as well I guess.
Hi @FrissAnalytics, I'm looking into using this with vue as well, and was just wondering if you might be interested in sharing your own vue implementation for this?
from force-graph.
@FrissAnalytics a few answers to your questions:
With respect to the simulation, it would be nice to be able to manually control the tick function e.g. to say simulation.tick(20). Is there currently a good way to do that?
You can control the dry-run ticks by doing .warmupTicks(20)
. The effect is exactly the same.
Furthermore, it would be handy to be able to manually- redraw - the canvas, e.g. because you've changed the color for a node. Currently I do this by using a function inside nodeCanvasObject that itself depends on a settings object. Of note, I need nodeCanvasObject because I draw more complex shapes as well. Hence if I change the settings object, the function changes the color. This is just an example of course, but in general it would be nice to be able to tell the graph object to re-render itself.
Changing the assignment or the behavior of nodeCanvasObject
will not cause a reheating of the simulation. The nodeCanvasObject
method is called at every canvas refresh tick using raf (requestAnimationFrame), therefore any behavioral changes you make to the to the nodeCanvasObject
mode should reflect automatically in the following raf tick, you shouldn't need to do anything to cause an update.
Finally, it would also be handy to be able to have direct access to the ctx object, outside of nodeCanvasObject in order to control the canvas element by another process / function. For instance, I do some additional manipulations to ctx after the force engine has done its thing.
The issue with exposing the context is that you wouldn't be able to do much manipulation with it, since it is cleared at every raf tick. Anything you'd write to it would be wiped almost immediately in the following tick. This is why it's not exposed, and all the relevant draws need to happen in the nodeCanvasObject
method. If you'd like to have some other persistent visual elements I'd suggest to have another canvas that you maintain externally that aligns exactly underneath (or above it) to this dom element. That way you're just layering the multiple canvases and you get better update performance by not repetitively drawing the same things.
As for vue.js
I can't be of much help because I haven't attempted the integration, but feel free to post examples here for the benefit of other users that may want to do the same thing. :)
from force-graph.
@FrissAnalytics good points. It's a little difficult to keep track of the variety of scenarios that the simulation could go dormant, even though there is certainly room for performance improvement.
Currently the decision is to let the consumer handle that state by choosing when to call pauseAnimation
and resumeAnimation
. A possible improvement is to decouple that from the pointer interaction events, so that one could still detect hover interactions and resume/pause the animation engine to permit node dragging. Actually the fact that dragging is not possible when the animation engine is off is the main reason why the pointer interactions are also disabled on pauseAnimation
.
As for vue.js I would love to see a bindings repo, similar to what there is for React at react-force-graph.
from force-graph.
@vasturiano I would also be interested in decoupling the pointer events from pause and resumeAnimation functions.
Is there any (planned) progress on this?
Mainly I would like to render the graph only once it's done with positioning, allow the user to add nodes through click (triggering a rerender) and only ever show the result of the finished positioning and not showing the steps to reach the new position.
from force-graph.
@klaraseitz you can achieve this by setting cooldownTicks(0)
and warmupTicks(80)
(adjust value to your case). This will essentially compute the final node positions in the warmup phase, and bypass the cooldown phase where the graph build-up is normally being animated.
from force-graph.
@vasturiano great thanks!
And as for the pointer events. I would like to pauseAnimations onEngineStop. Such that neither the linkCanvasObject nor the nodeCanvasObject get called after the enginestop but click/hover interactions can still be caught. (on clicking/dragging a node animations should resume)
I tried
this.graph.onEngineStop(() => { this.graph.pauseAnimation() })
but the linkCanvasObject and nodeCanvasObject callbacks keep being called and interactions were not deactivated.
from force-graph.
@vasturiano Sorry for bringing this back up but I am running into a refresh issue with the graph.
This is occurred using the latest version!
from force-graph.
Hi,
First of all, thanks for your amazing job @vasturiano ! It's a great lib and I'm having fun using it.
I have some trouble with the interactions and the forces/reheat:
I would like to have hover and be able to pan/zoom, but without it triggering a re-heat; all while keeping the ability to drag (and that would of course trigger the reheat).
The end goal is to recreate the example of d3-force but with your great library !
I'm pulling my hair over this, but don't seem to be able to figure it out.
Is it possible to do that ?
from force-graph.
@pebubblemaps don't know if I understand your question completely, but you can just fix nodes into place by setting a fx
and fy
value.
For instance, after a given number of ticks, when the layout engine has done its thing, loop over all the nodes and fix all the node x, y positions. See this. example for details.
The difference with the example is that in the example only the node that gets dragged is fixed, but if you fix all the nodes, the graph does not move.
Assuming gData
has you nodes, you can say
gData.nodes.map(node => {
node.fx = node.x;
node.fy = node.y;
})
You can set the node fx
or fy
position to null
to unfreeze it. See the example on how to move a node with a drag move.
After the nodes have a fixed position, you can pan and zoom the graph with node hovers without a reheat, meaning that the nodes do not change position anymore.
from force-graph.
Related Issues (20)
- Conditional node styling based on data values/accessor method (i.e. circles for person, squares for place) HOT 2
- mousedown event not working after adding it HOT 2
- Link offsets? HOT 1
- How to conditionally change linkLineDash between nodes HOT 1
- Curved arrows HOT 2
- How to draw nodes around a circle HOT 2
- How to avoid collisions of nodes. HOT 1
- Problems with labels, and dragging when openin from Brave browser with shield on. HOT 1
- Conditional in linkDirectionalParticles does not use correct return value HOT 1
- Option to always show node labels HOT 2
- How to implement incremental graphData update on zoom and pan? HOT 4
- [Bug]: When nodes are rapidly dragged multiple times in succession, it will be recognized as dragging the canvas
- Discrepency between .json files used in demo and syntax on README HOT 2
- Detecting right click when mouse is moving
- Constant node size, independent of zoom HOT 1
- onNodeRightClick doesnt on macbook keyboard+trackpad HOT 2
- How to display nodes together that are identical HOT 1
- Node is not below its parent when creating the tree HOT 1
- unconnected nodes drifting infinitely away HOT 1
- Scrolling on mobile browser
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from force-graph.