Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/467.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我可以在D3联接中合并新数据和现有数据吗?_Javascript_D3.js - Fatal编程技术网

Javascript 我可以在D3联接中合并新数据和现有数据吗?

Javascript 我可以在D3联接中合并新数据和现有数据吗?,javascript,d3.js,Javascript,D3.js,我想维护一个由键索引的元素列表,它的作用类似于该键上的累加器 我有一个实时更新周期,它会重复生成在同一个键上索引的项目子集,我想在它们被吸收到现有列表中时设置累积过程的动画 在我的简单示例中,我只想计算看到每个键的次数 如果我一开始就有所有的数据,我只会使用d3.nest(),但我不想在每次更新时重新汇总整个历史记录或重新绘制每个项目 我想使用D3将我的新数据项加入到现有选择中,并合并每个键的新旧数据,但我看不出如何避免我的新数据项仅仅覆盖任何现有数据。是否有方法将现有基准与新基准结合起来,以生

我想维护一个由键索引的元素列表,它的作用类似于该键上的累加器

我有一个实时更新周期,它会重复生成在同一个键上索引的项目子集,我想在它们被吸收到现有列表中时设置累积过程的动画

在我的简单示例中,我只想计算看到每个键的次数

如果我一开始就有所有的数据,我只会使用
d3.nest()
,但我不想在每次更新时重新汇总整个历史记录或重新绘制每个项目

我想使用D3将我的新数据项加入到现有选择中,并合并每个键的新旧数据,但我看不出如何避免我的新数据项仅仅覆盖任何现有数据。是否有方法将现有基准与新基准结合起来,以生成合并基准

<html>
    <head>
        <script src="http://d3js.org/d3.v3.min.js"></script>
    </head
    <body>
        <div id="stuff">
        </div>

<script>

// set up a list of accumulators with count set to 0
d3.select('#stuff')
  .selectAll('.grid')
  .data(
    d3.range(10).map(function(i) { return {key: i*2, count: 0}; }),
    function(d) { return d.key; }
  )
 .enter().append('div')
  .classed('grid', true)
  .text(function(d) { return 'key: ' + d.key + ', count: ' + d.count });

// while(true) receive new items...

// now repeatedly receive a new list of items to accumulate into the existing list
var ticks = [{key: 4}, {key: 8}, {key: 14}];

// how can I combine the old and new datums during this join?
d3.selectAll('.grid')
    .data(
        ticks, 
        function(d) { return d.key; } 
        /*  Conceptually want to provide a function to merge old and new datum */
        //  , function(dnew, dold) { dold.count += 1; return dold; }
   )
  .text(function(d) { return 'key: ' + d.key + ', count: ' + d.count });

</script>

    </body>
</html>

我不确定是否有一种惯用的D3方法来处理这个问题,但实现您想要的应该很简单,即通过在绑定之前与选择数据进行比较来增加ticks数据,即:

ticks.forEach(function(t) {
    var boundData = d3.selectAll('.grid').data().filter(function(d) { return d.key === t.key; });
    t.count = boundData[0] ? boundData[0].count += 1 : 0;
});
注意,这也说明了潜在的新元素

请参阅:

我最终使用了一个d3.map()来通过filter函数进行手动就地合并,这似乎有点像d3。这不处理新项目,但在我的例子中,我提前知道基本网格,我只是不知道每个时间步要更新哪些点

... 

var tickmap = d3.map();
ticks.forEach(function(d){ tickmap.set(d.key, 1); });

d3.selectAll('.grid')
  .filter(function(d) {  // filter and update only matching items
    if (tickmap.has(d.key)) {
      d.count += tickmap.get(d.key);
      return true;
    } else {
      return false;
    }
  })
  .style('color', 'red')  // redraw matching items in red
  .text(function(d) { return 'key: ' + d.key + ', count: ' + d.count });

...

是的,这类似于我必须在您编写的同时添加的提取/过滤/更新解决方案。虽然你的forEach方法需要扫描整个网格中的每一个新元素,但是你需要阅读D3Wiki的这一部分:这不是一个很有成效的评论。我不想输入新元素,我想更新现有元素中的数据。
ticks.forEach(function(t) {
    var boundData = d3.selectAll('.grid').data().filter(function(d) { return d.key === t.key; });
    t.count = boundData[0] ? boundData[0].count += 1 : 0;
});
... 

var tickmap = d3.map();
ticks.forEach(function(d){ tickmap.set(d.key, 1); });

d3.selectAll('.grid')
  .filter(function(d) {  // filter and update only matching items
    if (tickmap.has(d.key)) {
      d.count += tickmap.get(d.key);
      return true;
    } else {
      return false;
    }
  })
  .style('color', 'red')  // redraw matching items in red
  .text(function(d) { return 'key: ' + d.key + ', count: ' + d.count });

...