I'm using cytoscape.js. I have some nodes that are superposed and I’m trying to fix their z-index so I can bring to the front the nodes that are in the back. I don’t see to get it right. I did two examples:
1) http://jsfiddle.net/VzCZm/2/ In these one I used the parent attribute of the library, I fixed the z-index of the node “n2” to 10 and when you move the nodes “n1” and “n2” inside the node “father3”, you can see that these one is darker than “n1” but still it is behind the “father3” node. How can I bring it to the front?
ready: function(){
window.cy = this;
cy.nodes("[id='n2']").css('z-index', 10);
}
2) http://jsfiddle.net/6tKdD/ In these example I didn’t use the parent attribute because I thought that might be the problem, instead I used normal nodes and I superposed them manually. In this case you can manipulate the z-indexes and they work well, the only problem now is that the edges are drawn behind the nodes so you can’t see them, even if you change their z-index you still can’t see them. If you move either “George” or “Elaine” node outside “Jerry” node, you can see there’s an edge between those two nodes. How can make the edge visible?
ready: function(){
window.cy = this;
cy.nodes("[id='j']").css("z-index", 1);
cy.nodes("[id='g']").css("z-index", 3);
cy.nodes("[id='e']").css("z-index", 3);
cy.edges("[source='g']").css("z-index", 2);
cy.nodes("[id='k']").css("z-index", 0);
}
Thank you very much for your help!
Andreina
Amendment: There are properties for fine-grained control of z-ordering. You can set any order, if you like. The default is as specified in the OP that follows.
Properties:
z-index
z-index-compare
z-compound-depth
Docs: http://js.cytoscape.org/#style/visibility
—
OP:
Like HTML, setting the z-index is not global: It's relative to the parent node. Edges are drawn behind nodes for accessibility reasons. If you want to show the edges, don't put nodes in front of them. Please note that edges between compound nodes are an exception.
Related
Using arcgis for JS 4.24 MapView.
I have a feature layer with features of different importance to the user. The importance is defined in an attribute of the feature. What I want to achieve is, that less important features only show on a certain zoom level.
What I tried so far:
Clustering: is not what I want since it is grouping on occurrences not importance.
Unique Value Renderer: Does not seem to support visibility by zoom level but is otherwise exactly what I would use.
Setting the min-max visibility: This applies to all features and cannot be configured by attribute value.
What did I miss? Any other ways to apply custom styles to feature layers?
I guess a simple solution would be to create as many FeatureLayer instances as importances you have. In each of this instances you set,
definitionExpression to the importance level,
maxScale and minScale to constraint the visibility
This solution would work if the number of importance levels are "reasonable" (let say, less than 10 or so, you will have to test it).
Another solution would be to listen for scale changes in the map view (could be the updating event), and then apply a filter (could be definitionExpression again) with the correspondent importance. With this you do not need to have many instances of the same service.
EDIT
The reason for using updating, is to avoid doing stuff while the view is changing, something like this,
view.watch("updating", function (value) {
if (!value) {
// now is the moment to check view properties
// for example
if (view.scale < MIN_SCALE) {
doSomething();
};
}
});
I am trying to use cytoscape to replace my dot output and make it interactive (move nodes and compounds, expand/collapse compounds, etc.)
When a graph is first loaded, the user should be presented with a default layout though. However, I am struggling to find a layout/config that supports what dot calls rank.
In my graph I have compound nodes that represent components.
Components contain other components and/or states, transitions, variables.
Each component can specify inputs and outputs.
In dot I tried to add some form of flow within the system (rankdir=LR;) by positioning the inputs on the left (rank=source;) and the outputs on the right (rank=sink;).
Other elements have no rank and are hence freely positioned.
I then specified cluster subgraphs containing all recursive components.
Now, here is what I have in dot. I hope it explains what I would like to end up with.
First, I already saw this question, but as far as I understood it's for manual positioning, rather than layouts.
I haven't found a layout that fully supports positioning nodes within the compound.
I looked into using the cytoscape.js-cola layout with the following options:
layout: {
name: 'cola',
flow: { axis: 'y', minSeparation: 40 },
avoidOverlap: true
}
I ended up with this
As you can see, there is some flow, but not as nicely as in dot.
I tried adding some function for the alignment parameter, but as far as I understood I can only specify the absolute coordinates (e.g. return {'x': 0};). This basically allows me to align ALL inputs, rather than all inputs of a compound.
Here is a CodePen of my example to play around with: https://codepen.io/anon/pen/GEaOQQ
In the Javascript you can see the comments of
You could try Klay: https://github.com/cytoscape/cytoscape.js-klay
If any of the existing layouts don't meet your requirements, you can use any algorithm you'd like by writing a layout extension. You could port the exact layout you're using with dot/graphviz, if you like.
From the manual:
The latter four events have some overhead associated with them, so you
need to enable them with stage.enableMouseOver(frequency). The
frequency parameter indicates how many times per second EaselJS should
calculate what is currently under the pointer. A higher number is more
responsive, but also more computationally expensive.
I need to enable a mouseover functionality only on a certain class of objects on my otherwise crowded stage. Is there a way to enable the mouseover checking only for certain objects as opposed for the whole stage? Or is EaselJS only checking objects with a "mouseover / mouseout, and rollover / rollout" listener? What about the pointer property - it works only if enableMouseOver is enabled - is that checked for all objects or only for those with pointer property other than default?
Is EaselJS internally doing some space partitioning like k d trees to boost the performance?
You can prevent any object from receiving a mouse event by setting mouseEnabled=false.
myBitmap.mouseEnabled = false;
If you have a large amount of items (such as particles), make sure they are in a container, and set mouseEnabled AND mouseChildren=false on the container, and the Stage will not check any of the container's children.
myContainer.mouseEnabled = myContainer.mouseChildren = false;
If you still want to know when a container's general area is clicked, you can swap out the default mouse behaviour with a hitArea, which is used in place of its actual contents.
var hitArea = new createjs.Shape();
hitArea.graphics.drawRect(0, 0, 500, 500);
myContainer.hitArea = hitArea;
Hope that helps!
For improving the performance i used cache if any object is static
I used mouseEnabled =false;
I did not render any text or images inside the canvas i used mix of
angular or plain javascript to render the dom element
I'm currently trying to implement the developp the following behavior in my application embedding Cytoscape.js : I would like that when a particular child node of a compound node is grabbed, the whole compound node is grabbed.
If tried using this code but it does not work as I expect :
cy.$(mySubNodeSelector)
.on('grab', function(){
this.ungrabify();
this.parent().select();
this.parent().grabify();
});
Does anybody has an advice about how to implement this behavior ?
Thanks a lot.
Disable events on the child: http://js.cytoscape.org/#style/events
Your code doesn't do anything because (1) you're mutating grabbability after elements have been grabbed and (2) you conflate grabifying (allowing grabbing) with grabbing (a user gesture).
In cytoscape.js, I've been using the "breadthfirst" layout and configured it to be directed (the tree is directed downwards).
Here is an example: http://jsbin.com/jekago/1
It works great, however I would like the nodes to be closer together, especially vertically, and if possible without limiting the bounding box.
My node labels can be quite long so I would not mind having them spread apart horizontally.
How can I can achieve this with this layout? If I can't, what are you recommending? Thanks
The layout uses the available space and avoids node overlap. Reduce the available space as desired using the boundingBox, and specify fit: true if you want the graph to take up the entire viewport.
You can alternatively use spacingFactor, but this will not allow for as much control as boundingBox.
You'll have to experiment and see what functions best for your data.
You can use as an example spacingFactor=1.5 to have 1.5x space between the elements regarding to the elements dimension.
The fit:true is also a good idea. This is used regarding the div dimensions.
In conjunction to work nice you have to set properly the minZoom maxZoom of the Cy element. And you can set avoidOverlap: true also .