In a multi-line chart, learn how to efficiently toggle the visibility of data points and lines

My goal is to toggle data points in my line chart by clicking on the legend. You can view my code here. Currently, when I click on the legend, the lines and corresponding axis are toggled on and off successfully, but the data points do not change. Below is the relevant part of my code:

    //************* 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);            
    });

To assign a class to my points, I used

.attr("class", function(d, i) { return "dots" + i; })
, and attempted to toggle their visibility with
d3.selectAll("dots" + i).style("opacity", newOpacity);
. However, this method does not seem to be working. Any insights into what might be causing the issue?

Answer №1

To achieve the desired outcome, two modifications are required:

1 - Apply the dots class to the parent g element instead of individual dots, ensuring that the variable i is only incremented for each group of dots.

var pointGroups = 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 - To select elements with the dots class, remember to include "." in the selection pattern.

d3.selectAll(".dots" + i).style("opacity", newOpacity);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Retrieve the Corresponding Content Inside the Div Element

I have a div with text that needs to be matched with comma-separated values: <div class="val"> This is paragraph 1 </div> <div class="val"> This is paragraph 2 </div> Using an Ajax call, I retrieve the ...

The Filepond input field is not properly linked to the form data during the sending process

I am having trouble uploading a FilePond file field to the server along with other form elements. My form consists of input fields, a select field, a textarea, and a file input field connected to the Filepond plugin. <form class="uploadform"& ...

Exposing a Hidden Division with a Link via jQuery

I currently have a jQuery Panel set up to open when clicking a button. Now, I am looking to add a second link at the bottom of the page that will also open the same panel. Can anyone provide guidance on how to accomplish this? You can view my JSFiddle a ...

The Query.formatError message indicates that there is an issue with the 'users.email' column in the where clause of the database query

I'm having some trouble with a piece of code. Here's my signup function : exports.signup = (req, res) => { // Adding User to Database console.log("Processing func -> SignUp"); User.create({ name: req.body.name, username: req.body. ...

After refreshing, Angular route using html5Mode leads to a 'Page Not Found' error page

I have created several Angular routes as illustrated in the code snippet below. app.config(function($routeProvider, $locationProvider, $provide) { $routeProvider .when('/', { templateUrl: 'home.html', controll ...

Iterating through the sorted list in reverse order, retrieving the text of each list item

Is there a way to navigate through an ordered list, extract and return the text based on a scenario where the user clicks on an li element like Cat 1-2? The goal is to concatenate all parent li's text into either a string or an array. If an array is u ...

I am experiencing issues with my websocket connection following the deployment of my application

My frontend is built in React and my backend is in Node.js. Both are deployed on Vercel. The application runs smoothly locally, but I'm facing an issue when trying to replace the server-deployed link with my endpoint in the frontend. I am encounterin ...

What is the best way to incorporate an array of objects into the React state hook?

I have successfully retrieved data from the API in the specified format: { teamsregistered: [ { paid: false, _id: 602dea67451db71e71e4babd, name: 'MOH', mobile: '+919566879683', tag: 'JAR1NAH', __v: 0 }, { paid: false, _id: 6 ...

Gamepad interference causing obstruction of `requestAnimationFrame()`

I'm currently working with the Gamepad API and finding it a bit challenging due to its limited development. It appears that there is no "gamepadbuttondown" event available, which can be frustrating. I came across a library called 'awesome-react-g ...

Utilize dynamically generated form fields to upload multiple files at once

Currently, as I delve into learning the MEAN stack, I am encountering difficulties with file uploads. Specifically, within a company form: this.companyForm = this.fb.group({ trucks: this.fb.array([]), ... }); The 'trucks' field i ...

New techniques in VueJS 3: managing value changes without using watchers

I am currently working on coding a table with pagination components and I have implemented multiple v-models along with the use of watch on these variables to fetch data. Whenever the perPage value is updated, I need to reset the page value to 1. However, ...

Dynamic Filtering with Reactjs Autocomplete Component (Material UI) using API calls on each input modification

Just starting out with Reactjs and looking to build an Autocomplete component that fetches API data on every input change to update the options. I've been using the Autocomplete component from Material UI but struggling to get it working as expected. ...

Upgrading from V4 to React-Select V5 causes form submission to return undefined value

Looking to upgrade from react-select v4 to v5. The form/field currently functions with v4 and Uniform, producing an output like this: { "skill": { "value": "skill1", "label": "Skill 1" } } After attempting the upgrade to V5, I'm getting a ...

What is the best way to transform an array of objects into MenuItems for a Material-UI Select component?

I am facing an issue with mapping the values of field choices to create options for an MUI Select field from an array called fieldChoices. Here is how I populate the fieldChoices array: fieldChoices = { choices: filtered_status.map(function (item) { ...

Encountering an error while attempting to adjust the window height on a react.js app

I am encountering a runtime error when using useState to obtain the window height. The error message indicates that the window is not defined. Can you provide insights into why this might be happening? Below is the code in question: let [winHeight, setWin ...

Implementing closure within a recursive function allows for better control

One of my functions is designed to take a parameter and print the last number in the Fibonacci Series. For example, if the parameter is 3, it would return 2 as the series progresses like 1, 1, 2. function recursionFib(num){ if(num ...

Pass a reply from a function to a route in expressjs

I'm currently working on a project where I need to retrieve JSON data from an API using an Express server in Node.js. However, I'm facing some confusion regarding how Node.js manages this process. In my code, I have both a function and a route de ...

What could be causing the .text method to not retrieve text even when it is present?

Currently experimenting with web scraping using Selenium to extract the color of a particular dress. Despite finding the text content under the 'screen-reader-text' class when inspecting the website, my attempts at fetching it result in an empty ...

How does JavaScript handle type conversion when the types are mismatched?

Is the right side of the operator forced to convert to the type on the left? If a number is equal to a string -> number, is it actually equal to another number? Do both sides get converted to the same underlying type, such as a number? Can a boolean ...

Tips for enhancing the contents of a single card within a react-bootstrap accordion

Currently, I am facing an issue with my columns expanding all cards at once when utilizing react-bootstrap accordion. My goal is to have each card expand individually upon clicking on its respective link. However, I am encountering difficulties in implem ...