我可以在没有嵌套DOM元素的情况下在d3中表示层次结构吗?

时间:2013-10-27 18:02:14

标签: javascript d3.js

我在d3中用于表示分层数据的所有示例都涉及嵌套元素:例如,div中的div或表行中的表单元格。

显示分层数据的“正确”方法是什么,其中生成的DOM元素是兄弟姐妹?例如,不同级别的标题(h1,h2等)。

我的第一次尝试(http://jsfiddle.net/herbcaudill/dTd99/)获取了这些数据:

var data = [{
    "key" : "1",
    "values" : [{
            "key" : "101",
            "title" : "Sub Section 1.A"
        }, {
            "key" : "102",
            "title" : "Sub Section 1.B"
        }, {
            "key" : "103",
            "title" : "Sub Section 1.C"
        }
    ],
    "title" : "Section 1"
}, {
    "key" : "2",
    "values" : [{
            "key" : "201",
            "title" : "Sub Section 2.A"
        }, {
            "key" : "202",
            "title" : "Sub Section 2.B"
        }, {
            "key" : "203",
            "title" : "Sub Section 2.C"
        }
    ],
    "title" : "Section 2"
}] 

...并尝试使用标准示例将其转换为标题和副标题,假设我们是嵌套元素,如下所示:

d3.select("body").selectAll("h1")
    .data(data)
    .enter()
    .append("h1")
        .text(function(d) {return d.title })
        .selectAll("h2")
            .data(function(d) { return d.values })
            .enter()
            .append("h2")
                .text(function(d) {return d.title})

当然我最终会遇到嵌套元素,这不是我想要的:

<h1>Section 1
       <h2>Sub Section 1.A</h2>
       <h2>Sub Section 1.B</h2>
       <h2>Sub Section 1.C</h2>
</h1>
<h1>Section 2
       <h2>Sub Section 2.A</h2>
       <h2>Sub Section 2.B</h2>
       <h2>Sub Section 2.C</h2>
</h1>

我怎样才能得到这个呢?

<h1>Section 1</h1>
<h2>Sub Section 1.A</h2>
<h2>Sub Section 1.B</h2>
<h2>Sub Section 1.C</h2>
<h1>Section 2</h1>
<h2>Sub Section 2.A</h2>
<h2>Sub Section 2.B</h2>
<h2>Sub Section 2.C</h2>

1 个答案:

答案 0 :(得分:0)

好的,我在发布问题的过程中想到了这一点。解决方案是继续执行嵌套操作,但将数据附加到包含div;然后将标题添加到每个div。

var level1 = d3.select("body")
    .selectAll("div.Level1")
    .data(data)
    .enter()
    .append("div").attr("class", "Level1")

level1.append("h1").text(function(d) {return d.title })

var level2 = level1.selectAll("div.Level2")
    .data(function(d) { return d.values })
    .enter()
    .append("div").attr("class", "Level2")

level2.append("h2").text(function(d) {return d.title})

这给了我以下标记:

<div class="Level1">
    <h1>Section 1</h1>
    <div class="Level2">
        <h2>Sub Section 1.A</h2>
    </div>
    <div class="Level2">
        <h2>Sub Section 1.B</h2>
    </div>
    <div class="Level2">
        <h2>Sub Section 1.C</h2>
    </div>
</div>
<div class="Level1">
    <h1>Section 2</h1>
    <div class="Level2">
        <h2>Sub Section 2.A</h2>
    </div>
    <div class="Level2">
        <h2>Sub Section 2.B</h2>
    </div>
    <div class="Level2">
        <h2>Sub Section 2.C</h2>
    </div>
</div>

这里的工作示例:http://jsfiddle.net/herbcaudill/DuJsS/

更新:我同意@Lars的说法,这不是一个很好的解决方案。实际上它并没有真正解决我实际拥有的问题,这涉及到每个节点添加一个表行:没有可以嵌套的元素并用于在表中包装tr。所以我欢迎一个不涉及包装元素的更清洁的解决方案。