0

I have a d3 script for which the data that I have is as shown below:

var data = [{name: "A", rank: 0, student_percentile: 100.0},
            {name: "B", rank: 45, student_percentile: 40.3},
            {name: "C", rank: 89, student_percentile: 89.7},
            {name: "D", rank: 23, student_percentile: 10.9},
            {name: "E", rank: 56, student_percentile: 30.3}];

This data array has been fetched from the server.

I have a d3 script given below:

function d3Data(){
    data = data.sort(function(x,y){
            return d3.ascending(+x.rank, +y.rank);
        });
    var size = document.getElementById("range").value;
    console.log(size);
    data = data.slice(0,size);
    d3(data);
}

function d3(data){
    var margin = 40,
    width = 600,
    height = 400;
    console.log(data);

    var xscale = d3.scaleLinear()
                  .domain(
                        d3.extent(data, function(d) { return +d.student_percentile; })
                    )
                  .nice() 
                  .range([0, width]);

    var yscale = d3.scaleLinear()
                  .domain(d3.extent(data, function(d) { return +d.rank; }))
                  .nice()
                  .range([height, 0]);

    var xAxis = d3.axisBottom().scale(xscale);

    var yAxis = d3.axisLeft().scale(yscale);

    var svg = d3.select('.chart')
                    .append('svg')
                    .attr('class', 'chart')
                    .attr("width", width + margin + margin)
                    .attr("height", height + margin + margin + 10   )
                    .append("g")
                    .attr("transform", "translate(" + margin + "," + margin + ")");

    svg.append("g")
        .attr("class", "y axis")
        .call(yAxis);

    svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);

    var color = d3.scaleOrdinal(d3.schemeCategory10);

    var circles = svg.selectAll(null)
          .data(data)
          .enter()
          .append("circle")
          .attr("cx", width / 2)
          .attr("cy", height / 2)
          .attr("opacity", 0.3)
          .attr("r", 20)
          .style("fill", "blue")
          .attr("cx", function(d) {
            return xscale(+d.student_percentile);
          })
          .attr("cy", function(d) {
            return yscale(+d.rank);
          })
          .on('mouseover', function(d, i) {
            d3.select(this)
              .transition()
              .duration(1000)
              .ease(d3.easeBounce)
              .attr("r", 32)
              .style("fill", "orange")
              .style("cursor", "pointer")
              .attr("text-anchor", "middle");

    texts.filter(function(e) {
        return e.rank === d.rank;
      })
      .attr("font-size", "20px")
      })
      .on('mouseout', function(d, i) {
        d3.select(this).transition()
          .style("opacity", 0.3)
          .attr("r", 20)
          .style("fill", "blue")
          .style("cursor", "default");
        texts.filter(function(e) {
            return e.rank === d.rank;
          })
        .transition()
        .duration(1000)
        .ease(d3.easeBounce)
        .attr("font-size", "10px")
      });

    var texts = svg.selectAll(null)
      .data(data)
      .enter()
      .append('text')
      .attr("x", function(d) {
        return xscale(+d.student_percentile);
      })
      .attr("text-anchor", "middle")
      .attr("y", function(d) {
        return yscale(+d.rank);
      })
      .text(function(d) {
        return +d.student_percentile;
      })
      .attr("pointer-events", "none")
      .attr("font-family", "sans-serif")
      .attr("font-size", "10px")
      .attr("fill", "red");

    svg.append("text")
        .attr("transform", "translate(" + (width / 2) + " ," + (height + margin) + ")")
        .style("text-anchor", "middle")
        .text("Percentile");

    svg.append("text")
        .attr("transform", "rotate(-90)")
        .attr("y", 0 - margin)
        .attr("x",0 - (height / 2))
        .attr("dy", "1em")
        .style("text-anchor", "middle")
        .text("Rank");

    $('circle').tipsy({ 
        console.log("tipsy");
        gravity: 'w', 
        html: true, 
        title: function() {
            var d = this.__data__;
            return d.name + '<br/>' + d.rank; 
        }
    });
}

$(document).ready(function(){
    d3Data();
});

function rangeVal(){
    d3Data();
}

function fadeOut() {
    svg.selectAll("circle")
    .transition()
    .style("opacity", 0.3)
    .attr("r", 20)
    .style("fill", "blue");
}

function handleMouseOver() {
    d3.select(this)
    .attr("r", 32)
    .style("fill", "orange");
}

I call the function d3Data when the document gets loaded and also when button is clicked (rangeVal is the function that is called on button click). On button click, I want to apply different filters on data and then make the graph again. Currently what is happening is I am getting multiple graphs on button click but the existing graph is not getting updated. The current output is as shown: multiple graphs

I just want d3Data() function to update original data array every time button is clicked and then make the graph again. How can I do that?

2 Answers 2

1

Each an every time depend upon the data SVG is newly created. So you have to remove the SVG Before Creation

    //d3.select("Your Id Name or Your Class Name").select("svg").remove();

In Your Code, I changed follow as

d3.select('.chart').select("svg").remove();
var svg = d3.select('.chart')
Sign up to request clarification or add additional context in comments.

Comments

0

I found the solution. I had to make two changes. In function d3data, I was updating the same array again and again, so the data was not getting updated correctly and before calling d3(), I had to remove existing graph.

function d3Data(){
    data_sorted = data.sort(function(x,y){
            return d3.ascending(+x.rank, +y.rank);
        });  // update array and put it in another variable
    var size = document.getElementById("range").value;
    console.log(size);
    data_sliced = data_sorted.slice(0,size);
    d3.select('.chart').html("");  //this to remove existing graph
    d3(data_sliced);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.