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

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.

Related

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 ?

Edge bundling for Cose-Bilkent in 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
}
});

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),
}
})

Horizontal scrolling list

I would like to have images displayed in a horizontal list.
This is what I've done so far :
var list = Ext.create('Ext.List',{
store: store,
itemTpl: new Ext.XTemplate('<img src="{icon}" />'),
inline:true,
scrollable: {
direction: 'horizontal',
directionLock: true
}
});
My store has 5 items, but the list only display two (because the screen is not large enough to display more than two images).
I tried to solve this problem by setting the width of my list to 1000px like so :
style:'width: 1000px',
All the items are now shown, but now, the problem is the list is not scrollable anymore. I can't go further than the width of the screen.
[UPDATE]
I've tried with a hbox panel but nothing is showing. Any idea why ?
var hbox = Ext.create('Ext.Panel',{
layout:'hbox',
style:'background-color:red;',
data: [
{name: 'Jamie', age: 100},
{name: 'Rob', age: 21},
{name: 'Tommy', age: 24},
{name: 'Jacky', age: 24},
{name: 'Ed', age: 26}
],
tpl: new Ext.XTemplate('{name}')
});
this.setItems([hbox]);
I just see a red background?
Did you try passing an object instead of just true for the 'inline' config:
var list = Ext.create('Ext.List',{
store: store,
itemTpl: new Ext.XTemplate('<img src="{icon}" />'),
inline: { wrap: false },
scrollable: {
direction: 'horizontal',
directionLock: true
}
});
In the docs, they mention this avoids your wrapping problem and enables horizontal scrolling:
http://docs.sencha.com/touch/2-0/#!/api/Ext.dataview.DataView-cfg-inline.
I did not try it though.
Hope this will work for you.
Ok, I finally found this working example which was quite helpful :
http://dev.sencha.com/deploy/touch/examples/production/list-horizontal/index.html
You can also find it in the examples/production/list-horizontal when you download Sencha Touch 2
It's not a really good idea (or might be impossible) to create a horizontal Ext.List
If you tends to produce something like "image slider" or "carousel", then it would be better if you create an Ext.Carousel or something that is more customizable, hbox. Ext.Carousel is easy and well-documented, so I will talk a little bit more about hbox.
The idea is, first you create an empty hbox with fixed height. Then, you can eventually add items to it. Each item is whatever you like, for example: Ext.Image in your case. Each of your hbox item is a component then you can easily customize it the way you want.
Hope this idea helps.