我有一个用 d3.js 构建的散点图。它在图表中绘制圆圈来表示特定人群的消费习惯。
我有一个选择菜单,可以更改特定用户并更新散点图上的圆圈。
问题是旧的圆圈在更新时没有被删除。
哪里应该怎么使用.remove() .update()
,请看这个plnkr一个工作示例
最佳答案
首先,Alan,我建议您遵守一些编码风格约定,以使您的代码具有可读性。我知道 D3 示例以及库代码本身几乎从不提高代码可读性,但它首先符合您的利益,因为维护可读代码要容易得多。
其次,您需要了解当您更改数据时,D3 如何与进入、更新和退出集一起工作。迈克博斯托克的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
就足够了。如果您无论如何都希望尾随空格,只需在强制价格和日期的地方 trim 字符串即可。
这就是正确的 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();
}
关于javascript - 更新时从散点图中删除旧圆圈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26666334/