Update row order (z-orientation) on hover in d3
I am new to using d3 and JavaScript and would appreciate some constructive feedback. I'm mocking a practical example to find out d3, which involves plotting climate data (temperature anomalies) from 1880-2010. From two sources (GIS and HUD). So far I have created a multi-line chart in d3 using this data. The code and data is here https://gist.github.com/natemiller/0c3659e0e6a0b77dabb0
In this example, the data is initially grayed out, but each row is colored with a different color on hover.
I would like to add two additional features.
-
I would like, on hover, to change the order of the lines so that the moused-over line is on top, essentially changing the order of the lines. I read that it requires a substantial SVG replacement and I tried the code along the lines of this
source.append("path") .attr("class", "line") .attr("d", function(d) { return line(d.values); }) .style("stroke", "lightgrey") .on("mouseover", function() { if (active) active.classed("highlight", false); active = d3.select(this.parentNode.appendChild(this)) .classed("highlight", true); }) .style("stroke",function(d) {return color(d.name);}) .on("mouseout", function(d) { d3.select('#path-' + d.name) .transition() .duration(750) .style("stroke", "lightgrey") }) .attr("id", function(d, i) { return "path-" + d.name; });
where the code is .on ("mouseover" ... is for highlighting the current line "moused-over". In my example it doesn't work. All lines are first highlighted and then grayed out with mouseover / mouseout. If someone can help me to determine how to update my code so that I can change the order of the lines on the mouse, that would be great!
-
I've been playing around with line notation in such a way that when the line or its label is masked over the update of the lines and labels. I have played around with the id for a bit, but so far I cannot get the text and line to change color. I managed to 1. hover over the line and change the text color, 2. hover the text over the text and change the line color, 2. hover the mouse over the line and change the line, but not have both the line and the text change color when any of them obscured. Here's a section of code that serves as a startup (using ids) but doesn't quite work as it only specifies the path, not the text and path. I tried adding both of them to d3.select ('# path -', '# text -'... and variations of that, but it doesn't work.
source.append("path") .attr("class", "line") .attr("d", function(d) { return line(d.values); }) .style("stroke", "lightgrey") .on("mouseover", function(d){ d3.select(this) .style("stroke",function(d) {return color(d.name);}); }) .on("mouseout", function(d) { d3.select('#path-' + d.name) .transition() .duration(750) .style("stroke", "lightgrey") }) .attr("id", function(d, i) { return "path-" + d.name; }); source.append("text") .datum(function(d) { return {name: d.name, value: d.values[d.values.length - 15]}; }) .attr("transform", function(d) { return "translate(" + x(d.value.date) + "," + y(d.value.temperature) + ")"; }) .attr("x", 5) .attr("dy", ".35em") .style("stroke", "lightgrey") .on("mouseover", function(d){ d3.select('#path-' + d.name) .style("stroke",function(d) {return color(d.name);}); }) .on("mouseout", function(d) { d3.select('#path-' + d.name) .transition() .duration(750) .style("stroke", "lightgrey") }) .text(function(d) { return d.name; }) .attr("font-family","sans-serif") .attr("font-size","11px") .attr("id", function(d, i) { return "text-" + d.name; });
I really appreciate your help. I am new to d3 and this help. Its a steep learning curve at the moment, but I hope this example and code is clear enough. If it doesn't let me know how can I do it better and I can answer the question.
Many thanks,
Nat
source to share
Chris Vilois gave a good answer to this question in the d3 Google group. https://groups.google.com/forum/?fromgroups=#!topic/d3-js/-Ra66rqHGk4
The trick is to select the path g parent to change it to others:
this.parentNode.parentNode.appendChild (this.parentNode);
This adds the current selection container "g" on top of all other "g" s.
I found this useful in many other cases.
Thanks Chris!
source to share