var data = [{
parent: {path: "M80 0 L500 0 L500 40 L80 40 Z", color: "red"},
children: {
a: {path: "M80 0 L220 0 L220 40 L80 40 Z"},
b: {path: "M220 0 L360 0 L360 40 L220 40 Z"},
c: {path: "M360 0 L500 0 L500 40 L360 40 Z"}
}
},
{
parent: {path: "M80 40 L500 40 L500 80 L80 80 Z", color: "green"},
children: {
a: {path: "M80 40 L220 40 L220 80 L80 80 Z"},
b: {path: "M220 40 L360 40 L360 80 L220 80 Z"},
c: {path: "M360 40 L500 40 L500 80 L360 80 Z"}
}
},
]
var parents = d3.select("svg")
.selectAll("g")
.data(data)
.enter().append("g");
parents.append("path")
.attr("d", function (d) { return d.parent.path; })
.style("fill", function(d) {return d.parent.color} );
在父路径下绘制子路径的最佳方法是什么?我想知道是否有任何d3惯用的方法来做到这一点。
<svg>
<g><path d="M80 0 L500 0 L500 40 L80 40 Z" style="fill: red;"></path>
<g>
child a
child b
child c
</g>
</g>
<g><path d="M80 40 L500 40 L500 80 L80 80 Z" style="fill: green;"></path>
<g>
child a
child b
child c
</g>
</g>
</svg>
我创建了一个jsfiddle示例以获得帮助。 https://jsfiddle.net/kvslee/vkmpyjub/
答案 0 :(得分:0)
你要问的是复杂的,因为在D3中,data
函数接受三件事:一个数组,一个函数或什么都没有。更简单的解决方案是更改数据结构......但是,我将提出一个完全使用您的数据结构的解决方案。
为了实现这一点,在孩子们的路径中,我不得不使用这种丑陋的数据连接在数组中转换该对象:
var children = childrenGroup.selectAll("foo")
.data(function(d) {
var childrenData = [];
for (var key in d.children) {
childrenData.push({
path: d.children[key].path
})
};
return childrenData
})
.enter()
.append("path");
以下是整个代码,检查控制台是否有SVG:
var data = [{
parent: {
path: "M80 0 L500 0 L500 40 L80 40 Z",
color: "red"
},
children: {
a: {
path: "M80 0 L220 0 L220 40 L80 40 Z"
},
b: {
path: "M220 0 L360 0 L360 40 L220 40 Z"
},
c: {
path: "M360 0 L500 0 L500 40 L360 40 Z"
}
}
},
{
parent: {
path: "M80 40 L500 40 L500 80 L80 80 Z",
color: "green"
},
children: {
a: {
path: "M80 40 L220 40 L220 80 L80 80 Z"
},
b: {
path: "M220 40 L360 40 L360 80 L220 80 Z"
},
c: {
path: "M360 40 L500 40 L500 80 L360 80 Z"
}
}
},
];
var svg = d3.select("svg");
var parents = svg.selectAll("foo")
.data(data)
.enter()
.append("g")
.style("fill", function(d) {
return d.parent.color
});
parents.append("path")
.attr("d", function(d) {
return d.parent.path;
});
var childrenGroup = parents.selectAll("foo")
.data(function(d) {
return [d]
})
.enter()
.append("g");
var children = childrenGroup.selectAll("foo")
.data(function(d) {
var childrenData = [];
for (var key in d.children) {
childrenData.push({
path: d.children[key].path
})
};
return childrenData
})
.enter()
.append("path");
children.attr("d", function(d) {
return d.path;
})
var mySVG = (new XMLSerializer()).serializeToString(svg.node());
console.log(mySVG)
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
&#13;
这是console.log
具有适当缩进的结果:
<svg xmlns="http://www.w3.org/2000/svg">
<g style="fill: red;">
<path d="M80 0 L500 0 L500 40 L80 40 Z" />
<g>
<path d="M80 0 L220 0 L220 40 L80 40 Z" />
<path d="M220 0 L360 0 L360 40 L220 40 Z" />
<path d="M360 0 L500 0 L500 40 L360 40 Z" />
</g>
</g>
<g style="fill: green;">
<path d="M80 40 L500 40 L500 80 L80 80 Z" />
<g>
<path d="M80 40 L220 40 L220 80 L80 80 Z" />
<path d="M220 40 L360 40 L360 80 L220 80 Z" />
<path d="M360 40 L500 40 L500 80 L360 80 Z" />
</g>
</g>
</svg>
PS:我将样式移到了父组。