d3.js: "join" kullanan güncellemeyle İç İçe Seçim
D3.js'de yeniyim ve iç içe seçimlerle güncellemeleri destekleyen seçim-birleştirmeye benzer bir şeyi kopyalamaya çalışıyorum . Gördüğüm bu soruyu açık olan önceki sürümleri için / ve onu adapte çalıştı. Ancak, bu kodla iç bağlamayı tam olarak anlayamıyorum. Örneğin, en üstteki küçük harfli harfler, yinelemelerde değişmeyenler yerine sonraki aralıklarda pembedir. CodePenenterexitn-1
const main = d3.select("main");
function updateOld() {
content = randomUpper().map(u => {
return {
header: u,
list: randomLower()
};
});
let outer = main.selectAll("div")
.data(content, d => d.header)
outer.exit().remove();
const outerEnter = outer.enter()
.append("div")
.style("color", "green")
.text(d => d.header);
outer = outerEnter.merge(outer.style("color", "gray"));
inner = outer.selectAll("h6")
.data(d => d.list);
inner.exit().remove();
inner.enter()
.append("h6")
.style("color", "blue")
.merge(inner.style("color", "pink"))
.text(d => d);
}
setInterval(updateOld, 2000);
updateOld();
function randomUpper() {
return d3.shuffle("ABCDEFGHIJKLMNOPQRSTUVWXYZ".split(""))
.slice(0, Math.floor(6 + Math.random() * 20))
.sort();
}
function randomLower() {
return randomUpper().map(u => u.toLowerCase())
}
main {
display: flex;
}
div {
width: 40px;
}
h6 {
margin: 5px 0;
}
<main></main>
<script src="https://d3js.org/d3.v6.js"></script>
İdeal olarak, bunu v6'dan yararlanmak için uyarlamak isterim join(mümkünse). Elimdeki en yakın şey bu ancak veri bağlamayı ve seçimleri yönetmenin doğru yolunu tam olarak bulamıyorum.
function updateV6() {
content = randomUpper().map(u => {
return { header: u, list: randomLower() };
});
main.selectAll("div")
.data(content, d => d.header)
.join(
enter => {
root = enter.append("div")
root.append("h3")
.style("color", "green")
.text(d => d.header);
root.selectAll("h6")
.data(d => d.list)
.join("h6")
.style("color", "blue")
.text(d => d);
},
update => {
update.selectAll("h3")
.style("color", "gray")
// How to add the newly introduced h6 elements corresponding
// to each h3 and change color of others that remain across iterations?
}
);
}
Yanıtlar
Sen (sonra bu farklı işlemleri birleştirebilir enterve updateemin yaparak) return dan .join(). Seçimlerin geri döndürülmesi, bunların birleştirilmesine olanak tanır, ardından hepsine aynı şekilde davranabilirsiniz:
- pembe yapmak için yeni değerler girin
- mevcut değerleri mavi yapmak için güncelleyin
- tüm değerlere doğru metni verin
Düzenleme: İkinci .data()bölümünüzde d3'ün harflerin indeksleri yerine değerlerine bakmasını sağlayacak bir anahtar işlevi eksik olduğunu düşünüyorum . Daha cyclenet hale getirmek için işlevselliğini kullandım .
const main = d3.select("main");
const cycle = [
[{
header: "B",
list: ["a", "b", "c"]
},
{
header: "C",
list: ["c"]
},
],
[{
header: "B",
list: ["a", "c", "d", "e"]
}, // remove [b], add [d,e]
{
header: "D",
list: ["a", "b", "c", "d"]
},
],
[{
header: "D",
list: ["b", "c", "e"]
}, // remove [a, d], add [e]
{
header: "E",
list: ["a", "b", "c"]
},
],
]
var counter = 0;
function updateV6() {
content = cycle[counter % cycle.length];
counter++;
main.selectAll("div")
.data(content, d => d.header)
.join(
enter => {
root = enter.append("div")
root.append("h3")
.style("color", "green")
.text(d => d.header);
return root;
},
update => {
update.selectAll("h3")
.style("color", "gray");
return update;
}
)
.selectAll("h6")
.data(d => d.list, d => d)
.join(
enter => enter.append('h6').style("color", "blue"),
update => update.style("color", "pink")
)
.text(d => d);
}
setInterval(updateV6, 2000);
updateV6();
main {
display: flex;
}
div {
width: 40px;
}
h6 {
margin: 5px 0;
}
<main></main>
<script src="https://d3js.org/d3.v6.js"></script>