gpt4 book ai didi

javascript - d3.join() 输入调用而不是更新?

转载 作者:行者123 更新时间:2023-11-30 13:50:39 25 4
gpt4 key购买 nike

我试图让 D3 每秒更新一次 SVG 元素,方法是将一个新的 Date 对象传递给 data() 函数,然后是 join () 来更新页面。我实际上是在 Observable 中这样做的使用 Promises.tick() 的笔记本,但我认为下面的代码 ( full source ) 是相关位的粗略近似。我的最终目标是制作一个时钟,但此处的代码是我遇到的问题的最小演示。

此代码的问题是 join() 中的 update 函数从未被调用——每次循环时 enter而是调用函数,这导致每次都附加一个新的 text。因为我有一个数据和一个元素,所以我希望调用 joinupdate,而不是 enter。我知道 data() ( example ) 上的关键函数对于确定发生了什么变化很重要,但我的理解是默认键是数组索引,在这里它应该始终为 0。无论如何,指定不同的关键函数(从身份函数到返回常量)都没有帮助。

while (true) {
var data = [new Date()];

svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.selectAll("text")
.data(data)
.join(
enter => enter.append("text").text(d => "enter: " + d),
update => update.text(d => "update: " + d)
);

await new Promise(resolve => setTimeout(resolve, 1000));
}

最佳答案

看看这个:

svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
//etc...

您正在附加一个新的<g>每次运行循环时的元素,之后所有选定的元素(文本或其他)将引用新添加的组,即 selectAll选择新添加的组的所有文本。显然,没有。这就是为什么您总是只有一个输入选择,而没有更新选择。

看看这个演示,重现您的问题:

var body = d3.select("body");

function foo(data) {
var div = body.append("div")
.selectAll("p")
.data(data)
.join(
enter => enter.append("p").html(d => "enter: " + d),
update => update.html(d => "update: " + d)
);
};

foo([Math.random()]);
d3.interval(function() {
foo([Math.random()])
}, 1000)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.8.0/d3.min.js"></script>

假设你想只添加一次,你可以这样做:

var g = svg.selectAll(".myGroup")
.data([true]);

g = g.enter()
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.merge(g);

g.selectAll("text")
.data(data)
.join(
enter => enter.append("text").text(d => "enter: " + d),
update => update.text(d => "update: " + d)
);

在这里,data([true])表示数据本身并不重要,它只是一个真值,用于附加单个组元素。

这是一个展示其工作原理的演示:

var body = d3.select("body");

function foo(data) {
var div = body.selectAll(".myDiv")
.data([true]);

div = div.enter()
.append("div")
.attr("class", "myDiv")
.merge(div);

div.selectAll("p")
.data(data)
.join(
enter => enter.append("p").html(d => "enter: " + d),
update => update.html(d => "update: " + d)
);
};

foo([Math.random()])
d3.interval(function() {
foo([Math.random()])
}, 1000)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.8.0/d3.min.js"></script>

关于javascript - d3.join() 输入调用而不是更新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58322806/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com