|
<html> |
|
<head> |
|
<style> |
|
body{ |
|
font-family:sans-serif; |
|
} |
|
</style> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.5.0/d3.min.js"></script> |
|
</head> |
|
|
|
<body> |
|
<svg></svg> |
|
</body> |
|
<script> |
|
const rawData = [ |
|
{year:2018, data:[15,7,35]}, |
|
{year:2017, data:[10,20,30]}, |
|
{year:2016, data:[20,20,30]}, |
|
{year:2015, data:[5,40,3]}, |
|
{year:2014, data:[25,12,9]}, |
|
]; |
|
|
|
const colours = [ '#000000','#EB4125','#0031F5' ]; |
|
|
|
const width=600, height=600; |
|
|
|
const stackSegments = radialStackLayout(rawData, Math.min(width,height)/2); |
|
|
|
const arc = d3.arc(); |
|
|
|
d3.select('svg') |
|
.attr('width', width) |
|
.attr('height', height) |
|
.append('g') |
|
.attr('transform',`translate(${width/2},${height/2})`) |
|
.selectAll('path.segment') |
|
.data(stackSegments) |
|
.enter() |
|
.append('path') |
|
.attr('d', d=>arc(d)) |
|
.attr('fill', d=>d.fill); |
|
|
|
/* the radialStackLayout function converts the data into a set of arc segment definitions */ |
|
|
|
function radialStackLayout(data, radius){ |
|
const angularScale = d3.scaleLinear() |
|
.range([0, 2*Math.PI]) |
|
.domain([0, data.length]) |
|
|
|
const biggestStack = data.reduce( |
|
(maxValue, currentArray) => { |
|
return Math.max(d3.sum(currentArray.data), maxValue) |
|
},0); |
|
|
|
const stackScale = d3.scaleLinear() |
|
.range([0, radius]) |
|
.domain([0, biggestStack]); |
|
|
|
const layoutElements = []; |
|
|
|
data.forEach((d, i)=>{ |
|
let stackHeight = 0; |
|
d.data.forEach((datum,j)=>{ |
|
layoutElements.push({ |
|
data: { year: d.year, value: datum }, // retain the original data potentially useful for things like tooltips |
|
innerRadius: stackHeight, |
|
outerRadius: stackHeight + stackScale(datum), |
|
startAngle: angularScale(i), |
|
endAngle: angularScale(i+1), |
|
fill:colours[j] |
|
}); |
|
stackHeight = stackHeight + stackScale(datum); |
|
}) |
|
}); |
|
|
|
return layoutElements; |
|
} |
|
|
|
d3.select(self.frameElement).style("height", height + "px"); |
|
</script> |
|
</html> |