d3.js词云图出现文字重叠问题,如何调整代码避免重叠?
问题根源
d3-cloud 布局阶段会根据你传入的字号计算每个词的占据空间、碰撞边界和最终位置,你当前代码布局阶段传入的字号是原始d.size,实际渲染时将字号放大了10倍,布局阶段预留的间距无法适配放大后的字体尺寸,就会出现文字重叠。
解决步骤
- 统一布局和渲染的字号规则:直接在布局阶段就传入最终渲染用的字号,渲染时直接使用布局计算好的尺寸即可,修改代码如下:
// 布局阶段的fontSize改为最终渲染的大小 var layout = d3.layout.cloud() .size([width, height]) .words(myWords.map(function(d) { // 注意把字符串类型的size转为数字避免计算异常 return {text: d.word, size: Number(d.size), color:randomColor()}; })) .padding(10) // 可以适当调大padding增加间距 .rotate(function() { return ~~(Math.random() * 2) * 90; }) .font("Impact") .fontSize(function(d) { return d.size * 10; }) // 布局时就用放大后的字号计算 .on("end", draw) layout.start(); // 渲染阶段直接用布局计算好的尺寸 function draw(words) { svg .append("g") .attr("transform", "translate(" + layout.size()[0] / 2+ "," + layout.size()[1] / 2 + ")") .selectAll("text") .data(words) .enter().append("text") .style("font-size",function(d) { return d.size + "px" }) // 不需要再乘10 .style("fill", function(d) { return d.color }) .attr("text-anchor", "middle") .attr("font-family", "Impact") .attr("transform", function(d) { return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")"; }) .text(function(d) { return d.text; }); }
- 若调整后仍有重叠,可以继续调大
padding参数的数值,预留更多文字间距 - 确认画布尺寸足够容纳所有词,可适当调高
width和height的数值,避免画布过小导致文字被挤压重叠 - 可以调整旋转规则,比如降低旋转文字的比例、使用更小的旋转角度,减少文字排列时的空间浪费
内容的提问来源于stack exchange,提问作者Fabio
相关产品推荐
相关产品推荐

