GPT-Vis is an AI-native visualization library designed for the LLM era. It adopts a framework-agnostic architecture, supports 26 chart types, and enables LLMs to easily generate high-quality visualization charts through simple and natural syntax.
Steps
- Intent recognition: select the chart type based on user intent and data characteristics
- Determine the output mode: choose syntax mode or code mode based on the context
- Generate output: generate content according to the selected mode
Supported chart types
| type value | Applicable scenarios |
|---|---|
| line | Time series trends |
| area | Time series trends + total |
| column | Categorical data comparison |
| bar | Categorical comparison (long labels) |
| pie | Proportion of parts to the whole |
| scatter | Relationship between two variables |
| dual-axes | Comparison of data at different magnitudes |
| histogram | Frequency distribution of continuous values |
| boxplot | Data distribution and outliers |
| violin | Data distribution density |
| radar | Multi-dimensional comparison |
| funnel | Process conversion rate |
| waterfall | Cumulative increase/decrease changes |
| liquid | Percentage/progress |
| word-cloud | Word frequency display |
| venn | Set intersection and union relationships |
| treemap | Proportion of hierarchical data |
| sankey | Traffic flow |
| flow-diagram | Process steps |
| mindmap | Hierarchical knowledge organization |
| indented-tree | Tree node hierarchy/directory |
| network-graph | Association relationships between entities |
| organization-chart | Organizational hierarchy |
| fishbone-diagram | Root cause analysis |
| table | Tabular data display |
| summary | Content summary |
Output modes
Mode 1: Syntax mode (Syntax / JSON)
Used for LLM application integration scenarios, generating chart configurations for GPTVis.render() to consume. Supports two formats:
- Syntax format: Markdown-like indentation syntax, suitable for streaming output (can be rendered in real time when the LLM generates token by token)
- JSON format: standard JSON object, suitable for structured API calls
The two formats are equivalent;GPTVis.render() can accept both directly.
Mode 2: Code mode
Used for scenarios where the user needs complete code that can be run directly. Generate output containing installation instructions and complete code.
GPTVis API
GPTVis is the unified entry class of the library, responsible for creating, rendering, and destroying charts.
Constructor
new GPTVis(options: VisualizationOptions)
VisualizationOptions:
| Parameter | Type | Required | Default value | Description |
|---|---|---|---|---|
container |
string | HTMLElement |
Yes | — | CSS selector or DOM element |
width |
number |
No | — | Chart width (px) |
height |
number |
No | — | Chart height (px) |
theme |
'default' | 'light' | 'dark' | 'academy' |
No | 'light' |
Theme |
wrapper |
boolean |
No | false |
Whether to display the outer UI container (including tabs, download, copy, etc.) |
locale |
string |
No | 'zh-CN' |
Text language inside the wrapper |
Methods
render(config: string | object): void
Render charts. Accepts two kinds of input:
- Syntax string: text starting with
vis [type], automatically parsed into a configuration object - JSON configuration object: an object containing the
typefield - Plain text: a string not starting with
viswill be rendered as the summary type
Calling render() multiple times will automatically destroy the previous chart before rendering the new chart.
destroy(): void
Destroy the current chart instance and release resources.
Syntax mode: JSON format
Directly output a JSON object conforming to the chart TypeScript type,GPTVis.render() can be consumed directly.
JSON example
{
"type": "column",
"data": [
{ "category": "A产品", "value": 30, "group": "线上" },
{ "category": "B产品", "value": 50, "group": "线上" }
],
"title": "产品销量对比",
"axisXTitle": "产品",
"axisYTitle": "销量(万)",
"stack": true,
"theme": "academy",
"style": {
"palette": ["#5B8FF9", "#61DDAA"]
}
}
Syntax mode: Syntax format
A Markdown-like indented syntax that supports streaming rendering. The first line must be vis [type]。
Syntax rules
Basic properties — key value, one per line:
title 年度趋势
theme dark
Array of objects — data each item under it starts with - and child fields are indented:
{ data: { time: string; value: number; }[]; }
Corresponds to:
data
- time 2020
value 100
- time 2021
value 120
Array of plain values — each item starts with - :
{ data: number[] }
Corresponds to:
data
- 10
- 20
String values containing spaces — wrap in quotes (single or double); quotes can be omitted when no spaces are present:
categories
- "North America"
- '东南 亚'
- 欧洲
Nested objects — the object name occupies one line and child properties are indented:
{ style?: { backgroundColor?: string; palette?: string[] } }
Corresponds to:
style
backgroundColor #f0f2f5
palette
- #5B8FF9
- #61DDAA
Recursive tree — children array indented with - :
type TreeData = { name: string; children?: TreeData[] };
{ data: TreeData; }
Corresponds to:
data
name 根节点
children
- name 子节点A
children
- name 孙节点
- name 子节点B
Complete Syntax example
vis column
data
- category A产品
value 30
group 线上
- category B产品
value 50
group 线上
title 产品销量对比
axisXTitle 产品
axisYTitle 销量(万)
stack true
theme academy
style
palette
- #5B8FF9
- #61DDAA
Markdown syntax
When the output is in Markdown format, use GPT-Vis as the language tag for the fenced code block, and write the complete Syntax format:
```GPT-Vis
vis line
data
- time 2020
value 100
```
Format:
```GPT-Vis
<完整的 Syntax 内容,首行 vis <chart-type>>
```
Syntax rules:
- The language tag is fixed as
GPT-Vis - The content area is written using the Syntax formatrules,the first line must contain
vis <chart-type>(for the complete list, see aboveSupported chart types) - The code block will be converted by the Markdown plugin to , rendered on the browser side
Note: In Markdown mode, the content areamustwrite the first line
vis <type>, consistent with the pure Syntax mode format.
Code mode
Generate complete runnable code according to the target framework.
Installation method
NPM:
npm install @antv/gpt-vis
import { GPTVis } from '@antv/gpt-vis';
CDN:
<script src="https://unpkg.com/@antv/gpt-vis/dist/umd/index.min.js"></script>
After CDN import, access the main class via GPTVis.GPTVis .
Complete HTML example
<html>
<head>
<script src="https://unpkg.com/@antv/gpt-vis/dist/umd/index.min.js"></script>
</head>
<body>
<div id="container"></div>
<script>
const gptVis = new GPTVis.GPTVis({
container: '#container',
width: 600,
height: 400,
});
gptVis.render(`
vis line
data
- time 2020
value 100
- time 2021
value 120
title 年度趋势
`);
</script>
</body>
</html>
Chart type configuration
Common configuration
All charts include the following fields; these fields are omitted in the subsequent definitions for each chart type. The title of each subsection is the type value (such as line、column), corresponding to the type column in the chart type table above.
{ type: string; title?: string; theme?: 'default' | 'light' | 'dark' | 'academy'; style?: { backgroundColor?: string; palette?: string[] } }
line / area
{ data: { time: string | number; value: number; group?: string }[]; axisXTitle?: string; axisYTitle?: string; stack?: boolean; style?: { lineWidth?: number } }
stack only supported by area.
column / bar
{ data: { category: string; value: number; group?: string }[]; axisXTitle?: string; axisYTitle?: string; stack?: boolean; group?: boolean }
pie
value cannot use percentage numbers.
{ data: { category: string; value: number }[]; innerRadius?: number }
innerRadius set to 0.6 becomes a donut chart.
scatter
{ data: { x: number; y: number; group?: string }[]; axisXTitle?: string; axisYTitle?: string }
dual-axes
{ categories: string[]; series: { type: 'line' | 'column'; data: number[]; axisYTitle?: string }[]; axisXTitle?: string; style?: { startAtZero?: boolean } }
histogram
{ data: number[]; binNumber?: number; axisXTitle?: string; axisYTitle?: string }
boxplot / violin
The same category needs multiple data entries to show the distribution.
{ data: { category: string; value: number; group?: string }[]; axisXTitle?: string; axisYTitle?: string; style?: { startAtZero?: boolean } }
radar
{ data: { name: string; value: number; group?: string }[]; align?: boolean }
align: Whether to align the scales of each dimension, default false (each axis scales independently); when true, all axes share the same maximum value, suitable for comparing absolute values across multiple series.
funnel
{ data: { category: string; value: number; }[]; }
waterfall
value can be negative to indicate a decrease. palette is the color palette array, in the order [positive color, negative color, summary color].
{ data: { category: string; value: number }[]; axisXTitle?: string; axisYTitle?: string; style?: { palette?: string[] } }
liquid
percent Range 0~1.
{ percent: number; shape?: 'rect' | 'circle' | 'pin' | 'triangle' }
word-cloud
{ data: { text: string; value: number; }[]; }
venn
Separate set identifiers with commas:sets: "A,B"。label used to display the name of the corresponding set on the chart
{ data: { sets: string | string[]; value: number; label?: string }[] }
treemap
type TreeNode = { name: string; value: number; children?: TreeNode[] };
{ data: TreeNode[] }
sankey
{ data: { source: string; target: string; value: number }[]; nodeAlign?: 'left' | 'center' | 'right' | 'justify' }
flow-diagram / network-graph
source/target The referenced node's name。
type GraphData = { nodes: { name: string }[]; edges: { source: string; target: string; name?: string }[] };
// flow-diagram
{ data: GraphData }
// network-graph
{ data: GraphData; layout?: 'force' | 'circular' | 'grid' | 'radial' | 'concentric' | 'dagre' }
mindmap / indented-tree / organization-chart
type TreeData = { name: string; children?: TreeData[] };
// mindmap
{ data: TreeData; direction?: 'H' | 'LR' | 'RL' }
// indented-tree
{ data: TreeData; direction?: 'LR' | 'RL' | 'H' }
// organization-chart
type OrganizationChartData = {
name: string;
description?: string;
children?: OrganizationChartData[];
};
{ data: OrganizationChartData }
mindmap defaults to 'H', indented-tree defaults to 'LR'。
fishbone-diagram
type FishboneNode = { name: string; children?: FishboneNode[] };
{ data: FishboneNode; style?: { texture?: 'rough' | 'default' } }
texture: 'rough' is hand-drawn style.
table
{ data: Record<string, string | number>[]; }
summary
summary is completely different from other chart types: it does not use Syntax/JSON configuration, but instead uses T8 syntax (Markdown + semantic annotation).
⚠️ Before generating summary, you must: first read references/summary.md to get the T8 syntax rules, the complete list of entity types, attribute field definitions, generation requirements, and examples, and then generate the content. Skipping this step will cause syntax errors.
Best practices
- Pie charts should have no more than 5 categories; if more, it is recommended to merge them into "Other" or switch to a bar chart
- Do not use pie charts to show trends, and do not use line charts to show unordered categories
- Numeric fields must be of numeric type, and category fields must be of text type
- The distribution of continuous numeric values (such as salary, scores, age) must use a histogram
- Multi-dimensional data field mapping: when there are two categorical dimensions, write the x-axis dimension as
time/category, and write the other asgroup - In syntax mode, prefer the Syntax format (streaming-friendly)
- In code mode, generate the HTML + CDN solution by default (zero installation), and use the npm solution only when the user specifies a framework