commenting force directed graph code

master
Matt Huntington 7 years ago
parent cf514fa0b7
commit 8d5aaf203e

@ -1,10 +1,12 @@
var WIDTH = 300; var WIDTH = 300;
var HEIGHT = 200; var HEIGHT = 200;
//set height/width of the svg
d3.select("svg") d3.select("svg")
.attr("width", WIDTH) .attr("width", WIDTH)
.attr("height", HEIGHT); .attr("height", HEIGHT);
//data for each person
var nodesData = [ var nodesData = [
{"name": "Charlie", "age": 12}, {"name": "Charlie", "age": 12},
{"name": "Mac", "age": 32}, {"name": "Mac", "age": 32},
@ -14,6 +16,7 @@ var nodesData = [
{"name": "Cricket", "age": 95} {"name": "Cricket", "age": 95}
]; ];
//data showing relationships between people
var linksData = [ var linksData = [
{"source": "Charlie", "target": "Mac"}, {"source": "Charlie", "target": "Mac"},
{"source": "Dennis", "target": "Mac"}, {"source": "Dennis", "target": "Mac"},
@ -23,32 +26,33 @@ var linksData = [
{"source": "Cricket", "target": "Dee"} {"source": "Cricket", "target": "Dee"}
]; ];
var nodes = d3.select("#nodes") var nodes = d3.select("#nodes") //select the #nodes <g>
.selectAll("circle") .selectAll("circle") //select all circles within it (even if none exist)
.data(nodesData) .data(nodesData) //attach data to this selection
.enter() .enter() //find all data elements not matched to circles
.append("circle"); .append("circle"); //append a circle for each unmatched data element
//repeat what you do for nodes, but with lines, the #links <g>, and the linksData array
var links = d3.select("#links") var links = d3.select("#links")
.selectAll("line") .selectAll("line")
.data(linksData) .data(linksData)
.enter() .enter()
.append("line"); .append("line");
d3.forceSimulation() d3.forceSimulation() //create a force simulation
.nodes(nodesData) // add this line .nodes(nodesData) //set the nodes for the simulation, based on the nodesData array
.force("center_force", d3.forceCenter(WIDTH / 2, HEIGHT / 2)) //create a centering force in the middle of the svg
d3.forceSimulation() .force("charge_force", d3.forceManyBody()) //create a charge force, so the nodes repel each other
.nodes(nodesData) .force("links", d3.forceLink(linksData).id(function(datum){ //create a links so the nodes aren't repelled too far from nodes they're linked to in the linkData array
.force("center_force", d3.forceCenter(WIDTH / 2, HEIGHT / 2)) // add this line return datum.name //create the links by associating each link's source/target with a name property from the nodesData array
.force("charge_force", d3.forceManyBody()) //add this line }).distance(160)) //set the distance of the link
.force("links", d3.forceLink(linksData).id(function(datum){ //add this .on("tick", function(){ //create a function that will be called with each "tick" of the simulation
return datum.name //add this //with each tick...
}).distance(160)) //add this //update the circle cx/cy values based on the x/y values d3 added to the nodes data
.on("tick", function(){
nodes.attr("cx", function(datum) { return datum.x; }) nodes.attr("cx", function(datum) { return datum.x; })
.attr("cy", function(datum) { return datum.y; }); .attr("cy", function(datum) { return datum.y; });
//update the line x1/y1/x2/y2 values based on the source/target x/y values d3 added to the links data
links.attr("x1", function(datum) { return datum.source.x; }) links.attr("x1", function(datum) { return datum.source.x; })
.attr("y1", function(datum) { return datum.source.y; }) .attr("y1", function(datum) { return datum.source.y; })
.attr("x2", function(datum) { return datum.target.x; }) .attr("x2", function(datum) { return datum.target.x; })

Loading…
Cancel
Save