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)

Encode

Previous
sortBy
Next
Overview

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...

Visual Channels

The core content of data visualization is visual encoding, which is the technology of mapping data information into visual elements. Just like data contains attributes and values, visual encoding also consists of two parts: Marks and Visual Channels.

  • Data Attributes -> Marks: Intuitive representation of data nature classification, usually geometric graphic elements, such as: points, lines, areas, and volumes.
  • Data Values -> Visual Channels: Used to express quantitative information of data attributes, including mark position, size, shape, direction, hue, saturation, brightness, etc.

Visual channels can also be called chart attributes. The mapping relationship between raw data and visual channels enables us to quickly obtain information. So we can think of charts as a combination of graphic marks that carry some information, which we call encoded information. When people read information from these symbols, we call it decoding information.

Types of Visual Channels

Human recognition of visual channels has two basic perception modes. The first perception mode obtains information about the characteristics and positions of objects themselves, corresponding to the qualitative and categorical properties of visual channels; the second perception mode obtains information about the numerical magnitude of a certain attribute of objects, corresponding to the quantitative or ordinal properties of visual channels. Therefore, we divide visual channels into two major categories:

  • Qualitative (categorical) visual channels, such as shape, color hue, and control position.
  • Quantitative (continuous, ordered) visual channels, such as line length, area size, spatial volume, slope, angle, color saturation and brightness, etc.

However, the two categories are not absolute. For example, position information can both distinguish different categories and differentiate continuous data.

Expressiveness of Visual Channels

When performing visual encoding, we need to consider the expressiveness and effectiveness of different visual channels, mainly reflected in the following aspects:

  • Accuracy: Whether it can accurately express changes between visual data
  • Discriminability: The number of categories that can be encoded by the same visual channel, i.e., the upper limit of distinguishable categories
  • Separability: When encoded objects of different visual channels are placed together, whether they are easy to distinguish
  • Visual prominence: Whether important information uses more prominent visual channels for encoding

The following is a diagram showing the expressiveness of visual channels from best to worst:

G2 Visual Channel Design

Corresponding to visual channels in visual encoding, visual channels in G2 can be divided into the following five graphic attributes:

Position-related Visual Channels

Visual ChannelDescription
xDefines the position of elements in the horizontal direction
yDefines the position of elements in the vertical direction
zDefines the depth position of elements in three-dimensional space
x1Defines the end position of elements in the horizontal direction
y1Defines the end position of elements in the vertical direction; stacked bar charts internally calculate y1 channel values
seriesDistinguishes different data series through spatial position
positionCustom composite chart display position, used for parallel coordinates and circular facet charts, etc.
position${number}Custom composite chart display position, used for parallel coordinates and circular facet charts, etc.

Color-related Visual Channels


Visual ChannelDescription
colorMaps data categorical attributes through hue
opacityControls element transparency, commonly used to highlight focus or express numerical intensity (such as gradient transparency in heatmaps)

Shape-related Visual Channels

Visual ChannelDescription
shapeDistinguishes data categories through geometric forms, suitable for categorical data encoding

Size-related Visual Channels

Visual ChannelDescription
sizeControls element physical dimensions (point radius/line width/bar width), suitable for encoding quantitative data

Animation-related Visual Channels

Visual ChannelDescription
keyUnique identifier for animation elements, used for data updates
groupKeyAnimation group identifier, used for data updates
enterTypeAnimation type for element entry into scene (such as scale/fade in)
enterEasingEasing function for enter animation
enterDurationDuration of enter animation
enterDelayDelay time for enter animation
updateTypeTransition animation type for data updates
updateEasingEasing function for update animation
updateDurationDuration of update animation
updateDelayDelay time for update animation
exitTypeAnimation type for element exit from scene (such as slide out)
exitEasingEasing function for exit animation
exitDurationDuration of exit animation
exitDelayDelay time for exit animation

Encode

To control the style of marks, we often bind a column of data to one of its visual channels.

Here is a set of event planning timeline data:

table([
{ name: 'Event Planning', startTime: 1, endTime: 4 },
{ name: 'Venue Logistics Planning', startTime: 3, endTime: 13 },
{ name: 'Select Suppliers', startTime: 5, endTime: 8 },
{ name: 'Rent Venue', startTime: 9, endTime: 13 },
{ name: 'Book Catering Services', startTime: 10, endTime: 14 },
{ name: 'Rent Event Decoration Team', startTime: 12, endTime: 17 },
{ name: 'Rehearsal', startTime: 14, endTime: 16 },
{ name: 'Event Celebration', startTime: 17, endTime: 18 },
]);

In the following example, we bind the name column in the data to the x channel, and bind the value of endTime column minus startTime column to the y channel. This binding process is called Encode. We often say that a certain visual attribute of a graphic encodes a column of data, and this data-driven attribute is called a Channel. For example, the x and y channels of the interval mark below encode the corresponding column data respectively, clearly showing the relationship between different tasks and time consumption.

import { Chart } from '@antv/g2';
const chart = new Chart({
container: 'container',
});
chart.options({
type: 'interval',
autoFit: true,
data: [
{ name: 'Event Planning', startTime: 1, endTime: 4 },
{ name: 'Venue Logistics Planning', startTime: 3, endTime: 13 },
{ name: 'Select Suppliers', startTime: 5, endTime: 8 },
{ name: 'Rent Venue', startTime: 9, endTime: 13 },
{ name: 'Book Catering Services', startTime: 10, endTime: 14 },
{ name: 'Rent Event Decoration Team', startTime: 12, endTime: 17 },
{ name: 'Rehearsal', startTime: 14, endTime: 16 },
{ name: 'Event Celebration', startTime: 17, endTime: 18 },
],
encode: {
x: 'name', // Map task name field to X-axis position
y: (datum) => datum.endTime - datum.startTime, // Map end time minus start time to Y-axis position
},
coordinate: { transform: [{ type: 'transpose' }] },
axis: {
x: {
title: 'Task',
},
y: {
title: 'Time Consumed',
},
},
});
chart.render();

When we want to further analyze the temporal relationships of tasks, we need to leverage other visual channels.

In the following example, we bind the startTime column in the data to the y channel, and bind the endTime column to the y1 channel (of course, you can also bind [startTime, endTime] to the y channel, see Array Channels for details). Through this data encoding method, we achieve a Gantt chart effect. To better distinguish different tasks, in addition to encoding the name column data to the x channel, we also bind the name column data to the color channel. This way, through different colors and different x-axis positions, we can better distinguish different tasks.

import { Chart } from '@antv/g2';
const chart = new Chart({
container: 'container',
});
chart.options({
type: 'interval',
autoFit: true,
data: [
{ name: 'Event Planning', startTime: 1, endTime: 4 },
{ name: 'Venue Logistics Planning', startTime: 3, endTime: 13 },
{ name: 'Select Suppliers', startTime: 5, endTime: 8 },
{ name: 'Rent Venue', startTime: 9, endTime: 13 },
{ name: 'Book Catering Services', startTime: 10, endTime: 14 },
{ name: 'Rent Event Decoration Team', startTime: 12, endTime: 17 },
{ name: 'Rehearsal', startTime: 14, endTime: 16 },
{ name: 'Event Celebration', startTime: 17, endTime: 18 },
],
encode: {
x: 'name', // Map task name field to X-axis position
y: 'startTime', // Map task start time field to y position
y1: 'endTime', // Map task end time field to y1 axis position
color: 'name', // Map task name field to color
},
coordinate: { transform: [{ type: 'transpose' }] },
axis: {
x: {
title: 'Task',
},
y: {
title: 'Time',
},
},
});
chart.render();

This is already a relatively complete Gantt chart. If you want to emphasize the time sequence, you can use animation-related visual channels in G2 to achieve temporal animation effects. The following example encodes the enterDuration and enterDelay channels, making the enter animation delay time and duration of marks corresponding to different tasks correlate with the start time and end time in the data.

import { Chart } from '@antv/g2';
const chart = new Chart({
container: 'container',
});
chart.options({
type: 'interval',
autoFit: true,
data: [
{ name: 'Event Planning', startTime: 1, endTime: 4 },
{ name: 'Venue Logistics Planning', startTime: 3, endTime: 13 },
{ name: 'Select Suppliers', startTime: 5, endTime: 8 },
{ name: 'Rent Venue', startTime: 9, endTime: 13 },
{ name: 'Book Catering Services', startTime: 10, endTime: 14 },
{ name: 'Rent Event Decoration Team', startTime: 12, endTime: 17 },
{ name: 'Rehearsal', startTime: 14, endTime: 16 },
{ name: 'Event Celebration', startTime: 17, endTime: 18 },
],
encode: {
x: 'name', // Map task name field to X-axis position
y: 'startTime', // Map task start time field to y position
y1: 'endTime', // Map task end time field to y1 axis position
color: 'name', // Map task name field to color
enterDuration: (datum) => datum.endTime - datum.startTime, // Map task end time minus start time to enter animation duration
enterDelay: 'startTime', // Map task start time to enter animation delay time
},
scale: { enterDuration: { zero: true, range: [0, 3000] } },
coordinate: { transform: [{ type: 'transpose' }] },
axis: {
x: {
title: 'Task',
},
y: {
title: 'Time',
},
},
});
chart.render();

Configuration Levels

Encode in G2 is mainly used to specify the relationship between visual element attributes and data. You can specify encoding at the Mark level:

({
type: 'interval',
encode: {
x: 'name',
y: 'value',
},
});
// API
// First method
chart.interval().encode('x', 'name').encode('y', 'value');
// Second method
chart.interval().encode({ x: 'name', y: 'value' });

You can also specify encoding at the View level:

({
type: 'view',
encode: {
x: 'name',
y: 'value',
},
});
// API
// First method
chart.encode('x', 'name').encode('y', 'value');
// Second method
chart.encode({ x: 'name', y: 'value' });

Channel encoding has transitivity. View encoding will be passed to marks specified by children. If the mark doesn't have encoding for the corresponding channel, it will be set; otherwise, nothing will be done. For example, drawing a point-line chart:

import { Chart } from '@antv/g2';
const chart = new Chart({
container: 'container',
});
chart
.data([
{ year: '1991', value: 3 },
{ year: '1992', value: 4 },
{ year: '1993', value: 3.5 },
{ year: '1994', value: 5 },
{ year: '1995', value: 4.9 },
{ year: '1996', value: 6 },
{ year: '1997', value: 7 },
{ year: '1998', value: 9 },
{ year: '1999', value: 13 },
])
.encode('x', 'year') // View-level encoding
.encode('y', 'value');
chart.line();
chart.point();
chart.render();

Configuration Options

A complete encoding consists of encode.type and encode.value.

After encoding, an array will be generated under the specified channel according to the encoding method.

Encoding MethodtypevalueDescription
Field EncodingfieldstringField name of a data column
Function Encodingtransform(value, index, array) => number | string | boolean | DateSpecify channel binding through callback function
Constant EncodingconstantanySpecify channel value as constant
Data Encodingcolumnnumber[] | string[] | boolean[] | Date[]Specify channel value as an array

G2 provides syntactic sugar, and in most cases encode.type can be omitted.

({
type: 'point',
encode: {
x: { type: 'field', value: 'weight' },
y: { type: 'field', value: 'height' },
color: { type: 'field', value: 'gender' },
},
});

You can also use syntactic sugar to simplify the writing:

// Syntactic sugar
({
type: 'point',
encode: {
x: 'weight',
y: 'height',
color: 'gender',
},
});

Field Encoding

Specify channel binding to a certain column of data:

(data) => data.map((d) => d[value]);
({
type: 'interval',
encode: { x: { type: 'field', value: 'name' } },
});
// Syntactic sugar
({
type: 'interval',
encode: { x: 'name' },
});

Function Encoding

Specify channel binding to newly generated data:

(data) => data.map(value);
({
type: 'interval',
encode: {
color: {
type: 'transform',
value: (d) => (d.value > 100 ? 'high' : 'low'),
},
},
});
// Syntactic sugar
({
type: 'interval',
encode: {
color: (d) => (d.value > 100 ? 'high' : 'low'),
},
});

You can also generate corresponding channel legends in multi-axis charts through function encoding.

import { Chart } from '@antv/g2';
const chart = new Chart({
container: 'container',
});
chart.options({
type: 'view',
autoFit: true,
data: [
{ time: '10:10', call: 4, waiting: 2, people: 2 },
{ time: '10:15', call: 2, waiting: 6, people: 3 },
{ time: '10:20', call: 13, waiting: 2, people: 5 },
{ time: '10:25', call: 9, waiting: 9, people: 1 },
{ time: '10:30', call: 5, waiting: 2, people: 3 },
{ time: '10:35', call: 8, waiting: 2, people: 1 },
{ time: '10:40', call: 13, waiting: 1, people: 2 },
],
children: [
{
type: 'interval',
encode: {
x: 'time',
y: 'waiting',
color: () => 'waiting',
series: () => 'waiting',
},
scale: { y: { nice: true } },
axis: { y: { title: 'Waiting' } },
},
{
type: 'interval',
encode: {
x: 'time',
y: 'people',
color: () => 'people',
series: () => 'people',
},
scale: { y: { independent: true } },
axis: { y: { position: 'right', grid: null, title: 'People' } },
},
{
type: 'line',
encode: { x: 'time', y: 'call', color: () => 'call' },
scale: { series: { independent: true } },
},
],
});
chart.render();

Function encoding can also disable certain channels in some cases. In G2, when the series channel is not defined and the color channel is already defined, a copy of values will be made to the series channel to achieve categorization effects. In the following example, the color channel is mapped to a continuous field. If the series is also mapped to a continuous field, it will affect the display of gradient lines, so you need to disable it with series: () => undefined.

import { Chart } from '@antv/g2';
const chart = new Chart({
container: 'container',
});
chart.options({
type: 'area',
autoFit: true,
data: {
type: 'fetch',
value: 'https://assets.antv.antgroup.com/g2/temperatures3.json',
},
encode: {
x: (d) => new Date(d.date),
y: ['low', 'high'],
color: (d) => d.high - d.low,
series: () => undefined,
},
scale: { color: { palette: 'reds' } },
style: { gradient: 'x' },
axis: { x: { title: 'date' } },
});
chart.render();

Constant Encoding

Specify channel value as a constant, often used to specify color channels or size channels, setting marks to a certain color or size. This encoding method will not generate legends for the corresponding channels.

(data) => data.map(() => value);
({
type: 'point',
encode: {
color: { type: 'constant', value: 'steelblue' },
size: { type: 'constant', value: 10 },
},
});
// Syntactic sugar
({
type: 'interval',
encode: {
color: 'steelblue',
size: 10,
},
});

Data Encoding

Specify the value of a certain channel as an array.

() => value;
({
type: 'line',
encode: {
x: { type: 'column', value: [0, 1, , 2, 3] },
},
});

For some big data scenarios, using array columns would be more suitable. Here's a simple example.

import { Chart } from '@antv/g2';
const I = [0, 1, 2, 3, 4];
const X = I.map((i) => ((i - 2) * Math.PI) / 2);
const Y = X.map((x) => Math.sin(x));
const chart = new Chart({
container: 'container',
});
chart.options({
type: 'line',
data: I,
encode: {
x: {
type: 'column',
value: X,
},
y: {
type: 'column',
value: Y,
},
shape: 'smooth',
},
});
chart.render();

Array Channels

Of course, for position-related visual channels: such as x and y channels, often more than one column of data is needed. For example, in a waterfall chart, you can specify multiple columns for one channel through an array.

import { Chart } from '@antv/g2';
const chart = new Chart({
container: 'container',
});
chart.options({
type: 'interval',
data: [
{ month: 'Jan.', profit: 387264, start: 0, end: 387264 },
{ month: 'Feb.', profit: 772096, start: 387264, end: 1159360 },
{ month: 'Mar.', profit: 638075, start: 1159360, end: 1797435 },
{ month: 'Apr.', profit: -211386, start: 1797435, end: 1586049 },
{ month: 'May', profit: -138135, start: 1586049, end: 1447914 },
{ month: 'Jun', profit: -267238, start: 1447914, end: 1180676 },
{ month: 'Jul.', profit: 431406, start: 1180676, end: 1612082 },
{ month: 'Aug.', profit: 363018, start: 1612082, end: 1975100 },
{ month: 'Sep.', profit: -224638, start: 1975100, end: 1750462 },
{ month: 'Oct.', profit: -299867, start: 1750462, end: 1450595 },
{ month: 'Nov.', profit: 607365, start: 1450595, end: 2057960 },
{ month: 'Dec.', profit: 1106986, start: 2057960, end: 3164946 },
{ month: 'Total', start: 0, end: 3164946 },
],
encode: {
x: 'month',
y: ['end', 'start'], // Equivalent to y:'end', y1:'start'
color: (d) =>
d.month === 'Total' ? 'Total' : d.profit > 0 ? 'Increase' : 'Decrease',
},
axis: { y: { labelFormatter: '~s' } },
});
chart.render();

You can also specify them separately using the ${channel}${index} format:

// Equivalent to the above form
chart.encode('y', 'end').encode('y1', 'start');