Uses d3-area-label.
Built with blockbuilder.org
forked from curran's block: Labeled Streamgraph
license: mit |
Uses d3-area-label.
Built with blockbuilder.org
forked from curran's block: Labeled Streamgraph
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
<script src="https://unpkg.com/[email protected]"></script> | |
<script src="https://unpkg.com/[email protected]"></script> | |
<title>Area Label Test</title> | |
<style> | |
.area-label { | |
font-family: sans-serif; | |
fill-opacity: 0.5; | |
} | |
</style> | |
</head> | |
<body> | |
<svg width="960" height="500"></svg> | |
<script> | |
const svg = d3.select('svg') | |
const width = +svg.attr('width') | |
const height = +svg.attr('height') | |
const n = 100 | |
const keys = ['Leonardo', 'Donatello', 'Raphael', 'Michelangelo'] | |
const generateData = keys => { | |
const prev = {} | |
const velocity = {} | |
return d3.range(n).map((d, i) => { | |
const row = { time: i } | |
keys.forEach(key => { | |
velocity[key] = ((velocity[key] || 0) + (Math.random() - .5)) * 0.9 | |
const value = Math.max(0.2, (prev[key] || Math.random() * 10) + velocity[key]) | |
prev[key] = row[key] = value | |
}) | |
return row | |
}) | |
} | |
const data = generateData(keys) | |
const stack = d3.stack() | |
.keys(keys) | |
.offset(d3.stackOffsetWiggle) | |
const xValue = d => d.time | |
const xScale = d3.scaleLinear() | |
const yScale = d3.scaleLinear() | |
const colorScale = d3.scaleOrdinal() | |
.domain(keys) | |
.range(d3.schemeCategory10) | |
const areaFillOpacity = 0.3 | |
const area = d3.area() | |
.x(d => xScale(xValue(d.data))) | |
.y0(d => yScale(d[0])) | |
.y1(d => yScale(d[1])) | |
.curve(d3.curveBasis) | |
const stacked = stack(data) | |
xScale | |
.domain(d3.extent(data, d => xScale(xValue(d)))) | |
.range([0, width]) | |
yScale | |
.domain([ | |
d3.min(stacked[0], d => d[0]), | |
d3.max(stacked[stacked.length - 1], d => d[1]) | |
]) | |
.range([height, 0]) | |
const paths = svg.selectAll('path').data(stacked) | |
paths | |
.enter().append('path') | |
.attr('fill-opacity', areaFillOpacity) | |
.merge(paths) | |
.attr('d', area) | |
.attr('fill', d => colorScale(d.key)) | |
.attr('stroke', d => colorScale(d.key)) | |
const labels = svg.selectAll('text').data(stacked) | |
labels | |
.enter().append('text') | |
.attr('class', 'area-label') | |
.merge(labels) | |
.text(d => d.key) | |
.each(d3.areaLabel(area)) | |
</script> | |
</body> | |
</html> |