简体   繁体   中英

Replacing contents of HTML canvas with Springy force-directed graph

I have a nice force-directed graph using the Springy force-directed graph layout library. I've discovered that when I replace the graph with another via ajax (eg, after the user has changed some settings), both graphs occupy the same canvas.

What I'm looking for: I need to get rid of the old graph completely, so the new graph is the only one present in the canvas.

Here's a simplified usecase jsfiddle: http://jsfiddle.net/XPAqX/

// make a new graph
var graph = new Springy.Graph();

// make some nodes
var spruce = graph.newNode({label: 'Norway Spruce'});
var fir = graph.newNode({label: 'Sicilian Fir'});

// connect them with an edge
graph.newEdge(spruce, fir);


$('#my_canvas').springy({ graph: graph, nodeSelected: function(node) {
    alert(node.data.label);
} });

//now, I let the user update the dataset with ajax and re-render the graph. 

graph = null;
graph = new Springy.Graph();



// make some nodes
var kittens = graph.newNode({label: 'Furry Baby Cats'});
var puppies = graph.newNode({label: 'Fluffy Baby Dogs'});

// connect them with an edge
graph.newEdge(kittens,puppies);


$('#my_canvas').springy({ graph: graph });

Quick note: cross-posted as an issue on the springy github, no answers yet though: https://github.com/dhotson/springy/issues/47

The Springy Graph object is a little misleading. If you check out the sources you'll see it's just a access layer over the whole Springy context object (a signleton) that actually holds your nodes, so addNode does not add nodes to the Graph object but to a singleton Springy context object.

You'll have to use removeNode to remove the old nodes first, like I did here .

Just to make things clearer: Yes, Graph objects do contain lists of nodes, but those are passed to the renderer, and the renderer is a single instance for each canvas DOM node you 'springyfy'. Changing the Graph instance won't reset the renderer's internal context.

A more complicated solution would be to modify the SpringyUI (jQuery plugin) code and handle a $('#canvas').springy('reset') method that resets the internal renderer. Looking at the SpringyUI code I can say that won't be easy.

edit: (deleted all the wrong stuff of me)

to get a working solution:

add one of the following clear function to the springyui.js

this.clear = function(){
   for(var i=graph.nodes.length-1;i>=0;i--){
     graph.removeNode(graph.nodes[i]);
   }
}

or

this.clear = function(){
    graph.nodeSet = {};
    graph.nodes = [];
    graph.edges = [];
    graph.adjacency = {};
    graph.notify();
}

use it like this:

initial:

//don't call this twice!!
var graph = new Springy.Graph();
var springy=jQuery('#yourcanvas').springy({graph: graph});

workflow:

function makeGraph(){
    springy.clear();
    //generate your graph hear
    graph.addNodes(...)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM