Edge bundling for Cose-Bilkent in Cytoscape.js - cytoscape.js

I'm using the Cose-Bilkent layout to display a nested graph but it gets a bit messy when there are too many edges. To improve the graph in a visual way I was thinking about using some edge bundling for the graph. I've been doing some research and it seems I should be able to do this by setting things like control-point-step-size and/or control-point-weight but it is still not clear to me how to do that to be honest. My idea is to set that control point based on the position of some parent node. Below I attach a screenshot with a sketch of what I would like to get (sorry for the bad sketch). Could someone guide me a bit on how to get that parent control point and then set if for the edges? enter image description here Thanks!

I think you just have to add the control-point properties to your style :)
You can either use the bezier edge-style or the unbundled bezier edge-style
var cy = cytoscape({
container: yourContainer, // container to render in
elements: yourElements,
style: [ // the stylesheet for the graph
{
selector: 'node',
style: {
'background-color': yourColor,
'label': yourLabel
}
},
{
selector: 'edge',
style: {
'width': 3,
'line-color': '#ccc',
'target-arrow-color': '#ccc',
'target-arrow-shape': 'triangle'
'curve-style': 'bezier',
// 'curve-style': 'unbundled-bezier', // this is a manual bezier, maybe try out this one too
'control-point-things': xyz
}
}
],
layout: {
name: yourLayout
}
});

Related

Cytoscape.js combine multiple edges into one (thicker) edge

I'm using cytoscape.js 3.19.1 and I cannot figure out how to combine multiple edges into one, and have the weight increased of that one edge.
Current view
I am now looking for a solution where 2 edges get combined into one with a width of 2, 3 edges combined into one with a width of 3, etc.
I am changing the color of the nodes with this code:
style: [
{
selector: 'node',
css: {
'content': 'data(name)',
'text-outline-color': 'red',
},
style: {
'background-color': 'data(color)',
'label': 'data(name)',
'color': "white",
}
},
{
selector: 'edge',
css: {
'curve-style': 'bezier',
'target-arrow-shape': 'triangle'
}
}
],
and this cytoscape input works: {'nodes': [{'data': {'id': '1464848862', 'name': 'my_name', 'color': '#FFA00F'}}....
I could now do the same for the line width but I would rather not having to go through the data 'manually' to figure out which 2 nodes get connected, how often that happens, define how thick that lines has to be and then remove all the duplicates that no longer need to be drawn.
Is there any other way?
Many thanks for any suggestions!
Actually, you might achieve this using some different styles on the edges. "haystack" or "straight" might be useful. Check them https://js.cytoscape.org/demos/edge-types/
Or you might use https://github.com/iVis-at-Bilkent/cytoscape.js-expand-collapse
Check its demo and collapse the edges.

cytoscape.js with dagre layout, how to avoid edge overlap?

I moving my project from dagre-d3 to cytoscape.
Cytoscape.js is really more flexible and will allow more powerful control but for now, I just can't have the edge rendering as I want.
Here is the dagre-d3 version:
Here is the actual cytoscape:
As you can see, it's almost the same except :
cluster are not in the same order (not a big deal).
edge can overlap the whole graph.
The last one is my main issue, I just can't find a way to tell cytoscape to make edge as parallel as possible like dagre-d3.
I'll try to use segments edges (that seems the right edge type) but I can find a way to configure it.
Also try taxi one but label are unreadable.
Here is a full example : https://jsfiddle.net/uqtahcfs/
{
"elements": {
"nodes": ...,
"edges": ...,
},
"style": ...,
layout: {
name: "dagre",
rankDir: "LR",
animate: false,
fit: true,
padding: 50,
spacingFactor: 1.2,
},
pixelRatio: 1,
minZoom: 0.2,
maxZoom: 2
}
Any way to have segment that look like parallel ?

change arrow position for mid-target edges

Is there a way to change the midpoint position of edge arrows. Currently it's set at 50%, but I'd like to be able to adjust this to 25% or 75% depending on the edge. Is there a variable/option I can call within:
{selector: 'edge',
style: {
'curve-style': 'bezier',
'line-color': '#506368',
'mid-target-arrow-shape': 'triangle',
'mid-target-arrow-color': 'black',
'width': 1,
}
},
I don't think that's going to happen. The only reason that the mid arrow is allowed is because the point has to be calculated anyway. Arbitrary points become expensive for beziers.

Cytoscape.js - create circular nodes with size

In cytoscape I'd like to create nodes that are circular, with the diameter depending on the node label (the label is centered in the node). I've set the following:
style: {
'shape': 'ellipse',
'width': 'label'
}
How do I get the height to depend on the width value? Setting 'height': 'label' sets the height to the height of the label.
If you can use a fixed-width font, then #BeerBaron's answer is best.
Alternatively, use the stylesheet you have in the OP:
style: {
'shape': 'ellipse',
'width': 'label',
'height': 'data(height)'
}
Update node heights as a step post-init, e.g.
cy.nodes().forEach(function( n ){ n.data('height', n.width()); });
You should probably preset data.height for each node to some default value at init to ease debugging (e.g. when you add new nodes later).
Depending on label lenght and font, you can set width and height in the javascript part that is appending nodes to the graph, and leave the rest of the style to the initialization of the engine.
For example:
cy.add({
group: 'nodes',
style: {
height: (10*label.lenght),
width: (10*label.lenght),
}
})

Grid Panel Scrollbars in Extjs 4 not working

var gusersPanel = Ext.create('Ext.grid.Panel', {
flex:1,
columns: [{
header: 'User Login',
dataIndex: 'user_login',
width:150
},{
header: 'User Name',
dataIndex: 'user_nicename',
width:150
},{
header:'Privledge',
dataIndex:'admin',
width:150
}],
autoScroll: true,
layout:'fit',
selModel: gusersSel,
store: gusersStore
})
Hi I am using above code for the grid Panel in Extjs4.0.2a When I populate data dynamically in the store the scrollbars are not working .
I have also tried using doLayout() for grid Panel but dosent work too .
The grid Panel is in a Window .
Anything that can solve this problem ?
Actually it works for some time but dosen't work all the time .
I've had the same problem. They use custom scrollbar and it's pretty buggy (especialy in chrome). If you are not going to use infinite scroll the possible solution could be to remove custom scrollbar and use native one. To do that just add the following to the grid's config:
var gusersPanel = Ext.create('Ext.grid.Panel', {
scroll : false,
viewConfig : {
style : { overflow: 'auto', overflowX: 'hidden' }
},
// ...
});
I did gusersPanel.determineScrollbars() when i am adding and removing data from store and it is working fine .
The problem with this is the scroll listener is attached to the div element on the afterrender event, but then if the scrollbar is not needed after a layout operation the div element is removed from the dom. Then, when it's needed again it's added back, but only if enough time has passed the garbage collection makes extjs recreate the div node and this time it's added to the dom without attaching the scroll listener again. The following code solves the problem:
Ext.override(Ext.grid.Scroller, {
onAdded: function() {
this.callParent(arguments);
var me = this;
if (me.scrollEl) {
me.mun(me.scrollEl, 'scroll', me.onElScroll, me);
me.mon(me.scrollEl, 'scroll', me.onElScroll, me);
}
}
});
You written code to layout: 'fit'. It did not work autoScroll.
Change the code to some height and remove layout: 'fit' code.
Like this.
var gusersPanel = Ext.create('Ext.grid.Panel', {
flex:1,
columns: [{
...........
}],
autoScroll: true,
//layout:'fit',
height: 130,
selModel: gusersSel,
store: gusersStore
It is help you. Cheers.