编辑svg,而不是重新创建

时间:2019-06-05 04:02:58

标签: javascript d3.js

我对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('')的漏洞修复程序,但似乎我缺少该库的工作方式。

1 个答案:

答案 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上绘图。

Try it here

文档:

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