在更新时从散点图中删除旧圆圈

时间:2014-10-31 01:48:07

标签: javascript svg d3.js graph

我有一个用d3.js构建的散点图。它在图表中绘制了特定人群的消费习惯。

我有一个选择菜单,用于更改特定用户并更新散点图上的圆圈。

问题是更新时未删除旧圈子。

我应该如何使用.remove() .update(),请参阅此plnkr了解工作示例

http://plnkr.co/edit/qtj1ulsVVCW2vGBvDLXO?p=info

1 个答案:

答案 0 :(得分:3)

首先,Alan,我建议您遵循一些编码样式约定,以使您的代码可读。我知道D3示例和库代码本身几乎从不提升代码可读性,但它首先符合您的利益,因为它更容易维护可读代码。

其次,当您更改数据时,您需要了解D3如何使用输入更新退出设置。 Mike Bostock的Thinking with Joins可能是一个好的开始。除非您了解连接的工作原理,否则您将无法对动态D3图表进行编程。

第三,这是updateScatter中的错误。 name.length没有意义,因为您的名字变量是value。因此,首先不是删除旧数据的情况。

// Update circles for the selected user chosen in the select menu.
svg.selectAll(".markers")
    .data(data.filter(function(d){ return d.FirstName.substring(0, name.length) === value;}))
    .transition().duration(1000)
    .attr("cx", function(d) { return xScale(d.timestamp); })
    .attr("cy", function(d) { return yScale(d.price); });

同样奇怪的平等比较是d.FirstName.substring(0, name.length) === name。您的名字数据在CSV文件中的间距不均匀。简单d.FirstName == name是公平的。如果您仍然期望尾随空格,只需在您强制价格和日期的地方修剪字符串。

这就是updateScatter看起来如此正确的方式:

function updateScatter() 
{
  var selectedFirstName = this.value;
  var selectedData      = data.filter(function(d) 
  {
    return d.FirstName == selectedFirstName;
  });

  yScale.domain([
    0, 
    d3.max(selectedData.map(function(d) 
    {
      return d.price;
    }))
  ]);

  svg.select(".y.axis")
    .transition().duration(750)
    .call(yAxis);

  // create *update* set
  var markers = svg.selectAll(".markers").data(selectedData);

  // create new circles, *enter* set
  markers.enter()
    .append('circle')
    .attr("class", 'markers')
    .attr("cx", function(d) 
    {
      return xScale(d.timestamp);
    })
    .attr("cy", function(d) 
    {
      return yScale(d.price);
    })
    .attr('r', 5)
    .style('fill', function(d) 
    {
      return colour(cValue(d));
    });

  // transition *update* set
  markers.transition().duration(1000)
    .attr("cx", function(d) 
    {
      return xScale(d.timestamp);
    })
    .attr("cy", function(d) 
    {
      return yScale(d.price);
    });

  // remove *exit* set
  markers.exit().remove();
}