Reputation: 227
I am trying to toggle data points in my line chart when the legend is clicked. Here is the link to my fiddle. From my fiddle, when the legend is clicked, the lines and the corresponding axis will be toggled on and off but the points do not. The relevant code is as follows.
//************* Lines and Data Points ***************
var colors = ["blue", "red"];
var thisScale;
var line = d3.line()
.x(d => x(d.x))
.y(d => thisScale(d.y))
.curve(d3.curveLinear);
var paths = g.selectAll("foo")
.data(data)
.enter()
.append("path");
paths.attr("stroke", function (d,i){return colors[i]})
.attr("d", d => {
thisScale = yScale[d.yAxis]
return line(d.data);
})
.attr("stroke-width", 2)
.attr("id", function (d,i){return "line" + i})
.attr("fill", "none");
var pointsGroup = g.selectAll(null)
.data(data)
.enter()
.append("g")
.attr("fill", function(d, i) {
local.set(this, yScale[i])
return colors[i];
});
var points = pointsGroup.selectAll(null)
.data(function(d) {
return d.data
})
.enter()
.append("circle")
.attr("cx", function(d) {
return x(d.x);
})
.attr("cy", function(d, i) {
return local.get(this)(d.y);
})
.attr("r", 3)
.attr("class", function(d, i) {
return "dots" + i;
})
.attr("clip-path", "url(#clip)")
.on("mouseover", mouseover)
.on("mouseleave", mouseleave)
//************* Legend ***************
var legend = svg.selectAll(".legend")
.data(data)
.enter().append("g")
legend.append("rect")
.attr("x", width + 65)
.attr("y", function(d, i) {
return 30 + i * 20;
})
.attr("width", 18)
.attr("height", 4)
.style("fill", function(d, i) {
return colors[i];
})
legend.append("text")
.attr("x", width + 60)
.attr("y", function(d, i) {
return 30 + i * 20;
})
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d, i) {
return "Value" + (i + 1);
})
.on("click", function(d, i) {
// Determine if current line is visible
let opacity = d3.select("#line" + i).style("opacity");
let newOpacity;
if (opacity == 0) {
newOpacity = 1;
}else {
newOpacity = 0
}
d3.select("#line" + i).style("opacity", newOpacity);
d3.selectAll("dots" + i).style("opacity", newOpacity);
d3.select("#ySecAxis" + i).style("opacity", newOpacity);
d3.select("#yAxisLabel" + i).style("opacity", newOpacity);
});
I have attributed the class to my points .attr("class", function(d, i) { return "dots" + i; })
and tried to allow the points to be toggled by using d3.selectAll("dots" + i).style("opacity", newOpacity);
However, it is not working, anyone knows what could be the issue?
Upvotes: 0
Views: 111
Reputation: 1787
you need to make 2 changes
1 - Assign the dots class to the parent g element, so the i variable is only iterated per group of dots. Don't use assign class on the dots themselves.
var pointsGroup = g.selectAll(null)
.data(data)
.enter()
.append("g")
.attr("class", function(d, i) {
return "dots" + i
})
.attr("fill", function(d, i) {
local.set(this, yScale[i])
return colors[i];
});
2 - Select the dots class by including "." in the selection name
d3.selectAll(".dots" + i).style("opacity", newOpacity);
Upvotes: 1