为什么我的 d3.treemap() 返回的数据存在很大差距?
Why is my d3.treemap() returning a data viz with big gaps?
我正在尝试创建描述预算数据的树状图。
预期:树图中不应有任何间隙;描述每个节点的所有矩形都应该像 SVG 中的乐高积木一样适合。
实际:我的树形图的矩形在我的 SVG 中没有很好地排列;见下图:
目前,我的数据集很浅,主要是我编造的虚拟数据。 CSV file的结构是:
这些是代码中的相关步骤:
第 1 步:
加载 CSV 文件后,我使用 d3.stratify()
:
将其转换为层次结构
`let dataStratified = d3
.stratify()
.id(function (d) {
return d.Child;
})
.parentId(function (d) {
return d.Parent;
})(results);`
步骤 2:
然后我传递到一个分层布局,d3.treemap()
:
let myTreemap = (data) =>
d3.treemap().size([width, height]).padding(1).round(true)(
d3
.hierarchy(data)
.sum((d) => d.data["Rs,millions"])
.sort((a, b) => b.data["Rs,millions"] - a.data["Rs,millions"])
);
const root = myTreemap(dataStratified);
步骤 3:
使用此 Observable notebook 作为指南,我继续构建树图的叶子:
const leaf = g
.selectAll("g.leaf")
// root.leaves() returns all of the leaf nodes
.data(root.leaves())
.enter()
.append("g")
.attr("class", "leaf")
// position each group at the top left corner of the rect
.attr("transform", (d) => `translate(${d.x0},${d.y0})`)
.style("font-size", 10);
步骤 4:
并将其附加到我创建的 SVG 中:
// Now we append the rects.
leaf
.append("rect")
.attr("id", (d) => d.data.id)
.attr("fill", (d) => {
while (d.depth > 1) d = d.parent;
return color(d.data.data.Child);
})
.attr("opacity", 0.7)
// the width is the right edge position - the left edge position
.attr("width", (d) => d.x1 - d.x0)
// same for height, but bottom - top
.attr("height", (d) => d.y1 - d.y0)
// make corners rounded
.attr("rx", 3)
.attr("ry", 3);
其余代码主要是样式和标签放置,所以我认为这与我的问题无关,但可以在此处查看:Github or CodeSandbox.
mis-sized 矩形是树形图的总值,您实际上是在 parent 节点(因为它在 CSV 列中)上再次累加总和。
你应该只在它是叶节点时求和(意思是如果 obj 没有 children)。简而言之,如果您在 hierarchy.sum
函数中检查 children,并且仅在没有 children 的情况下求和,那么它应该正确计算总计
let dataHierarchy = d3
.hierarchy(dataStratified)
.sum(d => (d.children ? 0 : d.data["Rs,millions"]))
.sort((a, b) => b.data["Rs,millions"] - a.data["Rs,millions"]);
我正在尝试创建描述预算数据的树状图。
预期:树图中不应有任何间隙;描述每个节点的所有矩形都应该像 SVG 中的乐高积木一样适合。
实际:我的树形图的矩形在我的 SVG 中没有很好地排列;见下图:
目前,我的数据集很浅,主要是我编造的虚拟数据。 CSV file的结构是:
这些是代码中的相关步骤:
第 1 步:
加载 CSV 文件后,我使用 d3.stratify()
:
`let dataStratified = d3
.stratify()
.id(function (d) {
return d.Child;
})
.parentId(function (d) {
return d.Parent;
})(results);`
步骤 2:
然后我传递到一个分层布局,d3.treemap()
:
let myTreemap = (data) =>
d3.treemap().size([width, height]).padding(1).round(true)(
d3
.hierarchy(data)
.sum((d) => d.data["Rs,millions"])
.sort((a, b) => b.data["Rs,millions"] - a.data["Rs,millions"])
);
const root = myTreemap(dataStratified);
步骤 3: 使用此 Observable notebook 作为指南,我继续构建树图的叶子:
const leaf = g
.selectAll("g.leaf")
// root.leaves() returns all of the leaf nodes
.data(root.leaves())
.enter()
.append("g")
.attr("class", "leaf")
// position each group at the top left corner of the rect
.attr("transform", (d) => `translate(${d.x0},${d.y0})`)
.style("font-size", 10);
步骤 4: 并将其附加到我创建的 SVG 中:
// Now we append the rects.
leaf
.append("rect")
.attr("id", (d) => d.data.id)
.attr("fill", (d) => {
while (d.depth > 1) d = d.parent;
return color(d.data.data.Child);
})
.attr("opacity", 0.7)
// the width is the right edge position - the left edge position
.attr("width", (d) => d.x1 - d.x0)
// same for height, but bottom - top
.attr("height", (d) => d.y1 - d.y0)
// make corners rounded
.attr("rx", 3)
.attr("ry", 3);
其余代码主要是样式和标签放置,所以我认为这与我的问题无关,但可以在此处查看:Github or CodeSandbox.
mis-sized 矩形是树形图的总值,您实际上是在 parent 节点(因为它在 CSV 列中)上再次累加总和。
你应该只在它是叶节点时求和(意思是如果 obj 没有 children)。简而言之,如果您在 hierarchy.sum
函数中检查 children,并且仅在没有 children 的情况下求和,那么它应该正确计算总计
let dataHierarchy = d3
.hierarchy(dataStratified)
.sum(d => (d.children ? 0 : d.data["Rs,millions"]))
.sort((a, b) => b.data["Rs,millions"] - a.data["Rs,millions"]);