在包装元素中呈现更新的数据

时间:2014-06-26 02:17:56

标签: javascript d3.js

我是d3的新手,并努力理解数据绑定。这是一个fiddle,代码如下。

我们说我有一些数据会在以后更新。请注意,6变为1

data1 = [
    { key: 'orig7', val: 7 },
    { key: 'orig3', val: 3 },
    { key: 'orig6', val: 6 }
];
data2 = [
    { key: 'orig7', val: 7 },
    { key: 'orig3', val: 3 },
    { key: 'orig6', val: 1 },
    { key: 'new5', val: 5 }
];

然后我渲染它们。我的代码要求将数据更深入地嵌入到元素中。这是两个渲染功能;它们的区别仅在于第一个是简单的,没有这样的包装,第二个在文本周围创建了一个内部div。

function render1(data) {
    var result = d3.select('#list1').selectAll('.item')
        .data(data, function(d, i) { return d.key });
    result.enter()
        .append('div')
            .classed('item', true)                       // set up a div
    result                                               // set text in the div
        .text(function(d, i) { return '' + d.key + "=" + d.val; });
    result.exit().remove();
    result.sort(function(a, b) { return a.val < b.val ? -1 : 1 });
}

function render2(data) {
    var result = d3.select('#list2').selectAll('.item')
        .data(data, function(d, i) { return d.key });
    result.enter()
        .append('div')
            .classed('item', true)
        .append('div')                                   // set up an *inner* div
    result.selectAll('div')                              // set text in the inner div
        .text(function(d, i) { return '' + d.key + "=" + d.val; });
    result.exit().remove();
    result.sort(function(a, b) { return a.val < b.val ? -1 : 1 });
}

让我们使用两种渲染函数渲染数据。

render1(data1);
render1(data2);

render2(data1);
render2(data2);

输出如下:

orig6=1
orig3=3
new5=5
orig7=7

orig6=6
orig3=3
new5=5
orig7=7

排序效果很好,因为它对.item中存储的数据进行操作。

但是,文字存在差异。如果我插入一个内部div,它将从父级继承该数据,但此数据不会更新,并保持6(而我希望它反映更新的值1,如第一个渲染的例子。)

内部div究竟在哪里获取数据的副本,如何在新数据绑定时强制更新它?

编辑:标题与问题无关;道歉。

2 个答案:

答案 0 :(得分:1)

解决这个问题实际上是非常微不足道的。你所要做的就是改变

result.selectAll('div')

result.select('div')

完整演示here。如果使用.select(),则绑定到当前选择的数据(新选择的“基数”)也绑定到新选择的元素。如果您使用.selectAll(),则情况并非如此。这正是你所看到的。

在这里使用.select()似乎违反直觉,因为您选择了多个元素。但是,请记住原始选择已包含多个元素,并且为每个元素执行选择器。也就是说,对于当前选择中的每个元素,只选择一个元素.select()(这是您在这种情况下需要的),以及多个元素.selectAll()(这对于树状是有意义的)层次结构)。

答案 1 :(得分:0)

使用此解决:

result.each(function(d, i) {
  d3.select(this).select('div').datum(d);
});

但必须有一种我没有看到的更好的方法。不是吗?