使用D3.js创建嵌套的HTML结构

时间:2014-03-13 21:11:38

标签: javascript html d3.js

我有一个看起来像这样的对象:

data = {
  questions: [ 
               value: "Question 1", answers: [ {value:"answer1"}, {value:"answer2"} ],
               value: "Question 2", answers: [ {value:"answer1"}, {value:"answer2"} ]
             ]
}

(这是简化的 - 答案有一个计数,将使用条形图显示。但是,我想,一旦我到达那里,我知道该怎么做。)

我遇到的问题是动态(因为数据频繁更改)创建HTML结构,看起来应该是这样的:

<div class="question">
  Question 1  
  <div class="answer">Answer 1</div>
  <div class="answer">Answer 2</div>
</div>
<div class="question">
  Question 2  
  <div class="answer">Answer 1</div>
  <div class="answer">Answer 2</div>
</div>

我可以让D3创建问题div(带有class="question"的那些),然后输入文本(即“问题1”等),但我无法弄清楚如何让D3为答案创建一个子div(即带有class="answer"的那些。)

这就是我现在所拥有的:

var questions_chart = d3.select('#survey-questions')
    .selectAll("div")
    .data(data.questions);

questions_chart.transition()
    .text(function(d) { return d.value; });

questions_chart.enter().append("div")
    .text(function(d) { return d.value; })
    .attr("class", "question rounded")

questions_chart.exit().remove();

基本上,我如何以这样的方式嵌套D3附加,以便divsdiv内的每个答案嵌套{{1}}?

2 个答案:

答案 0 :(得分:2)

正如Lars所说,您希望使用嵌套选择:

var data = {
  questions: [ 
    {value: "Question 1", answers: [ {value:"answer1"}, {value:"answer2"} ]},
    {value: "Question 2", answers: [ {value:"answer1"}, {value:"answer2"} ]}
  ]
};

d3.select("body").selectAll("div")
  .data(data.questions)
  .enter().append("div") // this creates the question divs
    .text(function(d) { return d.value; })
  .selectAll("div")
  .data(function(d) { return d.answers; })
  .enter().append("div") // this creates the nested answer divs
    .text(function(d) { return d.value; });

注意:我必须稍微修改一下你的数据,使data.questions成为一个对象数组。

答案 1 :(得分:1)

这扩展了Peter给出的补充#34;类&#34;您在原始问题中请求的信息,以及在评论中回答您的后续问题:

var divQ = d3.select("body").selectAll("div")
    .data(data.questions);

divQ
    .enter()
    .append("div") // this creates the question divs
    .attr("class","question")
    .text(function(d) { return d.value; });

divQ
    .exit()
    .remove();


var divA = divQ.selectAll("div")
    .data(function(d) { return d.answers; });

divA
    .exit()
    .remove();

divA
    .enter()
    .append("div") // this creates the nested answer divs
    .attr("class","answer")
    .text(function(d) { return d.value; });