I am trying to get lines to change style on mouseover across multiple charts. In this example available here , I have two charts that both have five groups A,B,C,D,E. Each however is in a different csv (I am open to bringing the data in one csv or as one json array, but this is just how I have it set up right now).
I can get two charts each with five lines corresponding to the group. Using the below code, I get the hovered over line to change style whilst fading out the other lines in that chart.
// Fading and Selecting Lines
d3.selectAll('path.line.mainline')
.on("mouseover", function(d) {
var HoveredLine = this;
d3.selectAll('path.line.mainline').transition().duration(0)
.style('opacity',function () {
return (this === HoveredLine) ? 1.0 : 0.1;
})
.style('stroke-width',function () {
return (this === HoveredLine) ? 4 : 2;
})
;
})
This is achieved by giving the lines an id
using classed
. Using a different id, the lines in the other chart are selected similarly.
What I want to achieve is a way that if the line of eg group A is highlighted in one chart, it is also highlighted in the other chart also (and all other non-selected lines are faded in all charts). I thought maybe this could be done by getting the index of the selected line and somehow using that in the other chart.
We can solve it by having a single place where we handle mouseover
and mouseout
for both lines.
Primarily to avoid code repeat (DRY principle)
We will write mouse over and mouse out in a single place from where we can handle events in both svg.
So instead of attaching listeners individually like this
d3.selectAll('path.line.mainline')
.on("mouseover", function(d) {
and
d3.selectAll('path.line.mainlinel')
.on("mouseover", function(d) {
Do it like this:
d3.selectAll('path.line')//register this to all paths
.on("mouseover", function(d,i) {
Make use of filter to get the lines on which it is hovered.
d3.selectAll('path.line').filter(function(d1) {
return d.name == d1.name; all which have same name get it via filter
})
.style("opacity", 1)//show filtered links
.style("stroke-width", 4);
Full method will be like this:
function doHover() {
d3.selectAll('path.line')//register this to all paths
.on("mouseover", function(d,i) {
//first make all lines vanish
d3.selectAll('path.line')
.style("opacity", 0.1)
.style("stroke-width", 2)
//only show lines which have same name.
d3.selectAll('path.line').filter(function(d1) {
return d.name == d1.name
})
.style("opacity", 1)
.style("stroke-width", 4);
d3.select("div#chartw.container svg")
.append("text")
.attr("id", "cohorttext")
.html("Cohort " + d.name)
.attr("x", (width) / 1.2)
.attr("y", margin.top * 1.5)
.style("fill", color(d.name))
.style("font-weight", "bold")
.style("font-size", "18px");
d3.select("div#chartw.container svg")
.append("text")
.attr("id", "cohorttextx")
.html("Gini = " + giniw[i%giniw.length])//so that its always within the max length
.attr("x", (width) / 1.2)
.attr("y", 20 + margin.top * 1.5)
.style("fill", color(d.name))
.style("font-size", "14px");
d3.select("div#chartl.container svg")
.append("text")
.attr("id", "cohorttext")
.text("Cohort " + d.name)
.attr("x", (width) / 1.2)
.attr("y", margin.top * 1.5)
.style("fill", color(d.name))
.style("font-weight", "bold")
.style("font-size", "18px");
d3.select("div#chartl.container svg")
.append("text")
.attr("id", "cohorttextx")
.html("Gini = " + ginil[i%ginil.length])//so that its always within the max length
.attr("x", (width) / 1.2)
.attr("y", 20 + margin.top * 1.5)
.style("fill", color(d.name))
.style("font-size", "14px");
})
.on("mouseout", function() {
d3.selectAll('path.line')
.style("opacity", 1)
.style("stroke-width", 2);
//selectALL because we are giving same id to both text in 2 svgs
d3.selectAll("#cohorttext").remove()
d3.selectAll("#cohorttextx").remove()
})
}
Working code here
Please let me know if you have any queries on this.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.