Issue in JavaScript / D3.js: When button is clicked, data fails to update and instead new positions are plotted

When the user clicks a button, both the red woman (unvaccinated) and the blue woman (vaccinated) should be updated to reflect the new value. At present, when the button is clicked, the red woman updates correctly but the blue woman is recreated in the location where it should be updated. How can I make the blue woman transition and update like the red woman?

You can observe the issue of the blue woman being recreated at this link:
https://i.sstatic.net/AFCSE.png

I have defined two global variables:

 var numOfPartner = 'zero';
 var status = 0;

Here is where the initial data is loaded and the red image is introduced:

d3.csv("link to data", function(error, data) {

    if (error) {
      console.log("error reading file");
    }

    data.sort(function(a, b) {
      return d3.descending(+a.status, +b.status);
    });

    // Calculation using d3.max for the data is recommended
    widthScale.domain([0, d3.max(data, function(d) {
      return +d.start;
    })]);

    heightScale.domain(data.map(function(d) {
      return +d.average;
    }).slice(1));

    var rects = svg.selectAll("rect")
    .data(([data[0]]))
    .enter()
    .append("rect");

    rects
      .attr("x", 0)
      .attr("y", function(d) {
        return heightScale(d.status);
      })
      .attr("width", function(d) {
        return widthScale(+d.average);
      })
      .attr("height", heightScale.rangeBand());

    svg.selectAll("text")
      .attr("class", "label")
      .data(([data[0]]))
      .enter()
      .append("text")
      .text(function(d) {
        return +d.average + " %";
      })
      .attr("x", function(d) {
        return widthScale(+d.average) + 5;
      })
      .attr('y', '-45')
      .attr("fill", "#8a8c8e")
      .attr("font-size", "24")
      .attr("font-weight", "700")

    // Styling the axis
    svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis)
      .attr("fill", "#808285");

    // Label below x axis
    svg.append("text")
      .attr("class", "xlabel")
      .attr("transform", "translate(" + width / 2 + " ," +
            height + ")")
      .style("text-anchor", "middle")
      .attr("dy", "0")
      .text("  ")
      .attr("fill", "#5582b0")
      .attr("font-weight", "600");

    svg.selectAll("image1")
      .data(([data[0]]))
      .enter()
      .append("svg:image")
      .attr("x", function(d) {
        return widthScale(+d.average) - 45;
      })
      .attr('y', '-40')
      .attr("height", 200)
      .attr("width", 115)
      .attr("xlink:href", "link to red woman");

This is the function for updating the button, which works for the red woman but not for the blue woman:

d3.selectAll("button").on("click", function() {
     if (this.id == "unvaccinated")
         status = 0;
     else if (this.id == "vaccinated") {
         status = 1;
     } else {
         numOfPartner = this.id;
     }
     svg.selectAll("image2")
         .data(([data[1]]))
         .enter()
         .append("svg:image")
         .attr("x", function(d) {
             return widthScale(data[1][numOfPartner]) - 45;
         })
         .attr('y', '-40')
         .attr("height", 200)
         .attr("width", 115)
         .attr("xlink:href", "link to blue woman");

     rects
         .data(data)
         .transition()
         .duration(1000)
         .ease("linear")
         .attr("width", function(d) {
             return widthScale(data[status][numOfPartner]);
         });

     svg.selectAll("text")
         .data(([data[0]]))
         .transition()
         .duration(1000)
         .ease("linear")
         .attr("x", function(d) {
             return widthScale(data[status][numOfPartner])
         })
         .text(function(d) {
             return data[status][numOfPartner] + " %"
         });

     svg.selectAll("image")
         .data(([data[0]]))
         .transition()
         .duration(1000)
         .ease("linear")
         .attr("x", function(d) {
             return widthScale(data[status][numOfPartner]) - 45;
         });


     svg.selectAll("image2")
         .data(([data[1]]))
         .transition()
         .duration(1000)
         .ease("linear")
         .attr("x", function(d) {
             return widthScale(data[1][numOfPartner]) - 45;
         });

     });
});

I've experimented with the on-button click function and the data retrieval, but so far no success has been achieved.

Answer №1

To accurately pinpoint the issue without access to the data or a live demonstration, it's difficult to determine the exact problem. However, upon inspection, an error in the click callback is apparent. It's advisable to relocate this code snippet within the d3.csv callback:

 svg.selectAll("image2")
     .data(([data[1]]))
     .enter()
     .append("svg:image")
     .attr("x", function(d) {
         return widthScale(data[1][numOfPartner]) - 45;
     })
     .attr('y', '-40')
     .attr("height", 200)
     .attr("width", 115)
     .attr("xlink:href", "link to blue woman");

By incorporating a new element into your SVG rather than performing an update, this may not align with your intentions for the click callback. This segment should ideally be placed in an initialization function elsewhere. While the correct update code appears later in the callback, its functionality will be compromised due to the introduction of a new element.

Furthermore, I observed that you reference image1 both in the data callback and the click callback. Double-check to ensure accuracy and rule out any potential typographical errors.

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

AngularJS bracket-enhanced template

Why is AngularJS giving an error when brackets are used inside ng-template content? I am trying to create an input field that should accept an array, but I keep getting this error message: "Error: Syntax Error: Token ']' not a primary expression ...

Using Jquery and the cookie.split method to extract and eliminate a value from a cookie

I am trying to figure out how to remove a specific matching value from a cookie using JavaScript. I have written a script that loops over the cookie and checks for matches, but I can't seem to successfully remove just the matching value. Any tips on a ...

Analyze React.js source code for errors, instead of focusing solely on the DOM manipulation aspect

Can breakpoints be set in React.js code and debugged in the actual script rather than just in compiled javascript? For example: var HelloMessage = React.createClass({ render: function() { return <div>Hello {this.props.name}</div>; // ...

Is there a way to create a universal getter/setter for TypeScript classes?

One feature I understand is setting getters and setters for individual properties. export class Person { private _name: string; set name(value) { this._name = value; } get name() { return this._name; } } Is there a w ...

Understanding Variable Scope in JavaScript: How Variables are Accessed in Different Functions

I've been experimenting with a script that utilizes jQuery's get function to transfer data to another page and display the returned information as an alert on the current page. My goal is to send both the search field value from an input form (wh ...

Verifying website responsiveness using Puppeteer

Looking to create a script that can determine if a webpage has a responsive design? Wondering how to go about it? Well, it's quite simple. In responsive websites, elements like divs, spans, footers, headers, and sections typically adjust to fit the s ...

Automatically populate select boxes with values from a different source using PHP

I'm in the process of setting up automatic population for 2 select boxes on a website. When a user chooses a class, the second select box automatically displays the main specialization of that class. If the user selects Tank (for example), the third ...

Scrolling to zoom in on the div content

I need the ability to resize the content within a div without changing the size of the div itself when the user scrolls. The function I currently have is as follows: var zoomable = document.getElementById('zoomable'), zX = 1; window.addEvent ...

When using AngularJS services to pass data, the data may be lost when the page is refreshed

I'm facing an issue with transferring data from controller A to controller B using a Factory (or a Service) when the user refreshes the browser. I am able to successfully set the data in controller A and retrieve it in controller B, but upon refreshin ...

"Mongo server is rejecting the connection, and the reason is unclear to me

I created a MongoDB model with the following structure:- var mongoose = require('mongoose'); const itemsModel = new mongoose.Schema({ _id: { type: String, }, userName: { type: String, required: true }, ...

Custom JavaScript function throwing an error

function changeElementClass(path, changeClass, duration){ $(path).removeClass(changeClass); $(this).addClass(changeClass); )}; $('.flightDetails .option').changeElementClass('.flightDetails .option','selected',300); ...

Create PDF files on-the-fly using the html-pdf module

Recently, I've been using the npm package html-pdf for generating PDF invoices dynamically. However, I encountered a problem where instead of saving values to the PDF file, it was saving ejs code. Does anyone have any insight on why this might be happ ...

The comparison between AJAX and JSON passing and PHP generating HTML versus returning it

Currently, my code looks like this: <li onclick = " function CBAppData( callerObj, data ) { var string = ''; for( a in data ) { debug.push( data[ ...

Rotating camera independently from its parent in Three.js

I have a scenario where an Entity is traversing a CatmullRomCurve3 path, moving left with the left or down arrow keys and right with the right or up arrow keys. Initially, I encountered an issue where I wanted the Entity to face perpendicular to the path ...

Passing a PHP variable between PHP files with the help of jQuery

I'm facing a minor issue. I'm trying to pass a PHP variable from one PHP file to another using setInterval. However, I'm unsure of how to include the PHP variable in my jQuery code. Here is the content of first.php: <?php $phpvariable= ...

Using PHP to pass variables to an external JavaScript file

I have come across the following code snippet: PHP <?php include("db.php"); ?> <html> <head> <title>Title</title> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.0/j ...

Express Server React 403 Forbidden Error

Issue: When attempting to make a post request using the AXIOS library in React, I am receiving a 403 (Forbidden) error for http://localhost:5004/api/auth/login. Despite having installed cors on Express, the console continues to display the 403 error. My c ...

Transform the post data into a JSON string within the controller

Hello everyone, I have a sample table that I want to share: <table class="table table-bordered" width="100%" cellspacing="0" id="tableID"> <thead> <tr> <th>A</th> <th>B</th> <th>C< ...

NodeJS closes the previous server port before establishing a new server connection

During my development and testing process, whenever I make changes, I find myself having to exit the server, implement the updates, and then start a new server. The first time I run the command node server.js, everything works perfectly. However, when I m ...

Can a Stylus and Node.js with Express project utilize a local image?

Let's talk about using images in a Web app. In my Stylus file, style.styl, I typically set the image using code like this: .background background: url(http://path/to/image) But what if we want to save the image to our local app directory and use ...