gpt4 book ai didi

javascript - 如何在不破坏现有进入/退出绑定(bind)的情况下更新整个数据集?

转载 作者:行者123 更新时间:2023-12-03 11:04:27 25 4
gpt4 key购买 nike

编辑

我创建了一个更简单的示例,几乎完全源自 Mike Bostock 的 Sankey图表示例。你可以看到一个JSFiddle这证明了同样的事情。这只是加载 Sankey 可视化,然后定期重新加载完全相同的数据。

这使用了我相信的一般更新模式,并且由于这只处理已进入的节点/边,我预计不会发生任何事情。实际上,SVG 不断地在顶部分层。您可以看到更新代码非常简单 - 重新加载原始数据源,这应该意味着没有新输入的数据条目:

// Initial Load
d3.json("https://dl.dropboxusercontent.com/u/41796243/JSFiddle/D3%20Update/energy.json", function(energy) {
update(energy);
});

// Refresh
setInterval(function() {
d3.json("https://dl.dropboxusercontent.com/u/41796243/JSFiddle/D3%20Update/energy.json", function(energy) {
update(energy);
})
}, 2000);

在更新函数中,应该简单地为任何新数据条目渲染边缘:

 var link = svg.append("g").selectAll(".link")
.data(data.links)
.enter().append("path")
.attr("class", "link")
.attr("d", path)
.style("stroke-width", function(d) { return Math.max(1, d.dy); })
.sort(function(a, b) { return b.dy - a.dy; });

当渲染时,您可以从下面的屏幕截图中看到它如何错误地不断更新边缘:

enter image description here

<小时/>

原创

我帮助制​​作了一个可视化,我正在尝试对其进行更新。我见过的很多示例只是在内存中更新对象数据 - 而我想返回服务器并请求替换数据集以查看是否已引入新项目/值已更改。这个可视化看起来像这样:

enter image description here

我最初使用 d3.json 调用加载数据,如下所示:

d3.json("https://dl.dropboxusercontent.com/u/41796243/JSFiddle/Sankey/data.json", 
function(data) {
sankey.data(data);
sankey.render();
}
);

然后我想做的是加载一个新的 JSON 文件(包含几乎相同的数据 - 有一些细微的更改)并更新可视化:

$("#update").click(function() {
d3.json("https://dl.dropboxusercontent.com/u/41796243/JSFiddle/Sankey/data2.json",
function(data) {
sankey.data(data);
sankey.render();
})
})

然而,发生的情况是数据似乎丢失了所有绑定(bind)。如果我继续单击更新按钮,那么您可以看到半不透明的线条不断添加到彼此的顶部,产生如下所示的图片:

enter image description here

现在,虽然我没有明确删除链接,只是使用以下代码添加新链接,但我没想到在图表本身没有更改时添加任何链接:

// Create new links between nodes
var links = vis.append("g")
.selectAll(".link")
.data(data.links);

links.enter()
.append("path")
.attr("class", "link")
.attr("d", sankey.link())
.style("stroke-width", "6px")
.style("marker-end", "url(#end-arrow)")
.style("stroke", "#fff")
.style("opacity", 0.2)
.style("fill", "none")
.style("hover-opacity", 0.5)
.sort(function (a, b) { return b.dy - a.dy; });

我期望线路保持原样,并且不会有新的链接,而只是对现有链接进行更新。由于我没有明确更新现有链接,因此我不希望它们改变外观。

所以问题是为什么会发生这种情况(我的猜测是由于数据的完全重新加载)以及如何防止它发生,同时仍然再次加载整个数据集?

这是一个JSFiddle来演示这个问题。有趣的代码位于 #97-#150 行之间的 control.render 函数中。

最佳答案

您的实现中的问题是,您在调用 update 函数时不断添加两个新的 g 元素。您可以在 JSFiddle 中观察到这一点(一段时间后,您的 svg 元素中就会有很多 g)。

怎么解决这个问题?嗯,有很多方法,这里是一个例子:

首先添加一些容器来放置元素:

var linkContainer = svg.append('g');
var nodeContainer = svg.append('g');

(您可以在定义 svg 之后立即执行此操作,即外部更新函数。

接下来,在更新函数中将元素添加到这些容器中:

var link = linkContainer.selectAll(".link")....

节点也是如此。

我希望这应该可以解决问题。

另一种方法是将 svg 元素中的组绑定(bind)到一些随机固定数据,并对其使用 .enter().append() (从而确保它是只添加一次,因为数据是固定的...)

希望这会有所帮助!

关于javascript - 如何在不破坏现有进入/退出绑定(bind)的情况下更新整个数据集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27927588/

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