如何用 d3.treemap 把层级数据渲染为矩形布局?

发布时间:2026/9/13 16:07:51

如何用 d3.treemap 把层级数据渲染为矩形布局? 如何用 d3.treemap 把层级数据渲染为矩形布局【免费下载链接】d3Bring data to life with SVG, Canvas and HTML. :bar_chart::chart_with_upwards_trend::tada:项目地址: https://gitcode.com/GitHub_Trending/d3/d3如果你手里有一份带数值的层级数据比如按目录统计的文件大小、按部门拆分的营收想把它画成一块被递归细分的矩形区域——即 treemap——那么 d3-hierarchy 的d3.treemap()就是布局计算工具。本文的完整目标是在浏览器里加载 D3从一份层级 JSON 出发调用d3.treemap()为每个节点算出x0, y0, x1, y1四个矩形坐标再把它们渲染成 SVG 矩形并验证结果。依据是仓库中的 d3-hierarchy/treemap 与 d3-hierarchy/hierarchy 文档。D3 在任何 JavaScript 环境都能运行。按 getting started 的说明官方推荐使用 CDN 托管的 ES module 包如果你需要不依赖模块加载的环境还有 UMD 包和 npm 安装两种替代方式。准备加载 D3 并确认数据形态treemap 文档要求布局的输入是一个 hierarchy 根节点因此数据必须满足两点数据本身是层级结构。文档给出的标准形态是一个根对象其children数组逐层嵌套子节点const data { name: Eve, children: [ {name: Cain}, {name: Seth, children: [{name: Enos}, {name: Noam}]}, {name: Abel}, {name: Awan, children: [{name: Enoch}]}, {name: Azura} ] };如果你的数据还是 CSV 等表格形式hierarchy 文档指出需要先用 stratify 整理成层级后再传给d3.hierarchy。每个参与面积计算的节点要有非负数值。node.sum的文档明确要求 value 访问函数返回非负数。下面把上面的示例数据补充value字段叶子节点取数值内部节点不取值后面代码即按这份数据编写const data { name: Eve, children: [ {name: Cain, value: 45}, {name: Seth, children: [{name: Enos, value: 10}, {name: Noam, value: 20}]}, {name: Abel, value: 30}, {name: Awan, children: [{name: Enoch, value: 15}]}, {name: Azura, value: 40} ] };加载 D3 有三种方式任选其一后文代码对三者通用CDN ES module文档推荐!DOCTYPE html div idcontainer/div script typemodule import * as d3 from https://cdn.jsdelivr.net/npm/d37/esm; // ……后文的完整代码…… container.append(svg.node()); /scriptCDN UMD用script srchttps://cdn.jsdelivr.net/npm/d37/script加载它导出全局d3后续代码不变。npm执行npm install d3文档也列出 yarn / pnpm 对应命令然后在模块里import * as d3 from d3;。此外 getting started 还提到 Observable 笔记本内置 D3、返回单元格生成的 DOM 元素即可展示图表可作为在线调试环境。第一步构建层级并计算节点数值用d3.hierarchy(data)从上面的data构造根节点const root d3.hierarchy(data);不指定 children 访问函数时默认取d.children正好匹配上面的数据结构。构造完成后每个节点带有node.data、node.depth、node.height、node.parent、node.children等属性其中node.value是需要你显式计算汇总的可选属性。treemap 文档写明必须在把层级交给 treemap 布局之前调用root.sum或root.count否则节点没有value可用。sum按后序遍历把每个节点的值设为自身访问函数返回值 所有子节点值之和访问函数收到的是节点的 dataroot.sum((d) d.value ?? 0);?? 0只用于本示例内部节点没有value字段返回 0 表示数值全部来自叶子。这正是文档给出的做法——如果你只想让叶子节点贡献数值对任何有 children 的节点返回 0例如root.sum((d) d.value ? 1 : 0)。若数据每个节点都自带汇总值则写成root.sum((d) d.value)。如果只想按叶子数量布局可以直接用root.count()它把每个节点值设为其下属叶子数。第二步配置并调用 treemap 布局treemap 文档 的默认值size默认为[1, 1]padding默认为 0round默认false平铺方法默认为黄金比例的treemapSquarify。因此要得到实际尺寸的布局必须先设置size。hierarchy文档给出的官方示例写法是// Construct the treemap layout. const treemap d3.treemap(); treemap.size([width, height]); treemap.padding(2);其中width和height是画布尺寸取你自己的值padding(2)同时设置内边距和外边距本文取 2 像素数值可自定。文档同时建议在计算布局前调用root.sort对层级排序treemap 推荐的比较方式是高度降序、值降序root.sort((a, b) b.height - a.height || b.value - a.value);注意 sort 的比较函数收到的是两个节点而不是两个 data这与Array.prototype.sort比较 data 的习惯不同。排序必须在调用布局前完成否则不影响本次布局结果。最后调用布局计算treemap(root);调用后root及其每个后代节点都被写入了四个属性这就是渲染的全部输入node.x0—— 矩形左边缘node.y0—— 矩形上边缘node.x1—— 矩形右边缘node.y1—— 矩形下边缘第三步把节点渲染成 SVG 矩形布局只负责坐标画矩形需要 d3-selection 的数据绑定。按 joining 文档 的selectAll().join()模式先创建 SVG 容器getting-started 的空白图表示例即d3.create(svg)再为每个后代节点生成一个rect// 创建 SVG 容器尺寸与上一步 size 一致 const svg d3.create(svg) .attr(width, width) .attr(height, height); // 为每个节点生成一个矩形 svg.append(g) .selectAll(rect) .data(root.descendants()) .join(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); // 展示在独立 HTML 页面里把 SVG 挂到容器上 container.append(svg.node());root.descendants()按拓扑序返回根节点 所有后代每个节点恰好对应一个rectjoin(rect)完成数据到元素的绑定。在 Observable 里则不需要container.append直接把svg.node()从单元格返回即可。验证布局结果文档没有给出成功日志但给出了可判断的坐标契约每个节点必须有x0, y0, x1, y1矩形宽高即x1 - x0与y1 - y0。运行后在浏览器控制台检查console.log(root.x0, root.y0, root.x1, root.y1); // 根节点四个坐标 const leaf root.leaves()[0]; console.log(leaf.data.name, leaf.x0, leaf.y0, leaf.x1, leaf.y1);可核对的点根节点与每个叶子的x1 x0且y1 y0宽高为正画出的矩形不翻转、不为零宽leaf.data.name应等于你在data里写的名字如示例中的 Cain说明node.data关联正确视觉上所有矩形铺满width × height区域相邻子块之间有 2 像素缝隙对应padding(2)没有任何矩形越出 SVG 边界。若某个区域缺失或错位先检查两处最常见的文档明确要求是否漏了root.sum(...)treemap 文档将其列为布局前的强制步骤以及size([width, height])是否设置成了你实际的画布尺寸而不是默认[1, 1]。调整平铺方式与可选配置treemap.tile 用于更换递归细分算法。默认的treemapSquarify实现 Bruls 等人的 squarified 算法目标矩形宽高比默认为黄金比例 φ (1 √5) / 2。文档说明该比例只是给算法的提示不保证每个矩形恰好等于该比例squarify.ratio(ratio)可以改目标比例要求 ≥ 1。其余内置方法的行为方法文档描述的行为treemapDice按子节点数值水平划分从左边缘x0起依次排布treemapSlice按子节点数值垂直划分从上边缘y0起依次排布treemapSliceDice奇数深度委托给 slice否则委托给 dice即按深度交替横竖切分treemapBinary递归划分成近似平衡的二叉树宽矩形用水平划分、高矩形用垂直划分treemapResquarify与 squarify 类似但保留上一次treemapResquarify布局中节点相邻关系适合做 treemap 的形变动画只改尺寸不改相对位置代价是后续布局不再是严格 squarify 结果切换方式const treemap d3.treemap() .tile(d3.treemapSliceDice) .size([width, height]) .padding(2);其余可选配置均为 treemap 文档给出的默认值round(true)开启坐标取整默认falsepaddingInner(n)/paddingOuter(n)分别单独控制内边距分隔相邻子节点与外边距分隔节点边缘与其子节点都默认 0也可传按节点取值的函数。完整示例与文档限制把上面各步拼起来是一个可整页运行的独立 HTMLESM CDN 加载其余按你的数据替换!DOCTYPE html div idcontainer/div script typemodule import * as d3 from https://cdn.jsdelivr.net/npm/d37/esm; const width 640; const height 400; const data { name: Eve, children: [ {name: Cain, value: 45}, {name: Seth, children: [{name: Enos, value: 10}, {name: Noam, value: 20}]}, {name: Abel, value: 30}, {name: Awan, children: [{name: Enoch, value: 15}]}, {name: Azura, value: 40} ] }; const root d3.hierarchy(data); const treemap d3.treemap() .size([width, height]) .padding(2); root.sum((d) d.value ?? 0); root.sort((a, b) b.height - a.height || b.value - a.value); treemap(root); const svg d3.create(svg) .attr(width, width) .attr(height, height); svg.append(g) .selectAll(rect) .data(root.descendants()) .join(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); container.append(svg.node()); /script运行后按上一节的验证清单检查。文档明确给出的边界只有两条布局前必须sum或count以及sum的访问函数必须返回非负数。若你的数据是表格而非层级先走 stratify若想让节点间留白更精细再阅读 treemap 文档 中paddingTop/Right/Bottom/Left的单独控制接口。【免费下载链接】d3Bring data to life with SVG, Canvas and HTML. :bar_chart::chart_with_upwards_trend::tada:项目地址: https://gitcode.com/GitHub_Trending/d3/d3创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/13 16:07:51

嵌入式AI与Python实战:从零构建课堂考勤系统毕业设计

简介:基于嵌入式AI技术的Python课堂考勤系统毕业设计资源,主要面向本科毕业生、课程设计学生及嵌入式AI应用开发者,围绕人脸识别课堂考勤场景,提供从硬件选型、电路设计、三维结构到软件算法与论文撰写的全流程参考。系统采用端侧…

2026/9/13 16:52:54

Stable Diffusion WebUI Forge:一键上手AI图像生成的完整指南

Stable Diffusion WebUI Forge:一键上手AI图像生成的完整指南 【免费下载链接】stable-diffusion-webui-forge 项目地址: https://gitcode.com/GitHub_Trending/st/stable-diffusion-webui-forge 想把一张草图变成概念图时,需要的不是再装一堆插…

2026/9/13 16:52:54

Java Servlet+JDBC健身房会员管理系统实战解析

简介:本资源是一套完整的健身房会员管理系统设计源码,面向计算机专业本科生、Web开发初学者及中小型健身场馆信息化建设需求者,解决会员信息管理、课程预约、教练分配与财务统计等核心运营问题。压缩包共187个文件,含65个Java后端…

2026/9/13 16:47:53

基于STK11的卫星任务调度强化学习数据生成与训练实践

简介:基于STK11场景的卫星任务调度与强化学习训练数据生成系统,面向卫星任务规划与机器学习交叉领域的研究者或工程师,提供从随机观测任务生成、卫星可访问时段计算、数据对齐与批次排序,到数据增强、模型训练及奖励可视化的完整链…

2026/9/13 0:01:16

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/13 0:01:16

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/12 6:29:36

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/12 14:32:17

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/13 11:18:28

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码