我正在使用v4。
我想动态更改折线图的数据,但我无法弄清楚如何将数据传递到d
元素的path
属性。这不起作用(没有画线):
draw_line(data) {
let selection = this.svg.select('path.line').datum(data);
selection.enter()
.append('path')
.attr('class', 'line')
.attr('d', this.line);
selection
.transition(this.transition)
.attr('d', this.line);
}
以下内容确实有效,但它似乎并不惯用(不使用enter()
,exit()
等。
draw_line(data) {
let path = this.svg.select('path.line');
if (path.empty()) {
this.svg
.append('path')
.datum(data)
.attr('class', 'line')
.attr('d', this.line);
} else {
path
.datum(data)
.transition(this.transition)
.attr('d', this.line);
}
}
我确定我错过了一些明显的东西......?
以下内容不应与该问题相关,但包含在内以供参考。 构造函数和调用方法如下所示:
class LineGraph {
constructor(w, h, location) {
this.margin = {top: 50, right: 50, bottom: 50, left: 50};
this.outer_width = w;
this.outer_heigth = h;
this.width = this.outer_width - this.margin.left - this.margin.right;
this.height = this.outer_heigth - this.margin.top - this.margin.bottom;
this.svg = d3.select(location)
.append("svg") // append the svg object to location
.attr("width", w)
.attr("height", h)
.append("g") // appends a 'group' element to 'svg'
.attr("transform", `translate(${this.margin.left}, ${this.margin.top})`);
}
draw(data) {
this.transition = d3.transition()
.duration(2000);
// set the ranges
this.x = d3.scaleTime().range([0, this.width]);
this.bottomAxis = d3.axisBottom(this.x).ticks(d3.timeWeek);
this.y = d3.scaleLinear().range([this.height, 0]);
this.leftAxis = d3.axisLeft(this.y);
this.line = d3.line()
.x(d => this.x(d.date))
.y(d => this.y(d.value));
// this.draw_axes(data);
this.draw_line(data);
}
,调用如下:
let graph = new LineGraph(500, 500, '#content');
let parse_time = d3.timeParse('%d-%b-%y');
let data1 = [
{date: parse_time('1-May-12'), value: 158.13},
{date: parse_time('30-Apr-12'), value: 153.98},
{date: parse_time('27-Apr-12'), value: 167.00}
];
let data2 = [
{date: parse_time('2-May-12'), value: 242.42},
{date: parse_time('1-May-12'), value: 158.13},
{date: parse_time('30-Apr-12'), value: 153.98},
{date: parse_time('27-Apr-12'), value: 167.00}
];
graph.draw(data1.sort((a, b) => a.date - b.date));
setTimeout(() => {
graph.draw(data2.sort((a, b) => a.date - b.date));
}, 2000);
答案 0 :(得分:2)
与data()
方法不同,datum()
不计算连接。根据{{3}}:
与selection.data不同,此方法不计算连接,也不影响索引或输入和退出选择。
此外,select
和selectAll
在分组和数据传播方面表现不同。您应该使用selectAll
,即使图表中只有一行。看看这张表:
+--------------------+----------------------------------+----------------------------+
| Method | select() | selectAll() |
+--------------------+----------------------------------+----------------------------+
| Selection | selects the first element | selects all elements that |
| | that matches the selector string | match the selector string |
+--------------------+----------------------------------+----------------------------+
| Grouping | Does not affect grouping | Affects grouping |
+--------------------+----------------------------------+----------------------------+
| Data propagation | Propagates data | Doesn't propagate data |
+--------------------+----------------------------------+----------------------------+
因此,您的第一个代码段应为:
draw_line(data) {
let selection = this.svg.selectAll('path.line')
//'selectAll' here ----------^
.data([data]);
// ^--- 'data' instead of 'datum'
selection.enter()
.append('path')
.attr('class', 'line')
.attr('d', this.line);
selection.transition(this.transition)
.attr('d', this.line);
}