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

Creating nested HTML structures with D3.js

本文关键字:HTML 结构 嵌套 创建 D3 js      更新时间:2023-09-26

我有一个像这样的对象:

data = {
  questions: [ 
               value: "Question 1", answers: [ {value:"answerswer1"}, {value:"answerswer2"} ],
               value: "Question 2", answers: [ {value:"answerswer1"}, {value:"answerswer2"} ]
             ]
}

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

我遇到的问题是动态(因为数据经常变化)创建HTML结构,它应该看起来像这样:

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

我可以让D3创建问题div (w/class="question"),并将其放入文本(即。"问题1"等),但我不知道如何让D3为答案(即那些w/class="answerswer")创建子div。

这是我现在的情况:

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追加,我可以为该问题的div中的每个答案嵌套divs ?

正如Lars所指出的,您希望使用嵌套选择:

var data = {
  questions: [ 
    {value: "Question 1", answers: [ {value:"answerswer1"}, {value:"answerswer2"} ]},
    {value: "Question 2", answers: [ {value:"answerswer1"}, {value:"answerswer2"} ]}
  ]
};
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的对象数组。

这扩展了Peter给出的答案,添加了您在原始问题中要求的"class"信息,并回答了您在评论中的后续问题:

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","answerswer")
    .text(function(d) { return d.value; });