我有一个用d3.js构建的散点图。它在图表中绘制了特定人群的消费习惯。
我有一个选择菜单,用于更改特定用户并更新散点图上的圆圈。
问题是更新时未删除旧圈子。
我应该如何使用.remove() .update()
,请参阅此plnkr了解工作示例
答案 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();
}