d3 - 输入 - 附加太多元素,就好像数据没有绑定一样

时间:2013-12-30 15:41:30

标签: javascript d3.js

我要求这不要让代码正常工作,但要确保我正确理解d3。我创建了一个d3条形图示例,我用它来更好地理解d3的数据绑定和更新模式。小提琴在这里:http://jsfiddle.net/qP9j9/22/

小提琴最好地解释了这个问题,但我也会在下面尝试解释:

我已将数据绑定和视图拆分为两个独立的函数:

var updateData = function() {

  data = generateRandomData();
  chart = d3.select('.chart').selectAll('div').data(data);
  y = d3.scale.linear().domain([0, Math.floor(d3.max(data))]).range([1,300]);

  updateChart();

};

var updateChart = function() {

  var margin = 1;
  var barWidth = (parseInt(d3.select('.chart').style('width'))/15) - margin;

  chart.transition()
        .style('height', function(d) { return y(d) + 'px' })
        .style('width', function() { return barWidth + 'px' })
        .style('left', function(d, i) { return (i * (barWidth+margin)) + 'px' });

  chart.enter().append('div')
        .style('height', function() { return 0; })
        .style('width', function() { return barWidth + 'px' })
        .style('left', function(d, i) { return (i * (barWidth+margin)) + 'px' })
        .transition()
        .style('height', function(d) { return y(d) + 'px' });

  chart.exit().remove();

};

在调整大小时,我正在运行updateChart函数。我的想法是,当它没有改变时我宁愿不绑定数据,只需更新视图。当数据实际发生变化时,我运行updateData函数。

奇怪的是,updateData函数需要运行两次才能使事情正常工作。如果只调用updateData一次(当页面首次加载时),那么当updateChart运行时,enter()函数会再次附加数据。因此,当页面调整大小时,您只需获得重复的dom元素。

我已经尽可能地研究了这个问题,包括查看一些建议的“类似问题”,我当然可以轻松地“解决”这个问题。但感觉有一些基本的我不理解。

1 个答案:

答案 0 :(得分:1)

D3背后的主要思想是链接数据和文档,因此将两者分开是一个坏主意,就像你已经完成的那样。特别是,您正在使用.enter().exit()选项,如果您之前未明确绑定数据,则这些选择无法正常运行。在您的情况下,.enter()选项包含先前的选择,这就是为什么所有内容都被添加两次。

我的建议是两个一个功能更新,而不是两个单独的功能。如果您确实想要将它们分开,则需要在.enter()函数中处理.exit()updateData()选项,因为我已经在您更新过的小提琴{{1}} {{1}} 3}}