更新数据是输入更新和退出选择的基本示例
创建显示静态数据集的图表相对简单。例如,如果我们将这个对象数组作为数据:
var data = [
{title: "A", value: 53},
{title: "B", value: 12},
{title: "C", value: 91},
{title: "D", value: 24},
{title: "E", value: 59}
];
我们可以创建一个条形图,其中每个条形表示一个名为 title
的度量,其宽度表示该度量的值。由于此数据集未更改,我们的条形图只有一个输入选项:
var bars = svg.selectAll(".bars")
.data(data);
bars.enter()
.append("rect")
.attr("class", "bars")
.attr("x", xScale(0))
.attr("y", function(d){ return yScale(d.title)})
.attr("width", 0)
.attr("height", yScale.bandwidth())
.transition()
.duration(1000)
.delay(function(d,i){ return i*200})
.attr("width", function(d){ return xScale(d.value) - margin.left});
在这里,我们将每个条的宽度设置为 0,并在转换后将其设置为其最终值。
仅此输入选择就足以创建我们的图表,你可以在这个小提琴中看到。
但是如果我的数据发生了变化呢
在这种情况下,我们必须动态更改我们的图表。最好的方法是创建输入,更新和退出选择。但是,在此之前,我们必须对代码进行一些更改。
首先,我们将在名为 draw()
的函数中移动更改的部分:
function draw(){
//changing parts
};
这些变化的部分包括:
- 输入,更新和退出选择;
- 每个规模的领域;
- 轴的过渡;
在 draw()
函数里面,我们调用另一个函数来创建我们的数据。在这里,它只是一个返回 5 个对象的数组的函数,从 10 个中随机选择 5 个字母(按字母顺序排序),对于每个对象,选择 0 到 99 之间的值:
function getData(){
var title = "ABCDEFGHIJ".split("");
var data = [];
for(var i = 0; i < 5; i++){
var index = Math.floor(Math.random()*title.length);
data.push({title: title[index],
value: Math.floor(Math.random()*100)});
title.splice(index,1);
}
data = data.sort(function(a,b){ return d3.ascending(a.title,b.title)});
return data;
};
现在,让我们转向我们的选择。但在此之前,需要注意的是:为了维护我们所谓的对象恒定性,我们必须指定一个关键函数作为 selection.data 的第二个参数:
var bars = svg.selectAll(".bars")
.data(data, function(d){ return d.title});
如果没有它,我们的条形图将不会平滑过渡,并且很难跟踪轴上的变化(你可以看到删除下面的小提琴中的第二个参数)。
因此,在正确设置我们的 var bars
后,我们可以处理我们的选择。这是退出选择:
bars.exit()
.transition()
.duration(1000)
.attr("width", 0)
.remove();
这些是输入和更新选择(在 D3 v4.x 中,更新选择与使用 merge
的输入选择合并):
bars.enter()//this is the enter selection
.append("rect")
.attr("class", "bars")
.attr("x", xScale(0) + 1)
.attr("y", function(d){ return yScale(d.title)})
.attr("width", 0)
.attr("height", yScale.bandwidth())
.attr("fill", function(d){ return color(letters.indexOf(d.title)+1)})
.merge(bars)//and from now on, both the enter and the update selections
.transition()
.duration(1000)
.delay(1000)
.attr("y", function(d){ return yScale(d.title)})
.attr("width", function(d){ return xScale(d.value) - margin.left});
最后,每次单击按钮时我们都会调用 draw()
函数:
d3.select("#myButton").on("click", draw);
而这是小提琴显示在行动所有这些 3 种选择。