Stacked area chart from d3 in action
Built with blockbuilder.org
license: mit |
Stacked area chart from d3 in action
Built with blockbuilder.org
<!DOCTYPE html> | |
<html> | |
<head> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.25.6/d3-legend.min.js"></script> | |
<style> | |
g.tick line { | |
opacity: .4; | |
stroke: sandybrown; | |
} | |
path.domain { | |
stroke: sandybrown; | |
opacity: .4; | |
} | |
</style> | |
</head> | |
<body> | |
<script src="stackedarea2.js"></script> | |
</body> | |
</html> |
day | titanic | avatar | akira | frozen | deliverance | avengers | |
---|---|---|---|---|---|---|---|
1 | 20 | 8 | 3 | 0 | 0 | 0 | |
2 | 18 | 5 | 1 | 13 | 0 | 0 | |
3 | 14 | 3 | 1 | 10 | 0 | 0 | |
4 | 7 | 3 | 0 | 5 | 27 | 15 | |
5 | 4 | 3 | 0 | 2 | 20 | 14 | |
6 | 3 | 1 | 0 | 0 | 10 | 13 | |
7 | 2 | 0 | 0 | 0 | 8 | 12 | |
8 | 0 | 0 | 0 | 0 | 6 | 11 | |
9 | 0 | 0 | 0 | 0 | 3 | 9 | |
10 | 0 | 0 | 0 | 0 | 1 | 8 |
'use strict'; | |
d3.csv('movies.csv', stackedAreaChart); | |
function stackedAreaChart(data) { | |
const margin = {top: 25, left:25, bottom:25, right:50}; | |
const width = 600 - margin.right - margin.left; | |
const height = 500 - margin.top - margin.bottom; | |
const svg = d3.select('body').append('svg') | |
.attr('height', height + margin.top + margin.bottom) | |
.attr('width', width + margin.right + margin.left) | |
.append('g') | |
.attr('transform', 'translate(' + margin.left + ',' + margin.right + ')'); | |
const xScale = d3.scaleLinear().domain([1, 10]).range([0, width - margin.right]); | |
const yScale = d3.scaleLinear().domain([0, 55]).range([height - 5, 0]); | |
const fillScale = d3.scaleOrdinal() | |
.domain(['titanic', 'avatar', 'akira', 'frozen', 'deliverance', 'avengers']) | |
.range(['coral', 'skyblue', 'olive', 'sandybrown', 'royalblue', '#41a368']); | |
const xAxis = d3.axisBottom().scale(xScale) | |
.tickValues([1,2,3,4,5,6,7,8,9,10]) | |
.tickSize(height); | |
svg.append('g').attr('class', 'xAxis').call(xAxis) | |
const yAxis = d3.axisLeft().scale(yScale) | |
.tickSize(-(width - margin.right)); | |
svg.append('g').attr('class', 'yAxis').call(yAxis); | |
// if you only want to have the upper portion, use d3.line(). | |
// Create lines | |
Object.keys(data[0]).forEach(key => { | |
if (key !== 'day') { | |
var movieArea = d3.area() | |
.x(d => xScale(d.day)) | |
.y0(d => yScale(simpleStacking(d, key) - d[key])) | |
.y1(d => yScale(simpleStacking(d, key))) | |
.curve(d3.curveBasis); | |
svg.append('path') | |
.style('id', key + 'Area') | |
.attr('d', movieArea(data)) | |
.attr('fill', fillScale(key)) | |
.attr('stroke', 'black') | |
.attr('stroke-width', 1) | |
.attr('fill-opacity', .75); | |
} | |
}) | |
function simpleStacking(lineData, lineKey) { | |
var newHeight = 0; | |
Object.keys(lineData).every(key => { | |
if (key !== 'day') { | |
newHeight += parseInt(lineData[key]); | |
if (key === lineKey) { | |
return false | |
} | |
} | |
return true | |
}) | |
return newHeight | |
}; | |
var legendA = d3.legendColor().scale(fillScale); | |
d3.select('svg').append('g') | |
.attr('transform', 'translate(' + (width - margin.left) + ',' + margin.top + ')') | |
.call(legendA); | |
legendA.shapePadding(60) | |
.shapeHeight(5) | |
}; |