Cystoscape is out of canvas border - javascript

I'm traying to contain the objects inside of cytoscape canvas without moving outside of max width and height, but if i drag the objects inside of canvas , they go outside of canvas border:
Actually i'm not using the canvas from HTML5, instead im using the canvas from cytoscape.js plugin so this makes more complicated to fix it.
I already saw cystoscape documentation to see if there are any kind of option to make the borders fixed and make the content inside resposive,but didnt found anything.
I would like to kow if there any way to trick this.
my code test:
cystoscape box test
``
$(document).ready(function () {
// document.addEventListener('DOMContentLoaded', function() {
$('#cyto').attr("title", "try clicking and dragging around the canvas and nodes");
tippy('#cyto')
cy = cytoscape({
container: document.getElementById('cyto'),
style: cytoscape.stylesheet()
// style for the nodes
.selector('node')
.css({
'width': 70,
'height': 70,
'content': 'data(id)',
'text-align': 'center',
'color': '#506874',
'background-color': '#20b2aa',
'font-family': 'Oswald',
'shape': 'roundrectangle',
'font-size': 20
})
// style for the connecting lines
.selector('edge')
.css({
'width': .9,
'height': 0.2,
'curve-style': 'bezier',
'target-arrow-shape': 'triangle',
'target-arrow-color': '#F3A712',
'line-color': '#F3A712',
// 'line-color': '#C40E0E',
})
.selector(':selected')
.css({
'background-color': '#428bca',
'line-color': '#C40E0E',
'target-arrow-color': '#C40E0E',
'source-arrow-color': '#C40E0E'
})
.selector('.faded')
.css({
'opacity': 1,
'text-opacity': 0
}),
elements: [
{
group: 'nodes',
data: {
id: 'WORDS'
}
}, {
group: 'nodes',
data: {
id: 'REALITY'
}
},
{
group: 'nodes',
data: {
id: 'THE WORLD'
}
},
{
group: 'nodes',
data: {
id: 'PEOPLE'
}
},
{
group: 'nodes',
data: {
id: 'ME'
}
},
{
group: 'edges',
data: {
id: 'edge1',
source: 'PEOPLE',
target: 'WORDS'
}
},
{
group: 'edges',
data: {
id: 'edge2',
source: 'PEOPLE',
target: 'REALITY'
}
},
{
group: 'edges',
data: {
id: 'edge3',
source: 'ME',
target: 'WORDS'
}
},
{
group: 'edges',
data: {
id: 'edge4',
source: 'WORDS',
target: 'THE WORLD'
}
},
{
group: 'edges',
data: {
id: 'edge',
source: 'THE WORLD',
target: 'ME'
}
},
{
group: 'edges',
data: {
id: 'edge6',
source: 'PEOPLE',
target: 'THE WORLD'
}
},
{
group: 'edges',
data: {
id: 'edge7',
source: 'ME',
target: 'THE WORLD'
}
},
{
group: 'edges',
data: {
id: 'edge9',
source: 'WORDS',
target: 'REALITY'
}
},
{
group: 'edges',
data: {
id: 'edge5',
source: 'REALITY',
target: 'ME'
}
}
],
}); // end cytoscape
}, false);
``

Just like with any canvas object, you need to "listen" to the drag event and take action based on the position.
The code below is a push in the right direction, I'm just showing the position of the element as it is dragged, next you need to set your area boundaries and prevent the element from moving outside
tippy("#cyto");
cy = cytoscape({
container: document.getElementById("cyto"),
style: cytoscape
.stylesheet()
.selector("node")
.css({content: "data(id)"}),
elements: [
{data: { id: "WORDS" }},
{data: { id: "REALITY" }}
]
});
cy.on('drag', 'node', function (evt) {
var node = evt.target;
var point = node.point();
console.log(node.id() + " " + point.x + " " + point.y);
if (point.y < 10)
node.style({ 'background-color': 'red' });
else
node.style({ 'background-color': 'blue' });
});
.container {
display: grid;
border: 2px blue solid;
height: 160px;
width: 400px;
}
#cyto {
grid-row: 2/ span 1;
grid-column: 1/ span 6;
}
<script src="https://unpkg.com/tippy.js#2.0.8/dist/tippy.all.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.14.1/cytoscape.min.js"></script>
<div class="container">
<div id="cyto">
</div>
</div>
You could use the https://github.com/cytoscape/cytoscape.js-automove but I strongly recommend you to understand this clearly before you start using extensions

Related

js.cytoscape generating graph left to right

I am using js.cytoscape, and need to generate a graph from left to right.
when I use the layouts, it generate the chart from top to the bottom
code.js file is as follows
var cy = window.cy = cytoscape({
container: document.getElementById('cy'),
boxSelectionEnabled: false,
autounselectify: true,
layout: {
name: 'dagre'
},
style: [
{
selector: 'node',
style: {
'content': 'data(id)',
'text-opacity': 0.5,
'text-valign': 'center',
'text-halign': 'right',
'background-color': '#11479e'
}
},
{
selector: 'edge',
style: {
'curve-style': 'bezier',
'width': 4,
'target-arrow-shape': 'triangle',
'line-color': '#9dbaea',
'target-arrow-color': '#9dbaea'
}
}
],
elements: {
nodes: [
{ data: { id: 'n0' } , position: { x: 0, y: 0 } },
{ data: { id: 'n1' } , position: { x: 100, y: 0 } },
{ data: { id: 'n2' } , position: { x: 200, y: 0 } }
],
edges: [
{ data: { source: 'n0', target: 'n1' } },
{ data: { source: 'n1', target: 'n2' } },
]
},
});
When you set the layout to 'preset' the chat is generated from left to right with the given positions. But it is not possible to position all the nodes when it supposed to generate chart dynamically using user given data.
Please suggest a solution.
Thank you
As of cytoscape.js-dagre documentation, there's a layout option that can change the direction of your graph. Simply add to layout:
layout: {
name: 'dagre'
rankDir: 'LR', // 'TB' for top to bottom flow, 'LR' for left to right. default is undefined, making it plot top-bottom
},

How to select nodes by class in cytoscape.js?

CYTOSCAPE.JS
I can't manage to apply styles to a class defined in node-data (clLevel0). I wrote a function to work around the problem. So, the function also explains what i want to do, in a much simpler way that is ;-)
function setNodesClassStyles(cy, clas, styleobject)
{
var all = cy.nodes();
for (i = 0; i < all.length; i++) {
the_node = all[i];
all_classes = the_node.data().classes;
//alert(all_classes);
if (all_classes != undefined) {
all_classes = all_classes.split(' ');
for (i = 0; i < all_classes.length; i++) {
alert(all_classes[i]);
if (clas == all_classes[i]) {
the_node.style(styleobject)
}
}
}
}
};
setNodesClassStyles(cy, "clLevel0", {'background-color':'#00E'});
I tried this (not working):
{
selector: ".clLevel0",
style: {
'background-color': '#EAA',
}
},
What's the right way to apply styles on a node with a class 'clas'?
More code:
var cy = cytoscape({
container: document.getElementById('cy'), // container to render in
elements: [ // list of graph elements to start with
// LEVEL 0 NODE
{ // node
data: { id: 'me', name: 'Dirk\n#dickschrauwen', classes: 'clLevel0 clRoot', weight: 10000},
"position": {
"x": 600,
"y": 400 },
},
// LEVEL 1 NODES
{
data: { id: 'skills', name: 'Skills', }
},
{
data: { id: 'education', name: 'School' }
},
{
data: { id: 'work', name: 'Jobs\nProjects' }
},
{
data: { id: 'passion', name: 'Passions' }
},
// ....
style: [
{
selector: 'node',
style: {
'height': 40,
'width': 40,
//'height': 20,
//'width': 20,
'background-color': '#EE0',
// ....
{
selector: ".clLevel0",
style: {
'background-color': '#EAA',
}
},
],
//...
document.addEventListener("DOMContentLoaded", function() {
var cy = cytoscape({
container: document.getElementById('cy'),
elements: {
nodes: [
{ data: { id: 'n', label: 'Olo' } },
{ data: { id: 'c'}, classes: 'className'}
]}
});
cy.style.fromJson([
{
selector: 'node',
style: {
'color': 'red'
}
},{
selector: '.className',
style: {
'label': 'this has a class',
'color': 'blue'
}
}
])
});

Cytoscape.js - Circle layout

I'm trying to make this http://gcuculi.com/cda/imagens/grafico.png with Cytoscape.js. I'm using the circle layout, but it isn't working. I will add more items dynamically. The first node always be closer than the second and so on for the others.
Here is the code:
$(function(){
var cy = cytoscape({
container: document.getElementById('grafico-constelacao'),
style: cytoscape.stylesheet()
.selector('node')
.css({
'content': 'data(name)',
'text-valign' : 'center',
'color' : 'white',
})
.selector('edge')
.css({
'width': 2,
'line-color': '#000'
})
.selector('#p')
.css({
'background-color': '#fff',
'width': '60px',
'height': '60px',
'border-width': '2px',
'border-style': 'solid',
'border-color ': '#888',
}),
elements: {
nodes: [
{
data: {id: 'p', weight: 1 },
group: 'nodes',
position: {
x: 500,
y: 150
},
classes: 'principal',
selected: false,
selectable: false,
locked: true,
grabbable: false
},
{ data: { id: 'atr1', name : 'A'} },
{ data: { id: 'atr2', name : 'B' } },
{ data: { id: 'atr3', name : 'C' } },
{ data: { id: 'atr4', name : 'D' } },
{ data: { id: 'atr5', name : 'E' } }
],
edges: [
{ data: { id: 'p-atr1', weight: 1, source: 'p', target: 'atr1' } },
{ data: { id: 'p-atr2', weight: 10, source: 'p', target: 'atr2' } },
{ data: { id: 'p-atr3', weight: 50, source: 'p', target: 'atr3' } },
{ data: { id: 'p-atr4', weight: 100, source: 'p', target: 'atr4' } },
{ data: { id: 'p-atr5', weight: 250, source: 'p', target: 'atr5' } }
]
},
layout: {
name: 'circle',
fit: true,
padding: 30,
boundingBox: undefined,
avoidOverlap: true,
radius: undefined,
startAngle: 10 * Math.PI,
counterclockwise: true,
sort: undefined,
animate: false,
animationDuration: 500,
ready: undefined,
stop: undefined
},
// interaction options:
zoomingEnabled: false,
userZoomingEnabled: false,
panningEnabled: false,
userPanningEnabled: false,
boxSelectionEnabled: false,
selectionType: 'single',
touchTapThreshold: 8,
desktopTapThreshold: 4,
autolock: false,
autoungrabify: false,
autounselectify: false,
});
});
There is a way to control the size of the edges forcing a value?
Run the circle layout on the outside nodes only, specifying your radius as desired and the bounding box centred around the centre node. Run whatever layout you like on the other nodes after init, so you have initial positions to base the secondary layouts on.
http://js.cytoscape.org/#collection/layout

How to highlight the path between two nodes in CYTOSCAPE JS

i can create a graph using cytoscape js library . i am following the this tutorial and i implement like this.
CODE:
$(function(){ // on dom ready
$('#cy').cytoscape({
style: cytoscape.stylesheet()
.selector('node')
.css({
'content': 'data(id)'
})
.selector('edge')
.css({
'target-arrow-shape': 'triangle',
'width': 4,
'line-color': '#ddd',
'target-arrow-color': '#ddd'
})
.selector('.highlighted')
.css({
'background-color': '#61bffc',
'line-color': '#61bffc',
'target-arrow-color': '#61bffc',
'transition-property': 'background-color, line-color, target-arrow-color',
'transition-duration': '0.5s'
}),
elements: {
nodes: [
{ data: { id: 'a' } },
{ data: { id: 'b' } },
{ data: { id: 'c' } },
{ data: { id: 'd' } },
{ data: { id: 'e' } },
{ data: { id: 'f' } },
{ data: { id: 'g' } }
],
edges: [
{ data: { id: 'ab', weight: 1, source: 'a', target: 'b' } },
{ data: { id: 'ac', weight: 2, source: 'a', target: 'c' } },
{ data: { id: 'bd', weight: 3, source: 'b', target: 'd' } },
{ data: { id: 'be', weight: 4, source: 'b', target: 'e' } },
{ data: { id: 'cf', weight: 5, source: 'c', target: 'f' } },
{ data: { id: 'cg', weight: 6, source: 'c', target: 'g' } }
]
},
layout: {
name: 'breadthfirst',
directed: true,
roots: '#a',
padding: 5
},
ready: function(){
window.cy = this;
var bfs = cy.elements().bfs('#a', function(){}, true);
var i = 0;
var highlightNextEle = function(){
bfs.path[i].addClass('highlighted');
if( i < bfs.path.length ){
i++;
setTimeout(highlightNextEle, 1000);
}
};
// kick off first highlight
highlightNextEle();
}
});
}); // on dom ready
on my implementation i need to highlight the path between the nodes d and g.
How to find the path between the nodes and highlight them?
Using dijkstra algorithm method we can find the path between the nodes.
var dijkstra = cy.elements().dijkstra('#e',function(){
return this.data('weight');
},false);
var bfs = dijkstra.pathTo( cy.$('#i') );
Complete CODE :
$(function(){ // on dom ready
$('#cy').cytoscape({
style: cytoscape.stylesheet()
.selector('node')
.css({
'content': 'data(id)'
})
.selector('edge')
.css({
'target-arrow-shape': 'triangle',
'width': 4,
'line-color': '#ddd',
'target-arrow-color': '#ddd'
})
.selector('.highlighted')
.css({
'background-color': '#61bffc',
'line-color': '#61bffc',
'target-arrow-color': '#61bffc',
'transition-property': 'background-color, line-color, target-arrow-color',
'transition-duration': '0.5s'
}),
elements: {
nodes: [
{ data: { id: 'a' } },
{ data: { id: 'b' } },
{ data: { id: 'c' } },
{ data: { id: 'd' } },
{ data: { id: 'e' } },
{ data: { id: 'f' } },
{ data: { id: 'g' } },
{ data: { id: 'h' } },
{ data: { id: 'i' } }
],
edges: [
{ data: { id: 'ab', weight: 1, source: 'a', target: 'b' } },
{ data: { id: 'ac', weight: 2, source: 'a', target: 'c' } },
{ data: { id: 'bd', weight: 3, source: 'b', target: 'd' } },
{ data: { id: 'be', weight: 4, source: 'b', target: 'e' } },
{ data: { id: 'cf', weight: 5, source: 'c', target: 'f' } },
{ data: { id: 'cg', weight: 6, source: 'c', target: 'g' } },
{ data: { id: 'ah', weight: 7, source: 'a', target: 'h' } },
{ data: { id: 'hi', weight: 8, source: 'h', target: 'i' } }
]
},
layout: {
name: 'breadthfirst',
directed: true,
roots: '#a',
padding: 5
},
ready: function(){
window.cy = this;
var dijkstra = cy.elements().dijkstra('#e',function(){
return this.data('weight');
},false);
var bfs = dijkstra.pathTo( cy.$('#i') );
var x=0;
var highlightNextEle = function(){
var el=bfs[x];
el.addClass('highlighted');
if(x<bfs.length){
x++;
setTimeout(highlightNextEle, 500);
}
};
highlightNextEle();
}
});
}); // on dom ready
I you want to highlight all the possible paths
event.target- is the starting node
event.target.successors().animate({
style: { lineColor: 'red' }
});
Assuming you have picked two nodes and stored them in source_node and target_node, and you want to label everything in between with class 'path_element':
p = cy.elements().aStar({root: source_node, goal: target_node, directed: true}).path;
if (p) {
p.filter(function(i,x) { return x != source_node && x != target_node; })
.addClass('path_element');
p.edgesWith(p)
.addClass('path_element');
}

How to get cytoscape.js to work

I'm having problems getting a very simple cytoscape.js example to work at all. Here is my code in a pastebin link
I'm fairly new to Javascript in general, so this may be a very basic mistake. console.log statements put through the function calls indicate that the cy function is getting properly called and executed, and the browser console doesn't seem t throw any errors, however I cannot get the graph to show. Is there anything that I'm missing in my definition?
I tried to make it as minimalistic as possible. The code is only verbatim copied from some of the cytoscape.js examples. cy.cytoscape is the relevant function. Calling code is at the bottom
$('#cy').cytoscape({
.......
<body>
<div id="cy"></div>
</body>
edit: jsfiddle link
I have made some changes in your code.Now it is working fine.
Please look at the link below
CSS
body {
font: 14px helvetica neue, helvetica, arial, sans-serif;
}
#cy {
height: 100%;
width: 100%;
position: absolute;
left: 0;
top: 0;
}
JavaScript
$(function() { // on dom ready
$('#cy').cytoscape({
style: cytoscape.stylesheet()
.selector('node')
.css({
'content': 'data(name)',
'text-valign': 'center',
'color': 'white',
'text-outline-width': 2,
'text-outline-color': '#888'
})
.selector('edge')
.css({
'target-arrow-shape': 'triangle'
})
.selector(':selected')
.css({
'background-color': 'black',
'line-color': 'black',
'target-arrow-color': 'black',
'source-arrow-color': 'black'
})
.selector('.faded')
.css({
'opacity': 0.25,
'text-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'
}
}]
},
ready: function() {
window.cy = this;
// giddy up...
cy.elements().unselectify();
cy.on('tap', 'node', function(e) {
var node = e.cyTarget;
var neighborhood = node.neighborhood().add(node);
cy.elements().addClass('faded');
neighborhood.removeClass('faded');
});
cy.on('tap', function(e) {
if (e.cyTarget === cy) {
cy.elements().removeClass('faded');
}
});
}
});
}); // on dom ready
HTML
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="http://cytoscape.github.io/cytoscape.js/api/cytoscape.js-latest/cytoscape.min.js"></script>
<body>
<div id="cy"></div>
</body>

Categories