我读过Bostock的“Nested Selections”教程,但我无法完全使用嵌套数据。
我已将问题简化为这样的数据集:
var data = [{
"id": "foo",
"row": 0,
"col": 0,
"row_size": 200,
"col_size": 100,
"modules": [{
"id": "foo1",
"row": 0,
"col": 0
}, {
"id": "foo2",
"row": 1,
"col": 0
}]
}, {
"id": "bar",
"row": 0,
"col": 1,
"row_size": 200,
"col_size": 100,
"modules": [{
"id": "bar1",
"row": 0,
"col": 1
}, {
"id": "bar2",
"row": 1,
"col": 1
}]
}]
我正试图像这样动态创建svg
:
<svg width="500" height="500">
<g transform="translate(20,20)">
<g transform="translate(0,0)" class="outside_box">
<rect x="0" y="0" width="100" height="200" fill="white" stroke="red" stroke-width="10"></rect>
<text x="50" y="100" text-anchor="middle" alignment-baseline="central" font-size="50">foo</text>
<g class="inside_box">
<g transform="translate(0,0)">
<rect x="0" y="0" width="100" height="100" fill-opacity="0.5" stroke="blue"></rect>
<text x="50" y="50" text-anchor="middle" alignment-baseline="central">foo1</text>
</g>
<g transform="translate(0,100)">
<rect x="0" y="0" width="100" height="100" fill-opacity="0.5" stroke="blue"></rect>
<text x="50" y="50" text-anchor="middle" alignment-baseline="central">foo2</text>
</g>
</g>
</g>
<g transform="translate(100,0)" class="outside_box">
<rect x="0" y="0" width="100" height="200" fill="white" stroke="red" stroke-width="10"></rect>
<text x="50" y="100" text-anchor="middle" alignment-baseline="central" font-size="50">bar</text>
<g class="inside_box">
<g transform="translate(0,0)">
<rect x="0" y="0" width="100" height="100" fill-opacity="0.5" stroke="blue"></rect>
<text x="50" y="50" text-anchor="middle" alignment-baseline="central">bar1</text>
</g>
<g transform="translate(0,100)">
<rect x="0" y="0" width="100" height="100" fill-opacity="0.5" stroke="blue"></rect>
<text x="50" y="50" text-anchor="middle" alignment-baseline="central">bar2</text>
</g>
</g>
</g>
</g>
</svg>
我的示例中的定位,大小调整和颜色无关紧要(我只是添加了额外的属性以使SVG清晰易懂);但<g>
,<text>
和<rect>
的分组非常重要。我还想从头开始创建SVG(空白画布),所以尝试做类似
d3.selectAll("g").data(data).enter().append("g")...
谢谢!
答案 0 :(得分:2)
这应该这样做。我还没有对它进行过测试,因此可能会出现错误,但总体结构是您所追求的。
var svg = d3.select("body").append("svg") // here you'll also want to apply width and height .attr's
var mainG = svg.append("g") // this you'll also want to translate(20,20) as your mockup suggests
// Now bind the outer level, to produce a 2-element selection bound to 'data'
var gOuter = mainG.selectAll("g.outside_box").data(data)
var gOuterEnter = gOuter.enter().append("g")
.attr("class", "outside_box")
// also to this you can apply translation as you wish
gOuterEnter.append("rect") // and set the rect's attributes as needed
gOuterEnter.append("text") // and set the text's attributes and text as needed
gOuterEnter.append("g")
.attr("class", "inside_box")
// Now comes the work with the nested data:
var gModules = gOuterEnter.select(".inside_box").selectAll("g").data(function(d) {
// here d is the outer datum, and lets you access
// its nested 'modules' array, which is what you want
// to return, as instructed by Bostocks "Nested Selections" tutorial
return d.modules
})
var gModulesEnter = gModules.enter()
.append("g")
gModulesEnter.append("rect") // and set attributes
gModulesEnter.append("text")
.text(function(m) {
// here m is each module's datum, so you can return its id
// to set the text to what you want
return d.id
})