I have a working graph which displays some nodes & their attributes. Then I get a JSON with different data, where some nodes may already exist on my graph. How to combine both data sources, to make them both visible on the same graph - BUT nodes with the same ID must be combined into one and contain attributes from both data sources (not just from one, as is by default)?
Example:
Node from source 1 => "id": "1", "name": "1", "param1": 100;
Node from source 2 => "id": "1", "name": "1", "param2": 200;
What I wish to see on the graph is one node with attributes:
"id": "1", "name": "1", "param1": 100, "param2": 200
I'm in the middle of writing code in my own application to do exactly what you're asking. The code below works, though I suspect that it's not the most efficient way. So, please don't accept this answer without waiting at least a few days for someone more experienced to post a better answer or to add a comment criticizing this answer.
The trick is to query cy
(the cytoscape.js core object) for a "collection object" containing just the node with the givenĀ id, and then query the collection object to see if it's empty. If the node doesn't exist, you cy.add()
it. If the node does exist, you call node.data()
on the collection object to update it.
function updateGraph(g) { // g is the output from JSON.parse(), containing graph from server
gg = g; // save pointer to g, for console debugging
// Import nodes from server graph
for (const sn of g.nodes) { // sn = node as represented on the server
var node = cy.$id(sn.id) // node = cytoscape.js's representation of node
if (node.empty()) {
node = cy.add({group: 'nodes', data: {
id: sn.id,
label: sn['display-name'], // peculiar to my application
parent: sn.memberOf // peculiar to my application
/* . . . and whatever other data you want to copy to the cytoscape.js graph . . . */
}});
node.addClass(sn.class);
} else {
/* Update `node` with data from `sn`.*/
node.data( /* your overriding data goes here */ );
}
}
}
var gg; // We save the last graph dict from the server here so we can look at
// it in the Chrome debugger even after updateGraph() returns.
The gg
variable isn't necessary, of course, but I've found it indispensible for seeing what's going on in the Chrome debugger.
In your application, you might be able to call Object.assign()
to merge the data before calling node.data()
. That would be simpler and more efficient than my code above, where data from the source has different keys than the keys expected by cytoscape.js.
I wrote a code, that make the button not disabled when you check at least one checkbox with class "sum". I want to change the code, so I have to classes for and you can check only one checkbox (or ...
I wrote a code, that make the button not disabled when you check at least one checkbox with class "sum". I want to change the code, so I have to classes for and you can check only one checkbox (or ...
I'm trying to use WebCola http://marvl.infotech.monash.edu/webcola/ but I can't find a link to the real documentation. The website seems to have only a few examples and some (apparently) auto-...
I'm trying to use WebCola http://marvl.infotech.monash.edu/webcola/ but I can't find a link to the real documentation. The website seems to have only a few examples and some (apparently) auto-...
I've created a simple JavaScript statement to open and close the nav side bar but it will only successfully open it and I'm confused as to why? if someone could explain it would be very helpful <...
I've created a simple JavaScript statement to open and close the nav side bar but it will only successfully open it and I'm confused as to why? if someone could explain it would be very helpful <...
I am using ember-notify ember-notify in my ember-cli project. import { Component, inject } from 'ember'; export default Component.extend({ notify: inject.service('notify'), actions: { ...
I am using ember-notify ember-notify in my ember-cli project. import { Component, inject } from 'ember'; export default Component.extend({ notify: inject.service('notify'), actions: { ...