D3 环形菜单加文字标签
var arc_generator = d3.svg.arc()
.innerRadius(width*3 / 6.5)
.outerRadius(width*3 / 4)
var angle_data = d3.layout.pie()
.value(function (d) {
return d.population;
})
var pieData = angle_data(data)
var pieAngle = pieData.map(function (p) {
return (p.startAngle + p.endAngle) / 2 / Math.PI * 180;
});
// var color=d3.schemeCategory10;
//生成内部圆环
Pie.selectAll("path")
.data(angle_data(data))
.enter()
.append("path")
.attr("d", arc_generator)
.style("fill", function (d, i) {
return 'grey';
})
.style('stroke', 'black')
.attr("class", "path")
.attr('type', function (d) {
return d.data.type
})
.on('click', function (d) {
if (d.type === 'link'){
linkNode(currentD)
}else if (d.type === 'showon'){
showonNode(current, currentD)
}else if (d.type === 'showoff'){
showoffNode(currentD, highlightNodesId)
}else if (d.type === 'highlight'){
highlight(current, currentD)
}
d3.event.stopPropagation()//d3的阻止冒泡
})
var arc_label = d3.svg.arc()
.innerRadius(width*3 / 4)
.outerRadius(width*3 / 2)
Pie.selectAll(".arc_label")
.data(angle_data(data))
.enter()
.append("path")
.attr("d", arc_label)
.attr("class", "arc_label")
.style("fill", "none")
const labelFontSize = 12;
const labelValRadius = (170 * 0.35 - labelFontSize * 0.35); // 计算正确半径 文字位置
const labelValRadius1 = (170 * 0.35 + labelFontSize * 0.35);
// 定义两条路径以使标签的方向正确 labelsVals.append('def') .append('path') .attr('id', 'label-path-1') .attr('d', `m0 ${-labelValRadius} a${labelValRadius} ${labelValRadius} 0 1,1 -0.01 0`); labelsVals.append('def') .append('path') .attr('id', 'label-path-2') .attr('d', `m0 ${-labelValRadius1} a${labelValRadius1} ${labelValRadius1} 0 1,0 0.01 0`); labelsVals.selectAll('text') .data(data) .enter() .append('text') .style('font-size', labelFontSize) .style('fill', 'black') .style('font-weight', "bold") .style('text-anchor', 'middle') .append('textPath') .attr('href', function (d, i) { const p = pieData[i]; const angle = pieAngle[i]; if (angle > 90 && angle <= 270) { // 根据角度选择路径 return '#label-path-2'; } else { return '#label-path-1'; } }) .attr('startOffset', function (d, i) { const p = pieData[i]; const angle = pieAngle[i]; let percent = (p.startAngle + p.endAngle) / 2 / 2 / Math.PI * 100; if (angle > 90 && angle <= 270) { // 分别计算每条路径的正确百分比 return 100 - percent + "%"; } return percent + "%"; }) .text("") .on('click', function (d) { if (d.type === 'link'){ linkNode(currentD) }else if (d.type === 'showon'){ showonNode(current, currentD) }else if (d.type === 'showoff'){ showoffNode(currentD, highlightNodesId) }else if (d.type === 'highlight'){ highlight(current, currentD) } d3.event.stopPropagation() }, true)
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 我与微信审核的“相爱相杀”看个人小程序副业
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~