Built with blockbuilder.org
forked from sxywu's block: Metis: Data Transformation + Nest
forked from sxywu's block: Metis: Data Transformation + Stacked Bar
license: mit |
Built with blockbuilder.org
forked from sxywu's block: Metis: Data Transformation + Nest
forked from sxywu's block: Metis: Data Transformation + Stacked Bar
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<style> | |
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } | |
</style> | |
</head> | |
<body> | |
<svg /> | |
<script> | |
// var data = [{ | |
// name: 'Sequoia', | |
// investments: [ | |
// { | |
// name: 'Airbnb', | |
// amount: 20200, // millions | |
// year: 2010, | |
// sector: 'consumer' | |
// }, | |
// { | |
// name: 'Pinterest', | |
// amount: 23874, | |
// year: 2008, | |
// sector: 'consumer' | |
// } | |
// ] | |
// }, { | |
// }]; | |
var data = [{ | |
name: 'Airbnb', | |
amount: 20200, // millions | |
year: 2010, | |
sector: 'enterprise', | |
investor: 'Sequoia' | |
}, { | |
name: 'Pinterest', | |
amount: 23874, | |
year: 2008, | |
sector: 'consumer', | |
investor: 'Sequoia' | |
}, { | |
name: 'Airbnb', | |
amount: 20200, // millions | |
year: 2010, | |
sector: 'consumer', | |
investor: 'Benchmark' | |
}, { | |
name: 'Spotify', | |
amount: 239847, | |
year: 2091, | |
sector: 'consumer', | |
investor: 'Benchmark' | |
}, { | |
name: 'Spotify', | |
amount: 239847, | |
year: 2091, | |
sector: 'consumer', | |
investor: 'Sequoia' | |
}, { | |
name: 'Slack', | |
amount: 238947, | |
year: 2012, | |
sector: 'enterprise', | |
investor: 'a16z', | |
}, { | |
name: 'Slack', | |
amount: 238947, | |
year: 2012, | |
sector: 'enterprise', | |
investor: 'Google Ventures', | |
}, { | |
name: 'Tanium', | |
amount: 123987, | |
year: 2002, | |
sector: 'enterprise', | |
investor: 'IVP' | |
}, { | |
name: 'Lyft', | |
amount: 123987, | |
year: 2002, | |
sector: 'consumer', | |
investor: 'a16z' | |
}]; | |
// bar chart, x-axis (ordinal) investor | |
// y-axis # of unicorns | |
// if stacked, sector (consumer vs. enterprise) | |
// color by sector | |
// hover to see individual unicorns | |
// 1. group by investor (for x-axis) | |
// 2. calculate stack for each sector | |
data = d3.nest() | |
.key(function(d) {return d.investor}) | |
.key(function(d) {return d.sector}) | |
.entries(data); | |
var stack = d3.stack() | |
.keys(['consumer', 'enterprise']) | |
.value(function(investor, key) { | |
// if sector key matches key given | |
var sector = investor.values.find(function(sector) {return sector.key === key}); | |
if (!sector) return 0; | |
return sector.values.length; | |
}); | |
var series = stack(data); | |
var svg = d3.select('svg') | |
.attr('width', 960).attr('height', 500); | |
var sectors = svg.selectAll('g') | |
.data(series, function(sector) {return sector.key}); | |
// exit | |
sectors.exit().remove(); | |
// enter + update | |
sectors = sectors.enter().append('g') | |
.classed('sector', true) | |
.merge(sectors); | |
// rectangles for each investor | |
var g = sectors.selectAll('g') | |
.data(function(sector) {return sector;}, function(investor) {return investor.data.key}); | |
// exit | |
g.exit().remove(); | |
// enter+update | |
var enter = g.enter().append('g').attr('class', d => d.key); | |
enter.append('rect'); | |
enter.append('text'); | |
g = enter.merge(g); | |
var color = d3.scaleOrdinal(d3.schemeCategory10); | |
rect = g | |
.select('rect') | |
.attr('x', function(investor, i) {return i * 25}) | |
.attr('y', function(investor) {return 500 - investor[1] * 100}) | |
.attr('width', 20) | |
.attr('height', function(investor) {return (investor[1] - investor[0]) * 100}) | |
.attr('stroke', '#000').attr('stroke-opacity', 0.2) | |
.attr('fill', (d) => {console.log(d); return color(d.sector)}).attr('fill-opacity', 0.5); | |
g.select('text') | |
.text(d => {return d.data.key}) | |
.attr('x', function(investor, i) {return (i + 0.5) * 25}) | |
.attr('y', function(investor) {return 510 - investor[1] * 100}) | |
.attr('font-size', '12px') | |
.attr('writing-mode', 'tb'); | |
</script> | |
</body> |