You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何无需d3.hierarchy或多层级,用D3.js实现纯数值数组树形图?

不用d3.hierarchy实现扁平数值数组的Treemap布局

当然可以不用d3.hierarchy来实现!你的数据是扁平的单层级数值数组,根本没必要动用专门处理层级数据的d3.hierarchy——d3.treemap只需要输入符合特定结构的节点对象,不一定非得由d3.hierarchy生成。下面给你两种简单的实现方式:

方法一:手动构造Treemap所需的节点结构

我们直接创建一个根节点对象,把数值数组转换成带value属性的子节点数组,再手动计算根节点的总数值(替代d3.hierarchy的sum方法),就能让d3.treemap正常工作:

const data = [32, 16, 37, 56];
const treeMapLayout = d3.treemap().size([400, 200]).paddingOuter(10);

// 手动构造根节点:包含children数组,每个子节点存对应的数值
const root = {
  children: data.map(num => ({ value: num }))
};

// 手动计算根节点的总value(对应d3.hierarchy的sum逻辑)
root.value = root.children.reduce((total, child) => total + child.value, 0);

// 应用treemap布局
treeMapLayout(root);

// 绘制矩形(直接用根节点的children,不用descendants)
d3.select('svg g')
  .selectAll('rect')
  .data(root.children)
  .enter()
  .append('rect')
  .attr('x', d => d.x0)
  .attr('y', d => d.y0)
  .attr('width', d => d.x1 - d.x0)
  .attr('height', d => d.y1 - d.y0)

对应的CSS和HTML和你原来的完全一致,不需要修改:

rect {
  fill: cadetblue;
  opacity: 0.3;
  stroke: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="420" height="220">
  <g></g>
</svg>

方法二:核心逻辑简化说明

其实d3.treemap的核心要求非常简单,只要满足两个条件就能工作:

  • 根节点有value属性(存储所有子节点的数值总和)
  • 根节点有children数组,每个子节点拥有自己的value属性

只要符合这个结构,不管节点是手动创建还是其他方式生成,d3.treemap都能正确计算出每个子节点的位置和尺寸。

补充:你原来代码的问题

你最初用d3.hierarchy(data)处理纯数值数组时,d3.hierarchy会把整个数组当成一个单节点,而root.sum(d => d.value)里的d是数组本身,并没有value属性,所以无法正确计算数值总和,自然也生成不了正确的treemap布局——手动构造节点结构反而能更准确地控制数据逻辑。

内容的提问来源于stack exchange,提问作者Sosa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:24:22