我有一些資料偶爾會洗掉和添加資料。這并不經常發生,但可以快速連續發生。
我發現dataGroups.exit().transition()....remove()“覆寫”了 enter dataGroups.enter(...).append(...).transition()。
似乎當一個專案被移除,然后再次“進入”時,它無法停止移除程序,因此該專案要么被移除,要么處于移除狀態(例如透明或尺寸為 0)。
這是一個作業示例,緩慢單擊按鈕,它按預期作業,但太快了,您會在應該在那里時丟失下欄。
我嘗試添加interupt()以嘗試中斷退出影片,但它似乎不起作用。找不到對此的任何參考,但我很驚訝這不是有人以前見過并提出解決方案的問題:
const dataset1 = [
{ name: "item 1", value: 200 },
{ name: "item 2", value: 100 }
];
const dataset2 = [{ name: "item 1", value: 100 }];
let currentDataset = undefined;
function refresh() {
const newDataset = currentDataset === dataset1 ? dataset2 : dataset1;
currentDataset = newDataset;
// Join new data with old elements, if any.
const dataGroups = d3
.select(".vis")
.selectAll(".box")
.data(newDataset, (d) => d.name);
// Remove old elements as needed.
dataGroups
.exit()
.transition("remove")
.duration(400)
.attr("opacity", 0.2)
.remove();
// Create new elements as needed.
const newGroups = dataGroups
.enter()
.append("rect")
.attr("class", "box")
.attr("height", 10);
newGroups.transition("add").duration(400).attr("opacity", 1);
// Merge and update
newGroups
.merge(dataGroups)
.attr("width", (d) => d.value)
.attr("y", (d, i) => i * 12);
}
document.getElementById("button").onclick = () => {
refresh();
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
</head>
<body>
<button id="button">Update data</button>
<svg class="vis" width="200" height="30"></svg>
<p>
Click the button slowly, and see it add and remove elements with a
transition
</p>
<p>
Click the button twice in quick succession, and see it doesn't correctly
represent the data
</p>
<p>It should look like:</p>
<pre>
|====
|==
</pre
>
<p>Or:</p>
<pre>
|==
|
</pre
>
<p>Never:</p>
<pre>
|====
|
</pre
>
<script src="src/index.js"></script>
</body>
</html>
https://codesandbox.io/s/focused-almeida-dp58f?file=/src/index.js
uj5u.com熱心網友回復:
首先,應該注意到 D3 選擇是不可變的,因此merge在您的輸入選擇上使用您正在做的方式沒有任何影響。此外,0如果您想正確地看到過渡,您應該將輸入選擇的不透明度設定為。
回到問題,這里的問題是當您選擇所有具有box類的元素時,退出欄會被計算在內,因此您的輸入選擇是空的。最簡單的解決方案是使用selection.interrupt(). 與您所說的相反,interrupt 確實有效,但問題是因為您命名了退出轉換,因此需要使用相同的名稱:
dataGroups.interrupt("remove");
這是帶有該更改的代碼:
顯示代碼片段
const dataset1 = [{
name: "item 1",
value: 200
},
{
name: "item 2",
value: 100
}
];
const dataset2 = [{
name: "item 1",
value: 100
}];
let currentDataset = undefined;
function refresh() {
const newDataset = currentDataset === dataset1 ? dataset2 : dataset1;
currentDataset = newDataset;
// Join new data with old elements, if any.
let dataGroups = d3
.select(".vis")
.selectAll(".box")
.data(newDataset, (d) => d.name);
dataGroups.interrupt("remove");
dataGroups.attr("opacity", 1);
// Remove old elements as needed.
dataGroups
.exit()
.transition("remove")
.duration(400)
.attr("opacity", 0.2)
.remove();
// Create new elements as needed.
const newGroups = dataGroups
.enter()
.append("rect")
.attr("class", "box")
.attr("height", 10)
.attr("opacity", 0)
newGroups.transition("add").duration(400).attr("opacity", 1);
// Merge and update
dataGroups = newGroups.merge(dataGroups);
dataGroups.attr("width", (d) => d.value)
.attr("y", (d, i) => i * 12);
}
document.getElementById("button").onclick = () => {
refresh();
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
</head>
<body>
<button id="button">Update data</button>
<svg class="vis" width="200" height="30"></svg>
<p>
Click the button slowly, and see it add and remove elements with a transition
</p>
<p>
Click the button twice in quick succession, and see it doesn't correctly represent the data
</p>
<p>It should look like:</p>
<pre>
|====
|==
</pre
>
<p>Or:</p>
<pre>
|==
|
</pre
>
<p>Never:</p>
<pre>
|====
|
</pre
>
<script src="src/index.js"></script>
</body>
</html>
此外,我dataGroups.attr("opacity", 1);在中斷過渡后放置了一個,因此我們將淡入淡出欄的不透明度恢復為 1。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/404443.html
標籤:
下一篇:X軸和Y軸不在一起
