I am trying to get this donut charts with multiple ring working . This is using d3js v4. This is a continuation from another post where this was working in v3(multi-ring pie chart using d3js). The path created always shows up M0,0Z
. Could anyone let me know where is this going wrong. I also get Expected lenght NaN
in the console.
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>
I rewrote a bit your code. Check, now it works. Pay attention that I extend data object with property parentIndex
when I store the index of the current data item. In d3 version 3 you can get the index of parent data-item as third argument function(d,i,j)
(j
in this example), but in the d3 version 4, the third argument it's not the index.
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>