从this question开始,我一直在使用D3v4编写的分散堆栈图表。该图表旨在用作余烬组件。
图表在初始加载时正确呈现,但在数据刷新时会显示许多不良行为,并且它会转换为一组新的条形图。这些行为包括:
我不确定为什么会这样。我知道输入到图表的数据是正确的,并且初始渲染始终正确显示。
component.js文件按如下方式拆分:
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()
},
然后是didUpdateAttrs钩子:
didUpdateAttrs() {
this.buildChart()
},
然后构建图表的功能:
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]; });
}
}
不幸的是,我还没有能够使用ember-d3模块获得正确的Twiddle。
答案 0 :(得分:1)
上述行为是由于重绘图表时没有重新计算宽度的条形码造成的。
所以这个:
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]));
成为这个:
bars.transition()
.attr("y", d => y(d[1]))
.attr("height", d => Math.abs(y(d[0])) - y(d[1]))
.attr("width", x.bandwidth())
.attr("x", d => x(d.data.label));