Skip to content

Instantly share code, notes, and snippets.

@Bestra
Forked from mbostock/.block
Last active December 17, 2015 01:30
Show Gist options
  • Save Bestra/5529239 to your computer and use it in GitHub Desktop.
Save Bestra/5529239 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.node {
stroke: #fff;
stroke-width: 1.5px;
}
.node text {
font: 10px sans-serif;
pointer-events: none;
stroke: none;
}
.smallNode {
stroke: #fff;
stroke-width: 1.5px;
}
.sibLink {
fill: none;
stroke: #bbb;
}
.biLink {
fill: none;
stroke: #bbb;
}
</style>
<body>
<script src="http://d3js.org/d3.v2.min.js?2.10.0"></script>
<script>
var graph = {
nodes: d3.range(7).map(Object),
links: [
{source: 0, target: 1, type: 'child'},
{source: 0, target: 2, type: 'child'},
{source: 2, target: 4, type: 'child'},
{source: 2, target: 5, type: 'child'},
{source: 4, target: 5, type: 'sibling'},
{source: 0, target: 3, type: 'child'},
{source: 2, target: 3, type: 'sibling'},
{source: 1, target: 2, type: 'sibling'},
{source: 3, target: 6, type: 'child'},
]
};
var width = 960,
height = 500;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("weight", height);
var nodes = graph.nodes.slice(),
links = [],
bilinks = [];
graph.links.forEach(function(link) {
var s = nodes[link.source],
t = nodes[link.target];
if (link.type === 'child') {
var i = {}; // intermediate node
nodes.push(i);
links.push({source: s, target: i, type: link.type},
{source: i, target: t, type: link.type});
bilinks.push([s, i, t]);
} else {
links.push({source: s, target: t, type: link.type});
}
});
function linkDist(o, i) {
if(o.type === 'sibling') {return 60;}
else return 30;
}
var color = d3.scale.category10();
var force = d3.layout.force()
.nodes(nodes)
.links(links)
.size([width, height])
.charge(-200)
.gravity(0)
.alpha(.05)
.linkDistance(linkDist)
.linkStrength(3)
.on("tick", tick);
var topNode = force.nodes()[0];
topNode.fixed = true
topNode.x = 480;
topNode.y = 50;
force.start();
function adjustSiblingNodes(node1, node2, alpha) {
var force = (node1.y - node2.y) * .15;
if (node1.index == 2) console.log(node1.index + ":" + node2.index + ":" + force);
node1.y -= force;
node2.y += force;
}
var biLink = svg.selectAll(".biLink")
.data(bilinks)
.enter().append("path")
.attr("class", "biLink");
var sibLink = svg.selectAll('.sibLink')
.data(links.filter(function(e) { return e.type === 'sibling'; }))
.enter().append('line')
.attr('class', 'sibLink');
var rectWidth = 20;
var rectHeight = 20;
var rectRadius = 5;
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("g")
.attr("class", "node")
node.append("svg:rect")
.style("fill", function(d, i) { return color(i); })
.attr("rx", rectRadius)
.attr("ry", rectRadius)
.attr('width', rectWidth)
.attr('height', rectHeight);
node.append("text")
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text(function(d) { return d.index; })
.style('fill', 'black');
var biNode = svg.selectAll('.smallNode')
.data(nodes)
.enter().append('circle')
.attr('class','smallNode')
.style("fill", function(d, i) { return color(i); })
.attr('r', 5);
function tick(e) {
biLink.attr("d", function(d) {
return "M" + d[0].x + "," + d[0].y
+ "S" + d[1].x + "," + d[1].y
+ " " + d[2].x + "," + d[2].y;
});
sibLink.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; });
nodes.forEach(function(o, i) {
if (!o.fixed) {
o.y += 10 * e.alpha;
}
});
links.forEach(function(d) {
if (d.type === 'sibling') {
adjustSiblingNodes(d.source, d.target, e.alpha);
}
});
biNode.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
node.attr("transform", function(d) { return "translate(" + (d.x - rectWidth/2) + "," + (d.y - rectHeight/2) + ")"; });
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment