Skip to content

Instantly share code, notes, and snippets.

@robjens
Forked from mbostock/.block
Last active August 29, 2015 14:19
Show Gist options
  • Save robjens/7ec191b3367b05b23cd5 to your computer and use it in GitHub Desktop.
Save robjens/7ec191b3367b05b23cd5 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.link {
fill: none;
stroke: #aaa;
}
.node text {
font: 10px sans-serif;
}
.node circle {
stroke: #fff;
stroke-width: 1.5px;
}
.node.active {
fill: red;
}
</style>
<body>
<script src="http://d3js.org/d3.v2.js?2.9.6"></script>
<script>
var margin = {top: 40, right: 40, bottom: 40, left: 80},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var tree = d3.layout.tree()
.size([height, width]);
var diagonal = d3.svg.diagonal()
.projection(function(d) { return [d.y, d.x]; });
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.json("species.json", function(root) {
var nodes = tree.nodes(root),
links = tree.links(nodes);
// Create the link lines.
svg.selectAll(".link")
.data(links)
.enter().append("path")
.attr("class", "link")
.attr("d", diagonal);
// Create the node circles.
var node = svg.selectAll(".node")
.data(nodes)
.enter().append("g")
.attr("class", function(d) { return "node " + d.type; })
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
.on("mouseover", function(d) { highlight(d.type); })
.on("mouseout", function(d) { highlight(null); });
node.append("circle")
.attr("r", 4.5);
node.append("text")
.attr("x", -6)
.attr("dy", ".35em")
.attr("text-anchor", "end")
.text(function(d) { return d.name; });
});
function highlight(type) {
if (type == null) d3.selectAll(".node").classed("active", false);
else d3.selectAll(".node." + type).classed("active", true);
}
</script>

README

This is a simple example of using CSS class names to support cross-linking between tree elements. Each element in the tree has an associated type field in the data, indicating whether the species is wild or domesticated. (This is bogus data, of course, and only for demonstration purposes.) When you mouseover one of the leaf nodes, other nodes of the same type will highlight.

The coordination happens in two places. First, the G elements for the nodes have a computed class attribute:

Next, register a mouseover and mouseout handler for interaction:

Finally, the highlight function selects nodes by class and toggles an active class which overrides the fill color.

function highlight(type) { if (type == null) d3.selectAll(".node").classed("active", false); else d3.selectAll(".node." + type).classed("active", true); }

The active class is defined as:

node.active {
  fill: red;
}

For more details on how to select related nodes, see my answer to how do you select (and then modify) related elements?

{
"name": "Carnivora",
"children": [
{
"name": "Felidae",
"children": [
{
"name": "Felis",
"children": [
{
"name": "catus",
"type": "domesticated"
}
]
},
{
"name": "Panthera",
"children": [
{
"name": "tigris",
"type": "wild"
},
{
"name": "leo",
"type": "wild"
},
{
"name": "onca",
"type": "wild"
},
{
"name": "pardus",
"type": "wild"
}
]
}
]
},
{
"name": "Canidae",
"children": [
{
"name": "Canis",
"children": [
{
"name": "lupus",
"type": "domesticated"
},
{
"name": "latrans",
"type": "wild"
},
{
"name": "aureus",
"type": "wild"
}
]
}
]
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment