|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<meta charset="utf-8"> |
|
<title>Pyramid Pie</title> |
|
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> |
|
<script src="//cdnjs.cloudflare.com/ajax/libs/d3-legend/1.1.0/d3-legend.js"></script> |
|
<script src='https://npmcdn.com/babel-core@5.8.34/browser.min.js'></script> |
|
<link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'> |
|
<style> |
|
.color-legend text { |
|
font-family: 'Open Sans', sans-serif; |
|
font-size: 12pt; |
|
font-weight: 600 |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
<script lang='babel' type='text/babel'> |
|
const outerWidth = 960; |
|
const outerHeight = 500; |
|
const margin = { left: 0, top: 0, right: 0, bottom: 0 }; |
|
const radiusMax = 180; |
|
|
|
const xColumn = 'name'; |
|
const sliceSizeColumn = 'proportion'; |
|
const colorColumn = 'feature'; |
|
const skyBlue = '#3a5d8f'; |
|
const sunnySide = '#d8a34d'; |
|
const shadySide = '#633c27'; |
|
const pyramidColors = [ |
|
skyBlue, |
|
shadySide, |
|
sunnySide, |
|
]; |
|
const legendColors = [ |
|
skyBlue, |
|
sunnySide, |
|
shadySide |
|
]; |
|
|
|
const innerWidth = outerWidth - margin.left - margin.right; |
|
const innerHeight = outerHeight - margin.top - margin.bottom; |
|
|
|
const svg = d3.select('body').append('svg') |
|
.attr('width', outerWidth) |
|
.attr('height', outerHeight); |
|
const g = svg.append('g') |
|
.attr('transform', `translate(${margin.left}, ${margin.top})`); |
|
const xAxisG = g.append('g') |
|
.attr('class', 'x axis') |
|
.attr('transform', `translate(0, ${innerHeight})`); |
|
const pieG = g.append('g'); |
|
|
|
const colorLegendG = g.append('g') |
|
.attr('class', 'color-legend') |
|
.attr('transform', 'translate(620, 145)'); |
|
|
|
const xScale = d3.scale.ordinal().rangePoints([0, innerWidth]); |
|
const colorScale = d3.scale.ordinal() |
|
.range(pyramidColors); |
|
|
|
const labels = [ |
|
'Sky', |
|
'Sunny side of the pyramid', |
|
'Shady side of the pyramid' |
|
]; |
|
|
|
// a hack to get the legend elements to appear |
|
// in the desired order |
|
const legendColorScale = d3.scale.ordinal() |
|
.domain(labels) |
|
.range(legendColors); |
|
|
|
const pie = d3.layout.pie() |
|
.sort(null); |
|
|
|
const arc = d3.svg.arc(); |
|
arc.outerRadius(radiusMax); |
|
arc.innerRadius(0); |
|
|
|
const colorLegend = d3.legend.color() |
|
.scale(legendColorScale) |
|
.shape('circle') |
|
.shapePadding(50) |
|
.shapeRadius(25) |
|
.labelOffset(12); |
|
|
|
function render(data) { |
|
colorScale.domain(data.map(d => d[colorColumn])); |
|
pie.value(d => d[sliceSizeColumn]); |
|
|
|
const pieData = pie(data); |
|
|
|
pieG.attr('transform', `translate(${innerWidth / 3}, ${innerHeight / 2})`); |
|
|
|
const slices = pieG.selectAll('path').data(pieData); |
|
slices.enter().append('path'); |
|
slices |
|
.attr('d', arc) |
|
.attr('fill', d => colorScale(d.data[colorColumn])); |
|
slices.exit().remove(); |
|
|
|
slices |
|
.attr('transform', `rotate(220)`); |
|
|
|
colorLegend.labels(labels); |
|
colorLegendG.call(colorLegend); |
|
|
|
d3.selectAll('text.label') |
|
.attr('dy', '0em'); |
|
} |
|
|
|
function type(d) { |
|
d.name = 'World'; |
|
d.population = +d.population; |
|
return d; |
|
} |
|
|
|
d3.csv('data.csv', type, render); |
|
</script> |
|
</body> |
|
</html> |