I have a cytoscape.js model, where edges between nodes represent different relations.
I want to have possibility to display something like round shape or button in the middle of the edge, where user could click and get popup to change the relationship type.
So far I see in base package there is no option to display round shape.
I am using dagre layout, and this is my current edge configuration:
{
selector: "edge",
style: {
width: 1,
"font-size": "20px",
//opacity: "0.5",
label: "data(type)",
color: function(ele) {
return getEdgeColor(ele.data("type"));
},
"line-color": function(ele) {
return getEdgeColor(ele.data("type"));
},
"target-arrow-color": function(ele) {
return getEdgeColor(ele.data("type"));
},
"curve-style": "straight",
"target-arrow-shape": "triangle"
}
},
Could you recommend me any easy solution?
I have a workaround for this (the editation works on the whole edge, the dot is just for the looks:
var cy = window.cy = cytoscape({
container: document.getElementById('cy'),
style: [{
selector: 'node',
css: {
'content': 'data(id)',
'text-valign': 'center',
'text-halign': 'center',
'height': '60px',
'width': '60px'
}
},
{
selector: 'edge',
css: {
'font-size': "40px",
'label': "\u2022",
'curve-style': 'bezier',
'target-arrow-shape': 'data(arrow)'
}
}
],
elements: {
nodes: [{
data: {
id: 'n0'
}
},
{
data: {
id: 'n1'
}
},
{
data: {
id: 'n2'
}
},
{
data: {
id: 'n3'
}
}
],
edges: [{
data: {
source: 'n0',
target: 'n1',
arrow: 'triangle'
}
},
{
data: {
source: 'n1',
target: 'n2',
arrow: 'triangle'
}
},
{
data: {
source: 'n1',
target: 'n3',
arrow: 'triangle'
}
},
]
},
layout: {
name: 'concentric',
minNodeSpacing: 140,
}
});
cy.cxtmenu({
selector: 'edge',
menuRadius: 90,
commands: [{
content: 'Direction',
select: function(edge) {
edge.move({
source: edge.target().id(),
target: edge.source().id()
});
}
}]
});
body {
font: 14px helvetica neue, helvetica, arial, sans-serif;
}
#cy {
height: 100%;
width: 100%;
left: 0;
top: 0;
float: left;
position: absolute;
}
.cxtmenu-disabled {
opacity: 0.333;
}
<html>
<head>
<meta charset=utf-8 />
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
<script src="https://cdn.jsdelivr.net/npm/cytoscape#3.10.1/dist/cytoscape.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/cytoscape-cxtmenu#3.1.1/cytoscape-cxtmenu.min.js"></script>
</head>
<body>
<div id="cy"></div>
</body>
</html>
I use the ctx-menu extension here (right click on edge to open menu) and the dot is just an unicode character.
Related
When using edgehandles, the cytoscape extension, to create an edge between two nodes like this, I see "undefined" at the edge of the arrow. Is there some attribute I can set to get rid of this? Either in the inputs or in the style page with a selector?
For reference, I'm using
var eh = cy.edgehandles({defaults}) and eh.enableDrawMode() with the defaults defined in the edgehandles github.
Thanks!
The code from the edge-handles demo works fine in my snippet, you can use that as a starting point:
document.addEventListener('DOMContentLoaded', function() {
var cy = window.cy = cytoscape({
container: document.getElementById('cy'),
layout: {
name: 'grid',
rows: 2,
cols: 2
},
style: [{
selector: 'node[name]',
style: {
'content': 'data(name)'
}
},
{
selector: 'edge',
style: {
'curve-style': 'bezier',
'target-arrow-shape': 'triangle'
}
},
{
selector: '.eh-handle',
style: {
'background-color': 'red',
'width': 12,
'height': 12,
'shape': 'ellipse',
'overlay-opacity': 0,
'border-width': 12, // makes the handle easier to hit
'border-opacity': 0
}
},
{
selector: '.eh-hover',
style: {
'background-color': 'red'
}
},
{
selector: '.eh-source',
style: {
'border-width': 2,
'border-color': 'red'
}
},
{
selector: '.eh-target',
style: {
'border-width': 2,
'border-color': 'red'
}
},
{
selector: '.eh-preview, .eh-ghost-edge',
style: {
'background-color': 'red',
'line-color': 'red',
'target-arrow-color': 'red',
'source-arrow-color': 'red'
}
},
{
selector: '.eh-ghost-edge.eh-preview-active',
style: {
'opacity': 0
}
}
],
elements: {
nodes: [{
data: {
id: 'j',
name: 'Jerry'
}
},
{
data: {
id: 'e',
name: 'Elaine'
}
},
{
data: {
id: 'k',
name: 'Kramer'
}
},
{
data: {
id: 'g',
name: 'George'
}
}
],
edges: [{
data: {
source: 'j',
target: 'e'
}
},
{
data: {
source: 'j',
target: 'k'
}
},
{
data: {
source: 'j',
target: 'g'
}
},
{
data: {
source: 'e',
target: 'j'
}
},
{
data: {
source: 'e',
target: 'k'
}
},
{
data: {
source: 'k',
target: 'j'
}
},
{
data: {
source: 'k',
target: 'e'
}
},
{
data: {
source: 'k',
target: 'g'
}
},
{
data: {
source: 'g',
target: 'j'
}
}
]
}
});
var eh = cy.edgehandles();
document.querySelector('#draw-on').addEventListener('click', function() {
eh.enableDrawMode();
});
document.querySelector('#draw-off').addEventListener('click', function() {
eh.disableDrawMode();
});
document.querySelector('#start').addEventListener('click', function() {
eh.start(cy.$('node:selected'));
});
});
body {
font-family: helvetica neue, helvetica, liberation sans, arial, sans-serif;
font-size: 14px;
}
#cy {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: 999;
}
h1 {
opacity: 0.5;
font-size: 1em;
font-weight: bold;
}
#buttons {
position: absolute;
right: 0;
bottom: 0;
z-index: 99999;
}
<html>
<head>
<title>cytoscape-edgehandles.js demo</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
<script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>
<script src="https://cdn.jsdelivr.net/npm/cytoscape-edgehandles#3.6.0/cytoscape-edgehandles.min.js"></script>
</head>
<body>
<h1>cytoscape-edgehandles demo</h1>
<div id="cy"></div>
<div id="buttons">
<button id="start">Start on selected</button>
<button id="draw-on">Draw mode on</button>
<button id="draw-off">Draw mode off</button>
</div>
</body>
</html>
Using cytoscape.js, I am setting the style of a node while defining it.
Shortened example below:
window.addEventListener('DOMContentLoaded', function(){
var cy = window.cy = cytoscape({
elements: {
nodes: [
{ data: { id: 'a', name: 'apple' }, style: { 'background-color': 'darkgreen' } },
]
}
});
});
(I have a default style for a node that is a different color)
This works fine, but when I run my code, the browser console shows the following warning:
Setting a `style` bypass at element creation is deprecated
What does it mean and what is the correct (non-deprecated) way to set it?
Thank you in advance!
The correct way of doing this would be to use the cytoscape stylesheet, as can be seen in every example in the docs:
var cy = (window.cy = cytoscape({
container: document.getElementById("cy"),
boxSelectionEnabled: false,
autounselectify: true,
style: [{
selector: "node",
css: {
"label": "data(id)",
"text-valign": "center",
"text-halign": "center",
"background-color": "data(color)"
}
},
{
selector: "edge",
css: {
"line-fill": "radial-gradient",
"line-gradient-stop-colors": "red green blue",
"line-gradient-stop-positions": "25 50 75"
}
}
],
elements: {
nodes: [{
data: {
id: "a",
color: "#2763c4"
}
},
{
data: {
id: "b",
color: "#37a32d"
}
},
{
data: {
id: "c",
color: "#37a32d"
}
}
],
edges: [{
data: {
source: "a",
target: "b"
}
},
{
data: {
source: "a",
target: "c"
}
}
]
},
layout: {
name: "dagre"
}
}));
cy.ready(function() {
cy.dblclick();
});
var nid = 0;
cy.bind('dblclick', function(evt) {
console.log('dblclick');
cy.add({
group: 'nodes',
data: {
id: nid,
faveColor: 'red'
},
position: {
x: evt.x,
y: evt.y
}
});
nid++;
});
cy.bind('click', 'node', function(evt) {
console.log('node clicked: ', evt.target.id());
});
body {
font: 14px helvetica neue, helvetica, arial, sans-serif;
}
#cy {
height: 100%;
width: 100%;
float: right;
position: absolute;
}
<html>
<head>
<meta charset=utf-8 />
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
<script src="https://unpkg.com/cytoscape#3.3.0/dist/cytoscape.min.js">
</script>
<!-- cyposcape dagre -->
<script src="https://unpkg.com/dagre#0.7.4/dist/dagre.js"></script>
<script src="https://cdn.rawgit.com/cytoscape/cytoscape.js-dagre/1.5.0/cytoscape-dagre.js"></script>
<script src="https://unpkg.com/cytoscape-dblclick/dist/index.js"></script>
</head>
<body>
<div id="cy"></div>
</body>
</html>
I'm trying to create an edge between two parent nodes using 'curve-style': 'taxi'. Unfortunately, edges between parent nodes don't seem to turn at right angles and generally route themselves very erratically.
window.addEventListener('DOMContentLoaded', function() { // on dom ready
// photos from flickr with creative commons license
var cy = cytoscape({
container: document.getElementById('cy'),
style: cytoscape.stylesheet()
.selector('node')
.style({
'height': 80,
'width': 80,
'background-fit': 'cover',
'border-color': '#000',
'border-width': 3,
'border-opacity': 0.5
})
.selector('.eating')
.style({
'border-color': 'red'
})
.selector('.eater')
.style({
'border-width': 9
})
.selector('edge')
.style({
'width': 6,
'target-arrow-shape': 'triangle',
'line-color': '#ffaaaa',
'target-arrow-color': '#ffaaaa',
'curve-style': 'taxi'
})
.selector('#bird')
.style({
'background-image': 'https://farm8.staticflickr.com/7272/7633179468_3e19e45a0c_b.jpg'
})
.selector('#cat')
.style({
'background-image': 'https://farm2.staticflickr.com/1261/1413379559_412a540d29_b.jpg'
})
.selector('#ladybug')
.style({
'background-image': 'https://farm4.staticflickr.com/3063/2751740612_af11fb090b_b.jpg'
})
.selector('#aphid')
.style({
'background-image': 'https://farm9.staticflickr.com/8316/8003798443_32d01257c8_b.jpg'
})
.selector('#rose')
.style({
'background-image': 'https://farm6.staticflickr.com/5109/5817854163_eaccd688f5_b.jpg'
})
.selector('#grasshopper')
.style({
'background-image': 'https://farm7.staticflickr.com/6098/6224655456_f4c3c98589_b.jpg'
})
.selector('#plant')
.style({
'background-image': 'https://farm1.staticflickr.com/231/524893064_f49a4d1d10_z.jpg'
})
.selector('#wheat')
.style({
'background-image': 'https://farm3.staticflickr.com/2660/3715569167_7e978e8319_b.jpg'
}),
elements: {
nodes: [{
data: {
id: 'cat',
parent: 'bird'
}
},
{
data: {
id: 'bird'
}
},
{
data: {
id: 'ladybug'
}
},
{
data: {
id: 'aphid'
}
},
{
data: {
id: 'rose'
}
},
{
data: {
id: 'grasshopper'
}
},
{
data: {
id: 'plant'
}
},
{
data: {
id: 'wheat'
}
}
],
edges: [{
data: {
source: 'cat',
target: 'bird'
}
},
{
data: {
source: 'bird',
target: 'ladybug'
}
},
{
data: {
source: 'bird',
target: 'grasshopper'
}
},
{
data: {
source: 'grasshopper',
target: 'plant'
}
},
{
data: {
source: 'grasshopper',
target: 'wheat'
}
},
{
data: {
source: 'ladybug',
target: 'aphid'
}
},
{
data: {
source: 'aphid',
target: 'rose'
}
}
]
},
layout: {
name: 'breadthfirst',
directed: true
}
}); // cy init
}); // on dom ready
body {
font: 14px helvetica neue, helvetica, arial, sans-serif;
}
#cy {
height: 100%;
width: 100%;
position: absolute;
left: 0;
top: 0;
}
<!DOCTYPE html>
<html>
<head>
<link href="style.css" rel="stylesheet" />
<meta charset=utf-8 />
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
<title>Images</title>
<script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
</head>
<body>
<div id="cy"></div>
</body>
</html>
Is there a way to get taxi edges to behave the same way they do between non-parent nodes?
This is caused by a weired layout behaviour in the breadthfirst layout. When using compound nodes in breadthfirst, it seems that the layout can't handle inner nodes that well, so the outer edges are not really bfs edges (bonding together), but rather two seperate bfs edges (not bonding). In order to get the 'curve-style': 'taxi' to work, there is one simple but dumb way I think. Unfortunately, edges between parent nodes can't seem to turn at the right angles, so we have to make the bfs layout without the child nodes and add them afterwards (this is a stupid hack, but it works if you save all child nodes and add them afterwards:
window.addEventListener('DOMContentLoaded', function() { // on dom ready
// photos from flickr with creative commons license
var cy = cytoscape({
container: document.getElementById('cy'),
style: cytoscape.stylesheet()
.selector('node')
.style({
'height': 80,
'width': 80,
'background-fit': 'cover',
'border-color': '#000',
'border-width': 3,
'border-opacity': 0.5
})
.selector('.eating')
.style({
'border-color': 'red'
})
.selector('.eater')
.style({
'border-width': 9
})
.selector('edge')
.style({
"curve-style": "taxi",
"taxi-direction": "downward",
"taxi-turn": 20,
"taxi-turn-min-distance": 5
})
.selector('#bird')
.style({
'background-image': 'https://farm8.staticflickr.com/7272/7633179468_3e19e45a0c_b.jpg'
})
.selector('#cat')
.style({
'background-image': 'https://farm2.staticflickr.com/1261/1413379559_412a540d29_b.jpg'
})
.selector('#ladybug')
.style({
'background-image': 'https://farm4.staticflickr.com/3063/2751740612_af11fb090b_b.jpg'
})
.selector('#aphid')
.style({
'background-image': 'https://farm9.staticflickr.com/8316/8003798443_32d01257c8_b.jpg'
})
.selector('#rose')
.style({
'background-image': 'https://farm6.staticflickr.com/5109/5817854163_eaccd688f5_b.jpg'
})
.selector('#grasshopper')
.style({
'background-image': 'https://farm7.staticflickr.com/6098/6224655456_f4c3c98589_b.jpg'
})
.selector('#plant')
.style({
'background-image': 'https://farm1.staticflickr.com/231/524893064_f49a4d1d10_z.jpg'
})
.selector('#wheat')
.style({
'background-image': 'https://farm3.staticflickr.com/2660/3715569167_7e978e8319_b.jpg'
}),
elements: {
nodes: [{
data: {
id: 'bird'
}
},
{
data: {
id: 'ladybug'
}
},
{
data: {
id: 'aphid'
}
},
{
data: {
id: 'rose'
}
},
{
data: {
id: 'grasshopper'
}
},
{
data: {
id: 'plant'
}
},
{
data: {
id: 'wheat'
}
}
],
edges: [{
data: {
source: 'bird',
target: 'ladybug'
}
},
{
data: {
source: 'bird',
target: 'grasshopper'
}
},
{
data: {
source: 'grasshopper',
target: 'plant'
}
},
{
data: {
source: 'grasshopper',
target: 'wheat'
}
},
{
data: {
source: 'ladybug',
target: 'aphid'
}
},
{
data: {
source: 'aphid',
target: 'rose'
}
}
]
},
layout: {
name: 'breadthfirst',
directed: true
}
}); // cy init
cy.ready(function() {
cy.ready(function() {
cy.add({
data: {
id: 'cat',
parent: 'bird'
}
});
});
});
}); // on dom ready
body {
font: 14px helvetica neue, helvetica, arial, sans-serif;
}
#cy {
height: 100%;
width: 100%;
position: absolute;
left: 0;
top: 0;
}
<!DOCTYPE html>
<html>
<head>
<link href="style.css" rel="stylesheet" />
<meta charset=utf-8 />
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
<title>Images</title>
<script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
</head>
<body>
<div id="cy"></div>
</body>
</html>
I added a couple of lines in the css section of cytoscape, also the cy.ready() part at the end of the js file.
I dug into the source code a bit and found that you can make this work as expected by setting the target-endpoint and source-endpoint edge style attributes to outside-to-node.
There's a bit of a funky behavior where the edge disappears when the parent nodes get too close. I found that setting 'edge-distances': 'node-position' and 'taxi-turn-min-distance': '0px' helped with that. Here is the full edge style for reference:
'curve-style': 'taxi',
'edge-distances': 'node-position',
'taxi-turn-min-distance': '0px',
'source-arrow-shape': 'triangle-backcurve',
'target-arrow-shape': 'triangle',
'target-endpoint': 'outside-to-node',
'source-endpoint': 'outside-to-node'
I'm using Cytoscape in Plotly/Dash and I'm creating a simple graph. I then move a few nodes around to various positions. I am then trying to read the these positions in a Dash callback - I've tried:
State("cytoscape-graph", "stylesheets")
State("cytoscape-graph", "layout")
State("cytoscape-graph", "elements")
More or less anything I could find in the docs here
Example nodes:
{'data': {'id': 'id0', 'label': 'Node 0'}, 'position': {'x': 50, 'y': 150}},
{'data': {'id': 'node1', 'label': 'Node 1'}, 'position': {'x': 200, 'y': 100}},
{'data': {'id': 'node2', 'label': 'Node 2'}, 'position': {'x': 200, 'y': 200}},
{'data': {'source': 'node0', 'target': 'node1', 'id': '4300352b-9533-4fef-90ec-7a5cbff1f8c4'}},
{'data': {'source': 'node1', 'target': 'node2', 'id': '33d4c841-bcfc-4a07-ac56-90d36982601a'}},
}
The above either return None, anything else that doesn't contain relevant information, or the initial node positions. I tried looking at the rendered source code but I can't seem to find information there; only a canvas element. I'd appreciate pointers even for the Javascript backend.
EDIT:
It seems that Dash does not allow direct access to ...elements().jsons() so the answer to the question is that it's probably not possible to do purely with Dash. You will probably have to write a callback for every time a node is clicked to run this in javascript and output it to some hidden div, and then read it in Dash.
~ Credit goes to OP for answering this question
This is, as pointed out in this section of the documentation, easily achievable. The method cy.elements()/nodes()/edges().jsons() gets an array of the plain JavaScript object representation of all specified elements in the collection.
var json;
var cy = (window.cy = cytoscape({
container: document.getElementById("cy"),
boxSelectionEnabled: false,
autounselectify: true,
style: [{
selector: "node",
css: {
content: "data(id)",
"text-valign": "center",
"text-halign": "center",
height: "60px",
width: "100px",
shape: "rectangle",
"background-color": "data(faveColor)"
}
},
{
selector: "edge",
css: {
"curve-style": "bezier",
"control-point-step-size": 40,
"target-arrow-shape": "triangle"
}
}
],
elements: {
nodes: [{
data: {
id: "Top",
faveColor: "#2763c4"
}
},
{
data: {
id: "yes",
faveColor: "#37a32d"
}
},
{
data: {
id: "no",
faveColor: "#2763c4"
}
},
{
data: {
id: "Third",
faveColor: "#2763c4"
}
},
{
data: {
id: "Fourth",
faveColor: "#56a9f7"
}
}
],
edges: [{
data: {
source: "Top",
target: "yes"
}
},
{
data: {
source: "Top",
target: "no"
}
},
{
data: {
source: "no",
target: "Third"
}
},
{
data: {
source: "Third",
target: "Fourth"
}
},
{
data: {
source: "Fourth",
target: "Third"
}
}
]
},
layout: {
name: "dagre"
}
}));
cy.ready(function() {
console.log('Nodes:', cy.nodes().jsons());
console.log('Edges:', cy.edges().jsons());
console.log('Elements:', cy.elements().jsons());
});
document.getElementById('save').addEventListener('click', function() {
json = cy.json();
});
document.getElementById('load').addEventListener('click', function() {
cy.json(json);
});
body {
font: 14px helvetica neue, helvetica, arial, sans-serif;
}
#cy {
height: 85%;
width: 100%;
float: right;
position: absolute;
}
<html>
<head>
<meta charset=utf-8 />
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
<script src="https://unpkg.com/cytoscape#3.3.0/dist/cytoscape.min.js">
</script>
<!-- cyposcape dagre -->
<script src="https://unpkg.com/dagre#0.7.4/dist/dagre.js"></script>
<script src="https://cdn.rawgit.com/cytoscape/cytoscape.js-dagre/1.5.0/cytoscape-dagre.js"></script>
</head>
<body>
<b id="save" style="cursor: pointer; color: darksalmon">Save graph</b> / <b id="load" style="cursor: pointer; color: darkmagenta">Load graph</b>
<div id="cy"></div>
</body>
</html>
I first create a graph with 100's of connected nodes. After all the nodes have been added I call
cy.layout({name: "dagre"});
Next, I'm creating 5 or so additional connected nodes I call layout on the nodes added but it doesn't lay them out as expected. Instead of being more like a tree all the nodes are in a straight line.
It looks like this:
var collection = cy.collection();
collection.merge(eles);
...
// I merge in another 5 newly created nodes.
// Next I call layout
collection.layout({
name: "dagre", fit: false,
boundingBox: {
x1: mousex - width / 2, y1: mousey - height / 2, x2: mousex + width, y2: mousey + height
},
nodeSep: 30
}).run();
But I expect it to look like the image below.
In order to get it to look like the above, I call layout shown below.
cy.layout({name: "dagre"});
I've looked through all the options for a dagre layout and can't find anything to make it create the tree.
Edit: The dagre layout needs nodes and edges to calculate the right positions for the nodes, the way you use it, dagre thinks you give it 5 seperate nodes, which explains your wrong layout. The mistake lies here:
collection.merge(eles); // here you should add all relevant nodes and edges
End
I have an example for you --->here<---, just copy that and add your real data:
var cy = (window.cy = cytoscape({
container: document.getElementById("cy"),
boxSelectionEnabled: false,
autounselectify: true,
style: [
{
selector: "node",
css: {
content: "data(id)",
"text-valign": "center",
"text-halign": "center",
height: "60px",
width: "100px",
shape: "rectangle",
"background-color": "data(faveColor)"
}
},
{
selector: "edge",
css: {
"curve-style": "bezier",
"control-point-step-size": 40,
"target-arrow-shape": "triangle"
}
}
],
elements: {
nodes: [
{ data: { id: "Top", faveColor: "#2763c4" } },
{ data: { id: "yes", faveColor: "#37a32d" } },
{ data: { id: "no", faveColor: "#2763c4" } },
{ data: { id: "Third", faveColor: "#2763c4" } },
{ data: { id: "Fourth", faveColor: "#56a9f7" } }
],
edges: [
{ data: { source: "Top", target: "yes" } },
{ data: { source: "Top", target: "no" } },
{ data: { source: "no", target: "Third" } },
{ data: { source: "Third", target: "Fourth" } },
{ data: { source: "Fourth", target: "Third" } }
]
},
layout: {
name: "random"
}
}));
cy.ready(function () {
setTimeout(function () {
cy.nodes().layout({ name: 'dagre' }).run(); // this is what you do!!
setTimeout(function () {
cy.elements().layout({ name: 'dagre' }).run(); // this is what you should do!!
},5000);
}, 5000);
});
body {
font: 14px helvetica neue, helvetica, arial, sans-serif;
}
#cy {
height: 100%;
width: 100%;
left: 0;
top: 0;
float: left;
position: absolute;
}
<html>
<head>
<meta charset=utf-8 />
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
<script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.2.17/cytoscape.min.js">
</script>
<!-- cyposcape dagre -->
<script src="https://unpkg.com/dagre#0.7.4/dist/dagre.js"></script>
<script src="https://cdn.rawgit.com/cytoscape/cytoscape.js-dagre/1.5.0/cytoscape-dagre.js"></script>
</head>
<body>
<div id="cy"></div>
</body>
</html>