I am playing around with D3.js and I am trying to do two things:
- On hovering of the lines, I want to apply a style to the lines (color to light blue or something). It can go to the parent node, or the highest level parent, either one would greatly help me out. If you know how to do both, please share!
- On hovering of the text per each node, I would like to display a tooltip of the "test" attribute in the JSON data.
I have messed around with the tooltips before, but in this scenario I am not sure where to put the ,on("mouseover"
event handler. This is also my first time testing out the d3.tree
option.
var margin = {top: 20, right: 120, bottom: 20, left: 120},
width = 960 - margin.right - margin.left,
height = 800 - margin.top - margin.bottom;
var i = 0,
duration = 750,
root;
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.right + margin.left)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var root={ //json var root
"name": "flare",
"test": "blue",
"children": [{
"name": "analytics",
"test": "red",
"children": [{
"name": "cluster",
"test": "green",
"children": [{
"name": "AgglomerativeCluster",
"test": "blue",
"size": 3938
}, {
"name": "CommunityStructure",
"test": "yellow",
"size": 3812
}, {
"name": "HierarchicalCluster",
"test": "orange",
"size": 6714
}, {
"name": "MergeEdge",
"test": "someColor",
"size": 743
}]
}, {
"name": "graph",
"test": "someColor",
"children": [{
"name": "BetweennessCentrality",
"test": "someColor",
"size": 3534
}, {
"name": "LinkDistance",
"test": "someColor",
"size": 5731
}, {
"name": "MaxFlowMinCut",
"size": 7840
}, {
"name": "ShortestPaths",
"test": "someColor",
"size": 5914
}, {
"name": "SpanningTree",
"test": "someColor",
"size": 3416
}]
}, {
"name": "optimization",
"test": "someColor",
"children": [{
"name": "AspectRatioBanker",
"test": "someColor",
"size": 7074
}]
}]
}, {
"name": "animate",
"test": "someColor",
"children": [{
"name": "interpolate",
"test": "someColor",
"children": [{
"name": "ArrayInterpolator",
"test": "someColor",
"size": 1983
}, {
"name": "ColorInterpolator",
"test": "someColor",
"size": 2047
}, {
"name": "DateInterpolator",
"test": "someColor",
"size": 1375
}, {
"name": "Interpolator",
"test": "someColor",
"size": 8746
}, {
"name": "MatrixInterpolator",
"test": "someColor",
"size": 2202
}, {
"name": "NumberInterpolator",
"test": "someColor",
"size": 1382
}, {
"name": "ObjectInterpolator",
"test": "someColor",
"size": 1629
}, {
"name": "PointInterpolator",
"test": "someColor",
"size": 1675
}, {
"name": "RectangleInterpolator",
"test": "someColor",
"size": 2042
}]
}, {
"name": "ISchedulable",
"test": "someColor",
"size": 1041
}, {
"name": "Parallel",
"test": "someColor",
"size": 5176
}, {
"name": "Pause",
"test": "someColor",
"size": 449
}, {
"name": "Scheduler",
"test": "someColor",
"size": 5593
}, {
"name": "Sequence",
"test": "someColor",
"size": 5534
}, {
"name": "Transition",
"test": "someColor",
"size": 9201
}, {
"name": "Transitioner",
"test": "someColor",
"size": 19975
}, {
"name": "TransitionEvent",
"test": "someColor",
"size": 1116
}, {
"name": "Tween",
"test": "someColor",
"size": 6006
}]
}, {
"name": "data",
"test": "someColor",
"size": 4322
}]
} ;
root.x0 = height / 2;
root.y0 = 0;
function collapse(d) {
if (d.children) {
d._children = d.children;
d._children.forEach(collapse);
d.children = null;
}
}
root.children.forEach(collapse);
update(root);
d3.select(self.frameElement).style("height", "800px");
function update(source) {
// Compute the new tree layout.
var nodes = tree.nodes(root).reverse(),
links = tree.links(nodes);
// Normalize for fixed-depth.
nodes.forEach(function(d) { d.y = d.depth * 180; });
// Update the nodes…
var node = svg.selectAll("g.node")
.data(nodes, function(d) { return d.id || (d.id = ++i); });
// Enter any new nodes at the parent's previous position.
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
.on("click", click);
nodeEnter.append("circle")
.attr("r", 1e-6)
.style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });
nodeEnter.append("text")
.attr("x", function(d) { return d.children || d._children ? -10 : 10; })
.attr("dy", ".35em")
.attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; })
.text(function(d) { return d.name; })
.style("fill-opacity", 1e-6);
// Transition nodes to their new position.
var nodeUpdate = node.transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });
nodeUpdate.select("circle")
.attr("r", 4.5)
.style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });
nodeUpdate.select("text")
.style("fill-opacity", 1);
// Transition exiting nodes to the parent's new position.
var nodeExit = node.exit().transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; })
.remove();
nodeExit.select("circle")
.attr("r", 1e-6);
nodeExit.select("text")
.style("fill-opacity", 1e-6);
// Update the links…
var link = svg.selectAll("path.link")
.data(links, function(d) { return d.target.id; });
// Enter any new links at the parent's previous position.
link.enter().insert("path", "g")
.attr("class", "link")
.attr("d", function(d) {
var o = {x: source.x0, y: source.y0};
return diagonal({source: o, target: o});
});
// Transition links to their new position.
link.transition()
.duration(duration)
.attr("d", diagonal);
// Transition exiting nodes to the parent's new position.
link.exit().transition()
.duration(duration)
.attr("d", function(d) {
var o = {x: source.x, y: source.y};
return diagonal({source: o, target: o});
})
.remove();
// Stash the old positions for transition.
nodes.forEach(function(d) {
d.x0 = d.x;
d.y0 = d.y;
});
}
// Toggle children on click.
function click(d) {
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
update(d);
}
.node {
cursor: pointer;
}
.node circle {
fill: #fff;
stroke: steelblue;
stroke-width: 1.5px;
}
.node text {
font: 10px sans-serif;
}
.link {
fill: none;
stroke: #ccc;
stroke-width: 1.5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>