d3.js :`join`을 사용한 업데이트로 중첩 선택
Sep 02 2020
저는 d3.js를 처음 사용하고 중첩 된 선택으로 업데이트를 지원 하는 selection-join 과 유사한 것을 복제하려고합니다 . 나는 명시 적 /를 사용하여 이전 버전에 대해이 질문 을 보았고 그것을 수정하려고했습니다. 그러나이 코드로 내부 바인딩을 파악할 수 없습니다. 예를 들어 상위 반복 소문자는 반복에서 변경되지 않는 간격이 아니라 후속 간격에서 분홍색입니다. 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>
이상적으로는 v6 join(가능한 경우) 을 활용하기 위해 이것을 조정하고 싶습니다 . 이것은 내가 가진 가장 가까운 방법이지만 데이터 바인딩 및 선택을 관리하는 올바른 방법을 파악할 수 없습니다.
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?
}
);
}
답변
1 RubenHelsloot Sep 03 2020 at 01:14
에서 돌아 왔는지 확인 하여 이러한 다른 작업 ( enter및 이후 update)을 결합 할 수 있습니다 . 선택 항목을 반환하면 병합 할 수 있으며 그 후에 모두 동일하게 처리 할 수 있습니다..join()
- 새 값을 입력하여 분홍색으로 만듭니다.
- 기존 값을 업데이트하여 파란색으로 만듭니다.
- 모든 값에 올바른 텍스트 제공
편집 : 두 번째 .data()부분 에서 핵심 기능이 누락되어 d3가 색인 대신 문자 값을 볼 수 있다고 생각합니다 . 나는 당신의 cycle기능을 사용하여 더 명확하게 만들었습니다.
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>