我这里有个突如其来的飞车-https://stackblitz.com/edit/chart-update-1-34uvdo?file=src/app/bar-chart.ts
这是一个有角度的应用程序中的d3图表。
这些条带有箭头,以显示条的开始和结束位置。
我希望每个条形箭头组合都包含在一个g元素中-目前它们都在同一个g元素中。
如何为每个长条和箭头添加一个g元素。
bar.enter()
.append("line")
.attr("x1", d => this.x(d.phase) + this.x.bandwidth() / 2)
.attr("y1", d => this.y(d.start) + ((d.start < d.finish) ? -5 : 5))
.attr("x2", d => this.x(d.phase) + this.x.bandwidth() / 2)
.attr("y2", d => this.y(d.finish) + ((d.start < d.finish) ? 5 : -5))
.attr("stroke", "black")
.attr("stroke-width", 3)
.attr("marker-end", "url(#arrow)")
.style('pointer-events', 'none');
答案 0 :(得分:1)
再次查看d3 general update pattern。这是d3概念中的一个总是让人有些困惑,尤其是将其应用于除最简单的示例以外的任何内容时。
因此,通过查看上述模式,我们可以将其分解为:
使用旧元素加入新数据(如果有)。
根据需要更新旧元素。
根据需要创建新元素。
将输入的元素与更新选择合并后,对两者都应用操作。
根据需要删除旧元素。
private drawUpdate(data) {
this.x.domain(data.map((d: any) => {
return d.phase
}));
this.getExtent(data);
this.y.domain(d3.extent(this.values));
this.createAxis();
// Data Join
const bar = this.chart.selectAll(".bargroup")
.data(data);
// Updates
// Update rect dimensions
bar.select('rect').attr("x", (d, i) => {
return this.x(d.phase)
})
.attr("width", (d, i) => {
return this.x.bandwidth()
})
.attr("y", (d, i) => {
if (d.start < d.finish) {
return this.y(d.finish);
} else {
return this.y(d.start);
}
})
.attr("height", (d, i) => {
if (d.start < d.finish) {
return this.y(d.start) - this.y(d.finish);
} else {
return this.y(d.finish) - this.y(d.start);
}
})
// Update line dimensions
bar.select('line')
.attr("x1", d => this.x(d.phase) + this.x.bandwidth() / 2)
.attr("y1", d => this.y(d.start) + ((d.start < d.finish) ? -5 : 5))
.attr("x2", d => this.x(d.phase) + this.x.bandwidth() / 2)
.attr("y2", d => this.y(d.finish) + ((d.start < d.finish) ? 5 : -5))
// Enter
const barEnter = bar.enter()
.append("g")
.classed('bargroup', true)
// Enter & update - append new rects, update dimensions
barEnter
.append('rect')
.attr("x", (d, i) => {
return this.x(d.phase)
})
.attr("width", (d, i) => {
return this.x.bandwidth()
})
.attr("y", (d, i) => {
if (d.start < d.finish) {
return this.y(d.finish);
} else {
return this.y(d.start);
}
})
.attr("height", (d, i) => {
if (d.start < d.finish) {
return this.y(d.start) - this.y(d.finish);
} else {
return this.y(d.finish) - this.y(d.start);
}
})
// Enter & update - append new lines, update dimensions
barEnter
.append("line")
.attr("stroke", "white")
.attr("stroke-width", 3)
.attr("marker-end", "url(#arrow)")
.style('pointer-events', 'none')
.attr("x1", d => this.x(d.phase) + this.x.bandwidth() / 2)
.attr("y1", d => this.y(d.start) + ((d.start < d.finish) ? -5 : 5))
.attr("x2", d => this.x(d.phase) + this.x.bandwidth() / 2)
.attr("y2", d => this.y(d.finish) + ((d.start < d.finish) ? 5 : -5))
//Exit
bar.exit()
.remove();
d3.select('.y-axis').call(this.y_axis)
d3.select('.x-axis').call(this.x_axis)
.attr("transform", "translate(0," + this.height + ")");
}