Reputation: 8074
I have created a donut chart with D3 that uses two data sets and displays slightly different size rings for each. I would like to add labels to the data set(for a legend), but the selectAll("path")
expects each data set to be a simple array of values, so I have been unable to add the labels.
Below is the code I have so far and a fiddle:
var dataset = {
apples: [13245, 28479, 11111, 11000, 3876],
oranges: [53245, 28479, 19697, 24037, 19654],
};
var width = d3.select('#duration').node().offsetWidth,
height = 300,
cwidth = 33;
var colorO = ['#1352A4', '#2478E5', '#5D9CEC', '#A4C7F4', '#DBE8FB'];
var colorA = ['#58A53B', '#83C969', '#A8D996', '#CDE9C3', '#E6F4E1'];
var pie = d3.layout.pie()
.sort(null);
var arc = d3.svg.arc();
var svg = d3.select("#duration svg")
.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, i) { return pie(d); })
.enter().append("path")
.attr("fill", function(d, i, j) {
if (j == 0) {
return colorO[i];
} else {
return colorA[i];
}
})
.attr("d", function(d, i, j) {
if (j == 0) {
return arc.innerRadius(75 + cwidth * j - 17).outerRadius(cwidth * (j + 2.9))(d);
} else {
return arc.innerRadius(75 + cwidth * j - 5).outerRadius(cwidth * (j + 2.5))(d);
}
});
Upvotes: 0
Views: 1871
Reputation: 108517
expects each data set to be a simple array of values
This is not true. You can and should use an array of objects. Then use the value accessor to target a property of your object for the pie
function. Here's how I'd re-factor your code:
var dataset = {
apples: [{
value: 13245,
color: '#1352A4',
label: 'one'
}, {
value: 28479,
color: '#5D9CEC',
label: 'two'
}, {
value: 11111,
color: '#1352A4',
label: 'three'
}, {
value: 11000,
color: '#A4C7F4',
label: 'four'
}, {
value: 3876,
color: '#DBE8FB',
label: 'five'
}],
oranges: [{
value: 53245,
color: '#58A53B',
label: 'one'
}, {
value: 28479,
color: '#83C969',
label: 'two'
}, {
value: 19697,
color: '#A8D996',
label: 'three'
}, {
value: 24037,
color: '#CDE9C3',
label: 'four'
}, {
value: 19654,
color: '#E6F4E1',
label: 'five'
}]
};
var width = d3.select('#duration').node().offsetWidth,
height = 300,
cwidth = 33;
var pie = d3.layout.pie()
.sort(null)
.value(function(d) {
return d.value;
})
var innerArc = d3.svg.arc()
.innerRadius(58)
.outerRadius(cwidth * 2.9);
var outerArc = d3.svg.arc()
.innerRadius(70 + cwidth)
.outerRadius(cwidth * 3.5);
var svg = d3.select("#duration svg")
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var gs = svg.selectAll("g").data(d3.values(dataset)).enter().append("g");
var en = gs.selectAll("path")
.data(function(d, i) {
return pie(d);
})
.enter();
en.append("path")
.attr("fill", function(d) {
return d.data.color;
})
.attr("d", function(d, i, j) {
return j === 0 ? innerArc(d) : outerArc(d);
});
en.append("text")
.text(function(d) {
return d.data.label;
})
.attr("transform", function(d, i, j) {
return j === 0 ? "translate(" + innerArc.centroid(d) + ")" : "translate(" + outerArc.centroid(d) + ")";
});
<script src="https://d3js.org/d3.v3.min.js"></script>
<div id="duration">
<svg style="height:300px;width:100%"></svg>
</div>
Upvotes: 1