在d3中,我們可以更改選擇中元素的順序,例如使用raise.
然而,當我們重新系結資料并使用join時,這個順序就被丟棄了。
當我們使用“舊方式”系結資料時,不會發生這種情況,使用enterand merge。
請參閱以下小提琴,您可以在其中單擊一個圓圈(例如藍色圓圈)將其帶到前面。當您單擊“重繪”時,圓圈會在使用 時恢復到原來的 z 順序join,但在使用enterand時不會merge。
我可以實作圓圈保持其 z 順序并仍然使用join嗎?
const data = [{
id: 1,
v: 10,
c: 'red'
}, {
id: 2,
v: 30,
c: 'blue'
}, {
id: 3,
v: 60,
c: 'green'
}]
let nDrawCall = 0
function redraw() {
nDrawCall
//svg1 with old enter-merge pattern that works
const circles = d3.select('#svg1')
.selectAll('circle')
.data(data, d => d.id)
circles
.enter()
.append('circle')
.on('click', function() {
d3.select(this).raise()
})
.merge(circles)
.attr('cx', d => d.v * nDrawCall)
.attr('cy', d => d.v)
.attr('r', d => d.v)
.attr('fill', d => d.c)
//svg2 with new join pattern that sadly reorders
d3.select('#svg2')
.selectAll('circle')
.data(data, d => d.id)
.join(enter => enter
.append('circle')
.on('click', function() {
d3.select(this).raise()
})
)
.attr('cx', d => d.v * nDrawCall)
.attr('cy', d => d.v)
.attr('r', d => d.v)
.attr('fill', d => d.c)
}
function reset() {
nDrawCall = 0
redraw()
}
redraw()
/*
while (true) {
iter
console.log(iter)
sleepFor(500)
}
*/
svg {
height: 100px;
width: 100%;
}
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.3.0/d3.min.js"></script>
</head>
<body>
<button onclick="redraw()">
Redraw
</button>
<button onclick="reset()">
Reset
</button>
<div>
<svg id="svg1" />
<svg id="svg2" />
</div>
</body>
</html>
uj5u.com熱心網友回復:
joinorder在合并輸入和更新選擇后執行隱式操作,請參閱https://github.com/d3/d3-selection/blob/91245ee124ec4dd491e498ecbdc9679d75332b49/src/selection/join.js#L14。
即使更改了檔案順序,您的示例中資料系結后的選擇順序仍然是紅色、藍色、綠色。因此,使用 將圓圈重新排序為原始順序join。
您可以通過更改反映檔案順序更改的資料系結來解決此問題。我在這里通過將點擊的圓圈的基準移動到資料陣列的末尾來做到這一點。
let data = [{
id: 1,
v: 10,
c: 'red'
}, {
id: 2,
v: 30,
c: 'blue'
}, {
id: 3,
v: 60,
c: 'green'
}]
let nDrawCall = 0
function redraw() {
nDrawCall
d3.select('#svg2')
.selectAll('circle')
.data(data, d => d.id)
.join(enter => enter
.append('circle')
.on('click', function() {
const circle = d3.select(this).raise();
data.push(data.splice(data.indexOf(circle.datum()), 1)[0]);
})
)
.attr('cx', d => d.v * nDrawCall)
.attr('cy', d => d.v)
.attr('r', d => d.v)
.attr('fill', d => d.c)
}
function reset() {
nDrawCall = 0
redraw()
}
redraw()
svg {
height: 100px;
width: 100%;
}
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.3.0/d3.min.js"></script>
</head>
<body>
<button onclick="redraw()">
Redraw
</button>
<button onclick="reset()">
Reset
</button>
<div>
<svg id="svg2" />
</div>
</body>
</html>
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/427830.html
標籤:javascript 打字稿 d3.js 数据可视化 可视化
上一篇:如果RANK() 1因JOINS溢位,則選擇第一個排名
下一篇:帶有d3.js的日期軸標簽
