Skip to content

Instantly share code, notes, and snippets.

@guy4261
Forked from mbostock/.block
Last active December 21, 2015 03:08
Show Gist options
  • Save guy4261/6239752 to your computer and use it in GitHub Desktop.
Save guy4261/6239752 to your computer and use it in GitHub Desktop.

On mouseover, mark the node you're hovering over, and color its neighbours according to the type of the relationship. This style is only an example and anything goes - from adding icons, respecting asymmetric links (i.e. different markup of employee or manager in an unmutual hierarchy link) and the list goes on.

Not relying on markers etc gives a lot of visual relief.

Based on Mike Bostock's molecule example from: http://bl.ocks.org/mbostock/3037015

<!DOCTYPE html>
<html>
<head></head>
<body>
<meta charset="utf-8">
<style>
.link line {
stroke: #696969;
}
.link line.separator {
stroke: #fff;
stroke-width: 2px;
}
.node circle {
stroke: #000;
stroke-width: 1.5px;
}
.node text {
font: 10px sans-serif;
pointer-events: none;
}
circle.active{
fill: "red";
}
</style>
<body>
<script src="http://d3js.org/d3.v2.min.js?2.9.6"></script>
<script>
var q;
var width = 960,
height = 500;
var color = d3.scale.category20();
var radius = d3.scale.sqrt()
.range([0, 6]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var force = d3.layout.force()
.size([width, height])
.charge(-400)
.linkDistance(function(d) { return radius(d.source.size) + radius(d.target.size) + 20; });
var graph = {
"nodes": [
{"index":0, "atom": "C", "size": 12},
{"index":1, "atom": "C", "size": 12},
{"index":2, "atom": "C", "size": 12},
{"index":3, "atom": "N", "size": 14},
{"index":4, "atom": "H", "size": 1},
{"index":5, "atom": "O", "size": 16},
{"index":6, "atom": "O", "size": 16},
{"index":7, "atom": "H", "size": 1},
{"index":8, "atom": "H", "size": 1},
{"index":9, "atom": "H", "size": 1},
{"index":10, "atom": "H", "size": 1},
{"index":11, "atom": "H", "size": 1},
{"index":12, "atom": "H", "size": 1}
],
"links": [
{"source": 0, "target": 1, "bond": 1, "type":"work"},
{"source": 1, "target": 2, "bond": 1, "type":"work"},
{"source": 1, "target": 3, "bond": 1, "type":"hierarcy"},
{"source": 2, "target": 5, "bond": 2, "type":"work"},
{"source": 2, "target": 6, "bond": 1, "type":"work"},
{"source": 1, "target": 4, "bond": 1, "type":"hierarcy"},
{"source": 3, "target": 10, "bond": 1, "type":"work"},
{"source": 3, "target": 11, "bond": 1, "type":"work"},
{"source": 0, "target": 7, "bond": 1, "type":"hierarcy"},
{"source": 0, "target": 8, "bond": 1, "type":"work"},
{"source": 0, "target": 9, "bond": 1, "type":"work"},
{"source": 5, "target": 12, "bond": 1, "type":"work"}
]
};
var neighbours = {};
d3.range(graph.nodes.length).forEach(function(i){neighbours[i] = {};});
graph.links.forEach(function(l){
neighbours[l.source][l.target] = l.type;
neighbours[l.target][l.source] = l.type;
});
force
.nodes(graph.nodes)
.links(graph.links)
.on("tick", tick)
.start();
var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("g")
.attr("class", "link");
link.append("line")
.style("stroke-width", function(d) { return (d.bond * 2 - 1) * 2 + "px"; });
link.filter(function(d) { return d.bond > 1; }).append("line")
.attr("class", "separator");
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("g")
.attr("class", "node")
.call(force.drag);
node.append("circle")
.attr("r", function(d) { return radius(d.size); })
.attr("index",function(d) { return d.index;})
.style("fill", "white")
.on("mouseover", function (d) {
d3.selectAll("circle").each(function(e){
var eindex = parseInt(this.attributes["index"].value);
if (d.index === eindex){
this.style["stroke"] = "orange";
this.style["stroke-width"] = 5;
}
else if (e.index in neighbours[d.index]){
switch(neighbours[d.index][e.index]){
case "work" : {
this.style["stroke"] = "lightblue";
this.style["stroke-width"] = 3;
};break;
case "hierarcy" : {
this.style["stroke"] = "red"
this.style["stroke-width"] = 3;
}; break;
}
} else {
this.style["stroke"] = "black";
}
});
})
.on("mouseout", function () {
d3.selectAll("circle").each(function(e){
this.style["stroke"] = "black";
this.style["stroke-width"] = 1;
})
});
node.append("text")
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text(function(d) { return d.index; });
function tick() {
link.selectAll("line")
.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; });
node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
};
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment