使用D3.js为每个数据成员附加多个非嵌套元素

use*_*342 45 javascript dom d3.js

我想使用d3创建多个非嵌套元素来创建这样的结构:

    <div id="parent">
        <p> from data[0] </p>
        <p> from data[0] </p>

        <p> from data[1] </p>
        <p> from data[1] </p>

        <p> from data[2] </p>
        <p> from data[2] </p>
    </div>
Run Code Online (Sandbox Code Playgroud)

创建嵌套结构就像是

    d3.select('#parent').selectAll('p').data(data).enter().
           append('p')...append('p')
Run Code Online (Sandbox Code Playgroud)

但是我想在追加后保持原始选择,所以我可以继续追加到父元素.谢谢!

Ada*_*rce 60

这种自觉的做法嵌套:

var divs = d3.select('#parent').selectAll('p').data(data).enter().append('div');

divs.append('p')
divs.append('p')
Run Code Online (Sandbox Code Playgroud)

这创造了:

<div id="parent">
  <div>
    <p> from data[0] </p>
    <p> from data[0] </p>
  </div>

  <div>
    <p> from data[1] </p>
    <p> from data[1] </p>
  </div>

  <div>
    <p> from data[2] </p>
    <p> from data[2] </p>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

如果这不起作用,请保存您的选择并重复附加:

var enterSelection = d3.select('#parent').selectAll('p').data(data).enter();

enterSelection.append('p')
enterSelection.append('p')
Run Code Online (Sandbox Code Playgroud)

然后对你添加的内容进行排序:

d3.select('#parent').selectAll('p').sort(function(a, b){ return a.index - b.index; })
Run Code Online (Sandbox Code Playgroud)

您需要为描述排序顺序的index每个元素添加一个属性data.法线i仅在特定选择的上下文中定义,在重新选择时丢失.

  • 您还可以使用enterSelection.insert("p")作为第二个元素.这应该消除了作为最后一步排序的需要. (4认同)

小智 14

使用append()的第一个项目和insert()第二.这消除了事后排序的任何需要(感谢@ scuerda的评论指出这一点)(JSFiddle):

data = [{}, {}, {}];
var enterSelection = d3.select('#parent').selectAll('p').data(data).enter()

enterSelection.append('p').text(function(d, i) {return 'from data[' + i + ']'})
enterSelection.insert('p').text(function(d, i) {return 'from data[' + i + ']'})
Run Code Online (Sandbox Code Playgroud)

这将为您提供所需的确切结构:

<p>from data[0]</p>

<p>from data[0]</p>

<p>from data[1]</p>

<p>from data[1]</p>

<p>from data[2]</p>

<p>from data[2]</p>
Run Code Online (Sandbox Code Playgroud)

  • 在版本4.x中不再起作用 (3认同)
  • 这实际上是应该被接受的解决方案,因为它正是所要求的,没有任何弯路! (2认同)
  • 这很好,但你确定它不是:`&lt;p&gt;来自数据[0]&lt;/p&gt; &lt;p&gt;来自数据[1]&lt;/p&gt; &lt;p&gt;来自数据[2]&lt;/p&gt; &lt; p&gt;来自数据[0]&lt;/p&gt; &lt;p&gt;来自数据[1]&lt;/p&gt; &lt;p&gt;来自数据[2]&lt;/p&gt;` (2认同)
  • 这取决于 d3 版本。例如,对于 d3 v7,它不再起作用 (2认同)

小智 13

您也可以在单个选择/输入循环中执行此操作,如下所示

d3.select('#parent').selectAll('p').data(data).enter().
append('p').text(function(d) {return 'from data[0]')}).
select(function() { return this.parentNode; }).
append('p').text(function(d) {return 'from data[0]')});
Run Code Online (Sandbox Code Playgroud)

  • 这很严重,正是我在寻找什么_ (3认同)

小智 7

而不是.append(),

您还可以包装一个在a中创建新内容的函数 .html()

d3.select('#parent')
  .selectAll('div')
    .data(data)
  .enter()
    .append('div')
    .html(function(d) {return "<p>" + from data[0] + "<p>" etc..... ;});
Run Code Online (Sandbox Code Playgroud)