【发布时间】:2019-03-16 00:32:19
【问题描述】:
我对 D3 还很陌生,但是我看到的所有示例都重新定义了元素更新时的创建。如果您想更改元素的定义方式(例如将圆形更改为矩形),我可以看到一个论点,但在大多数情况下,我需要定义是相同的。
此示例是this 答案和this 答案的合并。它更接近我的实际用例,但也突出了重复的数量。
希望我在定义这一点的方式上偏离了基础,并且有一种更整洁的方式来做到这一点。或者,我猜答案是“是的,这是这样做的理想方式”。
var svg = d3.select("svg");
d3.select("button").on("click", update);
let color = d3.scaleOrdinal().range(d3.schemeAccent);
let data;
update();
function update() {
updateData();
updateNodes();
}
function updateData() {
let numNodes = ~~(Math.random() * 4 + 10);
data = d3.range(numNodes).map(function(d) {
return {
size: ~~(Math.random() * 20 + 3),
x: ~~(Math.random() * 600),
y: ~~(Math.random() * 200)
};
});
}
function updateNodes() {
var node = svg.selectAll(".node").data(data);
node.exit().remove();
node
.enter()
.append("g")
.classed("node", true)
.append("circle")
.classed("outer", true)
.attr("fill", d => color(d.size))
.attr("opacity", 0.5)
.attr("r", d => d.size * 2)
.attr("cx", d => d.x)
.attr("cy", d => d.y)
.select(function() { return this.parentNode; }) //needs an old style function for this reason: https://stackoverflow.com/questions/28371982/what-does-this-refer-to-in-arrow-functions-in-es6 .select(()=> this.parentNode) won't work
.append("circle")
.classed("inner", true)
.attr("fill", d => color(d.size))
.attr("r", d => d.size)
.attr("cx", d => d.x)
.attr("cy", d => d.y)
.select(function() { return this.parentNode; })
.append("text")
.attr("x", d => d.x)
.attr("y", d => d.y)
.attr("text-anchor", "middle")
.text(d => d.size);
node
.select("circle.inner")
.transition()
.duration(1000)
.attr("fill", d => color(d.size))
.attr("r", d => d.size)
.attr("cx", d => d.x)
.attr("cy", d => d.y);
node
.select("circle.outer")
.transition()
.duration(1000)
.attr("fill", d => color(d.size))
.attr("opacity", 0.5)
.attr("r", d => d.size * 2)
.attr("cx", d => d.x)
.attr("cy", d => d.y);
node
.select("text")
.transition()
.duration(1000)
.attr("x", d => d.x)
.attr("y", d => d.y)
.attr("text-anchor", "middle")
.text(d => d.size);
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<button>Update</button>
<br>
<svg width="600" height="200"></svg>
【问题讨论】:
-
您无法确定当前代码中的节点是否已更新,因此每次更新都会删除所有现有数据点并用新集合替换它们。
标签: d3.js