Keep edges seperated - cytoscape.js

I have created the following diagram using ELK.
Now I'm trying to use cytoscape.js with cytoscape.js-elk to generate the same routing. However I cannot get the edges the same was with ELK.
I keep getting the following:
What do I need to do to get the same edge route as ELK generates? I have tried changing the ELK options, but I don't think this is caused by elk, I think this is caused by cytoscape.
My style
const style = [ // the stylesheet for the graph
{
selector: 'node',
style: {
shape: 'rectangle',
label: 'data(id)',
'font-size': '0.5em',
}
},
{
selector: 'edge',
style: {
'width': 1,
'curve-style': 'taxi',
'line-color': '#ccc',
label: 'data(id)',
'font-size': '0.5em',
'color': 'blue',
'target-arrow-color': '#ccc',
'target-arrow-shape': 'triangle'
}
}
];
Settings
cytoscape.use(elk);
var cy = cytoscape({
container: document.getElementById('cy'),
style: style,
layout: { name: 'elk' }
});
Nodes & Edges
var nodes = cy.add([
{ group: 'nodes', data: { id: 'n1'} },
{ group: 'nodes', data: { id: 'n2'} },
{ group: 'nodes', data: { id: 'n4'} },
{ group: 'nodes', data: { id: 'n9'} },
{ group: 'nodes', data: { id: 'n10' } },
{ group: 'nodes', data: { id: 'n555'} },
{ group: 'nodes', data: { id: 'n556'} },
{ group: 'nodes', data: { id: 'n557'} },
])
var edges = cy.add([
{ group: 'edges', data: { id: 'e3', source: 'n1', target: 'n4' } },
{ group: 'edges', data: { id: 'e19', source: 'n1', target: 'n9' } },
{ group: 'edges', data: { id: 'e12', source: 'n2', target: 'n1' } },
{ group: 'edges', data: { id: 'e842', source: 'n2', target: 'n9' } },
{ group: 'edges', data: { id: 'e15', source: 'n2', target: 'n10' } },
{ group: 'edges', data: { id: 'e10', source: 'n4', target: 'n2' } },
{ group: 'edges', data: { id: 'e908', source: 'n4', target: 'n4' } },
{ group: 'edges', data: { id: 'e843', source: 'n4', target: 'n9' } },
{ group: 'edges', data: { id: 'e11', source: 'n4', target: 'n10' } },
{ group: 'edges', data: { id: 'e905', source: 'n4', target: 'n555' } },
{ group: 'edges', data: { id: 'e862', source: 'n4', target: 'n557' } },
{ group: 'edges', data: { id: 'e802', source: 'n9', target: 'n1' } },
{ group: 'edges', data: { id: 'e7', source: 'n10', target: 'n2' } },
{ group: 'edges', data: { id: 'e8', source: 'n10', target: 'n4' } },
]);
Options
var options = {
name: "elk",
nodeDimensionsIncludeLabels: true, // Boolean which changes whether label dimensions are included when calculating node dimensions
fit: true, // Whether to fit
padding: 20, // Padding on fit
animate: false, // Whether to transition the node positions
animateFilter: function (node, i) { return true; }, // Whether to animate specific nodes when animation is on; non-animated nodes immediately go to their final positions
animationDuration: 500, // Duration of animation in ms if enabled
animationEasing: undefined, // Easing of animation if enabled
transform: function (node, pos) { return pos; }, // A function that applies a transform to the final node position
ready: undefined, // Callback on layoutready
stop: undefined, // Callback on layoutstop
elk: {
'algorithm': 'layered',
'layered.mergeEdges': 'false',
'layered.mergeHierarchyEdges': 'false',
'crossingMinimization.semiInteractive': true,
'nodePlacement.strategy': 'NETWORK_SIMPLEX',
'layered.wrapping.additionalEdgeSpacing': 50,
'spacing.nodeNode': 50,
'spacing.nodeNodeBetweenLayers': 25,
'spacing.edgeNode': 25,
'spacing.edgeNodeBetweenLayers': 20,
'spacing.edgeEdge': 20,
'spacing.edgeEdgeBetweenLayers': 15,
// All options are available at http://www.eclipse.org/elk/reference.html
// 'org.eclipse.elk.' can be dropped from the Identifier
// Or look at demo-demo.js for an example.
// Enums use the name of the enum e.g.
// 'searchOrder': 'DFS'
//
// The main field to set is `algorithm`, which controls which particular
// layout algorithm is used.
},
priority: function (edge) { return null; }, // Edges with a non-nil value are skipped when geedy edge cycle breaking is enabled
};
cy.layout(options).run();

I hit the same problem. Another you will encounter is that the lines will go through the nodes, there is no effort to route around them. For me this has rendered taxi useless, even though I much prefer it's appearance. I am not aware of any line drawing algorithm in cytoscape that fixes either of these issues.
My reluctant conclusion is that I need to switch platforms, and transfer entirely to Sprotty and ELK (which was probably used to draw your reference graph).
https://rtsys.informatik.uni-kiel.de/elklive/examples.html?e=general%2FmixingDirection
https://www.typefox.io/blog/sprotty-a-web-based-diagramming-framework
Examples with Sprotty show lines actually routing around nodes, and junction points on nodes to show where overlapping lines actually join. Additionally it uses SVGs rather than a raster-render system. This may result in a crisper font, but also has the advantage of searchable text in your diagram (if you care about that).
I have yet to take the plunge on yet another framework, but it looks good.

I am also facing similar kind of problem where my edges are overlapping to each other. To overcome this problem you can use curve-style: straight;.
Edges type demo

Related

vue2 chart.js insert time data on x-axis in real time

I want to put time data in x-axis labels in vue chart.js . There is a way in pure js code, not vue, but I can't find it in vue version.
Below is my code.
export default {
name: "LineChart",
components: {
LineChartGenerator,
},
props: {
chartId: {
type: String,
default: "line-chart",
},
datasetIdKey: {
type: String,
default: "label",
},
width: {
type: Number,
default: 100,
},
height: {
type: Number,
default: 280,
},
cssClasses: {
default: "",
type: String,
},
styles: {
type: Object,
default: () => {},
},
plugins: {
type: Array,
default: () => [],
},
},
data() {
return {
chartData: {
labels: "???",
datasets: [
{
label: "vacuum",
backgroundColor: "#534e7f",
data: this.$store.state.cnc1,
},
],
},
chartOptions: {
maintainAspectRatio: false,
},
};
},
};
I tried a lot of things similar to the one below but failed.
I also installed the extension but it failed.
scales: {
x: {
type: "time",
time: {
unit: "day",
},
},
},
I want to make something like this.
Most of the vue examples don't help by putting specific values in 'labels:' beforehand.
How can I get the value of the label in real time?
I tried putting time data into the store, but only the time when execution started is displayed.
Or like this...My head is a potato.Any help would be appreciated.
did you match label and data like this?
chartData: {
labels: [ 'January', 'February', 'March'],
datasets: [
{
label: 'Data One',
backgroundColor: '#f87979',
data: [40, 20, 12]
}
]
},

Define (and preserve) compound node shape in Cytoscape, allowing rotation

Is it possible to specify a shape (i.e. square, or triangle) of a compound node in Cytoscape, which will be preserved when the layout of the graph is computed/rendered? The compound nodes should be rotated freely, as needed to give a good/simple layout.
As an example, consider the graph below with three compound nodes, I - III. Compound nodes II and III could be rotated to give a simple layout. Importantly, the internal layout of compound nodes is not affected (I remains a triangle, and the other two remain linear).
Is is possible to define such a graph, and get a similar output, using Cytoscape.js?
Or maybe a slightly more complex example where all three nodes are rotated
Here's what I've tried so far:
var cy = cytoscape({
container: document.getElementById('cy'),
elements: [
// nodes
{ data: { id: 'IA', parent: 'I' } },
{ data: { id: 'IB', parent: 'I' } },
{ data: { id: 'IC', parent: 'I' } },
{ data: { id: 'I' } },
{ data: { id: 'IIA', parent: 'II' } },
{ data: { id: 'IIB', parent: 'II' } },
{ data: { id: 'IIC', parent: 'II' } },
{ data: { id: 'II' } },
{ data: { id: 'IIIA', parent: 'III' } },
{ data: { id: 'IIIB', parent: 'III' } },
{ data: { id: 'III' } },
// edges
{
data: {
id: '1',
source: 'IA',
target: 'IIA'
}
},
{
data: {
id: '2',
source: 'IC',
target: 'IIB'
}
},
{
data: {
id: '3',
source: 'IC',
target: 'IIIA'
}
},
{
data: {
id: '4',
source: 'IB',
target: 'IIIB'
}
},
],
layout: {
name: 'grid'
},
style: [
{
selector: 'node',
style: {
label: 'data(id)'
}
}]
});
cy.layout({
name: 'fcose'
}).run();
which gives this

How to keep a node at the centre of circle layout in cytoscape.js?

I am trying to show metabolite-protein interaction using cytoscape.min.js. I am using the circle layout to view the network.
I have two types of node in the network,"prot" and "met". For the better visualization, I want to create a circular layout with the node "met" at the center. In this case, I want to keep the metabolite (here node 'a') at the center of the circle. How to do the same ?
Thanks,
Santosh
My script for cytoscape.min.js is as follows:
<script>
var cy = cytoscape({
container: document.getElementById('cy'),
elements: [
// nodes
{ data: { id: 'a', type: "met" } },
{ data: { id: 'b', type: "prot" } },
{ data: { id: 'c', type: "prot" } },
{ data: { id: 'd', type: "prot" } },
{ data: { id: 'e', type: "prot" } },
{ data: { id: 'f', type: "prot" } },
// edges
{
data: {
id: 'ab',
source: 'a',
target: 'b'
}
},
{
data: {
id: 'ae',
source: 'a',
target: 'e'
}
},
{
data: {
id: 'cd',
source: 'c',
target: 'd'
}
},
{
data: {
id: 'ef',
source: 'e',
target: 'f'
}
},
{
data: {
id: 'ac',
source: 'a',
target: 'c'
}
},
{
data: {
id: 'be',
source: 'b',
target: 'e'
}
}
],
style: [
{
selector: 'node[type="prot"]',
style: {
'shape': 'circle',
'background-color': 'red',
label: 'data(id)'
}
},
{
selector: 'node[type="met"]',
style: {
'shape': 'square',
'background-color': 'blue',
label: 'data(id)'
}
}]
});
cy.layout({
name: 'circle',
animate: true
}).run();
</script>

Edge Data Format

I am trying to find the most efficient way to return data for a network graph which will be constructed with cytoscape js on the front end. I know that the standard way to add edges and nodes is :
// can use reference to eles later
var eles = cy.add([
{ group: 'nodes', data: { id: 'n0' }, position: { x: 100, y: 100 } },
{ group: 'nodes', data: { id: 'n1' }, position: { x: 200, y: 200 } },
{ group: 'nodes', data: { id: 'n2' }, position: { x: 300, y: 300 } },
{ group: 'edges', data: { id: 'e0', source: 'n0', target: 'n1' } },
{ group: 'edges', data: { id: 'e0', source: 'n0', target: 'n2' } }
]);
Taken from their documentation
I was wondering if there is a way to effectively do the following:
// can use reference to eles later
var eles = cy.add([
{ group: 'nodes', data: { id: 'n0' }, position: { x: 100, y: 100 } },
{ group: 'nodes', data: { id: 'n1' }, position: { x: 200, y: 200 } },
{ group: 'nodes', data: { id: 'n2' }, position: { x: 300, y: 300 } },
{ group: 'edges', data: { id: 'e0', source: 'n0', target: ['n1', 'n2'] } }
]);
This way I can return an adjacency list from the server instead of an edge/node list.
Intresting format, but unfortunately, this won't work without maybe a new extension.
The thing is, that every element of the graph has to have an id! So when you add an edge to the graph and assign multiple targets, there ought to be 2 id's for every edge.
If you are trying to optimise your cy instance, you can go over this section of the documentation instead.

Cytoscape.js setting node colour and other details

I am using Cytoscape.js to create a basic diagram and am curious as to how to set the colour and particular shape of each node. Here is my existing code:
layout: {
name: 'preset'
},
ready: function(){
window.cy = this;
cy.add([
{ group: "nodes", data: { id: "n0" }, position: { x: 100, y: 100 } },
{ group: "nodes", data: { id: "n1", shape: 'rectangle' }, position: { x: 200, y: 200 } },
{ group: "edges", data: { id: "e0", source: "n0", target: "n1" } }
]);
}
});
});
I was also curious as to how to animate the diagram and if there were any similar examples out there on that.
cheers,
...
style: [ // the stylesheet for the graph
{
selector: 'node',
style: {
'background-color': '#666',
'shape': 'rectangle',
}
},
],
...
background-color is probably the attribute you are looking for, this is set in the style option. More info can be in http://js.cytoscape.org/#getting-started/specifying-basic-options.
As for the shape, cytoscape has a few predefined shapes such as rectangle, circle, etc. You can even make your own, or have an svg as the node's image. Options for nodes are listed in http://js.cytoscape.org/#style/node-body.
For animation I would look at some of the demos uploaded and go from there. This one is particularly interesting js.cytoscape.org/demos/aedff159b0df05ccfaa5