Skip to content

Instantly share code, notes, and snippets.

@ColinEberhardt
Last active May 28, 2019 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ColinEberhardt/493ed4a0c186e9cfe88afacbe2a16fe2 to your computer and use it in GitHub Desktop.
Save ColinEberhardt/493ed4a0c186e9cfe88afacbe2a16fe2 to your computer and use it in GitHub Desktop.
Stacked Chart
license: mit

This example demonstrates a stacked bar chart using energy production data from eurostat. The chart is constructed from the following components:

  • A Cartesian chart, with an ordinal y axis and a linear x axis.
  • The data is prepared using a D3 stack layout, which stacks the 'y' values.
  • The data is rendered via a horizontally oriented stacked bar series. The auto bandwidth component is used to obtain the bandwidth for the bar series from the y-oriented band scale.
  • A legend, courtesy of the d3-legend project.
<!DOCTYPE html>
<!-- include polyfills for custom event, Symbol and Custom Elements -->
<script src="//unpkg.com/babel-polyfill@6.26.0/dist/polyfill.js"></script>
<script src="//unpkg.com/custom-event-polyfill@0.3.0/custom-event-polyfill.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/document-register-element/1.8.0/document-register-element.js"></script>
<!-- use babel so that we can use arrow functions and other goodness in this block! -->
<script src="//unpkg.com/babel-standalone@6/babel.min.js"></script>
<script src="//unpkg.com/d3@5.5.0"></script>
<script src="//unpkg.com/d3fc@14.0.41"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.18.0/d3-legend.js"></script>
<style>
body {
font: 20px sans-serif;
}
#legend {
display: block;
position: absolute;
top: 40px;
right: 10px;
width: 400px;
height: 120px;
font-size: 0.6em;
}
#container {
position: relative;
}
#chart {
height: 480px;
}
</style>
<div id='container'>
<div id='chart' ></div>
<svg id='legend'></svg>
</div>
<script type='text/babel'>
d3.csv('https://d3fc.io/examples/stacked/data.csv').then(data => {
// manipulate the data into stacked series
var stack = d3.stack()
.keys(Object.keys(data[0]).filter(k => k !== 'Country'));
var series = stack(data);
var color = d3.scaleOrdinal(d3.schemeCategory10)
.domain(series.map(s => s.key));
console.log(series.map(s => s.key))
var legend = d3.legendColor()
.shapeWidth(70)
.orient('horizontal')
.scale(color);
// render the legend
d3.select('#legend')
.call(legend);
var barSeries = fc.autoBandwidth(fc.seriesSvgBar())
.orient('horizontal')
.align('left')
.crossValue(d => d.data.Country)
.mainValue(d => d[1])
.baseValue(d => d[0]);
var multi = fc.seriesSvgMulti()
.mapping((data, index) => data[index])
.series(series.map(() => barSeries))
.decorate((selection) => {
selection.each((data, index, nodes) => {
d3.select(nodes[index])
.selectAll('g.bar')
.attr('fill', color(series[index].key));
});
});
var xExtent = fc.extentLinear()
.accessors([function(a) {
return a.map(function(d) { return d[1]; });
}])
.pad([0, 1])
.padUnit('domain');
var chart = fc.chartCartesian(
d3.scaleLinear(),
d3.scaleBand())
.xDomain(xExtent(series))
.yDomain(data.map((entry) => entry.Country))
.yPadding([0.2])
.yOrient('left')
.xLabel('Million tonnes of oil equivalent')
.chartLabel('2013 Energy Production')
.svgPlotArea(multi);
d3.select('#chart')
.text(null) // Remove the loading text from the container
.datum(series)
.call(chart);
});
</script>
@stephaneduarte
Copy link

How can I do tooltips for each bar horizontal? Im trying to use mouseover but it's not working..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment