我对d3似乎有一个简单的误解,尽管我寻找的很多东西似乎很接近,但找不到匹配的解释。
基本上,我有一个数据数组,我想为每个项目渲染一个。我希望每个子元素都有自己的子元素(a和一个文本/>),这些子元素取决于绑定到每个子元素的基准。
我的问题是,当数据更新时,每个元素都会添加其他元素和元素,而不是替换它们。
已附加了最小再现码笔。任何帮助将不胜感激!
https://codepen.io/kamry-bowman/pen/GaLvKJ
html:
<body>
<svg />
<button>Increment</button>
</body>
js:
let state = [];
for (let i = 0; i < 5; i++) {
state.push({ id: i, value: (i + 1) * 2 });
}
function render() {
console.log('running', state)
const svg = d3
.select("svg")
.attr("width", "1000")
.attr("height", "200");
const gGroup = svg
.selectAll("g")
.data(state, d => d.id)
.join("g")
.attr("transform", (d, i) => `translate(${100 * i})`);
gGroup
.append("circle")
.attr("cx", "50")
.attr("cy", "50")
.attr("r", "50")
.attr("fill", "none")
.attr("stroke", "black");
gGroup
.append("text")
.text(d => d.value)
.attr("stroke", "black")
.attr("x", "40")
.attr("y", "55")
.attr("style", "font: bold 30px sans-serif");
}
function clickHandler() {
state = state.map(obj => ({ ...obj, value: obj.value + 1 }))
render()
}
document.querySelector('button').addEventListener('click', clickHandler)
render()
我发现了一个调用gGroup.html('')的漏洞修复程序,但似乎我缺少该库的工作方式。
答案 0 :(得分:-2)
在render方法中创建svg之后,直接添加以下行:
<?php
$video = 'https://www.youtube.com/watch?v=u00FY9vADfQ';
$parsed_video = parse_url($video, PHP_URL_QUERY);
parse_str($parsed_video, $arr);
?>
<iframe
src="https://www.youtube.com/embed/<?php echo $arr['v']; ?>"
frameborder="0">
</iframe>
这将删除根svg的所有子级。否则,您将继续在相同的svg上绘图。
文档:
d3.selectAll() selection.remove()
编辑
要仅更新文本值本身,请在点击处理程序中调用此svg.selectAll("*").remove();
函数:
update()
codepen已更新为使用此方法
再次编辑
如果要将值绑定到它们的function update() {
const svg = d3.select("svg")
d3.selectAll("svg text").each(function(d, i) {
d3.select(this).text(state[i].value);
});
}
,只需使用id
方法中的d
而不是.each()
(它是集合中的索引)来访问它们:
i
由于条目可以采用任何顺序,因此我们必须使用function update() {
const svg = d3.select("svg")
d3.selectAll("svg text").each(function(d, i) {
d3.select(this).text(
state.find((e) => e.id === d.id).value
);
});
}
来查找具有匹配ID的元素。这是another codepen。