Devstar34
Devstar34

Reputation: 1097

D3 Line Chart- Adding line interactivity: How to get id's and select a line with each?

So I'm trying to add a feature to my legend where when a data set is clicked, the corresponding line will almost disappear from the chart (by reducing opacity). Each line has a specific Id, and I want to use my legend to select the correct one when clicked. Problem is, I can't seem to loop through my list of id's that I applied to the lines properly with the loop where I create the legend, and therefore can't specify what to select. How can I alter my lineLegends to connect without applying an id to them as well?

The whole project is available here, legends on line 227: https://codepen.io/lahesty/pen/PaXQxy?editors=0111

I am using v4, and my data is an array of arrays, with which I loop through prior to pull out id's into var id_list:

var id_list = ["CB-01", "CB-02", "CB-03", "CB-04", "CB-05"]

Here is where I create my legends:

var lineLegend = svg.selectAll(".lineLegend").data(id_list)
    .enter().append("g")
    .attr("class","lineLegend")
    .attr("transform", function (d,i) {
            return "translate(" + width + "," + (i*20)+")";})

 .on("click", function(){
      //here is where I try to get my data:
      function choose(id_list, d){return id_list.d;}       
       var eachline = choose(id_list)  
       console.log(eachline)
       var active = eachline.active ? false : true,
          newOpacity = active ? .2 : 1;
        d3.select(eachline).style("opacity", newOpacity);   
        // d3.selectAll(".dot4").style("opacity", newOpacity); 
        eachline.active = active; })

lineLegend.append("text").text(function (d) {return d;})
    .attr("transform", "translate(-20,9)");
lineLegend.append("text").text(function (d) {return d;})
    .attr("transform", "translate(-20,9)");
    //successfully got "CB-01," etc with this!

Here are what my lines look like:

svg.append('g').attr('clip-path', 'url(#clipper)')
    .selectAll('path.line')
    .append('g')
    .data(data)
    .enter().append("path") 
    .attr("class", "line")
    .attr("id", function(d,i){return id_list[i%id_list.length]})
    .attr("d", line)
    .attr("stroke", function(d,i){return colors[i%colors.length]})

Let me know if I can get any other info! Thanks!

Upvotes: 1

Views: 597

Answers (1)

Zim
Zim

Reputation: 1483

Once again you're almost done! Just keep things simple: the datum bound to each lineLegend is the id you're looking for. Then don't forget to prefix the id with a # in your css selector.

I suggest toggling a class that will mark the line as active and only worry about visual considerations in the css:

js

 .on("click", function(id){
   var line = d3.select("#" + id);
   var isActive = line.classed("active");

   // remove any existing active class (if mutual exclusion is the desired behavior)
   d3.selectAll(".line.active").classed("active", false);

   line.classed("active", !isActive);
 });

css

.line.active {
  opacity: 0.2;
}

Updated codepen

Upvotes: 2

Related Questions