更新数据是输入更新和退出选择的基本示例

创建显示静态数据集的图表相对简单。例如,如果我们将这个对象数组作为数据:

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
};

这些变化的部分包括:

  1. 输入,更新和退出选择;
  2. 每个规模的领域;
  3. 轴的过渡;

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 种选择。