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

时间:2014-01-31 17:11:06

标签: 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>

创建嵌套结构将类似于

    d3.select('#parent').selectAll('p').data(data).enter().
           append('p')...append('p')

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

6 个答案:

答案 0 :(得分:58)

使用嵌套

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

divs.append('p')
divs.append('p')

创造了:

<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>

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

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

enterSelection.append('p')
enterSelection.append('p')

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

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

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

答案 1 :(得分: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 + ']'})

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

<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>

答案 2 :(得分:12)

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

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]')});

答案 3 :(得分:7)

而不是.append()

您还可以在.html()

中包装一个创建新内容的函数
d3.select('#parent')
  .selectAll('div')
    .data(data)
  .enter()
    .append('div')
    .html(function(d) {return "<p>" + from data[0] + "<p>" etc..... ;});

答案 4 :(得分:0)

与上述类似,但用不同的习语。这对于嵌套选择方法更为真实,并且无需排序或插入:

var divs = d3.select('#parent');

var ps = divs.selectAll('#parent > div')
    .data(d3.range(3)).enter().append('div');

ps.append('p').html(function(d,i) { return 'from data[' + i + ']'; });
ps.append('p').html(function(d,i) { return 'from data[' + i + ']'; });

更优雅(也可能更快):

var divs = d3.select('#parent');

  var ps = divs.selectAll('#parent > div')
    .data(d3.range(3)).enter().append('div');

    ps.append('p').html(function(d,i) { return 'from data[' + i + ']'; })
    .select(function() { return this.parentNode.appendChild(this.cloneNode(true)); });

答案 5 :(得分:0)

1。复制每个元素

创建一个新列表,其中两次包含所有元素(like this):


php -d memory_limit=-1 "C:\ProgramData\ComposerSetup\bin\composer.phar" update 

2。输入两次

有时您想对附加的元素做进一步的处理。在这种情况下,您可能想知道是要访问第一个还是第二个添加的元素。将doubleData = data.reduce(function (res, current, index, array) { return res.concat([current, current]); }, []); d3.select('#parent').selectAll('p').data(doubleData).enter().append('p') first-paragraph类添加到这些元素。

second-paragraph

在这种情况下,您可能必须根据Adam Pearce's answer对元素进行排序。