使用d3js的多环饼图

multi-ring pie chart using d3js

我想了解如何使用 d3js 创建多环饼图。这是我到目前为止所尝试过的。我很确定它在这里没有正确读取数据。关于我应该如何创建这样一个图表的任何例子。我想做的是根据流行季度等每个组来获得每个戒指。

var dataset = [
  {
    "name": "Population Quater",
    "code": "POP_QUATER",
    "parent": "POP_BY_QUAT",
    "children": [
      {
        "name": "POP_CYQ1",
        "code": "POP_CYQ1",
        "parent": "POP_QUATER",
        "value": "6772",
        "label": "CYQ1",
        "children": []
      },
      {
        "name": "POP_CYQ2",
        "code": "POP_CYQ2",
        "parent": "POP_QUATER",
        "value": "6716",
        "label": "CYQ2",
        "children": []
      },
      {
        "name": "POP_CYQ3",
        "code": "POP_CYQ3",
        "parent": "POP_QUATER",
        "value": "6714",
        "label": "CYQ3",
        "children": []
      },
      {
        "name": "POP_CYQ4",
        "code": "POP_CYQ4",
        "parent": "POP_QUATER",
        "value": "6703",
        "label": "CYQ4",
        "children": []
      },
      {
        "name": "POP_LYQ1",
        "code": "POP_LYQ1",
        "parent": "POP_QUATER",
        "value": "6721",
        "label": "LYQ1",
        "children": []
      },
      {
        "name": "POP_LYQ2",
        "code": "POP_LYQ2",
        "parent": "POP_QUATER",
        "value": "6671",
        "label": "LYQ2",
        "children": []
      },
      {
        "name": "POP_LYQ3",
        "code": "POP_LYQ3",
        "parent": "POP_QUATER",
        "value": "6708",
        "label": "LYQ3",
        "children": []
      },
      {
        "name": "POP_LYQ4",
        "code": "POP_LYQ4",
        "parent": "POP_QUATER",
        "value": "6734",
        "label": "LYQ4",
        "children": []
      }
    ]
  },
  {
    "name": "Transient Pop",
    "code": "TRANSIENT_POP",
    "parent": "POP_BY_QUAT",
    "label": "Transient Pop",
    "children": [
      {
        "name": "TRANSIENT_LYQ1",
        "code": "TRANSIENT_LYQ1",
        "parent": "TRANSIENT_POP",
        "value": "54",
        "label": "LYQ1",
        "children": []
      },
      {
        "name": "TRANSIENT_LYQ2",
        "code": "TRANSIENT_LYQ2",
        "parent": "TRANSIENT_POP",
        "value": "86",
        "label": "LYQ2",
        "children": []
      },
      {
        "name": "TRANSIENT_LYQ3",
        "code": "TRANSIENT_LYQ3",
        "parent": "TRANSIENT_POP",
        "value": "219",
        "label": "LYQ3",
        "children": []
      },
      {
        "name": "TRANSIENT_LYQ4",
        "code": "TRANSIENT_LYQ4",
        "parent": "TRANSIENT_POP",
        "value": "191",
        "label": "LYQ4",
        "children": []
      },
      {
        "name": "TRANSIENT_CYQ1",
        "code": "TRANSIENT_CYQ1",
        "parent": "TRANSIENT_POP",
        "value": "52",
        "label": "CYQ1",
        "children": []
      },
      {
        "name": "TRANSIENT_CYQ2",
        "code": "TRANSIENT_CYQ2",
        "parent": "TRANSIENT_POP",
        "value": "91",
        "label": "CYQ2",
        "children": []
      },
      {
        "name": "TRANSIENT_CYQ3",
        "code": "TRANSIENT_CYQ3",
        "parent": "TRANSIENT_POP",
        "value": "222",
        "label": "CYQ3",
        "children": []
      },
      {
        "name": "TRANSIENT_CYQ4",
        "code": "TRANSIENT_CYQ4",
        "parent": "TRANSIENT_POP",
        "value": "186",
        "label": "CYQ4",
        "children": []
      }
    ]
  },
  {
    "name": "Seasonal Pop",
    "code": "SEASONAL_POP",
    "parent": "POP_BY_QUAT",
    "label": "Seasonal Pop",
    "children": [
      {
        "name": "SEASONAL_LYQ1",
        "code": "SEASONAL_LYQ1",
        "parent": "SEASONAL_POP",
        "value": "2",
        "label": "LYQ1",
        "children": []
      },
      {
        "name": "SEASONAL_LYQ2",
        "code": "SEASONAL_LYQ2",
        "parent": "SEASONAL_POP",
        "value": "24",
        "label": "LYQ2",
        "children": []
      },
      {
        "name": "SEASONAL_LYQ3",
        "code": "SEASONAL_LYQ3",
        "parent": "SEASONAL_POP",
        "value": "152",
        "label": "LYQ3",
        "children": []
      },
      {
        "name": "SEASONAL_LYQ4",
        "code": "SEASONAL_LYQ4",
        "parent": "SEASONAL_POP",
        "value": "55",
        "label": "LYQ4",
        "children": []
      },
      {
        "name": "SEASONAL_CYQ1",
        "code": "SEASONAL_CYQ1",
        "parent": "SEASONAL_POP",
        "value": "2",
        "label": "CYQ1",
        "children": []
      },
      {
        "name": "SEASONAL_CYQ2",
        "code": "SEASONAL_CYQ2",
        "parent": "SEASONAL_POP",
        "value": "22",
        "label": "CYQ2",
        "children": []
      },
      {
        "name": "SEASONAL_CYQ3",
        "code": "SEASONAL_CYQ3",
        "parent": "SEASONAL_POP",
        "value": "161",
        "label": "CYQ3",
        "children": []
      },
      {
        "name": "SEASONAL_CYQ4",
        "code": "SEASONAL_CYQ4",
        "parent": "SEASONAL_POP",
        "value": "55",
        "label": "CYQ4",
        "children": []
      }
    ]
  }
];

var width = 460,
    height = 300,
    cwidth = 25;

var color = d3.scale.category20();

 var pie = d3.layout.pie()
            .sort(null).value(function (d) {
            return d.value;//since score is the parameter for the pie
        });

var arc = d3.svg.arc();

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

var gs = svg.selectAll("g").data(d3.values(dataset)).enter().append("g");
var path = gs.selectAll("path")
    .data(function(d) { return pie(d.value); })
  .enter().append("path")
    .attr("fill", function(d, i) { return color(i); })
    .attr("d", function(d, i, j) { return arc.innerRadius(10+cwidth*j).outerRadius(cwidth*(j+1))(d); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.13/d3.min.js"></script>

您没有将数据数组 (dataset) 绑定到您的组。应该是:

var gs = svg.selectAll("g")
    .data(dataset)
    .enter()
    .append("g");

然后,对于内部选择,使用 children:

var path = gs.selectAll("path")
    .data(function(d) {
        return pie(d.children);
    })
    //etc...

这是您的代码,其中包含这些更改:

var dataset = [{
  "name": "Population Quater",
  "code": "POP_QUATER",
  "parent": "POP_BY_QUAT",
  "children": [{
    "name": "POP_CYQ1",
    "code": "POP_CYQ1",
    "parent": "POP_QUATER",
    "value": "6772",
    "label": "CYQ1",
    "children": []
  }, {
    "name": "POP_CYQ2",
    "code": "POP_CYQ2",
    "parent": "POP_QUATER",
    "value": "6716",
    "label": "CYQ2",
    "children": []
  }, {
    "name": "POP_CYQ3",
    "code": "POP_CYQ3",
    "parent": "POP_QUATER",
    "value": "6714",
    "label": "CYQ3",
    "children": []
  }, {
    "name": "POP_CYQ4",
    "code": "POP_CYQ4",
    "parent": "POP_QUATER",
    "value": "6703",
    "label": "CYQ4",
    "children": []
  }, {
    "name": "POP_LYQ1",
    "code": "POP_LYQ1",
    "parent": "POP_QUATER",
    "value": "6721",
    "label": "LYQ1",
    "children": []
  }, {
    "name": "POP_LYQ2",
    "code": "POP_LYQ2",
    "parent": "POP_QUATER",
    "value": "6671",
    "label": "LYQ2",
    "children": []
  }, {
    "name": "POP_LYQ3",
    "code": "POP_LYQ3",
    "parent": "POP_QUATER",
    "value": "6708",
    "label": "LYQ3",
    "children": []
  }, {
    "name": "POP_LYQ4",
    "code": "POP_LYQ4",
    "parent": "POP_QUATER",
    "value": "6734",
    "label": "LYQ4",
    "children": []
  }]
}, {
  "name": "Transient Pop",
  "code": "TRANSIENT_POP",
  "parent": "POP_BY_QUAT",
  "label": "Transient Pop",
  "children": [{
    "name": "TRANSIENT_LYQ1",
    "code": "TRANSIENT_LYQ1",
    "parent": "TRANSIENT_POP",
    "value": "54",
    "label": "LYQ1",
    "children": []
  }, {
    "name": "TRANSIENT_LYQ2",
    "code": "TRANSIENT_LYQ2",
    "parent": "TRANSIENT_POP",
    "value": "86",
    "label": "LYQ2",
    "children": []
  }, {
    "name": "TRANSIENT_LYQ3",
    "code": "TRANSIENT_LYQ3",
    "parent": "TRANSIENT_POP",
    "value": "219",
    "label": "LYQ3",
    "children": []
  }, {
    "name": "TRANSIENT_LYQ4",
    "code": "TRANSIENT_LYQ4",
    "parent": "TRANSIENT_POP",
    "value": "191",
    "label": "LYQ4",
    "children": []
  }, {
    "name": "TRANSIENT_CYQ1",
    "code": "TRANSIENT_CYQ1",
    "parent": "TRANSIENT_POP",
    "value": "52",
    "label": "CYQ1",
    "children": []
  }, {
    "name": "TRANSIENT_CYQ2",
    "code": "TRANSIENT_CYQ2",
    "parent": "TRANSIENT_POP",
    "value": "91",
    "label": "CYQ2",
    "children": []
  }, {
    "name": "TRANSIENT_CYQ3",
    "code": "TRANSIENT_CYQ3",
    "parent": "TRANSIENT_POP",
    "value": "222",
    "label": "CYQ3",
    "children": []
  }, {
    "name": "TRANSIENT_CYQ4",
    "code": "TRANSIENT_CYQ4",
    "parent": "TRANSIENT_POP",
    "value": "186",
    "label": "CYQ4",
    "children": []
  }]
}, {
  "name": "Seasonal Pop",
  "code": "SEASONAL_POP",
  "parent": "POP_BY_QUAT",
  "label": "Seasonal Pop",
  "children": [{
    "name": "SEASONAL_LYQ1",
    "code": "SEASONAL_LYQ1",
    "parent": "SEASONAL_POP",
    "value": "2",
    "label": "LYQ1",
    "children": []
  }, {
    "name": "SEASONAL_LYQ2",
    "code": "SEASONAL_LYQ2",
    "parent": "SEASONAL_POP",
    "value": "24",
    "label": "LYQ2",
    "children": []
  }, {
    "name": "SEASONAL_LYQ3",
    "code": "SEASONAL_LYQ3",
    "parent": "SEASONAL_POP",
    "value": "152",
    "label": "LYQ3",
    "children": []
  }, {
    "name": "SEASONAL_LYQ4",
    "code": "SEASONAL_LYQ4",
    "parent": "SEASONAL_POP",
    "value": "55",
    "label": "LYQ4",
    "children": []
  }, {
    "name": "SEASONAL_CYQ1",
    "code": "SEASONAL_CYQ1",
    "parent": "SEASONAL_POP",
    "value": "2",
    "label": "CYQ1",
    "children": []
  }, {
    "name": "SEASONAL_CYQ2",
    "code": "SEASONAL_CYQ2",
    "parent": "SEASONAL_POP",
    "value": "22",
    "label": "CYQ2",
    "children": []
  }, {
    "name": "SEASONAL_CYQ3",
    "code": "SEASONAL_CYQ3",
    "parent": "SEASONAL_POP",
    "value": "161",
    "label": "CYQ3",
    "children": []
  }, {
    "name": "SEASONAL_CYQ4",
    "code": "SEASONAL_CYQ4",
    "parent": "SEASONAL_POP",
    "value": "55",
    "label": "CYQ4",
    "children": []
  }]
}];

var width = 460,
  height = 300,
  cwidth = 25;

var color = d3.scale.category20();

var pie = d3.layout.pie()
  .sort(null).value(function(d) {
    return d.value; //since score is the parameter for the pie
  });

var arc = d3.svg.arc();

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

var gs = svg.selectAll("g")
  .data(dataset)
  .enter()
  .append("g");
var path = gs.selectAll("path")
  .data(function(d) {
    return pie(d.children);
  })
  .enter().append("path")
  .attr("fill", function(d, i) {
    return color(i);
  })
  .attr("d", function(d, i, j) {
    return arc.innerRadius(10 + cwidth * j).outerRadius(cwidth * (j + 1))(d);
  });
<script src="https://d3js.org/d3.v3.min.js"></script>