logo

G2

  • Chart Gallery
  • Docs
  • Examples
  • Theme
  • Ecosystem
  • Productsantv logo arrow
  • 5.3.3
  • Get Started
  • Introduction
    • What is G2
    • Using in Frontend Frameworks
    • Experimental Spec API
  • Chart API
  • Core Concepts
    • Chart
      • Components of G2 Charts
      • How to Use Charts
    • Mark
      • Overview
      • area
      • box
      • boxplot
      • cell
      • chord
      • density
      • gauge
      • heatmap
      • image
      • interval
      • line
      • lineX
      • lineY
      • link
      • liquid
      • sunburst
      • point
      • polygon
      • range
      • rangeX
      • rangeY
      • rect
      • shape
      • text
      • vector
      • connector
      • wordCloud
    • View
    • Data
      • Overview
      • custom
      • ema
      • fetch
      • filter
      • fold
      • inline
      • join
      • kde
      • log
      • map
      • pick
      • rename
      • slice
      • sort
      • sortBy
    • Encode
    • Scale
      • Overview
      • band
      • linear
      • log
      • ordinal
      • point
      • quantile
      • quantize
      • sqrt
      • threshold
      • time
      • pow
    • Transform
      • Overview
      • bin
      • binX
      • diffY
      • dodgeX
      • flexX
      • group
      • groupColor
      • groupX
      • groupY
      • jitter
      • jitterX
      • jitterY
      • normalizeY
      • pack
      • sample
      • select
      • selectX
      • selectY
      • sortColor
      • sortX
      • sortY
      • stackEnter
      • stackY
      • symmetryY
    • Coordinate
      • Overview
      • fisheye
      • parallel
      • polar
      • theta
      • transpose
      • radial
      • cartesian3D
      • helix
    • Style
    • Animate
      • Overview
      • fadeIn
      • fadeOut
      • growInX
      • growInY
      • morphing
      • pathIn
      • scaleInX
      • scaleInY
      • scaleOutX
      • scaleOutY
      • waveIn
      • zoomIn
      • zoomOut
    • State
    • Interaction
      • Overview
      • brushAxisHighlight
      • brushHighlight
      • brushXHighlight
      • brushYHighlight
      • brushFilter
      • brushXFilter
      • brushYFilter
      • chartIndex
      • elementHighlight
      • elementHighlightByColor
      • elementHighlightByX
      • elementSelect
      • elementSelectByColor
      • elementSelectByX
      • legendFilter
      • legendHighlight
      • poptip
      • scrollbarFilter
      • sliderFilter
      • fisheye
    • Composition
      • Overview
      • facetCircle
      • facetRect
      • repeatMatrix
      • spaceFlex
      • spaceLayer
      • timingKeyframe
    • Theme
      • Overview
      • academy
      • classic
      • classicDark
    • Events
    • Color Mapping
  • Chart Component
    • Title
    • Axis
    • Legend
    • Scrollbar
    • Slider
    • Tooltip
    • Data Label
  • Extra Topics
    • Graph
      • forceGraph
      • pack
      • sankey
      • tree
      • treemap
    • Geo
      • geoPath
      • geoView
    • 3D
      • Draw 3D Chart
      • point3D
      • line3D
      • interval3D
      • surface3D
    • Plugin
      • renderer
      • rough
      • lottie
      • a11y
    • Package on demand
    • Set pattern
    • Server-Side Rendering (SSR)
    • Spec Function Expression Support (Available in 5.3.0)
  • Whats New
    • New Version Features
    • Migration from v4 to v5
  • Frequently Asked Questions (FAQ)

band

Previous
Overview
Next
linear

Resources

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

Community

Ant Financial Experience Tech
seeconfSEE Conf-Experience Tech Conference

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-互动图形解决方案
xtechLiven Experience technology
© Copyright 2025 Ant Group Co., Ltd..备案号:京ICP备15032932号-38

Loading...

Overview

The band scale is a special type of ordinal scale that maps discrete domains (such as categories, names, etc.) to continuous numerical ranges, allocating equal-width intervals (bands) for each category. Unlike regular ordinal scales, band scales not only focus on point positions but also consider the interval width occupied by each category.

Key characteristics of band scales:

  • Maps discrete data (such as categories) to continuous intervals
  • Allocates equal-width intervals (bands) for each category
  • Supports setting inner spacing between categories (paddingInner) and outer spacing (paddingOuter)
  • Commonly used in visualizations that need to represent categorical data, such as bar charts and column charts

In G2, the band scale is the default x-axis scale for bar charts (interval marks), automatically handling the mapping and layout of categorical data.

Configuration Options

PropertyDescriptionTypeDefaultRequired
domainSets the domain array, i.e., possible values of input datanumber[] | string[] | Date[][]
rangeSets the range of data mapping, i.e., the output rangenumber[] | string[][0, 1]
unknownReturn value for undefined, NaN, null empty valuesanyundefined
roundWhether to round the output valuesbooleanfalse
paddingInnerSets inner spacing between categories, in range [0, 1], larger values mean larger spacingnumber0
paddingOuterSets outer spacing at both ends, in range [0, 1], larger values mean larger spacingnumber0
paddingShortcut to set both paddingInner and paddingOuternumber0
alignAlignment, in range [0, 1], 0 means left-aligned, 0.5 means centered, 1 means right-alignednumber0.5
compareSorting function for domain mapping(a: string or number, b: string or number) => numberundefined
flexSets width allocation ratio for each categorynumber[][]

Layout Principles of Band Scale

The band scale divides the continuous range into equal-width intervals, with each interval corresponding to a discrete value in the domain. The following diagram illustrates the layout principles of the band scale:

|<------------------------------------------- range ------------------------------------------->|
| | | | | | |
|<--step*PO-->|<----bandWidth---->|<--step*PI-->|<----bandWidth---->|<--step*PI-->|<--step*PO-->|
| | ***************** | | ***************** | | |
| | ******* A ******* | | ******* B ******* | | |
| | ***************** | | ***************** | | |
| |<--------------step------------->| |
|-----------------------------------------------------------------------------------------------|

Where:

  • range: The entire range of the scale
  • bandWidth: The width occupied by each category
  • step: The distance between the center points of adjacent categories
  • step*PI (paddingInner): Inner spacing between categories
  • step*PO (paddingOuter): Outer spacing at both ends

Usage Examples

Basic Bar Chart

The most common application of band scales is in bar charts. By setting padding, you can control the spacing between bars:

import { Chart } from '@antv/g2';
const chart = new Chart({
container: 'container',
autoFit: true,
});
chart.options({
type: 'interval',
data: [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 120 },
{ genre: 'Shooter', sold: 350 },
{ genre: 'Other', sold: 150 },
],
encode: {
x: 'genre',
y: 'sold',
color: 'genre'
},
scale: {
x: {
type: 'band',
padding: 0.5 // Set spacing between bars
}
}
});
chart.render();

Grouped Bar Chart

In grouped bar charts, band scales work together with dodgeX transform to create grouping effects:

import { Chart } from '@antv/g2';
const chart = new Chart({
container: 'container',
autoFit: true,
});
chart.options({
type: 'interval',
data: [
{ month: 'Jan', value: 86.5, type: 'Precipitation' },
{ month: 'Feb', value: 86.5, type: 'Precipitation' },
{ month: 'Mar', value: 86.5, type: 'Precipitation' },
{ month: 'Apr', value: 86.5, type: 'Precipitation' },
{ month: 'May', value: 86.5, type: 'Precipitation' },
{ month: 'Jun', value: 86.5, type: 'Precipitation' },
{ month: 'Jan', value: 30.5, type: 'Evaporation' },
{ month: 'Feb', value: 30.5, type: 'Evaporation' },
{ month: 'Mar', value: 30.5, type: 'Evaporation' },
{ month: 'Apr', value: 30.5, type: 'Evaporation' },
{ month: 'May', value: 30.5, type: 'Evaporation' },
{ month: 'Jun', value: 30.5, type: 'Evaporation' },
],
encode: {
x: 'month',
y: 'value',
color: 'type'
},
transform: [{ type: 'dodgeX' }],
scale: {
x: {
type: 'band',
padding: 0.2 // Set spacing between groups
}
}
});
chart.render();

Custom Bar Width

Using the flex property allows setting different width ratios for different categories:

import { Chart } from '@antv/g2';
const chart = new Chart({
container: 'container',
autoFit: true,
});
chart.options({
type: 'interval',
data: [
{ country: 'USA', value: 12394, gdp: 21.4 },
{ country: 'China', value: 9608, gdp: 14.7 },
{ country: 'Japan', value: 4731, gdp: 5.0 },
{ country: 'Germany', value: 3861, gdp: 4.2 },
{ country: 'UK', value: 2678, gdp: 2.9 },
],
encode: {
x: 'country',
y: 'value',
color: 'country'
},
scale: {
x: {
type: 'band',
padding: 0.4,
flex: [2.14, 1.47, 0.5, 0.42, 0.29] // Set different widths based on GDP
}
}
});
chart.render();

Horizontal Bar Chart

By transposing the coordinate system, you can create horizontal bar charts where band scales still apply:

import { Chart } from '@antv/g2';
const chart = new Chart({
container: 'container',
autoFit: true,
});
chart.options({
type: 'interval',
coordinate: { transform: [{ type: 'transpose' }] },
data: [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 120 },
{ genre: 'Shooter', sold: 350 },
{ genre: 'Other', sold: 150 },
],
encode: {
x: 'genre',
y: 'sold',
color: 'genre'
},
scale: {
x: {
type: 'band',
padding: 0.5
}
}
});
chart.render();

Stacked Bar Chart

Using stackY transform creates stacked bar charts that show cumulative effects of different parts:

import { Chart } from '@antv/g2';
const chart = new Chart({
container: 'container',
autoFit: true,
});
chart.options({
type: 'interval',
data: [
{ quarter: 'Q1', department: 'Sales', value: 120 },
{ quarter: 'Q1', department: 'Marketing', value: 100 },
{ quarter: 'Q1', department: 'Engineering', value: 80 },
{ quarter: 'Q2', department: 'Sales', value: 140 },
{ quarter: 'Q2', department: 'Marketing', value: 110 },
{ quarter: 'Q2', department: 'Engineering', value: 90 },
{ quarter: 'Q3', department: 'Sales', value: 160 },
{ quarter: 'Q3', department: 'Marketing', value: 95 },
{ quarter: 'Q3', department: 'Engineering', value: 120 },
{ quarter: 'Q4', department: 'Sales', value: 180 },
{ quarter: 'Q4', department: 'Marketing', value: 100 },
{ quarter: 'Q4', department: 'Engineering', value: 130 },
],
encode: {
x: 'quarter',
y: 'value',
color: 'department'
},
transform: [{ type: 'stackY' }],
scale: {
x: {
type: 'band',
padding: 0.3
}
}
});
chart.render();

Variable-Width Bar Chart (Using flexX Transform)

Automatically adjusts bar width based on specified field values, suitable for representing weight or proportional relationships:

import { Chart } from '@antv/g2';
const chart = new Chart({
container: 'container',
autoFit: true,
});
chart.options({
type: 'interval',
data: [
{ region: 'East', sales: 8500, population: 2.4 },
{ region: 'South', sales: 6200, population: 1.8 },
{ region: 'North', sales: 7800, population: 2.1 },
{ region: 'Southwest', sales: 4500, population: 1.2 },
{ region: 'Northeast', sales: 3200, population: 0.9 },
{ region: 'Northwest', sales: 2800, population: 0.7 },
],
encode: {
x: 'region',
y: 'sales',
color: 'region'
},
transform: [{ type: 'flexX', field: 'population' }], // Adjust bar width based on population data
scale: {
x: {
type: 'band',
padding: 0.2
}
}
});
chart.render();

Time Series Bar Chart

When handling time data, band scales can effectively handle the visualization of time intervals:

import { Chart } from '@antv/g2';
const chart = new Chart({
container: 'container',
autoFit: true,
});
chart.options({
type: 'interval',
data: [
{ month: '2024-01', sales: 1200 },
{ month: '2024-02', sales: 1100 },
{ month: '2024-03', sales: 1350 },
{ month: '2024-04', sales: 1280 },
{ month: '2024-05', sales: 1400 },
{ month: '2024-06', sales: 1520 },
{ month: '2024-07', sales: 1680 },
{ month: '2024-08', sales: 1590 },
{ month: '2024-09', sales: 1450 },
{ month: '2024-10', sales: 1380 },
{ month: '2024-11', sales: 1250 },
{ month: '2024-12', sales: 1600 }
],
encode: {
x: 'month',
y: 'sales',
color: (d) => d.sales > 1500 ? 'high' : d.sales > 1300 ? 'medium' : 'low'
},
scale: {
x: {
type: 'band',
padding: 0.1
},
color: {
domain: ['low', 'medium', 'high'],
range: ['#faad14', '#1890ff', '#52c41a']
}
}
});
chart.render();

Multi-Level Categorical Bar Chart

Displaying categorical data with hierarchical structure:

import { Chart } from '@antv/g2';
const chart = new Chart({
container: 'container',
autoFit: true,
});
chart.options({
type: 'interval',
data: [
{ category: 'Clothing-Men', subcategory: 'Shirts', value: 850 },
{ category: 'Clothing-Men', subcategory: 'Pants', value: 750 },
{ category: 'Clothing-Men', subcategory: 'Jackets', value: 650 },
{ category: 'Clothing-Women', subcategory: 'Dresses', value: 950 },
{ category: 'Clothing-Women', subcategory: 'Tops', value: 800 },
{ category: 'Clothing-Women', subcategory: 'Skirts', value: 700 },
{ category: 'Electronics-Phones', subcategory: 'iPhone', value: 1200 },
{ category: 'Electronics-Phones', subcategory: 'Huawei', value: 1100 },
{ category: 'Electronics-Phones', subcategory: 'Xiaomi', value: 900 },
{ category: 'Electronics-Computers', subcategory: 'Laptops', value: 1500 },
{ category: 'Electronics-Computers', subcategory: 'Desktops', value: 800 },
{ category: 'Electronics-Computers', subcategory: 'Tablets', value: 600 }
],
encode: {
x: 'category',
y: 'value',
color: 'subcategory'
},
transform: [{ type: 'dodgeX' }],
scale: {
x: {
type: 'band',
padding: 0.4, // Larger spacing to distinguish different main categories
paddingInner: 0.3, // Inner spacing
paddingOuter: 0.1 // Outer spacing
}
}
});
chart.render();

Comparative Analysis Bar Chart

Using paddingInner and paddingOuter to precisely control spacing, suitable for comparative analysis:

import { Chart } from '@antv/g2';
const chart = new Chart({
container: 'container',
autoFit: true,
});
chart.options({
type: 'interval',
data: [
{ product: 'Product A', current: 320, target: 400 },
{ product: 'Product B', current: 280, target: 350 },
{ product: 'Product C', current: 410, target: 450 },
{ product: 'Product D', current: 180, target: 250 },
{ product: 'Product E', current: 350, target: 380 }
].flatMap(d => [
{ product: d.product, type: 'Current Sales', value: d.current },
{ product: d.product, type: 'Target Sales', value: d.target }
]),
encode: {
x: 'product',
y: 'value',
color: 'type'
},
transform: [{ type: 'dodgeX' }],
scale: {
x: {
type: 'band',
paddingInner: 0.2, // Smaller spacing within groups
paddingOuter: 0.3 // Larger spacing between groups
},
color: {
domain: ['Current Sales', 'Target Sales'],
range: ['#1890ff', '#52c41a']
}
}
});
chart.render();

Dynamic Bar Width Chart

Combining compare function to sort data with different bar width strategies:

import { Chart } from '@antv/g2';
const data = [
{ brand: 'Apple', market_share: 23.4, revenue: 365 },
{ brand: 'Samsung', market_share: 20.1, revenue: 220 },
{ brand: 'Huawei', market_share: 15.8, revenue: 180 },
{ brand: 'Xiaomi', market_share: 12.3, revenue: 120 },
{ brand: 'OPPO', market_share: 8.9, revenue: 95 },
{ brand: 'vivo', market_share: 7.2, revenue: 85 },
{ brand: 'Others', market_share: 12.3, revenue: 150 }
];
const chart = new Chart({
container: 'container',
autoFit: true,
});
chart.options({
type: 'interval',
data,
encode: {
x: 'brand',
y: 'market_share',
color: 'brand'
},
scale: {
x: {
type: 'band',
padding: 0.2,
compare: (a, b) => {
// Sort by market share in descending order
const dataA = data.find(d => d.brand === a);
const dataB = data.find(d => d.brand === b);
return (dataB?.market_share || 0) - (dataA?.market_share || 0);
},
flex: [2.34, 2.01, 1.58, 1.23, 0.89, 0.72, 1.23] // Set width based on market share
}
}
});
chart.render();

Advanced Application Scenarios

Waterfall Chart (Using Band Scale)

Displaying step-by-step cumulative changes in values:

import { Chart } from '@antv/g2';
// Waterfall chart data processing
const rawData = [
{ name: 'Initial Balance', value: 1000, type: 'start' },
{ name: 'Revenue Increase', value: 500, type: 'positive' },
{ name: 'Cost Expense', value: -200, type: 'negative' },
{ name: 'Tax Expense', value: -150, type: 'negative' },
{ name: 'Other Income', value: 100, type: 'positive' },
{ name: 'Final Balance', value: 1250, type: 'end' }
];
// Calculate cumulative values
let cumulative = 0;
const data = rawData.map((d, i) => {
if (d.type === 'start' || d.type === 'end') {
const result = { ...d, start: 0, end: d.value };
cumulative = d.value;
return result;
} else {
const start = cumulative;
cumulative += d.value;
return { ...d, start, end: cumulative };
}
});
const chart = new Chart({
container: 'container',
autoFit: true,
});
chart.options({
type: 'interval',
data: data.flatMap(d => [
{ name: d.name, value: d.end - d.start, position: d.start, type: d.type }
]),
encode: {
x: 'name',
y: ['position', (d) => d.position + d.value],
color: 'type'
},
scale: {
x: {
type: 'band',
padding: 0.4
},
color: {
domain: ['start', 'positive', 'negative', 'end'],
range: ['#722ed1', '#52c41a', '#ff4d4f', '#1890ff']
}
}
});
chart.render();

Faceted Bar Chart

Using band scales with faceted layout to display multi-dimensional data:

import { Chart } from '@antv/g2';
const chart = new Chart({
container: 'container',
autoFit: true,
});
chart.options({
type: 'facetRect',
data: [
{ region: 'North', quarter: 'Q1', product: 'Product A', sales: 120 },
{ region: 'North', quarter: 'Q1', product: 'Product B', sales: 100 },
{ region: 'North', quarter: 'Q1', product: 'Product C', sales: 80 },
{ region: 'North', quarter: 'Q2', product: 'Product A', sales: 140 },
{ region: 'North', quarter: 'Q2', product: 'Product B', sales: 110 },
{ region: 'North', quarter: 'Q2', product: 'Product C', sales: 90 },
{ region: 'South', quarter: 'Q1', product: 'Product A', sales: 150 },
{ region: 'South', quarter: 'Q1', product: 'Product B', sales: 130 },
{ region: 'South', quarter: 'Q1', product: 'Product C', sales: 110 },
{ region: 'South', quarter: 'Q2', product: 'Product A', sales: 170 },
{ region: 'South', quarter: 'Q2', product: 'Product B', sales: 140 },
{ region: 'South', quarter: 'Q2', product: 'Product C', sales: 120 }
],
encode: { x: 'region', y: 'quarter' },
children: [{
type: 'interval',
encode: {
x: 'product',
y: 'sales',
color: 'product'
},
scale: {
x: {
type: 'band',
padding: 0.3
}
}
}]
});
chart.render();

Common Questions

How to adjust the width of bars?

You can adjust the spacing between bars by setting the padding property, which indirectly adjusts the width of the bars. The larger the padding value, the narrower the bars; the smaller the value, the wider the bars.

chart
.interval()
.encode('x', 'type')
.encode('y', 'sale')
.scale('x', {
type: 'band',
padding: 0.5, // Value range is [0, 1]
});

What's the difference between band scale and point scale?

  • Band Scale: Allocates an interval (bandwidth) for each category, suitable for bar charts and other charts that need to occupy width
  • Point Scale: Allocates a point for each category, equivalent to a band scale with bandWidth = 0, suitable for scatter plots and other charts that only need point positions

How to set different widths for bars?

There are two methods:

  1. Use the flex property to set different width ratios for different categories
  2. Use the flexX transform to automatically set bar width based on specified field values
// Method 1: Using flex property
chart
.interval()
.encode('x', 'country')
.encode('y', 'value')
.scale('x', {
type: 'band',
flex: [2, 1, 3, 1.5] // Manually set width ratios
});
// Method 2: Using flexX transform
chart
.interval()
.encode('x', 'country')
.encode('y', 'value')
.transform({ type: 'flexX', field: 'gdp' }); // Automatically set width based on gdp field