javascript - 更改数据时如何更新子元素?

标签 javascript d3.js

我构建这些元素...

<svg>
  <g class="group">
    <text class="label">Hello</text>
  </g>
  <g class="group">
    <text class="label">World</text>
  </g>
</svg>

...来自以下数据:

[
  { id: 'a', label: 'Hello' },
  { id: 'b', label: 'World' },
]

创建它们后,我更改数据并再次运行 .data()。但是文本没有更新。

代码https://jsfiddle.net/ginpei/r7b65fzt/ :

function render (data, container) {
  const group = container.selectAll('.group')
    .data(data, d => d.id)

  const entered = group.enter().append('g')
    .attr({
      class: 'group'
    })

  entered.append('text')
    .attr({
      class: 'label'
    })
    .attr({ y: (d, i) => 20 + i * 20})

  const label = group.selectAll('.label')
    .text(d => d.label)
}

第二次,看起来绑定(bind)到 .group 的数据已更新,但绑定(bind)到 .label 的数据没有更新。我预计数据会设置得和第一次一样好。

如何更新它们?

实际上,我发现如果我为子元素添加 .data() ,它就会起作用。

  const label = container.selectAll('.label')
    .data(data, d => d.id)  // <--- added
    .text(d => d.label)

这是更新它们的正确方法吗?

如果能通过更简单的方式更新它们就太好了,因为我的实际代码有很多后代元素。

最佳答案

这里的解决方案非常简单:只需更改 selectAllselect .

const label = group.select('.label')
    .text(d => d.label);

为了了解原因,我制作了一张表格,其中列出了 select 之间的差异和selectAll :

<表类=“s-表”> <标题> 方法 选择() selectAll() <正文> 选择 选择与选择器字符串匹配的第一个元素 选择与选择器字符串匹配的所有元素 分组 不影响分组 影响分组 数据传播 传播数据 不传播数据

注意传播数据不传播数据

这是经过更改的代码和 setTimeout更改数据:

// d3.js 3.x

const container = d3.select('body').append('svg')

function render(data, container) {
  const group = container.selectAll('.group')
    .data(data, d => d.id)

  const entered = group.enter().append('g')
    .attr({
      class: 'group'
    })
  entered.append('text')
    .attr({
      class: 'label'
    })
    .attr({
      y: (d, i) => 20 + i * 20
    })
  const label = group.select('.label')
    .text(d => d.label);

}

// first try
const data1 = [{
  id: 'a',
  label: 'Hello'
}, {
  id: 'b',
  label: 'World'
}, ]
render(data1, container)

// update
const data2 = [{
  id: 'a',
  label: 'Goodbye'
}, {
  id: 'b',
  label: 'Universe'
}, ]
setTimeout(function() {
  render(data2, container)
}, 1000)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

PS:您的代码不适用于 v4(或 v5)。

关于javascript - 更改数据时如何更新子元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48819087/

相关文章:

javascript - typescript 错误 : Cannot redeclare block-scoped variable 'fetch'

javascript - 图像遮挡了我的可点击 div

javascript - 如何在响应式图表中正确调整 voronoi 的大小

d3.js - 描边宽度 = 1px 的线条的外观

javascript - 单击后如何禁用 JavaScript 功能?

javascript - 单击甚至不工作 <Label> [使用 EasyUI]

javascript - JavaScript onclick : this. id 中的参数传递与其他属性

d3.js - 将项目从 ionic 2 升级到 ionic 3 后显示找不到模块 "d3"错误

javascript - d3 : brush changes click to mouseover

javascript - D3.js 图形边缘反转未按预期运行