Build a "group by attributes" with cytoscape.js - cytoscape.js

I'm developping a small application with jquery and cytoscape.js. I can do almost what I expect, however, I'm blocked for several days on this topic : I would like to render the graph similar to what I can do in Cytoscape with the layout "group by attribute". In Cytoscape, the rendering is with circles, but it could be other layout per group. I was unable to find examples and I tried unsucessfully with boundingBox or pan().
The group of nodes filtered is displayed with the right layout (eg: grid or circle, etc...) but centered on the middle. I have something like that:
var persons= cy.nodes().filter('[Type="Person"]').select();
cy.elements(":selected").layout({ name: 'circle', boundingBox:{x1:'300', y1:'4OO', h:'500', w:'500'}});
Is there an existing layout I didn't see?
How can I do?
I'm not a "poweful" javascrip developper :)
Thank you

Use the concentric layout: http://js.cytoscape.org/#layouts/concentric
Set concentric and levelWidth appropriately to group your nodes in concentric circles as desired.

Related

Cytoscape Dagre shows connected Children when there are multiple children

I am using Cytoscape Dagre extension to show hierarchical graph from left to right.
It has 14 children and one parent 1 and main parent. All children are connected to parent 1 but whenever I use draw a graph using dagre extension, it seems like children are connected between each other. They do not have any edges between them but Dagre still shows that. Is Cytoscape with Dagre capable of showing hierarchical graphs with multiple children?
Here is the stackblitz example: https://stackblitz.com/edit/dagre-childrenconnected
Your edges overlap with your child nodes, that is not a dagre specific problem, your cytoscape-stylesheet is just missing some parameters. With taxi edges, the important thing to understand is, that your edges follow style rules like the layout algorithm you use. For layouts, you use the layout option to specify how the layout should place the nodes. The edges are styled via the stylesheet and they all have some options to play around with.
In your case, you should take a look at this section in the docs. There you can find options like the taxi-direction:
"taxi-direction": "rightward",
With this option, your edges will fit your layout a bit more. In your case, you didn't specify a direction, so taxi edges use the auto option as a default value, which automatically uses vertical or horizontal starting directions, based on whether the vertical or horizontal distance is largest. In your case, the vertical ones triggered resulting in overlapping nodes.

Can I add "cosmetic" edges to a cytoscape dagre layout?

I'm using cytoscape with a dagre layout to generate my graph and I want to include extra edges (depicted in red below) to effectively "annotate" the graph. However, this doesn't work the way I would like it to because the dagre layout takes all edges into account when generating the graph.
I know I can use a "preset" layout to achieve this behaviour, however there are distinct benefits to using the dagre layout including proper expand-collapse functionality via the expand-collapse extension.
I also tried playing around with the "edgeWeight" option within the dagre layout to no effect. Does anyone have any recommendations? Thanks!
I solved this problem by filtering out the edge before rendering the layout:
var processedElements = this.cy
.elements()
// Filter out edges we don't want contributing to the layout of
// of the graph
.filter(el => !el.hasClass("unbundled-bezier-1"))
var layout = processedElements.layout({
name: "dagre",
rankDir: "LR"
})
layout.run();

Dynamic/scrollable container size in Cytoscape (+ cy.fit() issues)

So I've been giving Cytoscape a try recently. My project's goal is basically a collaborative graph that people will be able to add/remove nodes to/from, making it grow in the process. The graph will include many compound nodes.
Most of the examples I've seen use container div that takes 100% of the screen space. This is fine for "controlled" graphs but won't work in my case because its size is intended to be dynamic.
Here's a JSFiddle using the circle layout within a fixed 3000px/3000px container:
https://jsfiddle.net/Jeto143/zj8ed82a/5/
Is there any way to have the container size be dynamic as opposed to stating it explicitly? Or do I have to compute the new optimal container size each time somehow, and then call cy.resize()?
edit: actually, using 100%/100% into cy.fit() might just work no matter how large the network is gonna be, so please ignore this question is this is the case.
Is there a recommended layout for displaying large/unknown amounts of data in a non-hierarchical way that would "smartly" place nodes (including compound ones) in the most efficient way possible, all the while avoiding any overlap? (I guess that's a lot to ask...)
Why doesn't cy.fit() seem to be working in my example? I'm using it both at graph initialization and when CTRL+clicking nodes (to show closed neighborhood), but it doesn't seem to like the 3000x3000px container (seems better with 100%x100%).
edit: also ignore this question if you ignored 1., as again it seems fine with 100%/100%.
Any help/suggestions would be greatly appreciated.
Thank you very much in advance.
TLDR: It's (1).
Cytoscape has a pannable viewport, like a map. You can define the dimensions of the viewport (div) in CSS. What's displayed in the viewport is a function of the positions of the nodes, the zoom level, and the pan level -- just like what is visible in a map's viewport is a function of zoom, pan, and positions of points of interest.
So either you have to
(a) rethink your UI in terms of zoom and pan and use those in-built facilities in Cytoscape, or
(b) disable zoom and pan in Cytoscape (probably stay at (0, 0) at zoom 1) and let the user scroll the page as you add content to the graph and resize its container div to accommodate the new content.

Cytoscape with Haystack or Bezier Layout: How to Shorten Edge Length

I am new to Cytoscape, and I have a working graph, but my nodes are very far apart. While I realize Cytoscape generates everything dynamically, it seems like it should be possible to say "use half as much space between nodes".
This demo:
http://js.cytoscape.org/demos/2ebdc40f1c2540de6cf0
seems to show that you can dynamically change the lengths of edges. However, when I look at the source code (https://gist.github.com/maxkfranz/2ebdc40f1c2540de6cf0), I can't figure out how it works.
It seems like the demo is passing a edgeLength option to makeLayout, but the Cytoscape documentation doesn't even mention edgeLength as a valid option.
Can anyone more experienced with Cytoscape point me to how I can shorten the edges between my nodes?
Each layout is different, and the combination of values you use depends on what effect you're trying to create.
Force-directed layouts usually have a weight that affects edge length by spring forces.
In general, the bounding box can affect the length.
Some layouts have spacing adjustment multipliers.
Some layouts have other, miscellaneous options that affect edge length.
You have to look at the options for the layout you're interested in and experiment with them to get the effect you're looking for. That holds true for every layout for every graph theory lib, Cytoscape included.

cytoscape.js node unwanted overlap and unexpected styling

I've got a working cytoscape.js instance that looks like this:
I have been trying unsuccessfully to configure the graph so that the node labels don't overlap. The graph uses arbor for layout. Playing with the repulsion levels doesn't have much effect on the problem. Gravity (or lack thereof) doesn't either. Is this a layout issue or a cytoscape.js config issue and how do I fix it?
Secondarily, node shape is supposed to be a 40x40 ellipse, which it generally is. But when a node is grabbed, it displays as a rounded rectangle. Why?
I've created a gist with my javascript and some data. It's dependent on jQuery (~2.1), cytoscape.js (>=2.3.9) and arbor.js as provided in the cytoscape.js lib directory. And it needs <div id="cy"></div> for a target.
(1) Overlap is a function of layout. If changing layout parameters is unsuccessful for your usecase, a different layout is probably the solution.
(2) That's the overlay -- not the node's body.