Reputation: 161
I am trying to dynamically update my bar chart from a json data set.
Data look like this :
[{x=a,y=1},{x=b,y=2},{x=c,y=4}],
[{x=d,y=0.1},{x=a,y=1}],{x=b,y=4}]
I used the code to set the dimensions of the canvas (y-axis and x-axis):
var margin = {top: 20, right: 20, bottom: 70, left: 40},
width = 600 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
The whole code :
// set the ranges
var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);
var y = d3.scale.linear().range([height, 0]);
// define the axis
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10);
// add the SVG element
var chart = d3.select(".chart")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// load the data
data=mydata
data.forEach(function(d) {
d.x = d.x;
d.y = +d.y;
});
// scale the range of the data
x.domain(data.map(function(d) { return d.x; }));
y.domain([0, d3.max(data, function(d) { return d.y; })]);
// add axis
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)" );
chart.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 5)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Frequency");
// Add bar chart
chart.selectAll("bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.x); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.y); })
.attr("height", function(d) { return height - y(d.y); });
//Call function to update barchart
function redraw(data){
x.domain(data.map(function(d) { return d.x; }));
y.domain([0, d3.max(data, function(d) { return d.y; })]);
chart.select(".x.axis").remove();
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)" );
// y-axis
chart.select(".y.axis").remove();
chart.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Frequency");
var bar = chart.selectAll(".bar")
.data(data, function(d) {
return d.x; });
// new data:
bar.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.x); })
.attr("y", function(d) { return y(d.y); })
.attr("height", function(d) { return height - y(d.y); })
.attr("width", x.rangeBand());
// removed data:
// bar.exit().remove();
chart.select(".y.axis").transition().delay(750).call(yAxis)
// updated data:
bar
.transition()
.duration(750)
.attr("y", function(d) { return y(d.y); })
.attr("height", function(d) { return height - y(d.y); });
}
Upvotes: 1
Views: 1866
Reputation: 66
In this case you will have to redefine the xAxis and yAxis to use the new scale values you define in the function, by pretty much copying the declaration into the function scope.
// define the axis
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10);
The primary reason you're getting the old values on the axis is because when you call ".call(xAxis)" inside the function the x scale associated with that axis declaration is the original one.
Hope this helps..
Upvotes: 2