logo

G2

  • Chart Gallery
  • Docs
  • Examples
  • Theme
  • Ecosystem
  • Productsantv logo arrow
  • 5.3.5
  • 📈 Chart Gallery
  • Arc Diagram
  • Mosaic Plot
  • Bar Chart
  • Bubble Chart
  • Color Map
  • Distribution Curve
  • Dot Map
  • Histogram Chart
  • Line Chart
  • Pack Chart
  • Parallel Coordinates
  • Radial Bar Chart
  • Regression Curve Chart
  • Stacked Area Chart
  • Stacked Bar Chart
  • Stem-and-Leaf Plot
  • Sunburst Chart
  • Treemap
  • Venn Diagram
  • Violin Plot
  • Area Chart
  • Box Plot
  • Bubble Map
  • Radar Chart
  • Bi-directional Bar Chart
  • Multi-set Bar Chart
  • Pie Chart
  • Donut Chart
  • Heatmap
  • Choropleth Map
  • Funnel Chart
  • K-Chart
  • Scatter Plot
  • Gauge Chart
  • Nightingale Rose Chart
  • Contour Line Chart
  • Spiral
  • Word Cloud
  • Bullet Chart
  • Sankey Diagram
  • Gantt Chart
  • Kagi Chart
  • Chord Diagram

Stacked Bar Chart

Previous
Stacked Area Chart
Next
Stem-and-Leaf Plot

Resource

Ant Design
Galacea Effects
Umi-React Application Framework
Dumi-Component doc generator
ahooks-React Hooks Library
WeaveFox-AI Coding Assistant

Community

Ant Financial Experience Tech
seeconfSEE Conf-Experience Tech Conference
weavefoxWeaveFox-AI Developer Community

Help

GitHub
StackOverflow

more productsMore Productions

Ant DesignAnt Design-Enterprise UI design language
yuqueYuque-Knowledge creation and Sharing tool
EggEgg-Enterprise-class Node development framework
kitchenKitchen-Sketch Tool set
GalaceanGalacean-Interactive solution
weavefoxWeaveFox-AI Coding Assistant
© Copyright 2025 Ant Group Co., Ltd..备案号:京ICP备15032932号-38

Loading...

stacked-bar

Introduction to Stacked Bar Charts

A stacked bar chart is an extension of the basic bar chart that displays categorical data by stacking multiple data series within a single bar. Each bar represents the total amount for a category, while the different colored segments within the bar represent the values of various subcategories. Stacked bar charts not only show the total quantity for each category but also display how each subcategory contributes to the total.

Stacked bar charts are particularly suitable for comparing the compositional structure of multiple categories and observing the distribution of subcategories across different main categories. Through color coding, users can easily identify different subcategories and compare their proportions within each main category.

When you need to display both totals and composition simultaneously, stacked bar charts are an excellent choice. They can be further extended to percentage stacked bar charts to show the relative proportions of each part.

Other Names: Stacked Column Chart

Components of Stacked Bar Charts

Vertical Stacked Bar Chart

stacked-bar-vertical
Chart TypeVertical Stacked Bar Chart
Suitable DataMulti-series categorical data: one categorical field, one continuous field, one series categorical field
FunctionCompare totals of different categories and composition of subcategories
Data-to-Visual MappingCategorical field mapped to horizontal axis position
Numerical field mapped to bar height
Series field mapped to color, displayed stacked in the same bar
Suitable Data VolumeMain categories no more than 12, subcategories no more than 8

Horizontal Stacked Bar Chart

stacked-bar-horizontal
Chart TypeHorizontal Stacked Bar Chart
Suitable DataMulti-series categorical data: one categorical field, one continuous field, one series categorical field
FunctionCompare totals of different categories and composition of subcategories
Data-to-Visual MappingCategorical field mapped to vertical axis position
Numerical field mapped to bar width
Series field mapped to color
Suitable Data VolumeMain categories no more than 30, subcategories no more than 8

Use Cases for Stacked Bar Charts

Suitable Scenarios

Example 1: Suitable for displaying monthly rainfall composition across multiple cities

The chart below shows the rainfall distribution in London and Berlin across different months, clearly showing both the total monthly rainfall and each city's contribution.

import { Chart } from '@antv/g2';
const chart = new Chart({
container: 'container',
theme: 'classic',
});
chart.options({
type: 'interval',
autoFit: true,
data: [
{ name: 'London', month: 'Jan.', rainfall: 18.9 },
{ name: 'London', month: 'Feb.', rainfall: 28.8 },
{ name: 'London', month: 'Mar.', rainfall: 39.3 },
{ name: 'London', month: 'Apr.', rainfall: 81.4 },
{ name: 'London', month: 'May', rainfall: 47 },
{ name: 'London', month: 'Jun.', rainfall: 20.3 },
{ name: 'London', month: 'Jul.', rainfall: 24 },
{ name: 'London', month: 'Aug.', rainfall: 35.6 },
{ name: 'Berlin', month: 'Jan.', rainfall: 12.4 },
{ name: 'Berlin', month: 'Feb.', rainfall: 23.2 },
{ name: 'Berlin', month: 'Mar.', rainfall: 34.5 },
{ name: 'Berlin', month: 'Apr.', rainfall: 99.7 },
{ name: 'Berlin', month: 'May', rainfall: 52.6 },
{ name: 'Berlin', month: 'Jun.', rainfall: 35.5 },
{ name: 'Berlin', month: 'Jul.', rainfall: 37.4 },
{ name: 'Berlin', month: 'Aug.', rainfall: 42.4 },
],
encode: { x: 'month', y: 'rainfall', color: 'name' },
transform: [{ type: 'stackY' }],
interaction: [
{
type: 'elementHighlight',
background: true,
region: true,
},
],
});
chart.render();

Explanation:

  • The month field is mapped to horizontal axis position, representing the time dimension
  • The rainfall field is mapped to bar height, stacked using the stackY transform
  • The name field is mapped to color to distinguish different cities
  • You can simultaneously compare total monthly rainfall and each city's contribution

Example 2: Suitable for displaying age structure comparison across regions

Stacked bar charts are very suitable for showing population age structure distribution across different regions, allowing you to see both total population and age composition.

import { Chart } from '@antv/g2';
const chart = new Chart({
container: 'container',
theme: 'classic',
});
chart.options({
type: 'interval',
autoFit: true,
data: {
type: 'fetch',
value:
'https://gw.alipayobjects.com/os/bmw-prod/f129b517-158d-41a9-83a3-3294d639b39e.csv',
format: 'csv',
},
encode: { x: 'state', y: 'population', color: 'age' },
transform: [{ type: 'stackY' }, { type: 'sortX', by: 'y', reverse: true }],
axis: {
x: {
labelSpacing: 4,
labelTransform: 'rotate(90)',
},
y: {
labelFormatter: '~s',
title: null,
},
},
legend: {
color: {
position: 'right',
title: 'Age Group',
},
},
interaction: [
{
type: 'elementHighlight',
background: true,
},
],
});
chart.render();

Explanation:

  • Uses sortX transform to sort by total population for easier comparison
  • labelFormatter: '~s' formats numeric display (e.g., 1M for 1 million)
  • Rotates x-axis labels to avoid overlap

Example 3: Horizontal stacked bar charts are suitable for scenarios with many categories

When there are many categories, horizontal stacked bar charts can better display labels and avoid text overlap.

import { Chart } from '@antv/g2';
const chart = new Chart({
container: 'container',
theme: 'classic',
width: 800,
height: 600,
});
chart.options({
type: 'interval',
autoFit: true,
data: {
type: 'fetch',
value:
'https://gw.alipayobjects.com/os/bmw-prod/f129b517-158d-41a9-83a3-3294d639b39e.csv',
format: 'csv',
},
coordinate: { transform: [{ type: 'transpose' }] },
encode: { x: 'state', y: 'population', color: 'age' },
transform: [{ type: 'stackY' }, { type: 'sortX', by: 'y', reverse: true }],
axis: {
y: {
labelFormatter: '~s',
title: null,
},
x: {
title: null,
},
},
legend: {
color: {
position: 'bottom',
title: 'Age Group',
},
},
});
chart.render();

Explanation:

  • Uses coordinate: { transform: [{ type: 'transpose' }] } to achieve horizontal orientation
  • Labels can be arranged horizontally, improving readability
  • Suitable for data with many categories

Example 4: Percentage stacked bar charts display proportional relationships

When focusing on the proportion of each part rather than absolute values, percentage stacked bar charts are a better choice.

import { Chart } from '@antv/g2';
const chart = new Chart({
container: 'container',
theme: 'classic',
width: 800,
height: 600,
});
chart.options({
type: 'interval',
autoFit: true,
data: {
type: 'fetch',
value:
'https://gw.alipayobjects.com/os/bmw-prod/f129b517-158d-41a9-83a3-3294d639b39e.csv',
format: 'csv',
},
coordinate: { transform: [{ type: 'transpose' }] },
encode: { x: 'state', y: 'population', color: 'age' },
transform: [
{ type: 'stackY' },
{ type: 'normalizeY' },
{ type: 'sortX', by: 'y', reverse: true },
],
axis: {
y: {
labelFormatter: '.0%',
title: null,
},
x: {
title: null,
},
},
legend: {
color: {
position: 'bottom',
title: 'Age Group',
},
},
tooltip: {
channel: 'y0',
valueFormatter: '.0%',
},
});
chart.render();

Explanation:

  • Combines stackY and normalizeY transforms to achieve percentage stacking
  • labelFormatter: '.0%' formats y-axis labels as percentages
  • Facilitates comparison of age structure proportions across states

Unsuitable Scenarios

Example 1: Not suitable for simple stacking of negative value data

Traditional stacked bar charts are not suitable for data containing negative values, as the stacking logic can cause visual confusion.

Example 2: Poor visual effect when there are too many subcategories

When the number of subcategories exceeds 8-10, color differentiation decreases, making it difficult for users to effectively distinguish and compare.

import { Chart } from '@antv/g2';
// Simulate data with too many subcategories
const chart = new Chart({
container: 'container',
theme: 'classic',
});
chart.options({
type: 'interval',
autoFit: true,
data: [
{ category: 'A', type: 'Type1', value: 10 },
{ category: 'A', type: 'Type2', value: 8 },
{ category: 'A', type: 'Type3', value: 6 },
{ category: 'A', type: 'Type4', value: 4 },
{ category: 'A', type: 'Type5', value: 3 },
{ category: 'A', type: 'Type6', value: 2 },
{ category: 'A', type: 'Type7', value: 2 },
{ category: 'A', type: 'Type8', value: 1 },
{ category: 'A', type: 'Type9', value: 1 },
{ category: 'A', type: 'Type10', value: 1 },
{ category: 'A', type: 'Type11', value: 1 },
{ category: 'A', type: 'Type12', value: 1 },
{ category: 'B', type: 'Type1', value: 12 },
{ category: 'B', type: 'Type2', value: 9 },
{ category: 'B', type: 'Type3', value: 7 },
{ category: 'B', type: 'Type4', value: 5 },
{ category: 'B', type: 'Type5', value: 4 },
{ category: 'B', type: 'Type6', value: 3 },
{ category: 'B', type: 'Type7', value: 2 },
{ category: 'B', type: 'Type8', value: 2 },
{ category: 'B', type: 'Type9', value: 1 },
{ category: 'B', type: 'Type10', value: 1 },
{ category: 'B', type: 'Type11', value: 1 },
{ category: 'B', type: 'Type12', value: 1 },
],
encode: { x: 'category', y: 'value', color: 'type' },
transform: [{ type: 'stackY' }],
});
chart.render();

In such cases, it's recommended to merge smaller categories into an "Others" category or use other chart types.

Extensions of Stacked Bar Charts

Diverging Stacked Bar Chart

Diverging stacked bar charts can display comparisons of positive and negative values, particularly suitable for showing profit/loss, increase/decrease contrasts.

import { Chart } from '@antv/g2';
const chart = new Chart({ container: 'container' });
chart.options({
type: 'view',
paddingLeft: 25,
children: [
{
type: 'interval',
data: {
type: 'fetch',
value: 'https://assets.antv.antgroup.com/g2/nivo-gain-lost.json',
transform: [
{
type: 'fold',
fields: [
'lost > 100$',
'lost <= 100$',
'gained <= 100$',
'gained > 100$',
],
},
],
},
encode: { x: 'user', y: 'value', color: 'key' },
transform: [{ type: 'stackY' }],
scale: {
x: { padding: 0.2 },
y: { domainMin: -100, domainMax: 100 },
color: {
domain: [
'lost > 100$',
'lost <= 100$',
'gained <= 100$',
'gained > 100$',
],
range: ['#97e3d5', '#61cdbb', '#e25c3b', '#f47560'],
},
},
style: { radius: 10 },
axis: {
y: { position: 'right', title: false, labelFormatter: (v) => `${v}%` },
},
legend: { color: { title: false } },
labels: [
{
text: 'value',
position: 'inside',
formatter: (v) => (v ? `${v}%` : ''),
transform: [{ type: 'overlapDodgeY' }],
fill: '#000',
fontSize: 10,
},
],
},
{
type: 'lineY',
data: [0],
style: { lineWidth: 2, stroke: '#e25c3b', strokeOpacity: 1 },
},
{
type: 'text',
style: {
x: -10,
y: '75%',
text: 'lost',
fontWeight: 'bold',
dy: -10,
transform: 'rotate(-90)',
fill: '#61cdbb',
},
},
{
type: 'text',
style: {
x: -10,
y: '20%',
text: 'gain',
fontWeight: 'bold',
dy: -10,
transform: 'rotate(-90)',
fill: '#e25c3b',
},
},
],
});
chart.render();

Explanation:

  • Uses positive and negative value data to show profit/loss comparison
  • Sets domainMin and domainMax to control axis range
  • Adds dividing line to highlight positive/negative value boundary
  • Uses rounded corner style to enhance visual effect

Comparison with Other Charts

Stacked Bar Charts vs Bar Charts

  • Stacked bar charts show compositional relationships and totals of multiple subcategories
  • Regular bar charts are mainly used to compare single values across different categories
  • Stacked bar charts can simultaneously show part-to-whole relationships

Stacked Bar Charts vs Stacked Area Charts

  • Stacked bar charts are suitable for discrete categorical data comparison
  • Stacked area charts are suitable for continuous time series data trend display
  • Stacked bar charts are more convenient for precise numerical comparison

Stacked Bar Charts vs Pie Charts

  • Stacked bar charts can simultaneously compare composition across multiple categories
  • Pie charts can only show the composition proportion of a single whole
  • Stacked bar charts have advantages when comparing multiple categories

Similar Charts

Categories

Bar Chart
Bar Chart
Comparison
Stacked Area Chart
Stacked Area Chart
Comparison
Proportion
Trend
Interval
Time
Multi-set Bar Chart
Multi-set Bar Chart
Comparison
Comparison
Proportion