I am using cytoscape.js for one of my usecases. Here, I prefer to display the graph with only nodes in the beginning as shown below.
var cy1 = cytoscape({
container: document.getElementById('cy'),
elements: {
nodes: countriesJSON
},
style: [
{
selector: 'node',
style: {
'background-color': '#666',
'label': 'data(id)'
}
},
{
selector: 'edge',
style: {
'width': 1,
'line-color': '#aaa',
}
}
]
});
cy1.layout({
name: 'circle'
});
Now, inside a function, I will form the edges as like this
function myfunc(){
...
...
allRoutes.map(function(d){
var inner={};
var obj = {}
inner["id"]="edge"+index
inner["source"]=data[0]
inner["target"]=data[1]
obj["data"]=inner
allLegsJSON[i]=obj;
i++;
})
...
...
cy1.elements({ edges: allLegsJSON });
}
Once edges are created, I want to assign edges to the graph as above. However, this code is not working. Can someone tell me how to do this? I wish to assign the edges and then update the cy1 graph.
This did this
cy1.add({ edges: allLegsJSON });
Related
I am using Cytoscape.js and the context menus extension within a React app through react-cytoscape.js. Right now, I can dynamically add nodes through an onClickFunction as a menu item. I would like to get the current state of the graph - that is, all the nodes that have been added as well as the ones it started with.
How can I do this? So far, I've tried cy.json(), but that only returns the initial state of the graph.
Below is all of my cytoscape code.
class MyApp extends React.Component {
constructor(props){
super(props);
}
render(){
const elements = [ // Nodes and edges to be added initially
{ data: { id: 'one', label: 'Node 1' }, position: { x: 250, y: 250 } },
{ data: { id: 'two', label: 'Node 2' }, position: { x: 300, y: 250 } },
{ data: { source: 'one', target: 'two', label: 'Edge from Node1 to Node2' } }
];
return <CytoscapeComponent
cy = {cy => { // Extensions and their options
cy.contextMenus({
menuItems: [
{ // Adds the ability to add nodes from the right-click menu
id: 'add-node',
content: 'add node',
tooltipText: 'add node',
image: {src: "./node_modules/cytoscape-context-menus/assets/add.svg", width: 12, height: 12, x: 6, y: 4},
coreAsWell: true,
// When we move adding nodes to a sidebar, probably use this as reference
onClickFunction: function (event) {
var data = {
group: 'nodes'
};
var pos = event.position || event.cyPosition;
cy.add({
data: data,
position: {
x: pos.x,
y: pos.y
}
});
}
}
]
})
}}
elements={elements}
style={ { width: '100%', height: '40vmax'} } />;
}
}
I use cytoscape js automove extention, I can move two node together:
cy.automove({
nodesMatching: cy.$('#a'),
reposition: 'drag',
dragWith: cy.$('#b')
});
But I must specify the node #a and #b, now I need whenever I move any node, its neighborhood move together, not a special node.
So I try this:
<style>
#cy{
width:600px;
height:800px
}
</style>
<script src="cytoscape.js"></script>
<script src="cytoscape-automove.js"></script>
<div id="cy"></div>
<script>
var cy = cytoscape({
container: document.getElementById('cy'), // container to render in
elements: [ // list of graph elements to start with
{ // node a
data: { id: 'a' }
},
{ // node b
data: { id: 'b' }
},
{ // node c
data: { id: 'c' }
},
{ // node d
data: { id: 'd' }
},
{ // edge ab
data: { id: 'ab', source: 'a', target: 'b' }
},
{ // edge cd
data: { id: 'cd', source: 'c', target: 'd' }
}
],
style: [ // the stylesheet for the graph
{
selector: 'node',
style: {
'background-color': '#566',
'label': 'data(id)'
}
},
{
selector: 'edge',
style: {
'width': 3,
'line-color': '#ccc',
'target-arrow-color': '#bcc',
'target-arrow-shape': 'triangle'
}
}
],
layout: {
name: 'grid',
rows: 1
},
boxSelectionEnabled:true,
panningEnabled: true,
selectionType:"additive"
});
cy.on("drag",function(evt){
var node=evt.target;
cy.automove({
nodesMatching: node.neighbourhood().nodes(),
reposition: 'drag',
dragWith: node
});
});
</script>
The result is once I move node #a, node #b will not move together.But I move the node #a again, #b is moved but the position is wrong, it is too far.
So does the dragWith must be a special one? What if I want to move any one?
How about this:
var i = 0;
cy.unbind("tapdrag");
cy.unbind("tapend");
cy.bind("tapdrag", "node", function(evt){
if (i = 0) {
i = 1;
var node = evt.target;
var target = cy.edges("[source = '" + node.id() + "']").target();
cy.automove({
nodesMatching: target,
reposition: 'drag',
dragWith: node
});
}
});
cy.bind("tapend", "node", function(evt) {
i = 0;
});
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'
});
Started exploring cytoscape.js since last one week. Its simply amazing. I am using cytoscape.js for one of my usecases wherein i need to show a graph of flight network. Here, I would like to show a small pop-up on clicking an airport (node) that contains few statistics such as degree, pagerank etc. Any pointer will help. For your reference, here is the code I wrote. I could see the graph exactly how I wanted. But what I am missing is the piece of code that can display a pop up on clicking the nodes. Thanks in advance for your help
<script>
var cy1 = cytoscape({
container: document.getElementById('cy1'),
layout: {
name: 'concentric',
concentric: function( node ){
return node.degree();
},
levelWidth: function( nodes ){
return 15;
}
},
style: [ // the stylesheet for the graph
{
selector: 'node',
style: {
'background-color': '#666',
'label': 'data(id)'
}
},
{
selector: 'edge',
style: {
'width': 1,
'line-color': '#ccc',
'target-arrow-color': '#ccc',
'target-arrow-shape': 'triangle'
}
}
],
elements: {
nodes: airportsJSON,
edges: edgeJSON
}
});
var pr = cy1.elements().pageRank();
console.log("Statistics*****");
for(i = 0; i<cy1.nodes().length; i++)
{
console.log(cy1.nodes()[i].data('id') + "->"+cy1.nodes()[i].indegree(true) + " "+cy1.nodes()[i].outdegree(true) + " "+cy1.nodes()[i].totalDegree(true));
}
console.log("done");
</script>
Try the qtip extension: https://github.com/cytoscape/cytoscape.js-qtip
It lets you show tooltips/popups on elements.
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