d3.js具有每个切片偏移起始角度的多层饼图

多米尼克·布·萨姆拉(Dominic Bou-Samra)

我在这里有一个饼图https://codepen.io/dbousamra/pen/rNVyMNR

我试图建立这个:

图表

注意派中第二个切片的角度和偏移量吗?我该如何实现?

var width = 600,
    height = 450,
    maxRadius = Math.min(width, height) / 2;

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
    .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");


var multiLevelData = [];
var setMultiLevelData = function(data) {
    if (data == null)
        return;
    var level = data.length,
        counter = 0,
        index = 0,
        currentLevelData = [],
        queue = [];
    for (var i = 0; i < data.length; i++) {
        queue.push(data[i]);
    };

    while (!queue.length == 0) {
        var node = queue.shift();
        currentLevelData.push(node);
        level--;

        if (node.subData) {
            for (var i = 0; i < node.subData.length; i++) {
                queue.push(node.subData[i]);
                counter++;
            };
        }
        if (level == 0) {
            level = counter;
            counter = 0;            multiLevelData.push(currentLevelData);
            currentLevelData = [];
        }
    }
}

var drawPieChart = function(_data, index) {
    var pie = d3.layout.pie()
        .sort(null)
        .value(function(d) {
            return d.nodeData.size;
        });
    var arc = d3.svg.arc()
        .outerRadius((index + 1) * pieWidth - 1)
        .innerRadius(index * pieWidth)
        .startAngle((d) => d.startAngle + Math.PI/4 )
        .endAngle((d) => d.endAngle + Math.PI/4 );

    var g = svg.selectAll(".arc" + index).data(pie(_data)).enter().append("g")
        .attr("class", "arc" + index);

    g.append("path").attr("d", arc)
        .style("fill", function(d) {
            return color(d.data.nodeData.number);
        });

    g.append("text").attr("transform", function(d) {
            return "translate(" + arc.centroid(d) + ")";
        })
        .attr("dy", ".35em").style("text-anchor", "middle")
        .text(function(d) {
            return d.data.nodeData.number;
        });
}


setMultiLevelData(data);

var pieWidth = parseInt(maxRadius / multiLevelData.length) - multiLevelData.length;

var color = d3.scale.category20();

for (var i = 0; i < multiLevelData.length; i++) {
    var _cData = multiLevelData[i];
    drawPieChart(_cData, i);
}

和数据:

<script>
  /*
  Here is the compact implementation of the json data. Ideally it should be stored in a json file and should be retrieved by d3.json
  */
  data = [{
    "nodeData": {
      "number": "17",
      "size": 100
    },
    "subData": [
      {
        "nodeData": {
          "number": "16",
          "size": 25
        }
      },
      {
        "nodeData": {
          "number": "15",
          "size": 25
        }
      },
      {
        "nodeData": {
          "number": "14",
          "size": 25
        }
      },
      {
        "nodeData": {
          "number": "13",
          "size": 25
        },
        "subData": [
          {
            "nodeData": {
              "number": "12",
              "size": 100 / 6
            },
          },
          {
            "nodeData": {
              "number": "11",
              "size": 100 / 6
            }
          },
          {
            "nodeData": {
              "number": "10",
              "size": 100 / 6
            }
          },
          {
            "nodeData": {
              "number": "9",
              "size": 100 / 6
            }
          },
          {
            "nodeData": {
              "number": "8",
              "size": 100 / 6
            }
          },
          {
            "nodeData": {
              "number": "7",
              "size": 100 / 6
            },
            "subData": [
              {
                "nodeData": {
                  "number": "6",
                  "size": 100 / 6
                },
              },
              {
                "nodeData": {
                  "number": "5",
                  "size": 100 / 6
                }
              },
              {
                "nodeData": {
                  "number": "4",
                  "size": 100 / 6
                }
              },
              {
                "nodeData": {
                  "number": "3",
                  "size": 100 / 6
                }
              },
              {
                "nodeData": {
                  "number": "2",
                  "size": 100 / 6
                }
              },
              {
                "nodeData": {
                  "number": "1",
                  "size": 100 / 6
                }
              }
            ]
          }
        ]
      }]
  }]
</script>

饼图是正确的方法吗?

没有部落

在定义属于该饼图行的弧段时,是否尝试过设置偏移角度。就像是:

var arc = d3.svg.arc()
   .outerRadius((index + 1) * pieWidth - 1)
   .innerRadius(index * pieWidth)
   .startAngle((d) => {
       if( radius < outerRadiusSecondSlice && radius > innerRadiusSecondSlice) 
       {
           return d.startAngle + Math.PI/4 + offset;
       })
       else {
          return d.startAngle + Math.PI /4;
       }
     })
   .endAngle((d) => {
       if( radius < outerRadiusSecondSlice && radius > innerRadiusSecondSlice) 
       {
          return d.endAngle + Math.PI/4 + offset;
       })
       else {
          return d.endAngle + Math.PI /4;
       }
     })

您将必须定义externalRadiusSecondSlice,innerRadiusSecondSlice和适当的偏移量。

如果您的数据结构是嵌套的,则可以考虑使用旭日形图-可缩放的版本非常棒。'''

d3 v5  https://observablehq.com/@d3/zoomable-sunburst
d3 v4  https://bl.ocks.org/vasturiano/12da9071095fbd4df434e60d52d2d58d
d3 v3  https://bl.ocks.org/WeikerWT/6008f1fc0a060a172b8ebec3e9e97ad7

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章