d3:stacked-bar-chart
by Richard Hunter
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"></script>
JavaScript
const width = 500;
const height = 400;
const margin = {
top: 10,
right: 20,
bottom: 30,
left: 30,
};
const data = [{
category: 'football',
male: 2,
female: 2,
nonBinary: 1
},
{
category: 'tennis',
male: 1,
female: 6,
nonBinary: 1,
},
{
category: 'athletics',
male: 4,
female: 2,
nonBinary: 2
},
{
category: 'gymnastics',
male: 1,
female: 2,
nonBinary: 0
},
{
category: 'chess',
male: 2,
female: 4,
nonBinary: 1,
},
];
const colors = d3.scaleOrdinal(d3.schemeCategory10);
const stack = d3.stack()
.keys(["male", "female", "nonBinary"])
.order(d3.stackOrderAscending);
const series = stack(data);
const xScale = d3
.scaleBand()
.domain(d3.range(data.length))
.range([margin.left, width])
.paddingInner(0.5)
.paddingOuter(0.4)
const xAxis = d3.axisBottom(xScale).tickFormat(d => {
return data[d].category;
});
const yScale = d3
.scaleLinear()
.domain([
d3.max(data, d => d.male + d.female + d.nonBinary),
0
])
.range([margin.top, height - margin.bottom]);
const yAxis = d3.axisLeft(yScale).ticks(5);
const svg = d3.select("body").append("svg").attr("width", width).attr("height", height);
const groups = svg.selectAll("g").data(series)
.enter()
.append("g")
.style("fill", (d, i) => colors(i));
const rects = groups.selectAll("rect").data(d => d).enter()
.append("rect")
.attr("x", (d, i) => xScale(i))
.attr("y", d => yScale(d[1]))
.attr("height", d => yScale(d[0]) - yScale(d[1]))
.attr("width", xScale.bandwidth());
svg.append('g').attr('transform', `translate(0, ${height - margin.bottom})`).call(xAxis);
svg.append('g').attr('transform', `translate(${margin.left}, 0)`).call(yAxis);