I was looking to this example of cola.js in which, when dragging a specific node, the other nodes have the capability to automove according to the new position of the node I'm dragging, and the thing I'm interested in is that you can see the graph transition to the new position in a sort of animation. I noticed that cytoscape does this with cytoscape-automove extention, but in every example I found there's no animation and no delay performed when nodes automove. Could you suggest any way to do this with cytoscape?
There is cytoscape.js-cola which does more or less what cola does. The option infinite: true animates the graph while moving nodes as seen in your example.
You simply would need to add the cola layout to the cy instance – after installing the cytoscape.js-cola-module with npm install cytoscape-cola f.e.
let options = {
name: 'cola',
infinite: true
};
cy.layout( options );
cy.layout.run()
Related
I have the following situation:
A parent Node, taking all the screen space.
A child for the top bar.
A child for the game area.
A child for the bottom bar.
An absolute positioned child for an overlay that must not be bound to the three above.
I can't quite get the above to work, because I can't find a way to define the z-order of the children, at least using the default UiCameraComponents. Here's what I've tried:
Adding a Translation component to the absolute positioned child and move it up the Z axis.
Giving the absolute positioned child a transform higher up in the Z axis.
Spawn the nodes in different orders.
It seems like the overlay child consistently renders behind the relatively positioned siblings.
Z order in Bevy UI is currently implicitly defined by the hierarchy. Nodes "stack" on top of their parents and on top of siblings that come before them in their parent's children list.
Functionally, z-order is defined using the z translation value of the entity's Transform. For normal sprites you can set this directly. For UI components, there is an underlying system that sets this for you.
Eventually, I would like to make it possible to optionally override Bevy UI's z-order behavior. That should be a matter of adding a new field to "opt out", then allowing people to set the transform's z translation directly.
As a workaround for the current stable bevy (0.7), I am using a fixed z for UI nodes.
#[derive(Debug, Component)]
pub(crate) struct UiFixedZ {
pub z: f32,
}
pub(crate) fn ui_apply_fixed_z(
mut node_query: Query<(&mut Transform, &mut GlobalTransform, &UiFixedZ), With<Node>>,
) {
for (mut transform, mut global_transform, fixed) in node_query.iter_mut() {
transform.translation.z = fixed.z;
global_transform.translation.z = fixed.z;
}
}
I am placing the system in the last stage just after the bevy's z-order system.
...
app.add_system_to_stage(CoreStage::Last, ui_apply_fixed_z)
...
when inserting UiFixedZ components keep in mind that you need to take care of all the descendants manually.
...
// inserting with manual z order
.insert(UiFixedZ { z: 101. })
...
// inserting children with increased z order
.insert(UiFixedZ { z: 102. })
hope the workaround helps someone. I am personally using it for tooltips.
Copied my own comment from github :P
Bevy is young and the situation may change in the future.
I'm backend developer for several years but a newbie in frontend issues.
I used "graphviz" (using d3.js) to draw an SVG graph from DOT notation.
Everything is working fine but one thing I don't get in my mind:
If I "open" another (or the same one) graph its starting position is the
same as this from the previous drawn graph even if I completely remove
the whole node content from the dom as follows:
var svg = d3.selectAll("svg");
var otherBelow = svg.selectAll("*");
otherBelow.remove();
// svg.remove();
Doing this and checking the page source the nodes below SVG are realy dropped
but drawing the new graph it has exactly the position of the previously
moved graph in "transform" attribute. Doing a work around by resetting the
position bevore solves this problem but then the problem remains for the
"moving on mousedown" capability. Then the graph immediately "jumps" to the old
ones position. But therefor I can't even get an information about somewhere
in the page source. Really the generated page code is 100% the same (with
diff tool) but has a different behaviour. Don't understand how this is possible.
So now my question: Is there a kind of caching? Or is there perhaps the
browser cache used somehow internally? How to fix this?
P.s. if I remove the SVG node itself I get a completely courious behaviour.
Then the newly drawn graph is not movable at all.
This (ugly) workaround does it for me.
// Snipped to render a new graph and reset its position
// #graph -> id of d3-graphviz div-container
document.getElementById('graph').innerHTML = ''
setTimeout(() => {
d3.select("#graph").graphviz()
.dot(yourDotData)
.render()
}, 50)
Explanation/Assumption why this works:
It seems that the deletion of the old graph with .innerHTML = ''and the creation of the new one should not happen in the same rendering phase/at the same time, therefore the timeout function.
The second part of the workaround is to use a new graphivz-instance to render the new graph, therefore the
d3.select(...) within the timeout function.
The graphviz renderer is still present on the element it was created on and has all its data still intact.
Removing the svg and then reuse the renderer is not a valid use case. Nico's answer is probably correct, but there are better ways to do it, but in order to tell you how you should do it instead I would need so see all of your code so I can understand what you really want to do.
I am trying to animate the change between layouts of a Cytoscape.js graph.
When switching from cose to grid, the change is animated. When switching from grid to cose, only the end position is shown without any animation.
I use a simple test scenario starting with a small graph in grid layout and this code to switch layouts:
...
function changeLayout(type){
var options = {
name: type,
animate: true
};
cy.layout(options);
}
...
<div onclick="changeLayout('cose')">to cose</div>
<div onclick="changeLayout('grid')">to grid</div>
I also tried the other options listed here:
http://js.cytoscape.org/#layouts/cose
but I am not able to animate from grid to cose.
What am I doing wrong?
A continuous layout like CoSE animates live. That is, it animates during the iterations of the calculations it does. If the layout runs very quickly -- as CoSE often does -- then you won't get much if any animation.
There is a proposal being discussed to have an option to animate continuous layouts like discrete ones (i.e. tweening between the start and end positions).
If you want this behaviour for now, you'll have to run the layout while batching. Now that you have saved the start and end positions for each node, you can just end batching and animate.
You can do this now using animate: 'end' in the layout definition. See https://github.com/cytoscape/cytoscape.js/blob/unstable/src/extensions/layout/cose.js#L31. This will animate the nodes from their initial starting position to their end position, in contrast with animate: true which will animate the changes in the layout, and only do so after a certain threshold of time (see animateThreshold).
I use a SELECT drop down box to choose a new JSON data source for a force network graph. The first graph draws correctly: Nodes draw on top of edges and mouseovers work as expected.
When I select the second data source, the edges draw on top of the nodes and I have lost my mouseovers. If I go back to selection "A", the same is true except for the last node.
A jsfiddle showing this problem is here:
http://jsfiddle.net/NovasTaylor/e6qjubaa/
Obligatory stack overflow code inclusion:
//EXIT
edges.exit().remove();
nodes.exit().remove();
I expect this is a problem with my ENTER/UPDATE/EXIT and perhaps the keys I am using to exit the elements? Please see the code in the fiddle.
Any advice would be greatly appreciated. My next step is to add edge labels so I want to ensure I get the nodes and edges and working first.
Tim
So just add some lines to the combobox:
d3.selectAll('#familytreecontentsvg .node')
.each(function (d) {
d.fixed = false;
})
.classed("fixed", false)
And I moved the svg object into the drawings while just initializing it empty above. Also I created an id for the SVG itself. Hope it helps. Please tell me if that is fixing your troubles.
Updated fiddle: http://jsfiddle.net/xg9fjze3/9/
I am editing with the latest code which is available in the fiddle
http://fiddle.jshell.net/nj11eruq/10/
I have reached the last leg. Now i could brush the graph and the graph gets redrawn for the selected area. I can zoom in to a detail level. However i need to reset the graph when i double click/ click the graph (no resizing brush). I am missing something here.
finally, found out the way to implement the same. (of course some more optimizations,validations expected)
http://fiddle.jshell.net/nj11eruq/12