使用D3js v4的多环甜甜圈图表

时间:2017-10-19 19:06:03

标签: d3.js charts donut-chart

我正试图通过多个环工作来获得这个圆环图。这是使用d3js v4。这是另一篇文章的延续,其中这是在v3(multi-ring pie chart using d3js)中工作的。创建的路径始终显示M0,0Z。谁能告诉我哪里出了问题呢?我也在控制台中获得了Expected lenght NaN



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.scaleOrdinal(d3.schemeCategory20);

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

var arc = d3.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://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.min.js"></script>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:2)

我重写了一下你的代码。检查,现在它的工作原理。当我存储当前数据项的索引时,请注意我使用属性parentIndex扩展数据对象。在d3版本3中,您可以获取父数据项的索引作为第三个参数function(d,i,j)(在此示例中为j),但在d3版本4中,第三个参数不是索引。

var path = gs.selectAll("path")
  .data(function(d, i) {
    return pie(d.children).map(function(payload) { // <-- !!!
      return {
        payload: payload,
        parentIndex: i
      }
    })
  })
  .enter().append("path")
  .attr("fill", function(d, i) {
    return color(i);
  })
  .attr("d", function(d, i) {
    return arc
            .innerRadius(10 + cwidth * d.parentIndex) //<-- !!!
            .outerRadius(cwidth * (d.parentIndex + 1))(d.payload); //<-- !!!
  });

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.scaleOrdinal(d3.schemeCategory20);

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

var arc = d3.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, i) {
  	return pie(d.children).map(function(payload) {
			return {
      	payload: payload,
        parentIndex: i
      }
    })
  })
  .enter().append("path")
  .attr("fill", function(d, i) {
    return color(i);
  })
  .attr("d", function(d, i, j) {
    return arc.innerRadius(10 + cwidth * d.parentIndex).outerRadius(cwidth * (d.parentIndex + 1))(d.payload);
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.min.js"></script>