javascript - D3: Y axis prints won't update with new data -
i'm working d3 library , have y-axis want update when new data updated. new data updated when slider changes numbers , works fine. problem new axis prints on old one. need old ones removed , new ones replacing when data changed. appreciate on this, thanks.
<script type="text/javascript"> var myyear = 2006; //width , 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 stack method var stack = d3.layout.stack(); //data, stacked stack(dataset); //set 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 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 group 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 rect 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 bar's x/y values, augment 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 tooltip position , value d3.select("#tooltip") .style("left", xposition + "px") .style("top", yposition + "px") .select(".deathcount") .text(d.y); //show tooltip d3.select("#tooltip").classed("hidden", false); }) .on("mouseout", function(d) { //hide 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 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 , layout d3.select("g").selectall("svg").remove(); //data, stacked stack(dataset); //set 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 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 updatedata()
function don't re-append axis. once on initial , update it. consistent d3's enter, update, , 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 d3.select('.yaxis').call(yaxis); }
example here.
Comments
Post a Comment