##simple d3.js graph ###add nodes with a click.
(cheers to mike bostock!)
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <title>Simple d3.js graph</title> | |
| <meta charset="utf-8"> | |
| <style> | |
| .link { | |
| stroke: #000; | |
| stroke-width: 1.5px; | |
| } | |
| .node { | |
| fill: #000; | |
| stroke: #fa0; | |
| stroke-width: 1.5px; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <script src="http://d3js.org/d3.v3.js"></script> | |
| <script> | |
| //need to implement callbacks etc for json node loading... | |
| var getRemoteNode = function(id){ | |
| var newnode = {"id":id}; | |
| return newnode; | |
| } | |
| //expand node | |
| var nodeclick = function(d){ | |
| if (d.fill == null) | |
| d.fill = "red"; | |
| else if (d.fill == "red") | |
| d.fill = "blue"; | |
| else if (d.fill == "blue") | |
| d.fill = "green"; | |
| //add a new node+link | |
| var newnode = getRemoteNode(Math.random()*100); | |
| nodes.push(newnode); | |
| links.push({"source":d,"target":newnode}); | |
| restart(); | |
| } | |
| //update vis | |
| var tick = function(){ | |
| node.attr("cx", function(d) { return d.x; }) | |
| .attr("cy", function(d) { return d.y; }); | |
| link.attr("x1", function(d) { return d.source.x; }) | |
| .attr("y1", function(d) { return d.source.y; }) | |
| .attr("x2", function(d) { return d.target.x; }) | |
| .attr("y2", function(d) { return d.target.y; }); | |
| } | |
| //data changed? restart sim. | |
| function restart() { | |
| link = link.data(links); | |
| //new links | |
| link.enter().insert("line", ".node") | |
| .attr("class", "link"); | |
| link.exit().remove(); | |
| //update nodes | |
| node = node.data(nodes).attr("style",function(d){console.log(d);return "fill:"+d.fill;}); | |
| //new nodes | |
| node.enter().insert("circle", ".cursor") | |
| .attr("class", "node") | |
| .attr("r", 10) | |
| .on("click",nodeclick) | |
| .call(force.drag); | |
| //nodes that no longer exist | |
| node.exit().remove(); | |
| force.start(); | |
| } | |
| //====================================================== | |
| //create a svg | |
| var width = 800, height = 400; | |
| var svg = d3.select("body").append("svg") | |
| .attr("width", width) | |
| .attr("height", height); | |
| //create a single start node and no links | |
| var nodes = [{"id":"startnode"}]; | |
| var links = []; | |
| //make a force layout | |
| var force = d3.layout.force() | |
| .nodes(nodes) | |
| .links(links) | |
| .size([width, height]) | |
| .linkDistance(40) | |
| .charge(-60) | |
| .on("tick", tick); | |
| //add the nodeholder | |
| var node = svg.selectAll(".node").data(nodes); | |
| //create linkholder | |
| var link = svg.selectAll(".link").data(links); | |
| //start sim | |
| restart(); | |
| </script> | |
| </body> | |
| </html> |