在单个 Join 中追加多个元素

run*_*ndy 4 d3.js

enter我正在尝试使用 d3v5 在单个连接的函数中附加多个元素。

使用时将多个元素附加到单个组的正确方法是什么selection.join()

我尝试创建的 DOM 结构如下所示:

<svg id="chart">
    <g class="data-group">
        <rect class="data-rect" x="5" y="5" width="10" height="10" style="fill: red;"></rect>
        <text class="data-text" x="15" y="20">data1</text>
    </g>
    <g class="data-group">
        <rect class="data-rect" x="25" y="25" width="10" height="10" style="fill: green;"></rect>
        <text class="data-text" x="35" y="40">data2</text>
    </g>
    <g class="data-group">
        <rect class="data-rect" x="50" y="50" width="10" height="10" style="fill: gray;"></rect>
        <text class="data-text" x="60" y="65">data3</text>
    </g>
</svg>
Run Code Online (Sandbox Code Playgroud)

我可以通过循环数据 小提琴轻松手动生成此结构

for(var i = 0; i < data.length; i++){
let o = data[i];
let g = d3.select('#chart')
    .append('g')
  .datum(o)
  .attr('class', 'data-group');
  
g.append('rect')
  .attr('class', 'data-rect')
  .attr('x',5)
  .attr('y', d => d.id * offset)
  .attr('width', 10)
  .attr('height', 10)
  .style('fill', d => d.color);
  
g.append('text')
  .attr('class', 'data-text')
  .attr('x', 15)
  .attr('y', d => d.id * offset + 9)
  .text(d => d.text);
}
Run Code Online (Sandbox Code Playgroud)

我想使用selection.join()这样我就可以干净地利用输入、更新和退出。

我可以接近这个结构,但是,我无法附加该text元素,因为它将附加到rect而不是g(并且你不能将文本附加到矩形!) 小提琴

d3.select('#chart')
    .selectAll('.data-group')
    .data(data, d => d.id)
  .join((enter) => {
    return enter
      .append('g')
      .attr('class', 'data-group')
      .append('rect')
      .attr('class', 'data-rect')
      .attr('x',d => d.id * offset)
      .attr('y', 5)
      .attr('width', 10)
      .attr('height', 10)
      .style('fill', d => d.color);
  })

Run Code Online (Sandbox Code Playgroud)

附加多个元素然后返回enter也不起作用,它会引发异常 小提琴

run*_*ndy 5

请参阅BallPointBen对我原来问题的评论。

可以通过执行以下操作将多个元素附加到连接中:

d3.select('#chart')
    .selectAll('.data-group')
    .data(data, d => d.id)
    .join((enter) => {
        let g = enter;
    
        g.append('g')
         .attr('class', 'data-group')

        g.append('rect')
         .attr('class', 'data-rect')
         .attr('x',d => d.id * offset)
         .attr('y', 5)
         .attr('width', 10)
         .attr('height', 10)
         .style('fill', d => d.color);

        g.append('text')
         .attr('class', 'data-text');

    return g;
  })
Run Code Online (Sandbox Code Playgroud)

  • 我相信 BallPointBen 的评论建议引用附加的数据组元素 - `const g = Enter.append('g')`。在这里,您引用了输入方法,而不是附加的组。 (4认同)