今天我使用enter-update-exit逻辑创建了一个简单的条形图 - 一切正常。现在我将使用折线图进行相同的操作 - 图表的整个数据集可以随时更改,因此我将顺利更新图表。我无法用折线图和enter-update-exit逻辑(或者我看错了)找到一个很好的例子。目前我必须记住,如果第一次调用图表或更新数据(数据已更改) - 这是我的脏版本:
var channelGroup = d3.select(".ch1");
// init. Line Chart
if (firstLoad) {
channelGroup
.append('path')
.attr("class", "line")
.style("stroke", channel.Color)
.transition()
.ease("linear")
.duration(animChart / 2)
.attr('d', line(channel.DataRows));
}
// update Line Chart
else {
channelGroup
.selectAll("path")
.data([channel.DataRows])
.transition()
.ease("linear")
.duration(animChart / 2)
.attr("d", function (d) { return line(d); });
}
我怎样才能以良好的方式实现这一目标?... thx!
答案 0 :(得分:10)
你混合了两种不同的方法,一种是将数据绑定到线上,另一种只是将数据传递给线函数。任何一个都可以工作(只要你只有一行),但如果你想摆脱你的if / else结构,你仍然需要将处理输入/附加元素的语句与语句更新分开它
选项1 (不要绑定数据,只需调用该函数):
var linegraph = channelGroup.select('path');
if ( linegraph.empty() ) {
//handle the entering data
linegraph = channelGroup.append('path')
.attr("class", "line")
.style("stroke", channel.Color);
}
linegraph
.transition()
.ease("linear")
.duration(animChart / 2)
.attr('d', line(channel.DataRows));
选项2 (使用数据连接):
var linegraph = channelGroup.selectAll("path")
.data([channel.DataRows]);
linegraph.enter().append('path')
.attr("class", "line");
linegraph
.transition()
.ease("linear")
.duration(animChart / 2)
.attr("d", line); //This is slightly more efficient than
//function (d) { return line(d); }
//and does the exact same thing.
//d3 sees that `line` is a function, and
//therefore calls it with the data as the
//first parameter.