Following from this question I have been working with a diverging stack chart written in D3v4. The chart is intended to be used as an ember component.
The chart renders correctly on the initial load but it displays a number of undesirable behaviours when the data refreshes and it transitions to a new set of bars. Such behaviours include:
- Bars not removing correctly when date goes backwards
- The furthest right bar being removed when the date goes forwards with the X axis not updating accordingly.
I'm unsure why this occuring. I know that the data being fed to the chart is correct and that the initial render always displays correctly.
The component.js file is split as follows:
didInsertElement() {
var data = this.get('data')
var margin = { top: 35, right: 145, bottom: 35, left: 45 };
var width = 800
var height = 350
var svg = 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 + ")");
this.set("svg", svg)
var x = scaleBand()
.rangeRound([0, width])
.padding(0.1);
this.set("x", x)
var y = scaleLinear()
.rangeRound([height, 0]);
this.set("y", y)
var z = scaleOrdinal()
.range(["steelblue", "darkorange", "red"]);
this.set("z", z)
svg.append("g")
.attr("class", "x-axis axisWhite");
svg.append("g")
.attr("class", "y-axis axisWhite");
this.buildChart()
},
Then a didUpdateAttrs hook:
didUpdateAttrs() {
this.buildChart()
},
Then the function to build the chart:
buildChart() {
var data = this.get('data')
var keys = ["count1", "count2", "count3"];
var series = stack()
.keys(keys)
.offset(stackOffsetDiverging)
(data);
this.get("x").domain(data.map(d => d.label));
this.get("y").domain([
min(series, stackMin),
max(series, stackMax)
]).nice();
var barGroups = this.get("svg").selectAll("g.layer")
.data(series);
barGroups.exit().remove();
barGroups.enter().insert("g", ".x-axis")
.classed('layer', true);
this.get("svg").selectAll("g.layer")
.attr("fill", d => this.get("z")(d.key));
var bars = this.get("svg").selectAll("g.layer").selectAll("rect")
.data(function(d) { return d; });
bars.exit().remove()
bars = bars
.enter()
.append("rect")
.attr("width", this.get("x").bandwidth())
.attr("x", d => this.get("x")(d.data.label))
.merge(bars)
bars.transition()
.attr("y", d => this.get("y")(d[1]))
.attr("height", d => Math.abs(this.get("y")(d[0])) - this.get("y")(d[1]));
this.get("svg").selectAll(".x-axis").transition()
.attr("transform", "translate(0," + this.get("y")(0) + ")")
.call(axisBottom(this.get("x")));
this.get("svg").selectAll(".y-axis").transition()
.call(axisLeft(this.get("y")));
function stackMin(serie) {
return min(serie, function(d) { return d[0]; });
}
function stackMax(serie) {
return max(serie, function(d) { return d[1]; });
}
}
Unfortunately I haven't been able to get a proper Twiddle up using the ember-d3 module.
Aucun commentaire:
Enregistrer un commentaire