矩形词云需用JavaScript在canvas或svg中逐词计算位置、避让与旋转实现,CSS flex/grid无法满足语义权重、动态避让、旋转及响应式重布局等核心需求。

矩形词云不是靠 HTML 标签堆出来,而是用 JavaScript 在 <canvas></canvas> 或 <svg></svg> 上逐词计算位置、避让、旋转后绘制的;主流库中 d3-cloud 默认布局就是矩形,wordcloud2.js 也支持 shape: 'rect' 参数,但需注意中文换行和碰撞检测精度问题。
为什么不能用 CSS flex 或 grid 做矩形词云
CSS 布局只管“排列”,不管“语义权重”和“视觉避让”。词云的核心逻辑是:高频词字号大、位置居中、不重叠、可旋转——这些必须由 JS 实时计算每个词的 x、y、rotate、fontSize,再注入到 SVG 或 Canvas。用 display: flex 只能做出静态标签云,无法实现真正的矩形填充式词云效果。
- flex 容器内元素无法自动避开已占区域,词会堆叠或溢出边界
- 没有碰撞检测机制,高频词放大后必然覆盖低频词
- 无法按权重动态调整旋转角度(如
rotate: -30到30随机分布) - 响应式缩放时,CSS 无法重跑布局算法,词云会变形或留白
d3-cloud 矩形布局的关键参数设置
d3-cloud 的 .size([width, height]) 和默认 .shape('rectangle') 是矩形词云的基础,但真正影响填充密度和可读性的,是这几个参数:
把任意文章或文档内容转换成精美的全屏翻页 HTML 演示文件(幻灯片风格)。当用户发来一篇文章、文档链接、Markdown 内容、或粘贴的文本,并且希望生成演示用的 HTML 时触发。支持任意内容来源:iWiki 链接、KM 链接、本地文件路径、直接粘贴的文本。生成的 HTML 文件保存到本地工作区,并通过企微直接发送给用户。触发词示例:帮我把这篇文章做成PPT、转成演示文档、生成HTML幻灯片、做个演示、转成可以演示的格式、article to deck、make a slide。
-
.padding(2):词与词之间的最小像素间距,设为0容易粘连,>5 则稀疏;中文建议用3–4 -
.rotate(() => ~~(Math.random() * 3) * 15 - 15):控制旋转范围,避免全横排或全竖排,-15°~+15° 对中文更友好 -
.font('Microsoft YaHei')或'sans-serif':必须显式指定中文字体,否则 fallback 到英文,显示为方块 -
.fontSize(d => Math.log(d.weight + 1) * 20):对原始频次做对数压缩,防止“一词独大”撑满画布 - 务必在
.on('end', draw)中统一处理fill颜色和text-anchor,否则部分词可能无样式
wordcloud2.js 启用矩形布局的注意事项
wordcloud2.js 更轻量,开箱即用,但矩形模式(shape: 'rect')不是默认行为,且中文支持依赖字体加载时机:
立即学习“前端免费学习笔记(深入)”;
- 必须传入
shape: 'rect',否则默认是'circle'(球面投影) - 中文词需确保
fontFamily指向已加载的本地字体,比如fontFamily: 'PingFang SC, Microsoft YaHei' -
minSize和maxSize单位是像素,别用em或rem,否则渲染异常 - 如果词云空白,大概率是
list数据格式不对:必须是[[word, weight], ...]数组,不是对象数组 - 移动端需加
clearCanvas: true和drawOutOfBound: false,否则缩放后词溢出容器看不见
真正难的不是调出矩形轮廓,而是让所有词在限定区域内自然分布、不重叠、不截断、中文字形完整——这取决于你选的库是否做了足够细的碰撞检测,以及你有没有对原始权重做平滑处理。没做对数归一化、又没设 padding 和 rotate 范围的词云,看起来永远像乱扔的贴纸,而不是一张有呼吸感的云。


















