如何追加一个新的div元素,它是使用d3创建的第一个div的兄弟?

时间:2017-12-03 19:20:46

标签: javascript html d3.js

基本上,我想在其他div之后添加一个新的div:不是子div,而是创建第一个div的兄弟

使用下一个Code,我在h4中得到一个div:(

let content = d3.select('#id_')
let divs = content.selectAll('div')
    .data(data.keys) // It contains 8 objects, will return 8 divs.
    .enter()
    .append('div')
    .attr('class', 'mydiv')
    .append('h4')
    .text((d) => {
      return d.title
    })
    .append('div')
    .attr('class', 'new-div')

我得到了我需要的div数量。但是,类new-div的新div元素位于h4标记内。

我想按此顺序创建一些东西:

<!-- Divs created with d3 -->
<div class='mydiv'>
  <h4>Title</h4>
</div>
<div class='new-div'></div>

我在添加.insert代码后尝试使用h4

    ...
    .append('h4')
    .text((d) => {
      return d.title
    })
    .insert('div')
    .attr('class', 'new-div')

但结果是一样的。

我知道这个过程中的层次结构不仅重要,而且它根据每个步骤构建标签。有没有办法创建一个新的div元素,它是第一个div创建的兄弟?

3 个答案:

答案 0 :(得分:2)

您可以在追加第二个.select(function() { return this.parentElement.parentElement; })之前使用div。在这种情况下,您不会中断链接,并且您的选择将返回父元素,因此第二个附加的div将是第一个附加div的兄弟。查看下面的演示:

var data = [{ title: 'foo', country: 1 }, { title: 'bar', country: 2 } ];

let divs = d3.select('body')
    .selectAll('div')
    .data(data)
    .enter()
    .append('div')
    .attr('class', 'mydiv')
    .append('h4')
    .text((d) => {
      return d.title
    })
    .select(function() { return this.parentElement.parentElement; })
    .append('div')
    .data(data)
    .attr('class', function(d) { return 'country-' + d.country; })
    .text(function(d) {return d.country });
.mydiv {
  width: 100px;
  height: 20px;
  border: 1px solid green;
  background-color: pink;
  display: inline-block;
}

.country-1, .country-2 {
  width: 100px;
  height: 20px;
  border: 1px solid green;
  background-color: aqua;
  display: inline-block;
}

h4 {
  margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.12.0/d3.min.js"></script>

答案 1 :(得分:1)

只是为了让你知道,accepted answer(在撰写本文时)创建了这个结构:

   # Localising favicons
   RewriteCond %{REQUEST_URI} .*/(favicon|ms-icon|apple-icon|android-icon)(-\d+x\d+)?\.png [OR]
   RewriteCond %{REQUEST_URI} .*/(favicon)?\.ico
   RewriteRule ^((?!favicons/).*)$ /favicons/$1 [L]
   # Localising favicons end

如您所见,所有具有类<div class='mydiv'> <h4>Title</h4> </div> <div class='mydiv'> <h4>Title</h4> </div> <div class='new-div'></div> <div class='new-div'></div> 的div将位于"new-div" div之后。我有一种强烈的感觉,这不是你想要的。

如果你想一个接一个地创建它们,你有不同的选择,像这样(繁琐).mydiv

&#13;
&#13;
each()
&#13;
var content = d3.select("body");
var data = [{
  title: "foo"
}, {
  title: "bar"
}];
var divs = content.selectAll(null)
  .data(data)
  .enter();

divs.each(function(d) {
  content.append("div")
    .attr('class', 'mydiv')
    .append('h4')
    .text(() => {
      return d.title
    });
  content.append('div')
    .attr("class", "new-div");
})
&#13;
&#13;
&#13;

这将创建以下结构:

<script src="https://d3js.org/d3.v4.min.js"></script>

答案 2 :(得分:0)

尝试这样的事情:

let divs = content.selectAll('div')
    .data(data.keys) // It contains 8 objects, will return 8 divs.
    .enter()
    .append('div')
    .attr('class', 'mydiv'); // stop here

// title
divs.append('h4')
  .text((d) => {
    return d.title
  });

// child div
let childDivs = divs.append('div')
  .attr('class', 'mychilddiv');

// second child div
let childDivs2 = childDivs.append('div')
  .attr('class', 'mychilddiv2');

// third child div
let childDivs3 = childDivs2.append('div')
  .attr('class', 'mychilddiv3');

// add h4 to second child
childDivs2.append('h4')
.text('second child')

您可以按照自己的意愿进行链接..