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

D3.js绘制双层环形图时Level2起始扇区不显示的技术问题

解决D3.js嵌套环形饼图Level2扇区缺失问题

我之前碰到过一模一样的情况,问题根源出在你两次绘制环形图时共用了同一个类名,导致D3的数据绑定逻辑发生冲突。

问题分析

当你绘制Level1环形图时,通过g.selectAll(".arc").data(pie(data)).enter()创建了一批带.arc类的<g>元素。等到绘制Level2时,再次调用g.selectAll(".arc")会直接选中这些已存在的元素。如果Level2的数据条目数和Level1相同或更少,enter()方法只会创建超出已有元素数量的新元素,而前面的元素会进入update阶段,但你的代码完全没处理这部分逻辑,直接跳过了,这就导致Level2开头的扇区根本没被创建出来。

解决方案

给两个环形图的组元素设置不同的类名,让D3能分别选择和绑定数据,互不干扰。修改后的代码如下:

Level1环形图绘制代码(修改类名为.arc-level1)

d3.json("http://localhost:50025/SportsWheelServices.asmx/WheelLevel1", function (error, data) { 
    data.forEach(function (d) { 
        d.SectionId = d.SectionId; 
        d.SectionLevel1 = d.SectionLevel1; 
        d.GroupName = d.GroupName; 
        d.SectionUpColor = d.SectionUpColor; 
        d.Rotation = d.Rotation; 
    }); 

    var label = d3.arc() 
        .outerRadius(radius - 20) 
        .innerRadius(400); 

    var pie = d3.pie() 
        .sort(null) 
        .value(function (d) { return d.SectionLevel1; }); 

    var arc = d3.arc() 
        .outerRadius(radius - 20) 
        .innerRadius(400); 

    var arcs = g.selectAll(".arc-level1") // 修改类名,避免和Level2冲突
        .data(pie(data)) 
        .enter().append("g") 
        .attr("class", "arc-level1"); // 设置专属类名

    arcs.append("path") 
        .attr("d", arc) 
        .attr("fill", function (d, i) { return colors(data[i].SectionUpColor); }); 

    arcs.append("text") 
        .attr("transform", function (d) { 
            var rotation = d.endAngle < Math.PI ? (d.startAngle / 2 + d.endAngle / 2) * 180 / Math.PI : (d.startAngle / 2 + d.endAngle / 2 + Math.PI) * 180 / Math.PI; 
            return "translate(" + label.centroid(d) + ") rotate("+ d.data.Rotation+") rotate(" + rotation + ")"; 
        }) 
        .attr("dy", "0.35em") 
        .text(function (d) { return d.data.GroupName; }); 
}); 

Level2环形图绘制代码(修改类名为.arc-level2)

d3.json("http://localhost:50025/SportsWheelServices.asmx/WheelLevel2", function (error, data) { 
    data.forEach(function(d) { 
        d.SectionId = d.SectionId; 
        d.SectionLevel2 = d.SectionLevel2; 
    }); 

    var label = d3.arc() 
        .outerRadius(radius - 20) 
        .innerRadius(300); 

    var pie = d3.pie() 
        .sort(null) 
        .value(function (d) { return d.SectionLevel2; }); 

    var arc = d3.arc() 
        .outerRadius(radius - 20) 
        .innerRadius(300); 

    var arcs = g.selectAll(".arc-level2") // 修改类名,避免和Level1冲突
        .data(pie(data)) 
        .enter().append("g") 
        .attr("class", "arc-level2"); // 设置专属类名

    arcs.append("path") 
        .attr("d", arc) 
        .attr("fill", function (d, i) { return colors(i); }); 
}); 

额外优化建议

你可以检查下两个环形的半径设置:Level1的innerRadius是400,而Level2的outerRadius是radius-20,如果radius-20大于400,两个环形会重叠,可能造成视觉上的遮挡。建议把Level2的outerRadius调整为390左右,确保和Level1的环形有间隔,显示更清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:00:30