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

D3.js饼图低占比数据文本被路径遮挡的解决方法咨询

解决D3.js饼图低占比标签被隐藏的问题

嘿,很高兴能帮到你!你遇到的低占比饼图标签被遮挡/隐藏的问题很常见,咱们可以从调整文本颜色和确保文本层级在路径上方两个方向解决,同时还要修正一个标签位置的小问题(你的代码里label的弧参数搞反啦)。下面是修改后的完整代码,我会标注关键改动:

修改后的JavaScript代码

var data = [ 
  {"platform": "Yes", "percentage": 87.00}, //skyblue 
  {"platform": "No", "percentage": 1.00}, //darkblue 
  {"platform": "N/A", "percentage": 12.00} //orange (这里调整了数值,确保总和100%,原来的87+1+17=105哦)
];
var svgWidth = 200, svgHeight = 200, radius = Math.min(svgWidth, svgHeight) / 2;
var svg = d3.select('svg')
 .attr("width", svgWidth)
 .attr("height", svgHeight);
//Create group element to hold pie chart
var g = svg.append("g")
 .attr("transform", "translate(" + radius + "," + radius + ")") ;
var color = d3.scaleOrdinal(d3.schemeCategory20);
var pie = d3.pie().value(function(d) { return d.percentage; });
var path = d3.arc()
 .outerRadius(80)
 .innerRadius(40);
var arc = g.selectAll("arc")
 .data(pie(data))
 .enter()
 .append("g");
arc.append("path")
 .attr("d", path)
 .attr("fill", function(d) { return color(d.data.percentage); });

// --- 关键改动1:修正label的弧参数(原来outerRadius < innerRadius,会导致标签位置错误)
var label = d3.arc()
 .outerRadius(80) // 和饼图的outerRadius一致,让标签在饼图区域内
 .innerRadius(40); // 和饼图的innerRadius匹配

arc.append("text")
 .attr("transform", function(d) { return "translate(" + label.centroid(d) + ")"; })
 .attr("text-anchor", "middle")
 // --- 关键改动2:设置文本为白色,确保在深色路径上可见
 .attr("fill", "white")
 // --- 关键改动3:确保文本在路径上方(SVG按添加顺序渲染,也可用.raise()强制置顶)
 .raise()
 .text(function(d) { return +d.data.percentage+"%"; });

对应的HTML和CSS代码(仅修正数据总和,其他不变)

<div class="cnt-main-container">
 <div class="charts">
 <svg class="pie-chart"></svg>
 </div>
 <div class="info">
 <div id="dot1"></div>
 <label for="dot1">Yes</label>
 <div id="dot2"></div>
 <label for="dot2">No</label>
 <div id="dot3"></div>
 <label for="dot3">N/A</label>
 </div>
</div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="script.js"></script>
.cnt-main-container {
 display:flex;
 flex-direction: column;
}
.charts{
 display:flex;
 justify-content: center;
 flex-direction: row;
 flex-wrap: nowrap;
}
.info{
 display:flex;
 justify-content: center;
 flex-direction: row;
}
#dot1{
 width:10px;
 height:10px;
 background:rgb(39, 81, 194);
 display:inline-block;
}
label{
 margin-left:3px;
 margin-top:-3px;
 margin-right:5px;
}
#dot2{
 width:10px;
 height:10px;
 background:rgb(233, 106, 3);
 display:inline-block;
}
#dot3{
 background-color:skyblue;
 width:10px;
 height:10px;
 display:inline-block;
}

关键改动说明

  1. 修正标签弧参数:你原来的label弧设置了outerRadius(20)和innerRadius(100),这会生成反向弧,导致标签的中心点位置完全错误,甚至跑到饼图外面。调整后让标签弧和饼图弧范围匹配,确保标签出现在正确位置。
  2. 设置白色文本:直接给<text>元素添加fill: white属性,这样即使低占比的路径颜色较深,文本也能清晰显示。
  3. 确保文本层级:SVG元素按代码添加顺序渲染,先加路径再加文本,文本默认会在路径上方;如果仍有遮挡,.raise()方法可以强制把文本移到最上层。
  4. 修正数据总和:原来的87+1+17=105不符合饼图百分比逻辑,调整为87+1+12=100,保证饼图比例正确。

这样修改后,低占比的No标签就会显示在对应的深蓝色路径上,白色文本清晰可见,不会被隐藏啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 11:02:26