JSFiddle - React, Tailwind, and code Playground
by paulL
HTML
<div id="chart"></div>
<div id="chart2"></div>
CSS
.donut {
shape-rendering: auto;
}
.legend-label {
text-anchor: middle;
}
.units-label {
font-size: .7em;
font-weight: normal;
text-transform: uppercase;
}
.data-label {
font-weight: bold;
font-size: 1.5em;
}
.value-1 {
fill: orange;
}
.value-2 {
fill: blue;
}
.value-3 {
fill: green;
}
JavaScript
function donutChart() {
var width = 420,
height = 420,
radius = 0,
factor = 0.7;
var legend = ['Low', 'Medium', 'High'];
function chart(selection) {
selection.each(function(data) {
if (radius == 0) {
radius = Math.min(width, height) / 2 - 10;
}
// hardcoding 36 here, you could use getBBox to get the actual SVG text height using sample text if you really wanted.
var legendHeight = 36;
// calculated height of all legend items together
var actualLegendHeight = data.length * legendHeight;
// inner diameter
var availableLegendHeight = radius * factor * 2;
// y-coordinate of first legend item (relative to the center b/c the main svg <g> element is translated
var legendOffset = (availableLegendHeight - actualLegendHeight) / 2 - (radius*factor);
var arc = d3.svg.arc()
.innerRadius(radius * factor)
.outerRadius(radius);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d; });
var svg = d3.select(this).append('svg')
.attr('width', width)
.attr('height', height)
.attr('class', 'donut')
.attr('dominant-baseline', 'hanging')
.append('g')
.attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')');
var g = svg.selectAll('.arc')
.data(pie(data))
.enter().append('g')
.attr('class', 'arc');
g.append('path')
.attr('d', arc)
.attr('class', function(d, i){return 'value-' + (i+1)})
.style('stroke', '#fff');
// append all the legend items to a common group which is translated
...