How to toggle data points on and off along with lines in multi-line chart

蓝咒 提交于 2019-12-24 18:31:18

问题


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?


回答1:


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);


来源:https://stackoverflow.com/questions/58830800/how-to-toggle-data-points-on-and-off-along-with-lines-in-multi-line-chart

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!