I have a parent node with two children ( and multiple grandchildren ). How do I select just the children of given node ( but not the node itself )?
The other functions edgesWith and edgesTo link two collections together, I just want the children of a node.
I've tried this unsuccessfully
$('#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' } }
]
},
ready: function(){
window.cy = this;
// Elaine, Kramer, George should be blue!
cy.elements('node[id="j"] node').css({'background-color': 'blue'});
}
});
Change your ready function to the following:
ready: function() {
window.cy = this;
var edgesFromJerry = cy.elements('edge[source="j"]');
var jerryChildren = edgesFromJerry.target();
jerryChildren.css('background-color', 'blue');
}
Slight changes from Matthew Burke's answer which selects all children instead of one child.
ready: function() {
window.cy = this;
var edgesFromJerry = cy.edges('edge[source="j"]');
var jerryChildren = edgesFromJerry.targets();
jerryChildren.css('background-color', 'blue');
}
Posting as answer instead of comment as answers in comments tend to be a hard find
Related
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>
I want to draw a simple graph with Nodes and Links between Nodes. The thing is that I want the thickness of the Links to be set depending on a variable, so I cannot pre-determine a CSS class for that.
The code is from the example http://js.cytoscape.org/demos/dagre-layout/
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' } },
{ data: { id: 'n1' } },
{ data: { id: 'n2' } }
],
edges: [
{ data: { source: 'n0', target: 'n1' } },
{ data: { source: 'n1', target: 'n2' } },
]
},
});
How to add this kind of feature to the { data } ?
You can always reference the data of the edges like this:
// Initialize cytoscape
cy = window.cy = cytoscape({
container: $('.cy'),
boxSelectionEnabled: false,
autounselectify: true,
layout: {
name: 'yourLayout'
},
style: [
{
selector: 'node',
style: {
'shape': 'data(faveShape)',
'content': 'data(DisplayName)',
'height': 'data(faveHeight)',
'width': 'data(faveWidth)',
'background-color': 'data(faveColor)',
'line-color': '#a8eae5',
'font-family': 'Segoe UI,Helvetica Neue,Helvetica,Arial,Verdana',
'font-size': '15px',
}
},
{
selector: 'edge',
style: {
'curve-style': 'bezier',
'width': data(myWidth),
'target-arrow-shape': 'triangle',
'line-color': '#9dbaea',
'target-arrow-color': '#9dbaea'
}
}
],
});
When you defined the style of your nodes, you used data(id) as the nodes name, so when you want to define the style of your edges, you can always get the data of the edges for their style by using the same method data(whateverYouWantToGet).
When you define the edge, you can do it like this maybe:
var x = 0; // This is your variable, alter it like you want
var i = 0;
cy.add({
data: {
id: ('edge' + (i)),
source: n0, // first node for example
target: n1,
myWidth: x
},
position: {},
group: 'edges',
removed: false,
selected: false,
selectable: true,
locked: false,
grabbed: false,
grabbable: true,
classes: 'autorotate'
});
Is it possible to obtain a circular hierarchy in Cytoscape js?
The breadthfirst layout gives a generic hierarchy layout, if somehow nodes could be arranged in a circrular hierarchy (with roots being in the center...), please do let me know the way out.
Thanks
Have you tried the concentric options for the breadth-first layout? By default breadth-first gives a pyramid-like layout but you can specify a circular layout.
For example:
var cy = cytoscape({
container: document.getElementById('cy'),
elements: {
nodes: [
{ data: { id: 'a' } },
{ data: { id: 'b' } },
{ data: { id: 'c' } },
{ data: { id: 'd' } },
{ data: { id: 'e' } }
],
edges: [
{ data: { id: 'ae', weight: 1, source: 'a', target: 'e' } },
{ data: { id: 'ab', weight: 3, source: 'a', target: 'b' } },
{ data: { id: 'be', weight: 4, source: 'b', target: 'e' } },
{ data: { id: 'bc', weight: 5, source: 'b', target: 'c' } },
{ data: { id: 'ce', weight: 6, source: 'c', target: 'e' } },
{ data: { id: 'cd', weight: 2, source: 'c', target: 'd' } },
{ data: { id: 'de', weight: 7, source: 'd', target: 'e' } }
]
},
layout: {
name: 'breadthfirst',
circle: true,
root: 'a',
},
});
See https://jsfiddle.net/josephst18/kznos1x9/2/ for the rest of my code.
I am exploring the potential of Cytoscape.js, and would like to know if it is possible to visualize connections from compound nodes (parents) to children within this node.
In the example below I would like to show the connection between the parent node 'b' and the children 'a' and 'c', but so far I am unsuccessful.
Minimal working example is given below below, and editable here: http://jsbin.com/lelinaduko/3/edit
elements: {
nodes: [
{ data: { id: 'a', parent: 'b' } },
{ data: { id: 'c', parent: 'b' } },
{ data: { id: 'd' } },
{ data: { id: 'e' } },
{ data: { id: 'f', parent: 'e' } },
{ data: { id: 'b' } }
],
edges: [
{ data: { id: 'bd', source: 'b', target: 'd' } },
{ data: { id: 'eb', source: 'e', target: 'b' } },
{ data: { id: 'ca', source: 'c', target: 'a' } },
{ data: { id: 'ab', source: 'a', target: 'b' } },
{ data: { id: 'bc', source: 'b', target: 'c' } }
]
},
<!DOCTYPE html>
<!--
Created using JS Bin
http://jsbin.com
Copyright (c) 2015 by anonymous (http://jsbin.com/lelinaduko/3/edit)
Released under the MIT license: http://jsbin.mit-license.org
-->
<meta name="robots" content="noindex">
<html>
<head>
<link href="style.css" rel="stylesheet" />
<meta charset=utf-8 />
<title>Cytoscape.js initialisation</title>
<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>
<script src="code.js"></script>
<style id="jsbin-css">
body {
font: 14px helvetica neue, helvetica, arial, sans-serif;
}
#cy {
height: 100%;
width: 100%;
position: absolute;
left: 0;
top: 0;
}
#info {
color: #c88;
font-size: 1em;
position: absolute;
z-index: -1;
left: 1em;
top: 1em;
}
</style>
</head>
<body>
<div id="cy"></div>
<script id="jsbin-javascript">
$(function(){ // on dom ready
var cy = cytoscape({
container: $('#cy')[0],
style: cytoscape.stylesheet()
.selector('node')
.css({
'content': 'data(id)',
'text-valign': 'center',
'text-halign': 'center',
'color': 'black'
})
.selector('$node > node')
.css({
'content': 'data(id)',
'text-valign': 'top',
'text-halign': 'center',
'color': 'blue'
})
.selector('edge')
.css({
'target-arrow-shape': 'triangle',
'target-arrow-color': 'black',
'source-arrow-color': 'black',
'line-color': 'red',
'line-style': 'dashed',
'text-valign': 'top',
'text-halign': 'center',
'content': 'data(id)'
})
.selector(':selected')
.css({
'background-color': '',
'line-color': 'black',
'target-arrow-color': 'black',
'source-arrow-color': 'black'
}),
elements: {
nodes: [
{ data: { id: 'a', parent: 'b' } },
{ data: { id: 'c', parent: 'b' } },
{ data: { id: 'd' } },
{ data: { id: 'e' } },
{ data: { id: 'f', parent: 'e' } },
{ data: { id: 'b' } }
],
edges: [
{ data: { id: 'bd', source: 'b', target: 'd' } },
{ data: { id: 'eb', source: 'e', target: 'b' } },
{ data: { id: 'ca', source: 'c', target: 'a' } },
{ data: { id: 'ab', source: 'a', target: 'b' } },
{ data: { id: 'bc', source: 'b', target: 'c' } }
]
},
layout: {
name: 'breadthfirst',
directed: false,
avoidOverlap: true,
padding: 5
}
});
}); // on dom ready
</script>
</body>
</html>
It seems you found a bug:
https://github.com/cytoscape/cytoscape.js/issues/866
Use haystack edges instead if you want to work around the issue until a new release -- as those edges are unaffected.
I used the following script for using the bfs function.
$(loadCy = function(){
options = {
showOverlay: false,
minZoom: 0.5,
maxZoom: 2,
style: cytoscape.stylesheet()
.selector('node')
.css({
'content': 'data(name)',
'font-family': 'helvetica',
'font-size': 24,
'text-outline-width': 3,
'text-outline-color': '#888',
'text-valign': 'center',
'color': '#fff',
'width': 'mapData(weight, 30, 80, 20, 50)',
'height': 'mapData(height, 0, 200, 10, 45)',
'border-color': '#fff'
})
.selector(':selected')
.css({
'background-color': '#000',
'line-color': '#000',
'target-arrow-color': '#000',
'text-outline-color': '#000'
})
.selector('edge')
.css({
'width': 2,
'target-arrow-shape': 'triangle'
})
,
elements: {
nodes: [
{
data: { id: 'j', name: 'Jerry', weight: 65, height: 174 }
},
{
data: { id: 'e', name: 'Elaine', weight: 48, height: 160 }
},
{
data: { id: 'k', name: 'Kramer', weight: 75, height: 185 }
},
{
data: { id: 'g', name: 'George', weight: 70, height: 150 }
}
,
{
data: { id: 'h', name: 'Hag', weight: 70, height: 150 }
}
,
{
data: { id: 'i', name: 'Iam', weight: 70, height: 150 }
}
],
edges: [
{ data: { source: 'j', target: 'e' } },
{ data: { source: 'j', target: 'k' } },
{ data: { source: 'e', target: 'j' } },
{ data: { source: 'e', target: 'k' } },
{ data: { source: 'e', target: 'g' } },
{ data: { source: 'k', target: 'j' } },
{ data: { source: 'k', target: 'e' } },
{ data: { source: 'k', target: 'g' } },
{ data: { source: 'h', target: 'g' } },
{ data: { source: 'j', target: 'h' } },
{ data: { source: 'g', target: 'i' } }
],
},
ready: function(){
cy = this;
cy.$('#j').bfs(function(i, depth){
console.log('visits ' + this.id()+depth);
}, false);
}
};
$('#cy').cytoscape(options);
});
Output on console
visits j0
visits h1
visits g2
visits i3
visits k1
visits e1
But expected output should be something like
visits j0
visits h1
visits k1
visits e1
visits g2
visits i3
Am i missing something ?
You've found a bug. That particular one has been fixed in the 2.2 branch for the soon upcoming 2.2 release. That branch also has better unit tests (incl. for bfs). You can wait until 2.2 is released, or you can gulp build on the branch to get a snapshot build now.