D3NodeExamplesPinANode
A mixture of the best parts of the following D3 examples http://bl.ocks.org/mbostock/4062045 http://bl.ocks.org/mbostock/929623 http://bl.ocks.org/Caged/6476579
by Simon Raper
HTML
<script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
<script type="application/json" id="mis">
{
"nodes": [{
"name": "Myriel",
"group": 1
}, {
"name": "Napoleon",
"group": 1
}, {
"name": "Mlle.Baptistine",
"group": 1
}, {
"name": "Mme.Magloire",
"group": 1
}, {
"name": "CountessdeLo",
"group": 1
}, {
"name": "Geborand",
"group": 1
}, {
"name": "Champtercier",
"group": 1
}, {
"name": "Cravatte",
"group": 1
}, {
"name": "Count",
"group": 1
}, {
"name": "OldMan",
"group": 1
}, {
"name": "Labarre",
"group": 2
}, {
"name": "Valjean",
"group": 2
}, {
"name": "Marguerite",
"group": 3
}, {
"name": "Mme.deR",
"group": 2
}, {
"name": "Isabeau",
"group": 2
}, {
"name": "Gervais",
"group": 2
}, {
"name": "Tholomyes",
"group": 3
}, {
"name": "Listolier",
"group": 3
}, {
"name": "Fameuil",
"group": 3
}, {
"name": "Blacheville",
"group": 3
}, {
"name": "Favourite",
"group": 3
}, {
"name": "Dahlia",
"group": 3
}, {
"name": "Zephine",
"group": 3
}, {
"name": "Fantine",
"group": 3
}, {
"name": "Mme.Thenardier",
"group": 4
}, {
"name":...
CSS
.node {
stroke: #fff;
stroke-width: 1.5px;
}
.link {
stroke: #999;
stroke-opacity: .6;
}
.d3-tip {
line-height: 1;
color: #999;
}
.cursor {
fill: none;
stroke: brown;
pointer-events: none;
}
JavaScript
var width = 960,
height = 500;
var color = d3.scale.category20();
var force = d3.layout.force()
.charge(-120)
.linkDistance(30)
.size([width, height]);
//AddCode from http://bl.ocks.org/norrs/2883411
var node_drag = d3.behavior.drag()
.on("dragstart", dragstart)
.on("drag", dragmove)
.on("dragend", dragend);
function dragstart(d, i) {
force.stop() // stops the force auto positioning before you start dragging
}
function dragmove(d, i) {
d.px += d3.event.dx;
d.py += d3.event.dy;
d.x += d3.event.dx;
d.y += d3.event.dy;
}
function dragend(d, i) {
d.fixed = true; // of course set the node to fixed so the force doesn't include the node in its auto positioning stuff
force.resume();
}
//AddCode End
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var stuff = document.getElementById('mis').innerHTML;
graph = JSON.parse(stuff);
force.nodes(graph.nodes) //Creates the graph data structure out of the json data
.links(graph.links)
.start();
//Create all the line svgs but without locations yet <line class="link" style="stroke-width: 1px;"></line>
var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function (d) {
return Math.sqrt(d.value);
});
//Do the same with the circles for the nodes - no
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", 5)
.style("fill", function (d) {
return color(d.group);
})
.call(node_drag); //ChangeCode
//Now we are giving the SVGs co-ordinates - looks like the force layout is generating the co-ordinates which this code is using to up date the attributes of the SVG elements
force.on("tick", function () {
link.attr("x1", function (d) {
return d.source.x;
})
...