简体   繁体   中英

D3: Y axis prints won't update with new data

I'm working with the D3 library and I have a Y-axis only that I want to update when my new data is updated. The new data is updated when the slider changes numbers and that works fine. The problem is that the new axis prints over the old one. I need the old ones to be removed obviously and the new ones replacing it when the data is changed. Would appreciate any help on this, thanks.

<script type="text/javascript">

       var myYear = 2006;

        //Width and height
        var w = 1000;
        var h = 500;
        var barPadding = 20;

     var myNames = ["Pedestrian", "Bicycle", "Motorbike", "Car", "Other"];


        //Original data
        var dataset = [
            [
                { y: 20 },   //male 
                { y: 4 },
                { y: 16},
                { y: 53},
                { y: 15 }
            ],
            [
                { y: 12 },   //female
                {  y: 4 },
                {  y: 3 },
                {  y: 36 },
                {  y: 2 }
            ],

        ];
        console.log(dataset);


        //Set up stack method
        var stack = d3.layout.stack();

        //Data, stacked
        stack(dataset);

        //Set up scales
        var xScale = d3.scale.ordinal()
            .domain(d3.range(dataset[0].length))
            .rangeRoundBands([30, w], 0.05);



        var yScale = d3.scale.linear()
            .domain([0,             
                d3.max(dataset, function(d) {
                    return d3.max(d, function(d) {
                        return d.y0 + d.y;
                    });
                })
            ])
            .range([0, h]);


         yScale2 = d3.scale.linear()        //for Y axis
            .domain([0,             
                d3.max(dataset, function(d) {
                    return d3.max(d, function(d) {
                        return d.y0 + d.y;
                    });
                })
            ])
            .range([h-10, 0]);





        //Easy colors accessible via a 10-step ordinal scale
    //  var colors = d3.scale.category20c();

        var color = d3.scale.ordinal()
  .domain(["Male", "Female"])
  .range(["#00B2EE", "#FF69B4"]);



        //Create SVG element
        var svg = d3.select("body")
                    .append("svg")
                    .attr("width", w)
                    .attr("height", h);



        // Add a group for each row of data
        var groups = svg.selectAll("g")
            .data(dataset)
            .enter()
            .append("g")
            .style("fill", function(d, i) {
                return color(i);
            });



        //Define X axis
        var xAxis = d3.svg.axis()
                          .scale(xScale)
                          .orient("bottom")
                          .ticks(5);

        //Define Y axis
        var yAxis = d3.svg.axis()
                          .scale(yScale2)
                          .orient("left")
                          .ticks(5);



        // Add a rect for each data value
        groups.selectAll("rect")
            .data(function(d) { return d; })
            .enter()
            .append("rect")
            .attr("x", function(d, i) {
                return xScale(i)
            })

            .attr("width", xScale.rangeBand())


           .attr("y", function(d) {
                return  h - yScale(d.y0) - yScale(d.y) -20
           })

           .attr("height", function(d) {
                return  yScale(d.y)
           })


        .on("mouseover", function(d) {
//Get this bar's x/y values, then augment for the tooltip

            d3.select(this)
            .attr("stroke", "white")
            .attr("stroke-width", "3px")

            var xPosition = parseFloat(d3.select(this).attr("x")) + xScale.rangeBand() / 2;                 var yPosition = parseFloat(d3.select(this).attr("y")) / 2 + h / 2;

        //Update the tooltip position and value
        d3.select("#tooltip")
        .style("left", xPosition + "px")
        .style("top", yPosition + "px")
        .select(".deathCount")
        .text(d.y);


            //Show the tooltip
            d3.select("#tooltip").classed("hidden", false);
        })


          .on("mouseout", function(d) {

    //Hide the tooltip
              d3.select("#tooltip").classed("hidden", true); 
            d3.select(this)
            .transition()
            .duration(2000)
            .attr("stroke", "none")
          //  .attr("fill", "rgb(0, 0, " + (d * 1) + ")");

          });






/////////   MOUSE CLICK TO CHANGE DATA  //////////////////////////////



        function data2012() {
           dataset = [
            [
                { y: 20 },   //male 
                { y: 4 },
                { y: 16},
                { y: 53},
                { y: 15 }
            ],
            [
                { y: 12 },   //female
                {  y: 4 },
                {  y: 3 },
                {  y: 36 },
                {  y: 2 }
            ],

        ];
        }




        function data2011() {
            dataset =   [
            [
                { y: 33 },   //male 
                { y: 9 },
                { y: 17},
                { y: 57},
                { y: 14 }
            ],
            [
                { y: 14 },   //female
                {  y: 0 },
                {  y: 1 },
                {  y: 38 },
                {  y: 3 }
            ],

        ]; 
        }

           function data2010() {
            dataset =   [
            [
                { y: 26 },   //male 
                { y: 7 },
                { y: 25},
                { y: 106},
                { y: 18 }
            ],
            [
                { y: 14 },   //female
                {  y: 0 },
                {  y: 0 },
                {  y: 40 },
                {  y: 2 }
            ],

        ]; 
        }

           function data2009() {
            dataset =   [
            [
                { y: 31 },   //male 
                { y: 11 },
                { y: 28},
                { y: 102},
                { y: 27 }
            ],
            [
                { y: 17 },   //female
                {  y: 2 },
                {  y: 1 },
                {  y: 55 },
                {  y: 0 }
            ],

        ]; 
        }



      function updateData() {  



    // RE-SET SCALES AND LAYOUT

          d3.select("g").selectAll("svg").remove();

        //Data, stacked
        stack(dataset);

        //Set up scales
         xScale = d3.scale.ordinal()
            .domain(d3.range(dataset[0].length))
            .rangeRoundBands([30, w], 0.05);

         yScale = d3.scale.linear()
            .domain([0,             
                d3.max(dataset, function(d) {
                    return d3.max(d, function(d) {
                        return d.y0 + d.y;
                    });
                })
            ])
            .range([0, h]);



  //    d3.selectAll(yAxis).remove();      //new stuff  

              groups = svg.selectAll("g")
            .data(dataset)


                //Update all rects
        var gas = groups.selectAll("rect")
        .data(function(d) {return d;});

              gas
              .exit
              .remove;

            gas
                .transition()
                .duration(750)
                .ease("linear")
                .attr("width", xScale.rangeBand())

              .attr("y", function(d) {
                return  h - yScale(d.y0) - yScale(d.y) - 20
           })

           .attr("height", function(d) {
                return  yScale(d.y)
           })
        .attr("x", function(d, i) {
            return xScale(i);
        });




        //   d3.select(yAxis).remove();
            //REDRAW Y AXIS

             yScale2 = d3.scale.linear()
            .domain([0,             
                d3.max(dataset, function(d) {
                    return d3.max(d, function(d) {
                        return d.y0 + d.y;
                    });
                })
            ])
            .range([h-10, 0]);




                yAxis = d3.svg.axis() 
                          .scale(yScale2)
                          .orient("left")
                          .ticks(5);

            svg.append("g")

            .attr("class", "axis")
            .attr("transform", "translate(" + 30  + ",-10)")
            .transition()
            .duration(500)

            .call(yAxis)



      }


       //SLIDER STUFF

xAxis = d3.svg.axis() 
                          .scale(xScale) 
                          .orient("bottom")
                          .ticks(5)
                        .tickFormat(function(d) {

                return  myNames[d];

            });


        //Create Y axis

        svg.append("g")
            .attr("class", "axis")
            .attr("transform", "translate(" + 30 + ",-10)")
        //    .call(yAxis);

               svg.append("g")

            .attr("class", "axis")

            .attr("transform", "translate(0," + (h - barPadding ) + ")")

            .transition()
            .duration(500)
            .call(xAxis)



    </script>




    <script> //Jquery slider


 $(function() {
$( "#slider" ).slider({
 value:2012,
  min: 2009,
  max: 2012,
  step: 1,
  slide: function( event, ui ) {
    $( "#amount" ).val(  ui.value );

      myYear = ui.value;
      console.log(myYear);

      if (myYear == 2012){
          data2012();

      }

     if (myYear == 2011){
          data2011();

      }


       if (myYear == 2010){
          data2010();

      }

       if (myYear == 2009){
          data2009();

      }

        updateData();




    //  console.log(myYear);
  }

});

In your updateData() function don't re-append the axis. Do it once on initial and then update it. This is consistent with d3's enter, update, and exit pattern.

function updateData(){

    ...

    yScale2 = d3.scale.linear()
        .domain([0,
          d3.max(dataset, function(d) {
            return d3.max(d, function(d) {
              return d.y0 + d.y;
            });
          })
        ])
        .range([h - 10, 0]);

    // set scale
    yAxis.scale(yScale2);
    // redraw it
    d3.select('.yaxis').call(yAxis);
}

Example here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM