d3.treemap()仅计算坐标不绘图,需配合渲染;关键步骤:d3.hierarchy()构建层级、treemap.size().padding()配置布局、layout(root)生成x0/y0/x1/y1;数据须含value字段或用sum()指定,父节点value需显式累加;推荐按depth或value着色,响应式应复用layout实例而非重建。

用 d3.js 的 d3.treemap() 生成基础矩形树图
原生 HTML 没有矩形树图(Treemap)标签,必须依赖 JavaScript 可视化库。当前最稳定、文档最全、适配性最强的是 d3.js v6+ 的 d3.treemap() ——它不画图,只计算每个节点的 x0、y0、x1、y1 坐标,你用 渲染即可。
关键步骤:
- 先用
d3.hierarchy()把嵌套数据转成层级结构,注意children字段名要匹配(默认找children,若字段是subs需传入访问器:d3.hierarchy(root, d => d.subs)) - 调用
d3.treemap().size([width, height]).padding(1)构建布局器,padding控制矩形间距,设为 0 会贴边但难区分相邻块 - 执行
layout(root)后,每个节点会多出x0/y0/x1/y1四个数值属性,直接绑定到的x、y、width、height
数据中必须带 value 字段,否则所有块面积为 0
d3.treemap() 默认按节点的 value 属性分配面积。如果数据里没这个字段,或字段名不一致(比如叫 size 或 count),渲染出来全是等宽高小方块,甚至报错 NaN 宽高。
解决方法:
- 预处理数据:遍历节点,补上
value(叶子节点通常填数值,父节点可设为子节点value之和) - 或用
sum方法自定义取值逻辑:layout.sum(d => d.size || d.count || 0) - 特别注意:父节点的
value不会自动累加,必须显式计算好再传入,否则 treemap 会把父节点当叶子处理,导致层级错乱
颜色映射别直接用 name,优先按深度或 value 分级
常见错误是给每个 填 fill="#xxx" 写死,或用节点 name 做哈希色 —— 这会导致同名不同层的块颜色重复,且无法反映数据量级差异。
把任意文章或文档内容转换成精美的全屏翻页 HTML 演示文件(幻灯片风格)。当用户发来一篇文章、文档链接、Markdown 内容、或粘贴的文本,并且希望生成演示用的 HTML 时触发。支持任意内容来源:iWiki 链接、KM 链接、本地文件路径、直接粘贴的文本。生成的 HTML 文件保存到本地工作区,并通过企微直接发送给用户。触发词示例:帮我把这篇文章做成PPT、转成演示文档、生成HTML幻灯片、做个演示、转成可以演示的格式、article to deck、make a slide。
更实用的做法:
- 按深度着色:
d3.scaleOrdinal(d3.schemeCategory10).domain([0, 1, 2]),然后fill(scale(node.depth)) - 按
value线性渐变:d3.scaleLinear().domain([minVal, maxVal]).range(['#eee', '#222']) - 鼠标悬停时用
title显示完整name和value,比塞在矩形里更清晰
响应式重绘时别反复调用 d3.treemap(),缓存 layout 实例
窗口缩放时若每次重新调用 d3.treemap().size([...]),会重建整个布局函数,性能差且可能触发重复绑定事件。正确做法是复用同一个 layout 实例,只更新尺寸:
const treemap = d3.treemap().padding(1); // 初始渲染 treemap.size([width, height])(root); // resize 时 treemap.size([newWidth, newHeight])(root); // 直接重算坐标,不新建对象
另外, 宽高建议用 JS 动态设置 attr('width')/attr('height'),避免 CSS 缩放导致像素模糊。
真正麻烦的是数据更新后如何平滑过渡 —— d3.treemap() 本身不支持动画,得靠 selection.transition().attrTween() 手动插值 x0→x1 等四个坐标,稍不注意就卡顿。除非强需求,否则首次实现建议先关掉过渡。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










