Site/Docs/Tutorial/Advanced/Custom View
---
title: 自定义 View
order: 1
---
在 F2 中,为了让显示更加灵活和自定义,我们把所有的组件都进行了高阶组件(HOC)的封装,形成了 withXXX 的逻辑封装。下面以 Legend 为例,来演示如何实现自定义 View。
Legend 的使用
import { Canvas, Chart, Legend } from '@antv/f2';<Canvas context={context}>
<Chart data={data}>
<Legend position="top" />
</Chart>
</Canvas>
除了 Legend 之外,还有 withLegend 和 LegendView 这两个对象,而 Legend = withLegend(LegendView)。所以我们只要定义自己的 LegendView 就能达到自定义 View 的效果。
定义自定义 View
const CustomLegendView = (props) => {
const { items } = props;
return (
<group
style={{
flexDirection: 'row',
}}
>
{items.map((item) => {
const { name, color } = item;
return (
<text
style={{
text: name,
fill: color,
}}
/>
);
})}
</group>
);
}使用自定义 View
import { Canvas, Chart, withLegend } from '@antv/f2';// 自定义 View
const CustomLegendView = (props) => {
const { items } = props;
return (
<group
style={{
flexDirection: 'row',
}}
>
{items.map((item) => {
const { name, color } = item;
return (
<text
style={{
text: name,
fill: color,
}}
/>
);
})}
</group>
);
}
// 使用自定义 view 的组件
const Legend = withLegend(CustomLegendView);
<Canvas context={context}>
<Chart data={data}>
<Legend position="top" />
</Chart>
</Canvas>
在 CustomLegendView 中,用户可以拿到计算逻辑后的结果 props,也可以使用 Legend 组件的 public function。
完整示例
---
Site/Docs/Tutorial/Framework/Jsx Transform.Zh
---
title: 配置 JSX Transform
order: 15
---
F2 使用 JSX 语法来构建图表,所以需要在运行前对 JSX 语法进行编译。JSX 更多细节可参考 React 的官方文档 JSX 简介。
Babel 和 TypeScript 都可以编译 JSX 语法,并且在编译时 JSX 语法时,会有 2 种编译模式,在实际项目中可根据实际情况选择和使用。
JSX 2 种编译的差别可见:
- https://babeljs.io/docs/en/babel-plugin-transform-react-jsx#runtime
- https://zh-hans.reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html
Babel
在 Babel 中是使用 @babel/plugin-transform-react-jsx 这个插件来编译 JSX 的。
安装
npm install --save-dev @babel/plugin-transform-react-jsx配置 babel.config
#### Classic 模式
{
"plugins": [
[
"@babel/plugin-transform-react-jsx",
{
"pragma": "jsx",
"pragmaFrag": "Fragment"
}
]
]
}#### Automatic 模式
{
"plugins": [
[
"@babel/plugin-transform-react-jsx",
{
"runtime": "automatic",
"importSource": "@antv/f2"
}
]
]
}TypeScript
在 TypeScript 中也分别支持这 2 种编译模式。
配置 tsconfig.json
#### Classic 模式
{
"compilerOptions": {
"jsxFactory": "jsx",
"jsxFragmentFactory": "Fragment"
}
}#### Automatic 模式
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "@antv/f2"
}
}---
Site/Docs/Tutorial/Framework/Miniprogram.En
---
title: 小程序上渲染 F2
order: 13
redirect_from:
- /zh/docs/tutorial/manual/miniprogram
---
F2 是基于 CanvasRenderingContext2D 的标准接口绘制的,所以只要能提供标准 CanvasRenderingContext2D 接口的实现对象,F2 就能进行图表绘制。
封装思路
在小程序中提供的 context 对象不是标准的 CanvasRenderingContext2D,所以封装的核心思路是将 context 和 CanvasRenderingContext2D 对齐。F2 针对支付宝和微信这两个常见场景做了一层 context 的对齐,详见:https://github.com/antvis/f2-context。其他小程序也可以按同样的思路封装。
小程序组件
为了方便使用,我们针对支付宝和微信分别封装了对应的自定义组件。
支付宝小程序
F2 的支付宝小程序版本。
微信小程序
F2 的微信小程序图表组件。
注意:详细使用说明请参考 小程序集成教程。
---
Site/Docs/Tutorial/Framework/Miniprogram.Zh
---
title: 如何在小程序中使用
order: 13
---
前置配置
安装依赖
安装 F2 依赖
npm i @antv/f2 --save支付宝小程序
npm i @antv/f-my --save微信小程序
npm i @antv/f-wx --save配置 JSX Transform
如果项目已有 JSX 编译,可忽略此步骤。
添加 JSX 编译脚本
package.json:
{
"scripts": {
"beforeCompile": "babel pages --out-dir pages --only /*.jsx"
}
}支付宝小程序
双 Canvas 模式说明
在小程序生态中,F2 提供了两套小程序组件:f-my(默认 NativeCanvas 实现)与 f-my-web(基于 WebCanvas 实现)。通过引入不同组件包来选择 Canvas 类型。
- f-my:使用 NativeCanvas(原生 Canvas 实现),对齐 Web Canvas API,适用于对原生特性有依赖或兼容性要求较高的场景
- f-my-web:使用 WebCanvas(在小程序内基于 web 技术栈实现的 Canvas),在包含大量同层组件或频繁跨层通信的复杂页面中,通常能显著降低总耗时,获得更优的交互性能
- 兼容性:F2 已屏蔽两者的 API 差异,图表代码无需修改即可在 f-my 与 f-my-web 之间复用
配置编译脚本
mini.project.json:
{
"scripts": {
"beforeCompile": "npm run beforeCompile"
}
}使用示例
#### 使用 NativeCanvas (f-my)
page.json:
{
"usingComponents": {
"f2": "@antv/f-my"
}
}page.axml:
<view class="container">
<f2 onRender="onRenderChart" onCanvasReady="onCanvasReady"></f2>
</view>#### 使用 WebCanvas (f-my-web)
page.json:
{
"usingComponents": {
"f2": "@antv/f-my-web"
}
}page.axml:
<view class="container">
<f2 onRender="onRenderChart"></f2>
</view>#### 样式定义
page.acss:
.container {
width: 100%;
height: 600rpx;
}#### 图表组件
chart.jsx:
import { Chart, Interval, Axis } from '@antv/f2';export default (props) => {
const { data } = props;
return (
<Chart data={data}>
<Axis field="genre" />
<Axis field="sold" />
<Interval x="genre" y="sold" color="genre" />
</Chart>
);
}
#### 页面入口
page.jsx:
import Chart from './chart';const data = [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 120 },
{ genre: 'Shooter', sold: 350 },
{ genre: 'Other', sold: 150 },
];
Page({
data: {},
onRenderChart() {
return <Chart data={data} />;
},
})
#### createElement 方式
如果不想在入口文件写 JSX 语法,可以使用 createElement 方式:
page.js:
import { createElement } from '@antv/f2';
import Chart from './chart';const data = [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 120 },
{ genre: 'Shooter', sold: 350 },
{ genre: 'Other', sold: 150 },
];
Page({
data: {},
onRenderChart() {
return createElement(Chart, {
data: data,
});
},
})
完整示例
微信小程序
使用示例
#### 页面配置
page.json:
{
"usingComponents": {
"f2": "@antv/f-wx"
}
}#### 页面模板
page.wxml:
<view class="container">
<f2 onRender="{{onRenderChart}}" />
</view>#### 样式定义
page.wxss:
.container {
width: 100%;
height: 600rpx;
}#### 图表组件
chart.jsx:
import { Chart, Interval, Axis } from '@antv/f2';export default (props) => {
const { data } = props;
return (
<Chart data={data}>
<Axis field="genre" />
<Axis field="sold" />
<Interval x="genre" y="sold" color="genre" />
</Chart>
);
}
#### 页面入口
page.jsx:
import Chart from './chart';const data = [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 120 },
{ genre: 'Shooter', sold: 350 },
{ genre: 'Other', sold: 150 },
];
Page({
data: {
onRenderChart() {
return <Chart data={data} />;
},
},
})
#### createElement 方式
page.js:
import { createElement } from '@antv/f2';const data = [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 120 },
{ genre: 'Shooter', sold: 350 },
{ genre: 'Other', sold: 150 },
];
Page({
data: {
onRenderChart() {
return createElement(Chart, {
data: data,
});
},
},
})
完整示例
---
Site/Docs/Tutorial/Framework/Nodejs.Zh
---
title: 如何在 Node.js 中使用
order: 14
---
在 Node.js 环境中使用 F2,可以通过 canvas 库提供 Canvas 实现,从而生成图表图片。
配置 JSX Transform
安装依赖
npm install @antv/f2 --save
npm install canvas --save使用示例
import { Canvas, Chart, Interval, Axis } from '@antv/f2';
import { createCanvas } from 'canvas';
import fs from 'fs';
import path from 'path';const canvas = createCanvas(200, 200);
const ctx = canvas.getContext('2d');
const data = [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 120 },
{ genre: 'Shooter', sold: 350 },
{ genre: 'Other', sold: 150 },
];
(async () => {
const { props } = (
<Canvas context={ctx} pixelRatio={1} animate={false}>
<Chart data={data}>
<Axis field="genre" />
<Axis field="sold" />
<Interval x="genre" y="sold" color="genre" />
</Chart>
</Canvas>
);
const fcanvas = new Canvas(props);
await fcanvas.render();
const out = fs.createWriteStream(path.join(__dirname, 'chart.png'));
const stream = canvas.createPNGStream();
stream.pipe(out);
out.on('finish', () => {
process.exit();
});
})();
说明
- 使用 canvas 库的 createCanvas 方法创建 Canvas 实例
- 将 Canvas 的 2D context 传递给 F2 的 Canvas 组件
- 设置 animate={false} 关闭动画,因为图片导出场景不需要动画
- 使用 createPNGStream 将 Canvas 内容输出为 PNG 图片文件
---
Site/Docs/Tutorial/Framework/Overview.Zh
---
title: 多端适配
order: 10
---
在 5.0 中,F 系列基于移动端特点和共性进行了移动端底层架构(Fengine)的统一,对接于最新的 G 5.0 之上。我们利用 Fengine 提供的多端适配,可以快速适配各种框架/端。
架构概览
其中:
- @antv/f-engine — 无框架(原生 JS)
- @antv/f-react — React 框架
- @antv/f-vue — Vue 框架
- @antv/f-my — 支付宝小程序端
- @antv/f-wx — 微信小程序端
使用方式
F2 默认引入 @antv/f-engine 中的 canvas。使用者根据框架/端,引入不同端的 canvas 以及 F2, 即可快速搭建可视化图表。具体使用方式可查看对应文档:
- React 集成
- Vue 集成
- 小程序集成
- Node.js 集成
- SVG 渲染器
封装思路
F2 是基于 CanvasRenderingContext2D 的标准接口绘制的,所以只要能提供标准 CanvasRenderingContext2D 接口的实现对象,F2 就能进行图表绘制。
因为在小程序中提供的 context 对象不是标准的 CanvasRenderingContext2D,所以封装的核心思路是将 context 和 CanvasRenderingContext2D 对齐。F2 针对支付宝和微信这两个常见场景做了一层 context 的对齐,详见:https://github.com/antvis/f2-context。其他小程序也可以按同样的思路封装。
---
Site/Docs/Tutorial/Framework/React.Zh
---
title: 如何在 React 中使用
order: 11
---
因为 F2 也是使用声明式构建图表 UI,也内置了一套统一的组件,可以很容易地与 React 生态结合,使用时可以完全按 React 组件库的方式来使用。
安装依赖
npm install @antv/f2 --save
npm install @antv/f-react --save完整示例
import React from 'react';
import ReactDOM from 'react-dom';
import Canvas from '@antv/f-react';
import { Chart, Interval } from '@antv/f2';const data = [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 120 },
{ genre: 'Shooter', sold: 350 },
{ genre: 'Other', sold: 150 },
];
ReactDOM.render(
<div>
<Canvas>
<Chart data={data}>
<Interval x="genre" y="sold" />
</Chart>
</Canvas>
</div>,
document.getElementById('root')
)
完整示例参考
---
Site/Docs/Tutorial/Framework/Svg Renderer.Zh
---
title: 使用 SVG 渲染
order: 16
---
借助 G 的 渲染器,F2 也可以使用 SVG 渲染。
安装依赖
npm install @antv/g-mobile-svg --save使用步骤
1. 定义渲染容器
<div id="container"></div>2. 使用 SVG 渲染器
import { Canvas, Chart, Interval, jsx, Axis } from '@antv/f2';
import { Renderer } from '@antv/g-mobile-svg';const container = document.getElementById('container');
// 实例化 SVG 渲染器
const renderer = new Renderer();
const { props } = (
// 声明渲染容器和渲染器
<Canvas container={container} renderer={renderer} width={300} height={200}>
<Chart data={data}>
<Axis field="genre" />
<Axis field="sold" />
<Interval x="genre" y="sold" color="genre" />
</Chart>
</Canvas>
);
const canvas = new Canvas(props);
canvas.render();
完整示例
说明
- SVG 渲染器适用于需要矢量输出或可缩放图表的场景
- 通过 renderer 属性将 SVG 渲染器传递给 Canvas 组件
- SVG 渲染器会生成 SVG DOM 元素,可以方便地进行后续操作(如导出 SVG 文件)
---
Site/Docs/Tutorial/Framework/Vue.Zh
---
title: 如何在 Vue 中使用
order: 12
---
为了方便 Vue 项目的使用,Fengine 也封装了一个 Vue 组件。
安装依赖
npm install @antv/f2 --save
npm install @antv/f-vue --save配置 JSX 编译
webpack (vue-cli)
安装 Babel 插件:
npm install @babel/plugin-transform-react-jsx --save-dev打开 vue.config.js 添加如下配置:
{
chainWebpack: (config) => {
config.module
.rule('F2')
.test(/\.jsx$/)
.use('babel')
.loader('babel-loader')
.options({
plugins: [
[
'@babel/plugin-transform-react-jsx',
{
runtime: 'automatic',
importSource: '@antv/f2',
},
],
],
})
.end();
},
}Vite
安装依赖:
npm install @rollup/plugin-babel --save-dev
npm install @babel/plugin-transform-react-jsx --save-dev打开 vite.config.js 添加如下配置:
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import { babel } from '@rollup/plugin-babel';export default defineConfig({
plugins: [
babel({
plugins: [
[
'@babel/plugin-transform-react-jsx',
{
runtime: 'automatic',
importSource: '@antv/f2',
},
],
],
}),
vue(),
vueJsx(),
],
});
使用示例
<script>
import { toRaw } from 'vue';
import Canvas from '@antv/f-vue';
import { Chart, Interval, Axis } from '@antv/f2';const data1 = [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 120 },
{ genre: 'Shooter', sold: 350 },
{ genre: 'Other', sold: 150 },
];
const data2 = [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 20 },
{ genre: 'Shooter', sold: 50 },
{ genre: 'Other', sold: 50 },
];
export default {
name: 'App',
data() {
return {
year: '2021',
chartData: data1,
};
},
mounted() {
setTimeout(() => {
this.year = '2022';
this.chartData = data2;
}, 1000);
},
render() {
const { year, chartData } = this;
return (
<div className="container">
<Canvas pixelRatio={window.devicePixelRatio}>
<Chart data={toRaw(chartData)}>
<Axis field="genre" />
<Axis field="sold" />
<Interval x="genre" y="sold" color="genre" />
</Chart>
</Canvas>
</div>
);
},
};
</script>
<style>
.container {
width: 500px;
height: 300px;
}
</style>
完整示例参考
---
Site/Docs/Tutorial/Question/With React Typescript.Zh
---
title: 和 React 同时使用时,TS 类型报错
order: 1
---
当和 React 同时使用时,遇到 group、circle、rect 等标签的类型提示错误,如下图所示:
问题原因
因为 React SVG 的标签类型里也有 circle、rect 等标签,这些和 F2 定义的冲突了,需要单独引入 F2 标签定义的命名空间。
解决方式
1. 确定当前项目的 JSX 编译模式
打开 tsconfig.json,找到 compilerOptions 下的 jsx 配置项。如果没有则默认为 react。
- react 为 Classic 编译模式
- react-jsx 为 Automatic 编译模式
2. Classic 编译模式
在文件顶部增加如下注释和模块引用:
/ @jsx jsx */
import { jsx } from '@antv/f2';3. Automatic 编译模式
在文件顶部增加如下注释:
/ @jsxImportSource @antv/f2 */完成后即可解决类型错误问题:
注意事项
因为代码编译是以文件为单位的,在一个文件里只能使用一种标签类型。如果需要在同一文件中混用,需要将 F2 图表代码拆分到新文件中。
---
Site/Docs/Tutorial/Animation.Zh
---
title: 动画属性 - Animation
order: 8
---
F2 动画定义与 Web Animations API 靠齐,除了组件层面,每个图形标签也都可以添加自定义动画。目前只支持基于 Keyframe 的动画,可定义动画执行阶段,以及变化效果 KeyframeEffect。
动画执行阶段
动画执行阶段分为 appear、update 以及 leave:
| 阶段 | 说明 | 触发时机 |
|------|------|----------|
| appear | 初始化时的入场动画 | render 阶段 |
| update | 数据更新时的更新动画 | props 发生改变 |
| leave | 销毁前的离场动画 | destroy 阶段 |
每个阶段都可以配置相应的 animation。
Animation 属性
基础属性
| 属性 | 类型 | 默认值 | 描述 |
|------|------|--------|------|
| easing | string | 'linear' | 缓动函数,动画持续效果 |
| duration | number | - | 动画持续时间(毫秒) |
| delay | number | 0 | 开始动画前的延迟(毫秒) |
| fill | string | 'none' | 定义图形在动画执行前后的表现,可选值:'none'、'forwards'、'backwards'、'both' |
| iterations | number | 1 | 循环次数,Infinity 为无限循环 |
| iterationStart | number | 0 | 从何处执行动画 |
| property | string[] | - | 声明需要变换的属性 |
| start | Keyframe | - | 开始帧状态 |
| end | Keyframe | - | 结束帧状态 |
| clip | Clip | - | 裁剪区域动画,见裁剪 |
easing 缓动函数
缓动函数,默认为 linear,并且内置提供以下缓动函数,可参考效果:
| 恒速 | 加速 | 减速 | 加速-减速 | 减速-加速 |
|------|------|------|-----------|-----------|
| linear | ease-in / in | ease-out / out | ease-in-out / in-out | ease-out-in / out-in |
| ease | in-sine | out-sine | in-out-sine | out-in-sine |
| steps | in-quad | out-quad | in-out-quad | out-in-quad |
| step-start | in-cubic | out-cubic | in-out-cubic | out-in-cubic |
| step-end | in-quart | out-quart | in-out-quart | out-in-quart |
| - | in-quint | out-quint | in-out-quint | out-in-quint |
| - | in-expo | out-expo | in-out-expo | out-in-expo |
| - | in-circ | out-circ | in-out-circ | out-in-circ |
| - | in-back | out-back | in-out-back | out-in-back |
| - | in-bounce | out-bounce | in-out-bounce | out-in-bounce |
| - | in-elastic | out-elastic | in-out-elastic | out-in-elastic |
| - | spring / spring-in | spring-out | spring-in-out | spring-out-in |
Keyframe 支持的属性
目前支持变换的属性:
| 属性 | 类型 | 说明 |
|------|------|------|
| transform | string | 和 CSS Transform 保持一致 |
| opacity | number | 透明度 |
| strokeOpacity | number | 描边透明度 |
| fill | string | 填充色 |
| stroke | string | 描边色 |
| lineWidth | number | 线宽 |
| r | number | Circle 的半径 |
| rx | number | Ellipse 的 x 半径 |
| ry | number | Ellipse 的 y 半径 |
| width | number | Rect/Image 的宽度 |
| height | number | Rect/Image 的高度 |
| x | number | 位置 x 坐标 |
| y | number | 位置 y 坐标 |
| x1 | number | Line 的起点 x 坐标 |
| y1 | number | Line 的起点 y 坐标 |
| x2 | number | Line 的终点 x 坐标 |
| y2 | number | Line 的终点 y 坐标 |
| offsetDistance | number | 路径偏移,和 CSS Offset 保持一致 |
| lineDash | number[] | 实线和间隔的长度 |
| lineDashOffset | number | 虚线的偏移量,可实现蚂蚁线效果 |
| path | string | Path 的定义,可做形变动画 |
基础用法
入场动画
<text
style={{
text: '测试',
x: 100,
y: 100,
}}
animation={{
appear: {
easing: 'linear',
duration: 450,
property: ['x', 'y'],
start: {
x: 0,
y: 0,
},
end: {
x: 100,
y: 100,
},
},
}}
/>更新动画
<rect
style={{
x: 100,
y: 100,
width: 50,
height: 50,
fill: 'blue',
}}
animation={{
appear: {
easing: 'linear',
duration: 450,
property: ['width', 'height'],
start: {
width: 0,
height: 0,
},
end: {
width: 50,
height: 50,
},
},
update: {
easing: 'ease-in-out',
duration: 300,
property: ['fill'],
start: {
fill: 'blue',
},
end: {
fill: 'red',
},
},
}}
/>离场动画
<circle
style={{
cx: 100,
cy: 100,
r: 50,
fill: 'green',
}}
animation={{
leave: {
easing: 'ease-out',
duration: 500,
property: ['opacity', 'r'],
start: {
opacity: 1,
r: 50,
},
end: {
opacity: 0,
r: 0,
},
},
}}
/>多属性动画
<rect
style={{
x: 50,
y: 50,
width: 100,
height: 100,
fill: '#1890ff',
}}
animation={{
appear: {
easing: 'ease-in-out',
duration: 1000,
property: ['x', 'y', 'width', 'height', 'opacity'],
start: {
x: 100,
y: 100,
width: 0,
height: 0,
opacity: 0,
},
end: {
x: 50,
y: 50,
width: 100,
height: 100,
opacity: 1,
},
},
}}
/>变换动画
<rect
style={{
x: 100,
y: 100,
width: 50,
height: 50,
fill: 'red',
transformOrigin: 'center',
}}
animation={{
appear: {
easing: 'linear',
duration: 2000,
property: ['transform'],
start: {
transform: 'rotate(0deg) scale(1)',
},
end: {
transform: 'rotate(360deg) scale(1.5)',
},
},
}}
/>裁剪动画
<text
style={{
text: '裁剪动画',
x: 100,
y: 100,
}}
animation={{
appear: {
easing: 'linear',
duration: 1000,
clip: {
type: 'rect',
property: ['width'],
style: {
x: 100,
y: 100,
height: 20,
},
start: {
width: 0,
},
end: {
width: 100,
},
},
},
}}
/>循环动画
<circle
style={{
cx: 100,
cy: 100,
r: 30,
fill: 'blue',
}}
animation={{
appear: {
easing: 'ease-in-out',
duration: 1000,
iterations: Infinity, // 无限循环
property: ['r'],
start: {
r: 20,
},
end: {
r: 40,
},
},
}}
/>延迟动画
<rect
style={{
x: 100,
y: 100,
width: 50,
height: 50,
fill: 'green',
}}
animation={{
appear: {
easing: 'linear',
duration: 500,
delay: 1000, // 延迟 1 秒开始
property: ['opacity'],
start: {
opacity: 0,
},
end: {
opacity: 1,
},
},
}}
/>路径动画
让图形沿着某个路径移动,在 CSS 中可通过 MotionPath 实现,F2 可通过图形标签上设置 offset 属性实现,目前支持 <line/> 和 <polyline/>。
基础路径动画
<circle
style={{
fill: '#808080',
r: 10,
offset: {
type: 'polyline',
style: {
points: [
[0, 3],
[50, 10],
[130, 80],
[250, 40],
],
},
},
}}
animation={{
appear: {
easing: 'ease-out',
duration: 1000,
property: ['offsetDistance'],
start: {
offsetDistance: 0,
},
end: {
offsetDistance: 1,
},
},
}}
/>Line 组件路径动画
F2 在组件 Line 中内置了该功能,提供 endView 接口,可设置沿着线段移动的元素,具体可见 demo。
TypeScript 类型定义
interface Animation {
appear?: AnimationConfig
update?: AnimationConfig | AnimationConfig[]
leave?: AnimationConfig
}interface AnimationConfig {
easing?: string
duration?: number
delay?: number
fill?: 'none' | 'forwards' | 'backwards' | 'both'
iterations?: number
iterationStart?: number
property?: string[]
start?: Keyframe
end?: Keyframe
clip?: ClipAnimation
}
interface Keyframe {
transform?: string
opacity?: number
strokeOpacity?: number
fill?: string
stroke?: string
lineWidth?: number
r?: number
rx?: number
ry?: number
width?: number
height?: number
x?: number
y?: number
x1?: number
y1?: number
x2?: number
y2?: number
offsetDistance?: number
lineDash?: number[]
lineDashOffset?: number
path?: string
}
interface ClipAnimation {
type: 'circle' | 'rect' | 'polygon'
property?: string[]
style: Record<string, any>
start?: Record<string, any>
end?: Record<string, any>
}
常见问题
如何让动画无限循环?
设置 iterations: Infinity:
animation={{
appear: {
easing: 'linear',
duration: 2000,
iterations: Infinity,
property: ['opacity'],
start: { opacity: 0 },
end: { opacity: 1 },
},
}}如何让动画结束时保持最终状态?
设置 fill: 'forwards':
animation={{
appear: {
easing: 'linear',
duration: 1000,
fill: 'forwards',
property: ['x'],
start: { x: 0 },
end: { x: 100 },
},
}}如何创建弹簧动画效果?
使用 spring 系列缓动函数:
animation={{
appear: {
easing: 'spring',
duration: 1000,
property: ['x'],
start: { x: 0 },
end: { x: 100 },
},
}}如何同时动画多个属性?
在 property 数组中声明多个属性:
animation={{
appear: {
easing: 'ease-in-out',
duration: 1000,
property: ['x', 'y', 'width', 'height', 'opacity'],
start: {
x: 100,
y: 100,
width: 0,
height: 0,
opacity: 0,
},
end: {
x: 50,
y: 50,
width: 100,
height: 100,
opacity: 1,
},
},
}}相关文档
---
Site/Docs/Tutorial/Component.Zh
---
title: 自定义组件
order: 9
---
F2 提供了完整的组件化能力,你可以创建自定义组件来扩展图表功能。组件结构基本保持和 React 一致,如果你了解 React,相信你一看就会。
为什么需要自定义组件
- 复用性: 将常用的可视化元素封装成组件,在多处复用
- 模块化: 将复杂的图表拆分成多个小组件,便于维护
- 扩展性: 创建 F2 内置组件无法满足的特殊可视化需求
组件定义
基础结构
自定义组件需要继承 Component 基类并实现 render 方法:
import { Component } from '@antv/f2';class MyComponent extends Component {
render() {
const { props } = this;
const { text, x, y } = props;
return <text style={{ text, x, y }} />;
}
}
完整生命周期
Component 提供完整的生命周期钩子:
import { Component } from '@antv/f2';class Hello extends Component {
constructor(props) {
super(props);
// 初始化状态
this.state = {
count: 0,
};
}
// 组件即将挂载
willMount() {
console.log('组件即将挂载');
}
// 组件挂载完成
didMount() {
console.log('组件已挂载');
// 可以执行副作用操作,如动画、请求等
}
// 判断是否需要更新
shouldUpdate(nextProps) {
// 返回 false 跳过更新
return true;
}
// 接收新属性
willReceiveProps(nextProps) {
console.log('即将接收新属性', nextProps);
}
// 组件即将更新
willUpdate() {
console.log('组件即将更新');
}
// 组件更新完成
didUpdate() {
console.log('组件已更新');
}
// 渲染组件
render() {
const { props, state } = this;
const { color } = props;
const { count } = state;
return (
<rect
style={{
x: 10,
y: 10,
width: 10,
height: 10,
fill: color,
}}
/>
);
}
// 组件即将卸载
willUnmount() {
console.log('组件即将卸载');
// 清理资源,如取消事件监听等
}
// 组件卸载完成
didUnmount() {
console.log('组件已卸载');
}
}
生命周期流程图
挂载阶段:
constructor() → willMount() → render() → didMount()更新阶段:
willReceiveProps() → shouldUpdate() → willUpdate() → render() → didUpdate()
卸载阶段:
willUnmount() → didUnmount()
组件状态管理
setState
使用 setState 更新组件状态:
class Counter extends Component {
constructor(props) {
super(props);
this.state = {
count: 0,
};
} handleClick() {
// 更新状态
this.setState({
count: this.state.count + 1,
});
// 或使用函数形式
this.setState((prevState) => ({
count: prevState.count + 1,
}));
// 可以传入回调函数
this.setState(
{ count: this.state.count + 1 },
() => {
console.log('状态已更新', this.state.count);
}
);
}
render() {
const { count } = this.state;
return <text style={{ text: Count: ${count} }} />;
}
}
forceUpdate
强制组件更新,跳过 shouldUpdate 检查:
class MyComponent extends Component {
forceRefresh() {
this.forceUpdate(() => {
console.log('组件已强制更新');
});
}
}组件属性
属性类型定义
使用 TypeScript 定义组件属性:
interface MyComponentProps {
title: string;
value: number;
color?: string;
}class MyComponent extends Component<MyComponentProps> {
render() {
const { props } = this;
const { title, value, color = 'red' } = props;
return <text style={{ text: ${title}: ${value}, fill: color }} />;
}
}
默认属性值
class MyComponent extends Component {
static defaultProps = {
color: 'red',
size: 12,
}; render() {
const { color, size } = this.props;
return <text style={{ fill: color, fontSize: size }} />;
}
}
使用上下文
组件可以通过 this.context 访问上下文信息:
class ContextAwareComponent extends Component {
didMount() {
const { context } = this;
const { px2hd, theme, layout } = context; // 像素单位转换
const x = px2hd(100);
// 访问主题
const primaryColor = theme.primaryColor;
// 访问布局信息
const { width, height } = layout;
}
render() {
const { context } = this;
const { px2hd } = context;
return (
<text
style={{
x: px2hd(50),
y: px2hd(50),
text: 'Hello',
}}
/>
);
}
}
IContext 接口
| 属性 | 类型 | 说明 |
|------|------|------|
| px2hd | (value: any) => any | 像素单位转换函数 |
| theme | Record<string, any> | 主题配置对象 |
| layout | { left, top, width, height } | 画布布局信息 |
组件使用
基础使用
import { Canvas } from '@antv/f2';
import Hello from './hello';<Canvas context={context}>
<Hello color="red" />
</Canvas>
在图表中使用
import { Canvas, Chart, Interval } from '@antv/f2';
import DataLabel from './data-label';<Canvas context={context}>
<Chart data={data}>
<Interval x="genre" y="sold" color="genre" />
<DataLabel field="sold" />
</Chart>
</Canvas>
实用示例
数据标签组件
创建一个显示数据标签的组件:
class DataLabel extends Component {
render() {
const { props, context } = this;
const { data, xField, yField } = props;
const { px2hd } = context; return (
<group>
{data.map((item) => {
const x = px2hd(item[xField]);
const y = px2hd(item[yField]);
return (
<text
style={{
text: String(item[yField]),
x,
y: y - 10,
fill: '#000',
fontSize: '12px',
textAlign: 'center',
}}
/>
);
})}
</group>
);
}
}
// 使用
<Canvas context={context}>
<Chart data={data}>
<Interval x="genre" y="sold" />
<DataLabel data={data} xField="genre" yField="sold" />
</Chart>
</Canvas>
自定义图例组件
class CustomLegend extends Component {
render() {
const { props } = this;
const { items, onClick } = props;
const { x = 10, y = 10 } = props; return (
<group>
{items.map((item, index) => (
<g
key={item.name}
style={{
transform: translate(${x}, ${y + index * 30}),
}}
onClick={() => onClick(item)}
>
<rect
style={{
width: 20,
height: 20,
fill: item.color,
}}
/>
<text
style={{
x: 30,
y: 15,
text: item.name,
}}
/>
</g>
))}
</group>
);
}
}
条件渲染组件
class ConditionalComponent extends Component {
render() {
const { props } = this;
const { data, threshold } = props; const shouldRender = data.some(item => item.value > threshold);
if (!shouldRender) {
return null;
}
return <rect style={{ x: 0, y: 0, width: 100, height: 100, fill: 'red' }} />;
}
}
动画组件
class AnimatedComponent extends Component {
constructor(props) {
super(props);
this.state = {
progress: 0,
};
} didMount() {
const { animate } = this.props;
if (animate) {
this.startAnimation();
}
}
startAnimation() {
let progress = 0;
const timer = setInterval(() => {
progress += 0.1;
if (progress >= 1) {
progress = 1;
clearInterval(timer);
}
this.setState({ progress });
}, 50);
}
render() {
const { props, state } = this;
const { progress } = state;
const { maxValue } = props;
const height = maxValue * progress;
return (
<rect
style={{
x: 0,
y: 100 - height,
width: 50,
height,
fill: 'blue',
}}
/>
);
}
willUnmount() {
// 清理定时器
if (this.timer) {
clearInterval(this.timer);
}
}
}
组件通信
父子组件通信
// 父组件
class ParentComponent extends Component {
render() {
return (
<group>
<ChildComponent
data={this.props.data}
onItemClick={this.handleItemClick}
/>
</group>
);
} handleItemClick = (item) => {
console.log('子组件被点击', item);
};
}
// 子组件
class ChildComponent extends Component {
render() {
const { props } = this;
const { data, onItemClick } = props;
return (
<group>
{data.map((item) => (
<rect
key={item.id}
style={{ x: item.x, y: item.y, width: 50, height: 50 }}
onClick={() => onItemClick(item)}
/>
))}
</group>
);
}
}
性能优化
使用 shouldUpdate
避免不必要的渲染:
class OptimizedComponent extends Component {
shouldUpdate(nextProps) {
// 只有当关键属性变化时才更新
return nextProps.value !== this.props.value;
} render() {
const { props } = this;
return <text style={{ text: props.value }} />;
}
}
避免在 render 中创建对象
// 错误示例
class BadComponent extends Component {
render() {
const style = { color: 'red' }; // 每次渲染都创建新对象
return <text style={style} />;
}
}// 正确示例
class GoodComponent extends Component {
render() {
return <text style={{ color: 'red' }} />;
}
}
相关文档
- Component API
- 图形语法
- 图形属性
---
Site/Docs/Tutorial/Coordinate.En
---
title: Coordinate System
order: 5
---
A coordinate system is a 2D positioning system that combines two position scales, describing how data is mapped to the plane where graphics are located.
F2 provides two types of coordinate systems: Cartesian (rect) and Polar. All coordinate systems are 2-dimensional.
Coordinate System Types
| Type | Description | Use Cases |
|------|-------------|-----------|
| rect | Cartesian coordinate system, formed by two perpendicular x and y axes | Bar charts, line charts, scatter plots, etc. |
| polar | Polar coordinate system, formed by angle and radius dimensions | Pie charts, rose charts, radar charts, etc. |
Coordinate System Comparison
Transforming coordinate system types changes the shape of geometry marks. For example, bar charts transform into various types under different coordinate systems:
| Chart Type | Cartesian | Polar (Not Transposed) | Polar (Transposed) |
|------------|------------|------------------------|---------------------|
| Stacked Bar | | | |
| Bar | | | |
How to Set Coordinate System
F2 uses Cartesian coordinate system by default. To switch coordinate systems, set the coord attribute on the Chart component:
<Chart
data={data}
coord={{
type: 'polar',
}}
{/ ... /}
</Chart>Cartesian Coordinate System
The Cartesian coordinate system (rect) is the default coordinate system type, formed by two perpendicular x and y axes.
Configuration Syntax
<Chart
coord={{
type: 'rect', // Declare Cartesian (can be omitted, default value)
transposed: false, // Whether to transpose axes
}}
<Interval x="genre" y="sold" />
</Chart>Transposed Coordinate System
Swap x and y axes, suitable for bar charts:
<Chart
coord={{
type: 'rect',
transposed: true, // Transpose axes
}}
<Interval x="genre" y="sold" />
</Chart>Polar Coordinate System
The polar coordinate system is formed by angle and radius dimensions, suitable for visualizing periodic data such as time and direction.
Configuration Syntax
<Chart
coord={{
type: 'polar', // Declare polar coordinate system
startAngle: -Math.PI, // Start angle (optional)
endAngle: 0, // End angle (optional)
innerRadius: 0.3, // Inner radius, for donut charts (optional)
radius: 1, // Outer radius (optional)
transposed: false, // Whether to transpose (optional)
}}
{/ ... /}
</Chart>CoordConfig Type Definition
interface CoordConfig {
type?: 'rect' | 'polar'; // Coordinate system type
transposed?: boolean; // Whether to transpose
startAngle?: number; // Start angle (polar only)
endAngle?: number; // End angle (polar only)
innerRadius?: number; // Inner radius (polar only)
radius?: number; // Outer radius (polar only)
}Angle Description
The default start and end angles for F2 polar coordinates are shown below:
- Default start angle: -π (9 o'clock direction)
- Default end angle: 0 (3 o'clock direction)
Chart Examples
Pie Chart
Draw a pie chart using polar coordinates:
const data = [
{ name: 'Movie A', percent: 0.4, a: '1' },
{ name: 'Movie B', percent: 0.2, a: '1' },
{ name: 'Movie C', percent: 0.18, a: '1' },
{ name: 'Movie D', percent: 0.15, a: '1' },
{ name: 'Movie E', percent: 0.05, a: '1' },
{ name: 'Others', percent: 0.02, a: '1' },
];<Chart data={data} coord={{ type: 'polar' }}>
<Interval x="a" y="percent" color="name" coord="polar" />
</Chart>
Rose Chart
Draw a rose chart using polar coordinates:
const data = [
{ name: 'Jan', value: 30 },
{ name: 'Feb', value: 40 },
{ name: 'Mar', value: 35 },
{ name: 'Apr', value: 50 },
{ name: 'May', value: 45 },
{ name: 'Jun', value: 60 },
];<Chart data={data} coord={{ type: 'polar', transposed: true }}>
<Interval x="name" y="value" color="name" coord="polar" />
</Chart>
Donut Chart
Set inner radius to draw a donut chart:
<Chart
data={data}
coord={{
type: 'polar',
innerRadius: 0.5, // Set inner radius to 0.5
}}
<Interval x="a" y="percent" color="name" coord="polar" />
</Chart>Semi-Circle Pie Chart
Adjust start and end angles:
<Chart
data={data}
coord={{
type: 'polar',
startAngle: -Math.PI / 2, // -90 degrees
endAngle: Math.PI / 2, // 90 degrees
}}
<Interval x="a" y="percent" color="name" coord="polar" />
</Chart>Radar Chart
Use transposed mode of polar coordinates:
const data = [
{ item: 'Attack', value: 80 },
{ item: 'Defense', value: 70 },
{ item: 'Speed', value: 90 },
{ item: 'Power', value: 60 },
{ item: 'Stamina', value: 75 },
];<Chart
data={data}
scale={{
value: {
min: 0,
max: 100,
},
}}
coord={{
type: 'polar',
radius: 0.8,
}}
<Line x="item" y="value" />
<Point x="item" y="value" />
<Axis field="item" />
<Axis field="value" />
</Chart>Bar Chart
Use transposed Cartesian coordinates:
<Chart
data={data}
coord={{
type: 'rect',
transposed: true, // Transpose axes
}}
<Interval x="genre" y="sold" color="genre" />
</Chart>Stacked Bar Chart
<Chart
data={data}
coord={{
type: 'rect',
transposed: true,
}}
scale={{
sold: {
stack: true, // Enable stacking
},
}}
<Interval x="genre" y="sold" color="type" />
</Chart>Advanced Configuration
Dynamic Coordinate System Switching
class SwitchableChart extends Component {
state = {
coordType: 'rect',
}; handleSwitch = () => {
this.setState({
coordType: this.state.coordType === 'rect' ? 'polar' : 'rect',
});
};
render() {
const { coordType } = this.state;
return (
<Chart
data={data}
coord={{ type: coordType }}
>
<Interval x="genre" y="sold" color="genre" />
</Chart>
);
}
}
Custom Coordinate System
<Chart
coord={{
type: 'polar',
startAngle: -Math.PI, // Start from 9 o'clock
endAngle: 0, // End at 3 o'clock
innerRadius: 0.2, // 20% inner radius
radius: 0.9, // 90% outer radius
}}
{/ ... /}
</Chart>Common Questions
How to draw a semi-circle pie chart?
Adjust start and end angles:
coord={{
type: 'polar',
startAngle: -Math.PI / 2, // Start from top
endAngle: Math.PI / 2, // End at top
}}How to draw a donut chart?
Set the innerRadius attribute:
coord={{
type: 'polar',
innerRadius: 0.5, // 50% inner radius
}}How to draw a rose chart?
Use transposed mode of polar coordinates:
coord={{
type: 'polar',
transposed: true, // Transpose
}}How to swap x and y axes?
Use the transposed attribute:
coord={{
type: 'rect',
transposed: true, // Swap x and y axes
}}Related Documentation
- Chart Grammar
- Scale
- Core Concepts
---
Site/Docs/Tutorial/Coordinate.Zh
---
title: 坐标系
order: 5
---
坐标系是将两种位置标度结合在一起组成的 2 维定位系统,描述了数据是如何映射到图形所在的平面。
F2 提供了直角坐标系和极坐标系两种类型,所有坐标系均是 2 维的。
坐标系类型
| 类型 | 说明 | 适用场景 |
|------|------|----------|
| rect | 直角坐标系,由 x、y 两个互相垂直的坐标轴构成 | 柱状图、折线图、散点图等 |
| polar | 极坐标系,由角度和半径两个维度构成 | 饼图、玫瑰图、雷达图等 |
坐标系对比
坐标系类型的变换会改变几何标记的形状。例如,柱状图在不同坐标系下会变换成各种类型:
| 图表类型 | 直角坐标系 | 极坐标(未转置) | 极坐标(转置) |
|----------|------------|------------------|----------------|
| 层叠柱状图 | | | |
| 柱状图 | | | |
如何设置坐标系
F2 默认使用直角坐标系。切换坐标系时,在 Chart 组件上设置 coord 属性:
<Chart
data={data}
coord={{
type: 'polar',
}}
{/ ... /}
</Chart>直角坐标系
直角坐标系(笛卡尔坐标系)是默认的坐标系类型,由 x、y 两个互相垂直的坐标轴构成。
配置语法
<Chart
coord={{
type: 'rect', // 声明直角坐标系(可省略,默认值)
transposed: false, // 是否转置坐标轴
}}
<Interval x="genre" y="sold" />
</Chart>转置坐标系
将 x 轴和 y 轴交换,适用于条形图:
<Chart
coord={{
type: 'rect',
transposed: true, // 转置坐标轴
}}
<Interval x="genre" y="sold" />
</Chart>极坐标系
极坐标系由角度和半径两个维度构成,适用于周期性数据的可视化,如时间和方向数据。
配置语法
<Chart
coord={{
type: 'polar', // 声明极坐标系
startAngle: -Math.PI, // 起始弧度(可选)
endAngle: 0, // 结束弧度(可选)
innerRadius: 0.3, // 内半径,用于绘制环形图(可选)
radius: 1, // 外半径(可选)
transposed: false, // 是否转置(可选)
}}
{/ ... /}
</Chart>CoordConfig 类型定义
interface CoordConfig {
type?: 'rect' | 'polar'; // 坐标系类型
transposed?: boolean; // 是否转置
startAngle?: number; // 起始弧度(仅极坐标)
endAngle?: number; // 结束弧度(仅极坐标)
innerRadius?: number; // 内半径(仅极坐标)
radius?: number; // 外半径(仅极坐标)
}角度说明
F2 极坐标的默认起始角度和结束角度如下图所示:
- 默认起始角度:-π(9 点钟方向)
- 默认结束角度:0(3 点钟方向)
图表示例
饼图
使用极坐标系绘制饼图:
const data = [
{ name: '芳华', percent: 0.4, a: '1' },
{ name: '妖猫传', percent: 0.2, a: '1' },
{ name: '机器之血', percent: 0.18, a: '1' },
{ name: '心理罪', percent: 0.15, a: '1' },
{ name: '寻梦环游记', percent: 0.05, a: '1' },
{ name: '其他', percent: 0.02, a: '1' },
];<Chart data={data} coord={{ type: 'polar' }}>
<Interval x="a" y="percent" color="name" coord="polar" />
</Chart>
玫瑰图
使用极坐标系绘制玫瑰图:
const data = [
{ name: '一月', value: 30 },
{ name: '二月', value: 40 },
{ name: '三月', value: 35 },
{ name: '四月', value: 50 },
{ name: '五月', value: 45 },
{ name: '六月', value: 60 },
];<Chart data={data} coord={{ type: 'polar', transposed: true }}>
<Interval x="name" y="value" color="name" coord="polar" />
</Chart>
环形图
设置内半径绘制环形图:
<Chart
data={data}
coord={{
type: 'polar',
innerRadius: 0.5, // 设置内半径为 0.5
}}
<Interval x="a" y="percent" color="name" coord="polar" />
</Chart>半圆饼图
调整起始和结束角度:
<Chart
data={data}
coord={{
type: 'polar',
startAngle: -Math.PI / 2, // -90 度
endAngle: Math.PI / 2, // 90 度
}}
<Interval x="a" y="percent" color="name" coord="polar" />
</Chart>雷达图
使用极坐标系的转置模式:
const data = [
{ item: '攻击力', value: 80 },
{ item: '防御力', value: 70 },
{ item: '速度', value: 90 },
{ item: '力量', value: 60 },
{ item: '耐力', value: 75 },
];<Chart
data={data}
scale={{
value: {
min: 0,
max: 100,
},
}}
coord={{
type: 'polar',
radius: 0.8,
}}
<Line x="item" y="value" />
<Point x="item" y="value" />
<Axis field="item" />
<Axis field="value" />
</Chart>条形图
使用转置的直角坐标系:
<Chart
data={data}
coord={{
type: 'rect',
transposed: true, // 转置坐标轴
}}
<Interval x="genre" y="sold" color="genre" />
</Chart>层叠条形图
<Chart
data={data}
coord={{
type: 'rect',
transposed: true,
}}
scale={{
sold: {
stack: true, // 启用堆叠
},
}}
<Interval x="genre" y="sold" color="type" />
</Chart>高级配置
动态切换坐标系
class SwitchableChart extends Component {
state = {
coordType: 'rect',
}; handleSwitch = () => {
this.setState({
coordType: this.state.coordType === 'rect' ? 'polar' : 'rect',
});
};
render() {
const { coordType } = this.state;
return (
<Chart
data={data}
coord={{ type: coordType }}
>
<Interval x="genre" y="sold" color="genre" />
</Chart>
);
}
}
自定义坐标系统
<Chart
coord={{
type: 'polar',
startAngle: -Math.PI, // 从 9 点钟方向开始
endAngle: 0, // 到 3 点钟方向结束
innerRadius: 0.2, // 20% 内半径
radius: 0.9, // 90% 外半径
}}
{/ ... /}
</Chart>常见问题
如何绘制半圆饼图?
调整起始和结束角度:
coord={{
type: 'polar',
startAngle: -Math.PI / 2, // 顶部开始
endAngle: Math.PI / 2, // 顶部结束
}}如何绘制环形图?
设置 innerRadius 属性:
coord={{
type: 'polar',
innerRadius: 0.5, // 50% 内半径
}}如何绘制玫瑰图?
使用极坐标系的转置模式:
coord={{
type: 'polar',
transposed: true, // 转置
}}如何切换 x 和 y 轴?
使用 transposed 属性:
coord={{
type: 'rect',
transposed: true, // 交换 x 和 y 轴
}}相关文档
---
Site/Docs/Tutorial/Data.En
---
title: Data Processing
order: 3
---
Data is the most fundamental part of creating charts. F2 requires data sources to be in JSON array format, where each element is a standard JSON object.
Basic Data Format
F2's basic data format is a JSON array:
const data = [
{ year: 2010, sales: 40 },
{ year: 2011, sales: 30 },
{ year: 2012, sales: 50 },
{ year: 2013, sales: 60 },
{ year: 2014, sales: 70 },
{ year: 2015, sales: 80 },
{ year: 2016, sales: 80 },
{ year: 2017, sales: 90 },
{ year: 2018, sales: 120 },
];Using data:
<Canvas context={context}>
<Chart data={data}>
<Line x="year" y="sales" />
<Point x="year" y="sales" />
<Tooltip />
</Chart>
</Canvas>Data Format Requirements
| Requirement | Description |
|-------------|-------------|
| Array Format | Data source must be an array |
| Object Elements | Array elements must be objects |
| Field Names | Object keys serve as field names for mapping to chart properties |
| Field Values | Supports string, number, array, date, and other types |
Special Chart Data Formats
Pie Chart
When drawing a pie chart, each record in the dataset must include a constant field (and must be of string type):
const data = [
{ name: 'Movie A', percent: 0.4, a: '1' },
{ name: 'Movie B', percent: 0.2, a: '1' },
{ name: 'Movie C', percent: 0.18, a: '1' },
{ name: 'Movie D', percent: 0.15, a: '1' },
{ name: 'Movie E', percent: 0.05, a: '1' },
{ name: 'Others', percent: 0.02, a: '1' },
];<Chart data={data} coord={{ type: 'polar' }}>
<Interval x="a" y="percent" color="name" coord="polar" />
</Chart>
Why is a constant field needed?
Pie charts use polar coordinate systems where all data needs to be mapped to the same angular range. The constant field (e.g., a: '1') ensures all data points share the same angular starting position.
Interval Bar Chart
When data on the x-axis or y-axis is an array, it will automatically be mapped to an interval, creating an interval bar chart:
const data = [
{ x: 'Category 1', y: [76, 100] },
{ x: 'Category 2', y: [56, 108] },
{ x: 'Category 3', y: [38, 129] },
{ x: 'Category 4', y: [58, 155] },
{ x: 'Category 5', y: [45, 120] },
{ x: 'Category 6', y: [23, 99] },
{ x: 'Category 7', y: [18, 56] },
{ x: 'Category 8', y: [18, 34] },
];<Chart data={data}>
<Interval x="x" y="y" />
</Chart>
The array represents the minimum and maximum values of the interval: [minimum, maximum]
Candlestick Chart
Candlestick charts require open, close, highest, and lowest prices, using array format:
const data = [
{ date: '2023-01', value: [100, 110, 95, 120] }, // [open, close, lowest, highest]
{ date: '2023-02', value: [110, 105, 100, 115] },
{ date: '2023-03', value: [105, 120, 102, 125] },
];<Chart data={data}>
<Axis field="date" type="timeCat" />
<Candlestick x="date" y="value" />
</Chart>
Array format: [open, close, lowest, highest]
- open - Opening price
- close - Closing price
- lowest - Lowest price
- highest - Highest price
Scatter Plot (Bubble Chart)
Scatter plots can include additional dimensions (such as size):
const data = [
{ x: 10, y: 20, size: 5, category: 'A' },
{ x: 15, y: 25, size: 10, category: 'B' },
{ x: 20, y: 18, size: 8, category: 'A' },
];<Chart data={data}>
<Point x="x" y="y" size="size" color="category" />
</Chart>
Data Processing
Data Filtering
Before passing to Chart, you can use JavaScript array methods to filter data:
const rawData = [
{ year: 2010, sales: 40, category: 'A' },
{ year: 2011, sales: 30, category: 'B' },
{ year: 2012, sales: 50, category: 'A' },
{ year: 2013, sales: 60, category: 'B' },
];// Keep only data where category is 'A'
const data = rawData.filter(item => item.category === 'A');
<Chart data={data}>
<Line x="year" y="sales" />
</Chart>
Data Sorting
const rawData = [
{ name: 'A', value: 30 },
{ name: 'B', value: 50 },
{ name: 'C', value: 20 },
];// Sort by value in descending order
const data = [...rawData].sort((a, b) => b.value - a.value);
<Chart data={data}>
<Interval x="name" y="value" />
</Chart>
Data Aggregation
const rawData = [
{ category: 'A', value: 10 },
{ category: 'A', value: 20 },
{ category: 'B', value: 30 },
{ category: 'B', value: 40 },
];// Aggregate by category (sum)
const aggregated = {};
rawData.forEach(item => {
if (!aggregated[item.category]) {
aggregated[item.category] = 0;
}
aggregated[item.category] += item.value;
});
const data = Object.entries(aggregated).map(([category, value]) => ({
category,
value,
}));
// Result: [{ category: 'A', value: 30 }, { category: 'B', value: 70 }]
Data Transformation
const rawData = [
{ date: '2023-01-01', value: 100 },
{ date: '2023-02-01', value: 120 },
];// Transform date format
const data = rawData.map(item => ({
...item,
date: new Date(item.date),
// Or add computed fields
valueFormatted: item.value.toFixed(2),
}));
Data Updates
F2 supports dynamic data updates with animated transitions:
let chart = null;// Initial data
const data1 = [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
];
const { props } = (
<Canvas context={context}>
<Chart data={data1}>
<Interval x="genre" y="sold" />
</Chart>
</Canvas>
);
chart = new Canvas(props);
chart.render();
// Update data
const data2 = [
{ genre: 'Sports', sold: 350 },
{ genre: 'Strategy', sold: 200 },
];
const { props: newProps } = (
<Canvas context={context}>
<Chart data={data2}>
<Interval x="genre" y="sold" />
</Chart>
</Canvas>
);
chart.update(newProps); // Automatically triggers animation
Common Issues
Handling Empty Data
// Display empty state when data is empty
const data = [];if (data.length === 0) {
// Show empty state
return <EmptyState />;
}
return (
<Chart data={data}>
<Interval x="genre" y="sold" />
</Chart>
);
Handling Missing Values
const data = [
{ year: 2010, sales: 40 },
{ year: 2011, sales: null }, // Missing value
{ year: 2012, sales: 50 },
];// Filter out missing values
const cleanData = data.filter(item => item.sales != null);
// Or fill with default value
const filledData = data.map(item => ({
...item,
sales: item.sales ?? 0,
}));
Handling Large Datasets
For large datasets, consider:
1. Data Sampling: Random sampling on the frontend
2. Data Pagination: Only load current page data
3. Server-side Aggregation: Complete aggregation calculations on the server
// Data sampling example
function sampleData(data, maxSize) {
if (data.length <= maxSize) return data;
const step = Math.ceil(data.length / maxSize);
return data.filter((_, index) => index % step === 0);
}const largeData = [...]; // Large dataset
const sampledData = sampleData(largeData, 1000);
<Chart data={sampledData}>
<Line x="date" y="value" />
</Chart>
Complete Example
import { Canvas, Chart, Interval, Axis, Tooltip } from '@antv/f2';const rawData = [
{ month: 'Jan', sales: 100, profit: 20 },
{ month: 'Feb', sales: 120, profit: 25 },
{ month: 'Mar', sales: 90, profit: 15 },
{ month: 'Apr', sales: 150, profit: 35 },
{ month: 'May', sales: 180, profit: 40 },
{ month: 'Jun', sales: 200, profit: 45 },
];
// Data processing: Add profit rate field
const data = rawData.map(item => ({
...item,
profitRate: (item.profit / item.sales * 100).toFixed(2) + '%',
}));
const context = document.getElementById('container').getContext('2d');
const { props } = (
<Canvas context={context}>
<Chart
data={data}
scale={{
sales: {
min: 0,
},
}}
>
<Axis field="month" />
<Axis field="sales" />
<Interval x="month" y="sales" color="month" />
<Tooltip />
</Chart>
</Canvas>
);
const canvas = new Canvas(props);
canvas.render();
Data Source Types
Static Data
Constant data defined directly in code:
const data = [
{ x: 1, y: 2 },
{ x: 2, y: 4 },
];API Data
Fetched from remote API:
async function fetchData() {
const response = await fetch('https://api.example.com/data');
const data = await response.json(); const { props } = (
<Canvas context={context}>
<Chart data={data}>
<Interval x="category" y="value" />
</Chart>
</Canvas>
);
const canvas = new Canvas(props);
canvas.render();
}
fetchData();
User Input
Responsive to user interactions:
function updateChart(userInput) {
const data = processData(userInput); const { props: newProps } = (
<Canvas context={context}>
<Chart data={data}>
<Interval x="category" y="value" />
</Chart>
</Canvas>
);
chart.update(newProps);
}
More Examples
- Pie Chart Example
- Interval Bar Chart Example
- Candlestick Chart Example
- Dynamic Data Example
Related Documentation
- Scale
- Core Concepts
- Chart Grammar
---
Site/Docs/Tutorial/Data.Zh
---
title: 数据处理
order: 3
---
数据是绘制图表最基本的部分。F2 要求数据源为 JSON 数组格式,数组的每个元素是一个标准 JSON 对象。
基本数据格式
F2 的基本数据格式是 JSON 数组:
const data = [
{ year: 2010, sales: 40 },
{ year: 2011, sales: 30 },
{ year: 2012, sales: 50 },
{ year: 2013, sales: 60 },
{ year: 2014, sales: 70 },
{ year: 2015, sales: 80 },
{ year: 2016, sales: 80 },
{ year: 2017, sales: 90 },
{ year: 2018, sales: 120 },
];使用数据:
<Canvas context={context}>
<Chart data={data}>
<Line x="year" y="sales" />
<Point x="year" y="sales" />
<Tooltip />
</Chart>
</Canvas>数据格式要求
| 要求 | 说明 |
|------|------|
| 数组格式 | 数据源必须是数组 |
| 对象元素 | 数组元素必须是对象 |
| 字段名 | 对象的键作为字段名,用于映射到图表属性 |
| 字段值 | 支持字符串、数字、数组、日期等类型 |
特殊图表的数据格式
饼图
绘制饼图时,数据集中的每条记录必须包含一个常量字段(且必须是字符串类型):
const data = [
{ name: '芳华', percent: 0.4, a: '1' },
{ name: '妖猫传', percent: 0.2, a: '1' },
{ name: '机器之血', percent: 0.18, a: '1' },
{ name: '心理罪', percent: 0.15, a: '1' },
{ name: '寻梦环游记', percent: 0.05, a: '1' },
{ name: '其他', percent: 0.02, a: '1' },
];<Chart data={data} coord={{ type: 'polar' }}>
<Interval x="a" y="percent" color="name" coord="polar" />
</Chart>
为什么需要常量字段?
饼图使用极坐标系,所有数据需要映射到相同的角度范围。常量字段(如 a: '1')确保所有数据点共享相同的角度起始位置。
区间柱状图
当 x 轴或 y 轴的数据为数组时,会自动映射为区间,绘制区间柱状图:
const data = [
{ x: '分类一', y: [76, 100] },
{ x: '分类二', y: [56, 108] },
{ x: '分类三', y: [38, 129] },
{ x: '分类四', y: [58, 155] },
{ x: '分类五', y: [45, 120] },
{ x: '分类六', y: [23, 99] },
{ x: '分类七', y: [18, 56] },
{ x: '分类八', y: [18, 34] },
];<Chart data={data}>
<Interval x="x" y="y" />
</Chart>
数组表示区间的最小值和最大值:[最小值, 最大值]
股票图(K线图)
股票图需要包含开盘价、收盘价、最高价、最低价,使用数组格式:
const data = [
{ date: '2023-01', value: [100, 110, 95, 120] }, // [open, close, lowest, highest]
{ date: '2023-02', value: [110, 105, 100, 115] },
{ date: '2023-03', value: [105, 120, 102, 125] },
];<Chart data={data}>
<Axis field="date" type="timeCat" />
<Candlestick x="date" y="value" />
</Chart>
数组格式说明: [open, close, lowest, highest]
- open - 开盘价
- close - 收盘价
- lowest - 最低价
- highest - 最高价
散点图(气泡图)
散点图可以包含额外的维度(如大小):
const data = [
{ x: 10, y: 20, size: 5, category: 'A' },
{ x: 15, y: 25, size: 10, category: 'B' },
{ x: 20, y: 18, size: 8, category: 'A' },
];<Chart data={data}>
<Point x="x" y="y" size="size" color="category" />
</Chart>
数据处理
数据过滤
在传递给 Chart 前,可以使用 JavaScript 的数组方法过滤数据:
const rawData = [
{ year: 2010, sales: 40, category: 'A' },
{ year: 2011, sales: 30, category: 'B' },
{ year: 2012, sales: 50, category: 'A' },
{ year: 2013, sales: 60, category: 'B' },
];// 只保留 category 为 'A' 的数据
const data = rawData.filter(item => item.category === 'A');
<Chart data={data}>
<Line x="year" y="sales" />
</Chart>
数据排序
const rawData = [
{ name: 'A', value: 30 },
{ name: 'B', value: 50 },
{ name: 'C', value: 20 },
];// 按 value 降序排列
const data = [...rawData].sort((a, b) => b.value - a.value);
<Chart data={data}>
<Interval x="name" y="value" />
</Chart>
数据聚合
const rawData = [
{ category: 'A', value: 10 },
{ category: 'A', value: 20 },
{ category: 'B', value: 30 },
{ category: 'B', value: 40 },
];// 按 category 聚合求和
const aggregated = {};
rawData.forEach(item => {
if (!aggregated[item.category]) {
aggregated[item.category] = 0;
}
aggregated[item.category] += item.value;
});
const data = Object.entries(aggregated).map(([category, value]) => ({
category,
value,
}));
// 结果: [{ category: 'A', value: 30 }, { category: 'B', value: 70 }]
数据转换
const rawData = [
{ date: '2023-01-01', value: 100 },
{ date: '2023-02-01', value: 120 },
];// 转换日期格式
const data = rawData.map(item => ({
...item,
date: new Date(item.date),
// 或添加计算字段
valueFormatted: item.value.toFixed(2),
}));
数据更新
F2 支持动态更新数据,实现动画过渡效果:
let chart = null;// 初始化数据
const data1 = [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
];
const { props } = (
<Canvas context={context}>
<Chart data={data1}>
<Interval x="genre" y="sold" />
</Chart>
</Canvas>
);
chart = new Canvas(props);
chart.render();
// 更新数据
const data2 = [
{ genre: 'Sports', sold: 350 },
{ genre: 'Strategy', sold: 200 },
];
const { props: newProps } = (
<Canvas context={context}>
<Chart data={data2}>
<Interval x="genre" y="sold" />
</Chart>
</Canvas>
);
chart.update(newProps); // 自动触发动画
常见问题
空数据处理
// 数据为空时显示空状态
const data = [];if (data.length === 0) {
// 显示空状态提示
return <EmptyState />;
}
return (
<Chart data={data}>
<Interval x="genre" y="sold" />
</Chart>
);
缺失值处理
const data = [
{ year: 2010, sales: 40 },
{ year: 2011, sales: null }, // 缺失值
{ year: 2012, sales: 50 },
];// 过滤掉缺失值
const cleanData = data.filter(item => item.sales != null);
// 或使用默认值填充
const filledData = data.map(item => ({
...item,
sales: item.sales ?? 0,
}));
大数据量处理
对于大数据量,建议:
1. 数据抽样:在前端进行随机抽样
2. 数据分页:只加载当前页的数据
3. 服务端聚合:在服务端完成聚合计算
// 数据抽样示例
function sampleData(data, maxSize) {
if (data.length <= maxSize) return data;
const step = Math.ceil(data.length / maxSize);
return data.filter((_, index) => index % step === 0);
}const largeData = [...]; // 大数据集
const sampledData = sampleData(largeData, 1000);
<Chart data={sampledData}>
<Line x="date" y="value" />
</Chart>
完整示例
import { Canvas, Chart, Interval, Axis, Tooltip } from '@antv/f2';const rawData = [
{ month: '1月', sales: 100, profit: 20 },
{ month: '2月', sales: 120, profit: 25 },
{ month: '3月', sales: 90, profit: 15 },
{ month: '4月', sales: 150, profit: 35 },
{ month: '5月', sales: 180, profit: 40 },
{ month: '6月', sales: 200, profit: 45 },
];
// 数据处理:添加利润率字段
const data = rawData.map(item => ({
...item,
profitRate: (item.profit / item.sales * 100).toFixed(2) + '%',
}));
const context = document.getElementById('container').getContext('2d');
const { props } = (
<Canvas context={context}>
<Chart
data={data}
scale={{
sales: {
min: 0,
},
}}
>
<Axis field="month" />
<Axis field="sales" />
<Interval x="month" y="sales" color="month" />
<Tooltip />
</Chart>
</Canvas>
);
const canvas = new Canvas(props);
canvas.render();
数据源类型
静态数据
直接定义在代码中的常量数据:
const data = [
{ x: 1, y: 2 },
{ x: 2, y: 4 },
];API 数据
从远程 API 获取:
async function fetchData() {
const response = await fetch('https://api.example.com/data');
const data = await response.json(); const { props } = (
<Canvas context={context}>
<Chart data={data}>
<Interval x="category" y="value" />
</Chart>
</Canvas>
);
const canvas = new Canvas(props);
canvas.render();
}
fetchData();
用户输入
响应用户交互:
function updateChart(userInput) {
const data = processData(userInput); const { props: newProps } = (
<Canvas context={context}>
<Chart data={data}>
<Interval x="category" y="value" />
</Chart>
</Canvas>
);
chart.update(newProps);
}
更多示例
- 饼图示例
- 区间柱状图示例
- 股票图示例
- 动态数据示例
相关文档
---
Site/Docs/Tutorial/Event.Zh
---
title: 事件属性 - Event
order: 9
---
5.x 版本中,F2 的事件系统也得以升级,基于 PointerEvent 标准监听封装了移动端事件。得益于底层引擎的事件系统以及拾取系统,F2 支持在图形标签上直接监听常见的移动端事件。
事件属性
| 事件名 | 类型 | 描述 |
| ------------------- | ------- | -------------------------- |
| onClick | function | 点击事件 |
| onPanStart | function | 手指触摸图形时触发 0 |
| onPan | function | 手指在图形上移动时触发 |
| onPanEnd | function | 手指从图形上离开时触发 |
| onTouchStart | function | 手指触摸图形时触发 |
| onTouchMove | function | 手指在图形上移动时触发 |
| onTouchEnd | function | 手指从图形上离开时触发 |
| onTouchEndOutside | function | 手指从图形外离开时触发 |
| onPressStart | function | 手指在图形上开始按压时触发 |
| onPress | function | 手指在图形上按压时触发 |
| onPressEnd | function | 手指在图形上结束按压时触发 |
| onSwipe | function | 手指快扫时触发 |
| onPinchStart | function | 手指开始缩放时触发 |
| onPinch | function | 手指缩放时触发 |
| onPinchEnd | function | 手指结束缩放时触发 |
---
Site/Docs/Tutorial/Getting Started.En
---
title: Quick Start
order: 0
---
This guide will help you get started with F2, from installation to rendering your first chart.
Features
Starting from F2 4.0, we use declarative programming to build charts, providing a more intuitive development experience:
Declarative
Declarative programming makes code more intuitive and concise, avoiding complex API calls. F2 uses JSX syntax, which is not only easy to use but also integrates seamlessly with frameworks like React and Vue.
Component-Based
Components are essential for building complex visualizations. F2 follows React's design patterns and provides a complete set of component capabilities, making it simple to encapsulate your own components.
Installation
Install via npm
[](https://npmjs.com/package/@antv/f2) [](https://npmjs.com/package/@antv/f2)
npm install @antv/f2 --saveInstall via CDN
<script src="https://unpkg.com/@antv/f2/dist/index.min.js"></script>Configure JSX Transform
F2 uses JSX syntax to build charts, so you need to configure JSX transformation tools.
Note: If your project is already using React, refer to How to use with React
For detailed configuration instructions, see: Configure JSX Transform
One-Minute Quick Start
1. Create a canvas element
Create a <canvas> element on your page:
<canvas id="myChart" width="400" height="260"></canvas>2. Write the code
// F2 requires data in JSON array format, where each element is a standard JSON object
const data = [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 120 },
{ genre: 'Shooter', sold: 350 },
{ genre: 'Other', sold: 150 },
];// Get canvas context
const context = document.getElementById('myChart').getContext('2d');
const { props } = (
<Canvas context={context} pixelRatio={window.devicePixelRatio}>
<Chart data={data}>
<Axis field="genre" />
<Axis field="sold" />
<Interval x="genre" y="sold" color="genre" />
<Tooltip />
</Chart>
</Canvas>
);
const canvas = new Canvas(props);
canvas.render();
After completing these two steps, save the file and open it in your browser. A bar chart will be successfully rendered:
Code Analysis
Canvas Component
Canvas is the root container of the chart, responsible for providing the rendering environment:
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| context | CanvasRenderingContext2D | - | Required, Canvas 2D context |
| pixelRatio | number | window.devicePixelRatio | Device pixel ratio for high-DPI screen adaptation |
| width | number | - | Canvas width (prioritizes canvas element's width) |
| height | number | - | Canvas height (prioritizes canvas element's height) |
| animate | boolean | true | Whether to enable animation |
| children | ReactNode | - | Child components |
Chart Component
Chart is the core component of the chart, responsible for data processing and coordinate transformation:
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| data | Data[] | - | Required, data source |
| scale | ScaleConfig | - | Scale configuration |
| coord | CoordConfig | - | Coordinate system configuration |
| children | ReactNode | - | Child components |
Interval Component
Interval is used to render bar charts:
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| x | string | - | Required, x-axis field name |
| y | string | - | Required, y-axis field name |
| color | string \| Function | - | Color field or color mapping function |
Axis Component
Axis is used to configure coordinate axes:
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| field | string | - | Required, field name |
| position | string | - | Axis position (top, bottom, left, right) |
Tooltip Component
Tooltip is used to display data tooltip information.
More Examples
For more examples, see Demos.
Next Steps
- Learn about Core Concepts
- Study Chart Grammar
- View Component API
- Learn how to Use with Frameworks
---
Site/Docs/Tutorial/Getting Started.Zh
---
title: 快速上手
order: 0
---
本指南将帮助你快速上手 F2,从安装到绘制第一个图表。
特性介绍
F2 4.0 开始采用声明式编写图表,带来更直观的开发体验:
声明式
声明式编程可以让代码更直观和简洁,避免了复杂的 API 调用。F2 采用了 JSX 语法,不仅方便使用,还可以很方便地和 React、Vue 等框架结合。
组件化
为了构建复杂的可视化图表,组件是一种不可或缺的能力。F2 参考了 React 的设计模式,内置了一套完善的组件能力,能简单方便地封装自己的组件。
安装
通过 npm 安装
[](https://npmjs.com/package/@antv/f2) [](https://npmjs.com/package/@antv/f2)
npm install @antv/f2 --save通过 CDN 引入
<script src="https://unpkg.com/@antv/f2/dist/index.min.js"></script>配置 JSX 转换
F2 使用 JSX 语法构建图表,需要配置 JSX 转换工具。
注意:如果项目已经是 React,可以参考 如何在 React 中使用
详细配置说明请参考:配置 JSX Transform
一分钟上手
1. 创建 canvas 标签
在页面上创建一个 <canvas> 元素:
<canvas id="myChart" width="400" height="260"></canvas>2. 编写代码
// F2 对数据源格式的要求是 JSON 数组,数组的每个元素是一个标准 JSON 对象
const data = [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 120 },
{ genre: 'Shooter', sold: 350 },
{ genre: 'Other', sold: 150 },
];// 获取 canvas context
const context = document.getElementById('myChart').getContext('2d');
const { props } = (
<Canvas context={context} pixelRatio={window.devicePixelRatio}>
<Chart data={data}>
<Axis field="genre" />
<Axis field="sold" />
<Interval x="genre" y="sold" color="genre" />
<Tooltip />
</Chart>
</Canvas>
);
const canvas = new Canvas(props);
canvas.render();
完成上述两步之后,保存文件并用浏览器打开,一张柱状图就绘制成功了:
代码解析
Canvas 画布组件
Canvas 是图表的根容器,负责提供渲染环境:
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| context | CanvasRenderingContext2D | - | 必填,Canvas 2D 上下文 |
| pixelRatio | number | window.devicePixelRatio | 设备像素比,用于高清屏适配 |
| width | number | - | 画布宽度(优先使用 canvas 元素的 width) |
| height | number | - | 画布高度(优先使用 canvas 元素的 height) |
| animate | boolean | true | 是否开启动画 |
| children | JSX.Element | - | 通过 JSX 语法创建的 F2 组件节点(如 <Chart />) |
Chart 图表组件
Chart 是图表的核心组件,负责数据处理和坐标转换:
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| data | Data[] | - | 必填,数据源 |
| scale | ScaleConfig | - | 度量配置 |
| coord | CoordConfig | - | 坐标系配置 |
| children | JSX.Element | - | 通过 JSX 语法创建的 F2 组件节点(如 <Interval />、<Axis /> 等) |
Interval 柱状图组件
Interval 用于绘制柱状图:
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| x | string | - | 必填,x 轴字段名 |
| y | string | - | 必填,y 轴字段名 |
| color | string \| Function | - | 颜色字段或颜色映射函数 |
Axis 坐标轴组件
Axis 用于配置坐标轴:
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| field | string | - | 必填,字段名 |
| position | string | - | 坐标轴位置(top、bottom、left、right) |
Tooltip 提示框组件
Tooltip 用于显示数据提示信息。
更多示例
更多示例请查看 示例。
下一步
- 了解 核心概念
- 学习 图表语法
- 查看 组件 API
- 了解 如何在框架中使用
---
Site/Docs/Tutorial/Grammar.En
---
title: Chart Grammar
order: 2
---
Introduction
F2 is based on the graphic theory proposed in the book "The Grammar of Graphics" by Leland Wilkinson. This theory is a set of grammar rules that describe the deep characteristics of all statistical graphics, answering the question "what is a statistical graphic" by organizing the most basic elements in a bottom-up manner to form higher-level elements.
For F2, there is no concept of specific chart types. All charts are formed by combining different graphic grammar elements.
Graphic Grammar Components
F2's graphic grammar consists of the following core elements:
Data
↓
Scale
↓
Geometry + Attribute
↓
Coordinate
↓
Auxiliary Elements (Axis, Legend, Tooltip, Guide)Data
Data is the most fundamental part of visualization. F2 requires the data source to be in JSON array format:
const data = [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 120 },
{ genre: 'Shooter', sold: 350 },
{ genre: 'Other', sold: 150 },
];For detailed data processing instructions, see: Data Processing
Geometry
Geometry marks are the graphic elements you actually see in charts, such as points, lines, polygons, etc. Each geometry mark object contains multiple graphic attributes. The core of F2's graphic grammar is establishing the mapping from variables in data to graphic attributes.
Built-in Geometry Marks
| Geometry Mark | Component | Chart Type |
|---------------|-----------|------------|
| Interval | <Interval /> | Bar chart, column chart, histogram |
| Line | <Line /> | Line chart, curve chart |
| Point | <Point /> | Scatter plot, dot plot, bubble chart |
| Area | <Area /> | Area chart, interval chart |
| Candlestick | <Candlestick /> | Candlestick chart |
Geometry Examples
// Bar chart
<Interval x="genre" y="sold" color="genre" />// Line chart
<Line x="date" y="value" color="type" />
// Scatter plot
<Point x="weight" y="height" color="gender" size="value" />
// Area chart
<Area x="date" y="value" color="type" />
For detailed geometry instructions, see: Geometry
Graphic Attributes
Graphic attributes control the visual appearance of geometry marks. F2 provides the following four graphic attributes:
| Attribute | Description | Example |
|-----------|-------------|---------|
| position | Position, maps fields to x or y axis | x="genre", y="sold" |
| color | Color, supports field or function | color="genre" or color={datum => datum.value > 100 ? 'red' : 'blue'} |
| size | Size, controls point size, line thickness, etc. | size={10} or size={datum => datum.value} |
| shape | Shape, controls the shape of geometry marks | shape="circle" or shape="hollowCircle" |
Graphic Attribute Examples
// Color mapping - field
<Interval x="genre" y="sold" color="genre" />// Color mapping - function
<Point
x="weight"
y="height"
color={datum => datum.weight > 70 ? 'red' : 'blue'}
/>
// Size mapping
<Point x="category" y="value" size={datum => datum.value} />
// Shape mapping
<Point x="category" y="value" shape="circle" />
For detailed graphic attribute instructions, see: Shape Attributes
Scale
Scale serves as the bridge for converting from data space to graphic attribute space. Each graphic attribute corresponds to one or more scales.
Scale Types
| Type | Description | Use Case |
|------|-------------|----------|
| linear | Linear scale | Continuous numeric data |
| cat | Category scale | Categorical data |
| time | Time scale | Time/date data |
| log | Logarithmic scale | Exponential growth data |
| pow | Power scale | Data emphasizing differences |
Scale Configuration Examples
<Chart
data={data}
scale={{
sold: {
type: 'linear',
min: 0,
max: 500,
tickCount: 5,
},
genre: {
type: 'cat',
},
date: {
type: 'time',
mask: 'YYYY-MM-DD',
},
}}
{/ ... /}
</Chart>For detailed scale instructions, see: Scale
Coordinate
Coordinate describes how data is mapped to the plane where the graphic is located. A geometry mark will have different appearances under different coordinate systems.
Coordinate Types
| Type | Description | Use Case |
|------|-------------|----------|
| rect | Cartesian coordinate system (default) | Bar charts, line charts, scatter plots, etc. |
| polar | Polar coordinate system | Pie charts, rose charts, radar charts, etc. |
| helix | Helix coordinate system | Special visualization scenarios |
Coordinate Configuration Examples
// Cartesian coordinate system (default)
<Chart data={data}>
<Interval x="genre" y="sold" />
</Chart>// Polar coordinate system - pie chart
<Chart data={data} coord={{ type: 'polar' }}>
<Interval x="genre" y="sold" color="genre" coord="polar" />
</Chart>
// Polar coordinate system - rose chart
<Chart data={data} coord={{ type: 'polar', innerRadius: 0.3 }}>
<Interval x="genre" y="sold" color="genre" coord="polar" />
</Chart>
For detailed coordinate instructions, see: Coordinate
Auxiliary Elements
Auxiliary elements are used to enhance the readability and comprehensibility of charts, including:
| Component | Description |
|-----------|-------------|
| Axis | Coordinate axis, displaying data ticks and labels |
| Legend | Legend, indicating different data types |
| Tooltip | Tooltip, displaying detailed data information |
| Guide | Guide mark, adding auxiliary lines, text, etc. |
Auxiliary Element Examples
<Chart data={data}>
<Axis field="genre" />
<Axis field="sold" />
<Interval x="genre" y="sold" color="genre" />
<Tooltip />
<Legend />
</Chart>Complete Example
The following is an example using the complete graphic grammar:
const data = [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 120 },
{ genre: 'Shooter', sold: 350 },
{ genre: 'Other', sold: 150 },
];const context = document.getElementById('container').getContext('2d');
const { props } = (
<Canvas context={context}>
<Chart
data={data}
scale={{
sold: {
min: 0,
tickInterval: 50,
},
}}
>
<Axis field="genre" />
<Axis field="sold" />
<Interval x="genre" y="sold" color="genre" />
<Tooltip />
<Legend />
</Chart>
</Canvas>
);
const canvas = new Canvas(props);
canvas.render();
Graphic Grammar Mapping
The graphic grammar mapping relationship in the above example:
| Level | Element | Description |
|-------|---------|-------------|
| Data | data | Sales data in JSON array format |
| Scale | scale | sold field uses linear scale with minimum value of 0 |
| Geometry | <Interval /> | Uses bar chart geometry mark |
| Graphic Attributes | x, y, color | genre maps to x-axis, sold maps to y-axis, genre maps to color |
| Coordinate | Default rect | Uses Cartesian coordinate system |
| Auxiliary Elements | <Axis />, <Tooltip />, <Legend /> | Adds coordinate axis, tooltip, and legend |
Summary
In F2, a chart is a mapping from data to the graphic attributes of geometry mark objects. After understanding the graphic grammar, you can:
1. Flexible Combination: Create various charts by combining different geometry marks and graphic attributes
2. Precise Control: Precisely control chart appearance through scales, coordinates, and other elements
3. Quick Extension: Quickly create new visualization types based on graphic grammar
More Content
- Core Concepts
- Data Processing
- Scale
- Geometry
- Shape Attributes
- Coordinate
---
Site/Docs/Tutorial/Grammar.Zh
---
title: 图形语法
order: 2
---
简介
F2 基于《The Grammar of Graphics》(Leland Wilkinson 著)一书提出的图形理论。该理论是一套用来描述所有统计图形深层特性的语法规则,回答了"什么是统计图形"这一问题,以自底向上的方式组织最基本的元素形成更高级的元素。
对于 F2 来说,没有具体的图表类型的概念,所有的图表都是通过组合不同的图形语法元素形成的。
图形语法组成
F2 的图形语法由以下核心元素组成:
数据 (Data)
↓
度量 (Scale)
↓
几何标记 (Geometry) + 图形属性 (Attribute)
↓
坐标系 (Coordinate)
↓
辅助元素 (Axis, Legend, Tooltip, Guide)数据
数据是可视化最基础的部分。F2 要求数据源为 JSON 数组格式:
const data = [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 120 },
{ genre: 'Shooter', sold: 350 },
{ genre: 'Other', sold: 150 },
];数据处理详细说明请参考:数据处理
几何标记
几何标记是图表中实际看到的图形元素,如点、线、多边形等。每个几何标记对象含有多个图形属性,F2 图形语法的核心就是建立数据中的变量到图形属性的映射。
内置几何标记
| 几何标记 | 组件 | 图表类型 |
|----------|------|----------|
| Interval | <Interval /> | 柱状图、条形图、直方图 |
| Line | <Line /> | 折线图、曲线图 |
| Point | <Point /> | 散点图、点图、气泡图 |
| Area | <Area /> | 面积图、区间图 |
| Candlestick | <Candlestick /> | 蜡烛图(K线图) |
几何标记示例
// 柱状图
<Interval x="genre" y="sold" color="genre" />// 折线图
<Line x="date" y="value" color="type" />
// 散点图
<Point x="weight" y="height" color="gender" size="value" />
// 面积图
<Area x="date" y="value" color="type" />
几何标记详细说明请参考:Geometry
图形属性
图形属性控制几何标记的视觉表现。F2 提供以下四种图形属性:
| 属性 | 说明 | 示例 |
|------|------|------|
| position | 位置,将字段映射到 x 或 y 轴 | x="genre", y="sold" |
| color | 颜色,支持字段或函数 | color="genre" 或 color={datum => datum.value > 100 ? 'red' : 'blue'} |
| size | 大小,控制点的大小、线的粗细等 | size={10} 或 size={datum => datum.value} |
| shape | 形状,控制几何标记的形状 | shape="circle" 或 shape="hollowCircle" |
图形属性示例
// 颜色映射 - 字段
<Interval x="genre" y="sold" color="genre" />// 颜色映射 - 函数
<Point
x="weight"
y="height"
color={datum => datum.weight > 70 ? 'red' : 'blue'}
/>
// 大小映射
<Point x="category" y="value" size={datum => datum.value} />
// 形状映射
<Point x="category" y="value" shape="circle" />
图形属性详细说明请参考:绘图属性
度量
度量(Scale)作为数据空间到图形属性空间的转换桥梁,每一个图形属性都对应着一个或多个度量。
度量类型
| 类型 | 说明 | 适用场景 |
|------|------|----------|
| linear | 线性度量 | 连续数值型数据 |
| cat | 分类度量 | 分类数据 |
| time | 时间度量 | 时间日期数据 |
| log | 对数度量 | 指数级增长数据 |
| pow | 指数度量 | 需要强调差异的数据 |
度量配置示例
<Chart
data={data}
scale={{
sold: {
type: 'linear',
min: 0,
max: 500,
tickCount: 5,
},
genre: {
type: 'cat',
},
date: {
type: 'time',
mask: 'YYYY-MM-DD',
},
}}
{/ ... /}
</Chart>度量详细说明请参考:度量
坐标系
坐标系描述了数据是如何映射到图形所在的平面的。一个几何标记在不同坐标系下会有不同的表现。
坐标系类型
| 类型 | 说明 | 适用场景 |
|------|------|----------|
| rect | 直角坐标系(默认) | 柱状图、折线图、散点图等 |
| polar | 极坐标系 | 饼图、玫瑰图、雷达图等 |
| helix | 螺旋坐标系 | 特殊可视化场景 |
坐标系配置示例
// 直角坐标系(默认)
<Chart data={data}>
<Interval x="genre" y="sold" />
</Chart>// 极坐标系 - 饼图
<Chart data={data} coord={{ type: 'polar' }}>
<Interval x="genre" y="sold" color="genre" coord="polar" />
</Chart>
// 极坐标系 - 玫瑰图
<Chart data={data} coord={{ type: 'polar', innerRadius: 0.3 }}>
<Interval x="genre" y="sold" color="genre" coord="polar" />
</Chart>
坐标系详细说明请参考:坐标系
辅助元素
辅助元素用于增强图表的可读性和可理解性,包括:
| 组件 | 说明 |
|------|------|
| Axis | 坐标轴,显示数据刻度和标签 |
| Legend | 图例,标定不同数据类型 |
| Tooltip | 提示框,显示详细数据信息 |
| Guide | 辅助标记,添加辅助线、文本等 |
辅助元素示例
<Chart data={data}>
<Axis field="genre" />
<Axis field="sold" />
<Interval x="genre" y="sold" color="genre" />
<Tooltip />
<Legend />
</Chart>完整示例
下面是一个使用完整图形语法的示例:
const data = [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 120 },
{ genre: 'Shooter', sold: 350 },
{ genre: 'Other', sold: 150 },
];const context = document.getElementById('container').getContext('2d');
const { props } = (
<Canvas context={context}>
<Chart
data={data}
scale={{
sold: {
min: 0,
tickInterval: 50,
},
}}
>
<Axis field="genre" />
<Axis field="sold" />
<Interval x="genre" y="sold" color="genre" />
<Tooltip />
<Legend />
</Chart>
</Canvas>
);
const canvas = new Canvas(props);
canvas.render();
图形语法映射
上述示例的图形语法映射关系:
| 层级 | 元素 | 说明 |
|------|------|------|
| 数据 | data | JSON 数组格式的销售数据 |
| 度量 | scale | sold 字段使用线性度量,最小值为 0 |
| 几何标记 | <Interval /> | 使用柱状图几何标记 |
| 图形属性 | x, y, color | genre 映射到 x 轴,sold 映射到 y 轴,genre 映射到颜色 |
| 坐标系 | 默认 rect | 使用直角坐标系 |
| 辅助元素 | <Axis />, <Tooltip />, <Legend /> | 添加坐标轴、提示框和图例 |
总结
在 F2 中,一张图表就是从数据到几何标记对象的图形属性的一个映射。理解图形语法后,你可以:
1. 灵活组合:通过组合不同的几何标记和图形属性创建各种图表
2. 精确控制:通过度量、坐标系等元素精确控制图表表现
3. 快速扩展:基于图形语法快速创建新的可视化类型
更多内容
- 核心概念
- 数据处理
- 度量
- 几何标记
- 绘图属性
- 坐标系
---
Site/Docs/Tutorial/Graphic.Zh
---
title: 图形使用 - JSX
order: 9
---
在 F2 里,可以利用 JSX 和图形标签 Shape更方便构造自定义图形。
基础用法
创建自定义图形
/ @jsx jsx */
import { jsx, Canvas } from '@antv/f2';const context = document.getElementById('container').getContext('2d');
const Hello = () => {
return (
<group>
<rect
style={{
x: 10,
y: 10,
width: 40,
height: 40,
lineWidth: '2px',
stroke: '#000',
fill: 'red',
}}
/>
<circle
style={{
cx: 80,
cy: 30,
r: 20,
lineWidth: '2px',
stroke: '#000',
fill: 'red',
}}
/>
<text
style={{
x: 120,
y: 30,
text: '文本',
fontSize: 20,
fill: '#000',
}}
/>
</group>
);
};
const { props } = (
<Canvas context={context} pixelRatio={window.devicePixelRatio}>
<Hello />
</Canvas>
);
const chart = new Canvas(props);
chart.render();
以上就可以利用标签绘制各种自定义元素。
使用组件
假如想让自定义图形走组件 Component 渲染,拥有生命周期,可以监测数据变化,可以参考组件介绍。
使用 Class 组件
/ @jsx jsx */
import { jsx, Canvas, Component } from '@antv/f2';const context = document.getElementById('container').getContext('2d');
class CustomShape extends Component {
render() {
const { x, y, color } = this.props;
return (
<group>
<rect
style={{
x,
y,
width: 50,
height: 50,
fill: color,
}}
/>
<text
style={{
x: x + 15,
y: y + 30,
text: '自定义',
fontSize: 14,
fill: '#fff',
}}
/>
</group>
);
}
}
const Page = () => {
return (
<group>
<CustomShape x={10} y={10} color="#1890ff" />
<CustomShape x={80} y={10} color="#f5222d" />
<CustomShape x={150} y={10} color="#52c41a" />
</group>
);
};
const { props } = (
<Canvas context={context} pixelRatio={window.devicePixelRatio}>
<Page />
</Canvas>
);
const chart = new Canvas(props);
chart.render();
使用函数组件
/ @jsx jsx */
import { jsx, Canvas } from '@antv/f2';const context = document.getElementById('container').getContext('2d');
const CustomRect = ({ x, y, width, height, color, text }) => {
return (
<group>
<rect
style={{
x,
y,
width,
height,
fill: color,
stroke: '#000',
lineWidth: 2,
}}
/>
<text
style={{
x: x + width / 2 - 20,
y: y + height / 2,
text,
fontSize: 16,
fill: '#fff',
}}
/>
</group>
);
};
const App = () => {
return (
<group>
<CustomRect x={10} y={10} width={80} height={50} color="#1890ff" text="蓝色" />
<CustomRect x={110} y={10} width={80} height={50} color="#f5222d" text="红色" />
</group>
);
};
const { props } = (
<Canvas context={context} pixelRatio={window.devicePixelRatio}>
<App />
</Canvas>
);
const chart = new Canvas(props);
chart.render();
传递数据
通过 props 传递数据
/ @jsx jsx */
import { jsx, Canvas } from '@antv/f2';const context = document.getElementById('container').getContext('2d');
const Bar = ({ data, index, x }) => {
const { name, value } = data;
const height = value * 2;
const y = 200 - height;
return (
<group>
<rect
style={{
x,
y,
width: 40,
height,
fill: index % 2 === 0 ? '#1890ff' : '#f5222d',
}}
/>
<text
style={{
x: x + 10,
y: y - 10,
text: ${value},
fontSize: 12,
fill: '#000',
}}
/>
<text
style={{
x: x + 5,
y: 220,
text: name,
fontSize: 12,
fill: '#666',
}}
/>
</group>
);
};
const Chart = ({ data }) => {
return (
<group>
{data.map((item, index) => (
<Bar key={index} data={item} index={index} x={10 + index * 60} />
))}
</group>
);
};
const data = [
{ name: 'A', value: 30 },
{ name: 'B', value: 50 },
{ name: 'C', value: 40 },
{ name: 'D', value: 60 },
];
const { props } = (
<Canvas context={context} pixelRatio={window.devicePixelRatio} width={400} height={300}>
<Chart data={data} />
</Canvas>
);
const chart = new Canvas(props);
chart.render();
使用 state 管理状态
/ @jsx jsx */
import { jsx, Canvas, Component } from '@antv/f2';const context = document.getElementById('container').getContext('2d');
class InteractiveShape extends Component {
state = {
color: '#1890ff',
scale: 1,
};
handleClick = () => {
this.setState({
color: this.state.color === '#1890ff' ? '#f5222d' : '#1890ff',
});
};
render() {
const { x, y } = this.props;
const { color, scale } = this.state;
const size = 50 * scale;
return (
<group
style={{
x,
y,
cursor: 'pointer',
}}
onTap={this.handleClick}
>
<rect
style={{
x: -size / 2,
y: -size / 2,
width: size,
height: size,
fill: color,
}}
/>
<text
style={{
x: -15,
y: 5,
text: '点击',
fontSize: 14,
fill: '#fff',
}}
/>
</group>
);
}
}
const Page = () => {
return (
<group>
<InteractiveShape x={100} y={100} />
</group>
);
};
const { props } = (
<Canvas context={context} pixelRatio={window.devicePixelRatio} width={300} height={300}>
<Page />
</Canvas>
);
const chart = new Canvas(props);
chart.render();
使用坐标变换
旋转和缩放
/ @jsx jsx */
import { jsx, Canvas } from '@antv/f2';const context = document.getElementById('container').getContext('2d');
const RotatedRect = ({ x, y, angle, color }) => {
return (
<group
style={{
x,
y,
transform: rotate(${angle}deg),
}}
>
<rect
style={{
x: -25,
y: -25,
width: 50,
height: 50,
fill: color,
}}
/>
</group>
);
};
const App = () => {
return (
<group>
<RotatedRect x={100} y={100} angle={0} color="#1890ff" />
<RotatedRect x={200} y={100} angle={45} color="#f5222d" />
<RotatedRect x={300} y={100} angle={90} color="#52c41a" />
</group>
);
};
const { props } = (
<Canvas context={context} pixelRatio={window.devicePixelRatio} width={400} height={300}>
<App />
</Canvas>
);
const chart = new Canvas(props);
chart.render();
使用渐变和纹理
线性渐变
/ @jsx jsx */
import { jsx, Canvas } from '@antv/f2';const context = document.getElementById('container').getContext('2d');
const GradientRect = () => {
return (
<rect
style={{
x: 50,
y: 50,
width: 200,
height: 100,
fill: 'linear-gradient(90deg, #1890ff, #f5222d)',
}}
/>
);
};
const { props } = (
<Canvas context={context} pixelRatio={window.devicePixelRatio} width={300} height={200}>
<GradientRect />
</Canvas>
);
const chart = new Canvas(props);
chart.render();
径向渐变
/ @jsx jsx */
import { jsx, Canvas } from '@antv/f2';const context = document.getElementById('container').getContext('2d');
const GradientCircle = () => {
return (
<circle
style={{
cx: 150,
cy: 100,
r: 80,
fill: 'radial-gradient(circle at center, #fff, #1890ff)',
}}
/>
);
};
const { props } = (
<Canvas context={context} pixelRatio={window.devicePixelRatio} width={300} height={200}>
<GradientCircle />
</Canvas>
);
const chart = new Canvas(props);
chart.render();
与图表结合
自定义图表元素
/ @jsx jsx */
import { jsx, Canvas, Chart, Interval, Axis } from '@antv/f2';const context = document.getElementById('container').getContext('2d');
const data = [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 120 },
{ genre: 'Shooter', sold: 350 },
{ genre: 'Other', sold: 150 },
];
const Page = () => {
return (
<Chart data={data} scale={{ sold: { min: 0 } }}>
<Axis field="genre" />
<Axis field="sold" />
<Interval x="genre" y="sold" />
{/ 自定义标题 /}
<text
style={{
x: 150,
y: 30,
text: '游戏销量统计',
fontSize: 18,
fill: '#000',
textAlign: 'center',
}}
/>
</Chart>
);
};
const { props } = (
<Canvas context={context} pixelRatio={window.devicePixelRatio} width={300} height={300}>
<Page />
</Canvas>
);
const chart = new Canvas(props);
chart.render();
常见问题
如何让自定义图形支持交互?
在 group 或图形标签上添加事件处理器:
<group
style={{ cursor: 'pointer' }}
onTap={() => console.log('点击了图形')}
onPress={() => console.log('按住了图形')}
<rect style={{ x: 10, y: 10, width: 50, height: 50, fill: 'blue' }} />
</group>如何让自定义图形具有动画效果?
使用 animation 属性:
<rect
style={{
x: 10,
y: 10,
width: 50,
height: 50,
fill: 'blue',
animation: {
appear: {
easing: 'linear',
duration: 1000,
property: ['y', 'height'],
start: { y: 200, height: 0 },
end: { y: 10, height: 50 },
},
},
}}
/>如何在自定义图形中使用图表的计算逻辑?
参考 自定义 View。
相关文档
- 图形标签
- 绘图属性
- 图形动画
- 图形事件
- 组件介绍
- 自定义 View
---
Site/Docs/Tutorial/Scale.En
---
title: Scale
order: 4
---
Scale is the conversion bridge between data space and graphic space, responsible for converting raw data to values in the [0, 1] range and vice versa. Different data types correspond to different scale types.
Scale Types
Based on data types, F2 supports the following scale types:
| Type | Description | Use Cases |
|------|-------------|-----------|
| identity | Constant type, where a data field remains unchanged | Constant fields |
| linear | Continuous numbers, such as [1, 2, 3, 4, 5] | Continuous numerical data |
| cat | Categorical, such as ['Male', 'Female'] | Categorical data |
| timeCat | Time type | Time and date data |
How to Set Scale
Define scales through the scale property of the Chart component:
const data = [
{ a: 'a', b: 20 },
{ a: 'b', b: 12 },
{ a: 'c', b: 8 },
];<Chart
data={data}
scale={{
a: {
type: 'cat', // Declare field a as categorical type
},
b: {
min: 0, // Manually specify minimum value
max: 100, // Manually specify maximum value
},
}}
<Interval x="a" y="b" />
</Chart>Common Properties
Common properties supported by all scale types:
| Property | Type | Description |
|----------|------|-------------|
| type | string | Scale type: identity, linear, cat, timeCat |
| formatter | Function | Format tick point text, affects axis, legend, and tooltip display |
| range | Array | Output range in format [min, max], defaults to [0, 1] |
| alias | string | Display alias for the field, used for converting English names to Chinese names |
| tickCount | number | Number of tick points on the axis |
| ticks | Array | Specify the text information for tick points |
Linear Scale
For continuous numerical data.
Configuration Properties
| Property | Type | Description |
|----------|------|-------------|
| nice | boolean | Optimize numeric range to make tick marks evenly distributed, defaults to true |
| min | number | Minimum value of numeric range |
| max | number | Maximum value of numeric range |
| tickInterval | number | Interval between tick points, mutually exclusive with tickCount |
Configuration Examples
// Basic configuration
<Chart
scale={{
value: {
type: 'linear',
min: 0,
max: 100,
tickCount: 5,
},
}}
<Line x="date" y="value" />
</Chart>// Using tickInterval
<Chart
scale={{
value: {
type: 'linear',
min: 0,
max: 100,
tickInterval: 20, // 0, 20, 40, 60, 80, 100
},
}}
<Line x="date" y="value" />
</Chart>// Using nice to optimize range
<Chart
scale={{
value: {
type: 'linear',
nice: true, // [3, 97] → [0, 100]
},
}}
<Line x="date" y="value" />
</Chart>// Using formatter for formatting
<Chart
scale={{
value: {
type: 'linear',
formatter: (val) => ${val}%,
},
}}
<Line x="date" y="value" />
</Chart>Type Definition
interface LinearScaleConfig {
type?: 'linear';
min?: number;
max?: number;
nice?: boolean;
tickCount?: number;
tickInterval?: number;
range?: [number, number];
alias?: string;
formatter?: (value: number) => string;
ticks?: number[];
}Cat Scale
For categorical data.
Configuration Properties
| Property | Type | Description |
|----------|------|-------------|
| values | Array | Specify the order of categorical values |
| isRounding | boolean | Whether to allow rounding to satisfy even tick distribution, defaults to false |
Configuration Examples
// Basic configuration
<Chart
scale={{
genre: {
type: 'cat',
},
}}
<Interval x="genre" y="sold" />
</Chart>// Specify category order
<Chart
scale={{
level: {
type: 'cat',
values: ['Minimum', 'Moderate', 'Maximum'],
},
}}
<Interval x="level" y="value" />
</Chart>values Property Use Cases
Scenario 1: Specify Category Order
const data = [
{ level: 'max', value: 100 },
{ level: 'min', value: 10 },
{ level: 'mid', value: 50 },
];<Chart
data={data}
scale={{
level: {
type: 'cat',
values: ['min', 'mid', 'max'], // Display in specified order
},
}}
<Interval x="level" y="value" />
</Chart>Scenario 2: Numeric to Category Mapping (Index Mapping)
const data = [
{ month: 0, value: 7 },
{ month: 1, value: 12 },
{ month: 2, value: 18 },
];<Chart
data={data}
scale={{
month: {
type: 'cat',
values: ['January', 'February', 'March'], // month values serve as indices
},
}}
<Line x="month" y="value" />
</Chart>TimeCat Scale
For time and date data, sorts data by default.
Configuration Properties
| Property | Type | Description |
|----------|------|-------------|
| nice | boolean | Whether to optimize ticks for better readability |
| mask | string | Time format, defaults to 'YYYY-MM-DD' |
| sortable | boolean | Whether to sort, defaults to true. Can be set to false for pre-sorted data to improve performance |
| values | Array | Specify the order of specific time values |
Configuration Examples
// Basic configuration
<Chart
scale={{
date: {
type: 'timeCat',
mask: 'YYYY-MM-DD',
},
}}
<Line x="date" y="value" />
</Chart>// Custom time format
<Chart
scale={{
date: {
type: 'timeCat',
mask: 'MM/DD', // 01/15
},
}}
<Line x="date" y="value" />
</Chart>// Performance optimization: data already sorted
<Chart
data={sortedData}
scale={{
date: {
type: 'timeCat',
sortable: false, // Skip sorting, improve performance
},
}}
<Line x="date" y="value" />
</Chart>// Specify time order
<Chart
scale={{
quarter: {
type: 'cat',
values: ['Q1', 'Q2', 'Q3', 'Q4'],
},
}}
<Interval x="quarter" y="value" />
</Chart>Type Definition
interface TimeCatScaleConfig {
type?: 'timeCat';
nice?: boolean;
mask?: string;
sortable?: boolean;
tickCount?: number;
values?: string[];
range?: [number, number];
alias?: string;
formatter?: (value: string | Date) => string;
ticks?: string[];
}Common Configuration Scenarios
Set Axis Range
<Chart
scale={{
value: {
min: 0, // Set minimum value
max: 100, // Set maximum value
tickCount: 5, // 5 tick points
},
}}
<Line x="date" y="value" />
</Chart>Format Tick Labels
<Chart
scale={{
value: {
formatter: (val) => ${val}K,
},
date: {
formatter: (val) => {
const date = new Date(val);
return ${date.getMonth() + 1}/${date.getDate()};
},
},
}}
<Line x="date" y="value" />
<Axis field="value" />
<Axis field="date" />
</Chart>Set Tick Interval
<Chart
scale={{
value: {
min: 0,
max: 100,
tickInterval: 25, // 0, 25, 50, 75, 100
},
}}
<Line x="date" y="value" />
</Chart>Custom Tick Values
<Chart
scale={{
value: {
ticks: [0, 25, 50, 75, 100], // Custom tick values
},
}}
<Line x="date" y="value" />
</Chart>Multiple Scale Configurations
<Chart
scale={{
// x-axis: categorical scale
genre: {
type: 'cat',
values: ['Sports', 'Strategy', 'Action', 'Shooter', 'Other'],
},
// y-axis: linear scale
sold: {
type: 'linear',
min: 0,
nice: true,
},
// color: categorical scale
color: {
type: 'cat',
},
}}
<Interval x="genre" y="sold" color="genre" />
</Chart>Advanced Configuration
Range Control
Control the position where data maps to graphics:
<Chart
scale={{
value: {
min: 0,
max: 100,
range: [0, 0.8], // Leave 20% space at the top
},
}}
<Interval x="genre" y="sold" />
</Chart>Alias Setting
Used to convert English field names to Chinese names:
<Chart
scale={{
genre: {
alias: 'Type', // Display alias in legend, tooltip, etc.
},
sold: {
alias: 'Sales',
},
}}
<Interval x="genre" y="sold" />
<Legend />
<Tooltip />
</Chart>Dynamic Scale Configuration
class DynamicChart extends Component {
state = {
maxValue: 100,
}; updateMaxValue = () => {
this.setState({
maxValue: 200,
});
};
render() {
const { maxValue } = this.state;
return (
<Chart
data={data}
scale={{
value: {
type: 'linear',
max: maxValue,
},
}}
>
<Interval x="genre" y="sold" />
</Chart>
);
}
}
Type Definitions
Complete ScaleConfig Type
interface ScaleConfig {
type?: 'linear' | 'cat' | 'timeCat' | 'identity'; // Common properties
range?: [number, number];
alias?: string;
formatter?: (value: any) => string;
tickCount?: number;
ticks?: any[];
// linear specific
min?: number;
max?: number;
nice?: boolean;
tickInterval?: number;
// cat specific
values?: any[];
isRounding?: boolean;
// timeCat specific
mask?: string;
sortable?: boolean;
}
interface ChartScaleConfig {
[fieldName: string]: ScaleConfig;
}
Common Questions
How to set axis to start from 0?
scale={{
value: {
min: 0, // Set minimum value to 0
},
}}How to set tick interval?
Use the tickInterval property:
scale={{
value: {
tickInterval: 20,
},
}}How to customize tick labels?
Use formatter or ticks:
// Method 1: formatter
scale={{
value: {
formatter: (val) => ${val}K,
},
}}// Method 2: ticks
scale={{
value: {
ticks: [0, 25, 50, 75, 100],
},
}}
How to optimize performance for sorted time data?
Set sortable: false to skip sorting:
scale={{
date: {
type: 'timeCat',
sortable: false,
},
}}Can mask and formatter be used together?
No. If both are set, formatter takes precedence and mask will not take effect.
Related Documentation
- Coordinate System
- Chart Grammar
- Core Concepts
---
Site/Docs/Tutorial/Scale.Zh
---
title: 度量
order: 4
---
度量(Scale)是数据空间到图形空间的转换桥梁,负责原始数据到 [0, 1] 区间数值的相互转换工作。针对不同的数据类型对应不同类型的度量。
度量类型
根据数据类型,F2 支持以下几种度量类型:
| 类型 | 说明 | 适用场景 |
|------|------|----------|
| identity | 常量类型数值,数据字段是不变的常量 | 常量字段 |
| linear | 连续数字,如 [1, 2, 3, 4, 5] | 连续数值型数据 |
| cat | 分类,如 ['男', '女'] | 分类数据 |
| timeCat | 时间类型 | 时间日期数据 |
如何设置度量
通过 Chart 组件的 scale 属性定义度量:
const data = [
{ a: 'a', b: 20 },
{ a: 'b', b: 12 },
{ a: 'c', b: 8 },
];<Chart
data={data}
scale={{
a: {
type: 'cat', // 声明 a 字段为分类类型
},
b: {
min: 0, // 手动指定最小值
max: 100, // 手动指定最大值
},
}}
<Interval x="a" y="b" />
</Chart>通用属性
所有度量类型都支持的通用属性:
| 属性 | 类型 | 说明 |
|------|------|------|
| type | string | 度量类型:identity、linear、cat、timeCat |
| formatter | Function | 格式化刻度点文本,影响坐标轴、图例、tooltip 显示 |
| range | Array | 输出范围,格式为 [min, max],默认 [0, 1] |
| alias | string | 字段显示别名,用于英文名称转中文名称 |
| tickCount | number | 坐标轴刻度点个数 |
| ticks | Array | 指定刻度点的文本信息 |
Linear 度量
用于连续数值型数据。
配置属性
| 属性 | 类型 | 说明 |
|------|------|------|
| nice | boolean | 优化数值范围,使刻度线均匀分布,默认 true |
| min | number | 数值范围最小值 |
| max | number | 数值范围最大值 |
| tickInterval | number | 刻度点间距,与 tickCount 互斥 |
配置示例
// 基础配置
<Chart
scale={{
value: {
type: 'linear',
min: 0,
max: 100,
tickCount: 5,
},
}}
<Line x="date" y="value" />
</Chart>// 使用 tickInterval
<Chart
scale={{
value: {
type: 'linear',
min: 0,
max: 100,
tickInterval: 20, // 0, 20, 40, 60, 80, 100
},
}}
<Line x="date" y="value" />
</Chart>// 使用 nice 优化范围
<Chart
scale={{
value: {
type: 'linear',
nice: true, // [3, 97] → [0, 100]
},
}}
<Line x="date" y="value" />
</Chart>// 使用 formatter 格式化
<Chart
scale={{
value: {
type: 'linear',
formatter: (val) => ${val}%,
},
}}
<Line x="date" y="value" />
</Chart>类型定义
interface LinearScaleConfig {
type?: 'linear';
min?: number;
max?: number;
nice?: boolean;
tickCount?: number;
tickInterval?: number;
range?: [number, number];
alias?: string;
formatter?: (value: number) => string;
ticks?: number[];
}Cat 度量
用于分类数据。
配置属性
| 属性 | 类型 | 说明 |
|------|------|------|
| values | Array | 指定分类值顺序 |
| isRounding | boolean | 是否允许取整以满足刻度均匀分布,默认 false |
配置示例
// 基础配置
<Chart
scale={{
genre: {
type: 'cat',
},
}}
<Interval x="genre" y="sold" />
</Chart>// 指定分类顺序
<Chart
scale={{
level: {
type: 'cat',
values: ['最小', '适中', '最大'],
},
}}
<Interval x="level" y="value" />
</Chart>values 属性使用场景
场景 1:指定分类顺序
const data = [
{ level: 'max', value: 100 },
{ level: 'min', value: 10 },
{ level: 'mid', value: 50 },
];<Chart
data={data}
scale={{
level: {
type: 'cat',
values: ['min', 'mid', 'max'], // 按指定顺序显示
},
}}
<Interval x="level" y="value" />
</Chart>场景 2:数值转分类(索引映射)
const data = [
{ month: 0, value: 7 },
{ month: 1, value: 12 },
{ month: 2, value: 18 },
];<Chart
data={data}
scale={{
month: {
type: 'cat',
values: ['一月', '二月', '三月'], // month 值作为索引
},
}}
<Line x="month" y="value" />
</Chart>TimeCat 度量
用于时间日期数据,默认会对数据排序。
配置属性
| 属性 | 类型 | 说明 |
|------|------|------|
| nice | boolean | 是否优化 ticks,使刻度更易理解 |
| mask | string | 时间格式,默认 'YYYY-MM-DD' |
| sortable | boolean | 是否排序,默认 true,已排序数据可设为 false 提升性能 |
| values | Array | 指定具体的时间值顺序 |
配置示例
// 基础配置
<Chart
scale={{
date: {
type: 'timeCat',
mask: 'YYYY-MM-DD',
},
}}
<Line x="date" y="value" />
</Chart>// 自定义时间格式
<Chart
scale={{
date: {
type: 'timeCat',
mask: 'MM/DD', // 01/15
},
}}
<Line x="date" y="value" />
</Chart>// 性能优化:数据已排序
<Chart
data={sortedData}
scale={{
date: {
type: 'timeCat',
sortable: false, // 跳过排序,提升性能
},
}}
<Line x="date" y="value" />
</Chart>// 指定时间顺序
<Chart
scale={{
quarter: {
type: 'cat',
values: ['Q1', 'Q2', 'Q3', 'Q4'],
},
}}
<Interval x="quarter" y="value" />
</Chart>类型定义
interface TimeCatScaleConfig {
type?: 'timeCat';
nice?: boolean;
mask?: string;
sortable?: boolean;
tickCount?: number;
values?: string[];
range?: [number, number];
alias?: string;
formatter?: (value: string | Date) => string;
ticks?: string[];
}常用配置场景
设置坐标轴范围
<Chart
scale={{
value: {
min: 0, // 设置最小值
max: 100, // 设置最大值
tickCount: 5, // 5 个刻度点
},
}}
<Line x="date" y="value" />
</Chart>格式化刻度标签
<Chart
scale={{
value: {
formatter: (val) => ${val}万,
},
date: {
formatter: (val) => {
const date = new Date(val);
return ${date.getMonth() + 1}月${date.getDate()}日;
},
},
}}
<Line x="date" y="value" />
<Axis field="value" />
<Axis field="date" />
</Chart>设置刻度间隔
<Chart
scale={{
value: {
min: 0,
max: 100,
tickInterval: 25, // 0, 25, 50, 75, 100
},
}}
<Line x="date" y="value" />
</Chart>自定义刻度值
<Chart
scale={{
value: {
ticks: [0, 25, 50, 75, 100], // 自定义刻度值
},
}}
<Line x="date" y="value" />
</Chart>多个度量配置
<Chart
scale={{
// x 轴:分类度量
genre: {
type: 'cat',
values: ['Sports', 'Strategy', 'Action', 'Shooter', 'Other'],
},
// y 轴:线性度量
sold: {
type: 'linear',
min: 0,
nice: true,
},
// 颜色:分类度量
color: {
type: 'cat',
},
}}
<Interval x="genre" y="sold" color="genre" />
</Chart>高级配置
范围控制
控制数据映射到图形的位置:
<Chart
scale={{
value: {
min: 0,
max: 100,
range: [0, 0.8], // 留出顶部 20% 空间
},
}}
<Interval x="genre" y="sold" />
</Chart>别名设置
用于将字段英文名称转换为中文名称:
<Chart
scale={{
genre: {
alias: '类型', // 图例、tooltip 等显示别名
},
sold: {
alias: '销量',
},
}}
<Interval x="genre" y="sold" />
<Legend />
<Tooltip />
</Chart>动态度量配置
class DynamicChart extends Component {
state = {
maxValue: 100,
}; updateMaxValue = () => {
this.setState({
maxValue: 200,
});
};
render() {
const { maxValue } = this.state;
return (
<Chart
data={data}
scale={{
value: {
type: 'linear',
max: maxValue,
},
}}
>
<Interval x="genre" y="sold" />
</Chart>
);
}
}
类型定义
ScaleConfig 完整类型
interface ScaleConfig {
type?: 'linear' | 'cat' | 'timeCat' | 'identity'; // 通用属性
range?: [number, number];
alias?: string;
formatter?: (value: any) => string;
tickCount?: number;
ticks?: any[];
// linear 特有
min?: number;
max?: number;
nice?: boolean;
tickInterval?: number;
// cat 特有
values?: any[];
isRounding?: boolean;
// timeCat 特有
mask?: string;
sortable?: boolean;
}
interface ChartScaleConfig {
[fieldName: string]: ScaleConfig;
}
常见问题
如何设置坐标轴从 0 开始?
scale={{
value: {
min: 0, // 设置最小值为 0
},
}}如何设置刻度间隔?
使用 tickInterval 属性:
scale={{
value: {
tickInterval: 20,
},
}}如何自定义刻度标签?
使用 formatter 或 ticks:
// 方式 1: formatter
scale={{
value: {
formatter: (val) => ${val}K,
},
}}// 方式 2: ticks
scale={{
value: {
ticks: [0, 25, 50, 75, 100],
},
}}
如何优化已排序时间数据的性能?
设置 sortable: false 跳过排序:
scale={{
date: {
type: 'timeCat',
sortable: false,
},
}}mask 和 formatter 能同时使用吗?
不能。如果同时设置,formatter 优先生效,mask 不生效。
相关文档
---
Site/Docs/Tutorial/Shape.Zh
---
title: 图形标签 - Shape
order: 6
---
F2 底层使用了 G 绘图引擎。本篇列出了常见的图形标签。
如何使用
详见:图形使用
图形标签列表
- group 分组
- rect 矩形
- circle 圆
- sector 扇形
- polygon 多边形
- line 线
- arc 圆弧
- polyline 多点线段
- text 文本
- image 图片
通用属性
所有图形标签支持的通用属性:
| 属性 | 类型 | 描述 |
|------|------|------|
| className | string | 对象标记,由用户指定 |
| visible | boolean | 显示或隐藏图形 |
| zIndex | number | z-index 值,用于调整绘制顺序 |
| style | Style | 图形样式 |
| animation | Animation | 图形动画 |
| onPan 等 | Event | 图形事件 |
Style 绘图属性
更多详情:绘图属性
Animation 动画属性
更多详情:图形动画属性
Event 事件属性
更多详情:图形事件属性
演示示例
- 图形标签
group
包含一组图形,用于图形分组管理。
基础示例
<group className="my-group">
<rect style={{ x: 10, y: 10, width: 50, height: 50, fill: 'red' }} />
<rect style={{ x: 70, y: 10, width: 50, height: 50, fill: 'blue' }} />
</group>使用场景
- 将多个图形组合在一起
- 统一管理一组图形的变换和动画
- 创建可复用的图形组件
rect
矩形,用于绘制矩形区域。
Style 属性
| 属性 | 类型 | 描述 | 默认值 |
|------|------|------|--------|
| x | number | 左上角 x 坐标 | 0 |
| y | number | 左上角 y 坐标 | 0 |
| width | number | 宽度 | 0 |
| height | number | 高度 | 0 |
| radius | number \| number[] | 圆角半径 | 0 |
基础示例
// 基础矩形
<rect
style={{
x: 100,
y: 100,
width: 50,
height: 50,
lineWidth: '2px',
stroke: '#000',
fill: 'red',
}}
/>圆角矩形
// 统一圆角
<rect
style={{
x: 100,
y: 100,
width: 100,
height: 50,
radius: 10,
fill: 'blue',
}}
/>// 分别设置每个角
<rect
style={{
x: 100,
y: 100,
width: 100,
height: 50,
radius: [10, 20, 30, 40], // [top-left, top-right, bottom-right, bottom-left]
fill: 'green',
}}
/>
circle
圆形,用于绘制圆形区域。
Style 属性
| 属性 | 类型 | 描述 | 默认值 |
|------|------|------|--------|
| cx | number | 圆心 x 坐标 | 0 |
| cy | number | 圆心 y 坐标 | 0 |
| r | number | 圆的半径 | 0 |
基础示例
<circle
style={{
cx: 100,
cy: 100,
r: 50,
lineWidth: '2px',
stroke: '#000',
fill: 'red',
}}
/>sector
扇形,用于绘制饼图、环形图等。
Style 属性
| 属性 | 类型 | 描述 | 默认值 |
|------|------|------|--------|
| cx | number | 圆心 x 坐标 | 0 |
| cy | number | 圆心 y 坐标 | 0 |
| r | number | 外半径 | 0 |
| r0 | number | 内半径 | 0 |
| startAngle | number \| string | 起始角度/弧度 | 0 |
| endAngle | number \| string | 结束角度/弧度 | 0 |
| anticlockwise | boolean | 是否逆时针方向 | false |
基础示例
// 使用弧度
<sector
style={{
cx: 100,
cy: 100,
r: 50,
startAngle: 0,
endAngle: Math.PI / 2,
fill: 'red',
}}
/>// 使用角度
<sector
style={{
cx: 100,
cy: 100,
r: 50,
startAngle: '0 deg',
endAngle: '90 deg',
fill: 'blue',
}}
/>
环形扇形
<sector
style={{
cx: 100,
cy: 100,
r: 50,
r0: 30,
startAngle: 0,
endAngle: Math.PI,
fill: 'green',
}}
/>polygon
多边形,用于绘制任意多边形。
Style 属性
| 属性 | 类型 | 描述 | 默认值 |
|------|------|------|--------|
| points | [number, number][] | 多边形的顶点坐标数组 | [] |
基础示例
// 三角形
<polygon
style={{
points: [
[50, 10],
[90, 90],
[10, 90],
],
lineWidth: '2px',
stroke: '#000',
fill: 'red',
}}
/>复杂多边形
// 五边形
<polygon
style={{
points: [
[50, 10],
[90, 40],
[75, 90],
[25, 90],
[10, 40],
],
lineWidth: '2px',
stroke: '#000',
fill: 'blue',
}}
/>line
直线,用于绘制两点之间的线段。
Style 属性
| 属性 | 类型 | 描述 | 默认值 |
|------|------|------|--------|
| x1 | number | 起始点 x 坐标 | 0 |
| y1 | number | 起始点 y 坐标 | 0 |
| x2 | number | 结束点 x 坐标 | 0 |
| y2 | number | 结束点 y 坐标 | 0 |
基础示例
<line
style={{
x1: 10,
y1: 10,
x2: 100,
y2: 100,
lineWidth: '2px',
stroke: '#000',
}}
/>虚线
<line
style={{
x1: 10,
y1: 10,
x2: 100,
y2: 100,
lineWidth: '2px',
stroke: '#000',
lineDash: [5, 5],
}}
/>arc
圆弧,用于绘制圆弧形曲线。
Style 属性
| 属性 | 类型 | 描述 | 默认值 |
|------|------|------|--------|
| cx | number | 圆心 x 坐标 | 0 |
| cy | number | 圆心 y 坐标 | 0 |
| r | number | 半径 | 0 |
| startAngle | number \| string | 起始角度/弧度 | 0 |
| endAngle | number \| string | 结束角度/弧度 | 0 |
| anticlockwise | boolean | 是否逆时针方向 | false |
基础示例
<arc
style={{
cx: 100,
cy: 100,
r: 50,
startAngle: 0,
endAngle: Math.PI,
lineWidth: '2px',
stroke: '#000',
}}
/>polyline
多点线段,用于绘制连续的折线。
Style 属性
| 属性 | 类型 | 描述 | 默认值 |
|------|------|------|--------|
| points | [number, number][] | 线段的点坐标数组 | [] |
| smooth | boolean | 是否平滑曲线 | false |
基础示例
// 折线
<polyline
style={{
points: [
[10, 10],
[50, 50],
[80, 70],
],
lineWidth: '2px',
stroke: '#000',
}}
/>平滑曲线
<polyline
style={{
points: [
[10, 10],
[50, 50],
[80, 70],
[100, 30],
],
lineWidth: '2px',
stroke: '#000',
smooth: true,
}}
/>text
文本,用于显示文字。
Style 属性
| 属性 | 类型 | 描述 | 默认值 |
|------|------|------|--------|
| x | number | 文本 x 坐标 | 0 |
| y | number | 文本 y 坐标 | 0 |
| text | string | 文本内容 | '' |
| textAlign | string | 文本水平对齐方式 | 'start' |
| textBaseline | string | 文本垂直基线 | 'alphabetic' |
| fontStyle | string | 字体样式 | 'normal' |
| fontSize | number | 字号(像素) | 12 |
| fontFamily | string | 字体系列 | 'sans-serif' |
| fontWeight | string | 字体粗细 | 'normal' |
| fontVariant | string | 字体变体 | 'normal' |
| lineHeight | number | 行高(像素) | - |
textAlign 可选值
- 'start' - 默认,文本从指定位置开始
- 'center' - 文本居中对齐
- 'end' - 文本从指定位置结束
- 'left' - 文本左对齐
- 'right' - 文本右对齐
textBaseline 可选值
- 'top' - 文本顶部对齐
- 'hanging' - 悬挂基线
- 'middle' - 文本垂直居中
- 'alphabetic' - 默认,字母基线
- 'ideographic' - 表意基线
- 'bottom' - 文本底部对齐
基础示例
// 简单文本
<text
style={{
x: 100,
y: 100,
text: 'Hello F2',
fontSize: 20,
fill: '#000',
}}
/>对齐方式
// 居中文本
<text
style={{
x: 150,
y: 100,
text: '居中文本',
fontSize: 16,
textAlign: 'center',
textBaseline: 'middle',
fill: '#000',
}}
/>字体样式
// 粗体斜体
<text
style={{
x: 100,
y: 100,
text: '粗体斜体',
fontSize: 18,
fontWeight: 'bold',
fontStyle: 'italic',
fill: '#000',
}}
/>image
图片,用于显示图像。
Style 属性
| 属性 | 类型 | 描述 | 默认值 |
|------|------|------|--------|
| x | number | 左上角 x 坐标 | 0 |
| y | number | 左上角 y 坐标 | 0 |
| width | number | 宽度 | 0 |
| height | number | 高度 | 0 |
| src | string | 图片 URL | '' |
| cacheImage | boolean | 是否缓存图片(解决闪动问题) | false |
基础示例
<image
style={{
src: 'https://f2.antv.vision/favicon-32x32.png',
x: 10,
y: 10,
width: 32,
height: 32,
}}
/>缓存图片
// 如果图片有闪动,可以开启缓存
<image
style={{
src: 'https://example.com/image.png',
x: 10,
y: 10,
width: 100,
height: 100,
cacheImage: true,
}}
/>TypeScript 类型定义
/ Detailed source-code truncated for AI context efficiency. /常见问题
如何绘制带边框的图形?
使用 stroke 和 lineWidth 属性:
<rect
style={{
x: 10,
y: 10,
width: 100,
height: 50,
fill: 'blue',
stroke: 'red',
lineWidth: 2,
}}
/>如何绘制虚线?
使用 lineDash 属性:
<line
style={{
x1: 10,
y1: 10,
x2: 100,
y2: 10,
stroke: '#000',
lineWidth: 2,
lineDash: [5, 5], // 5px 实线,5px 空白
}}
/>如何绘制半透明图形?
使用 fillOpacity 或 strokeOpacity 属性:
<circle
style={{
cx: 100,
cy: 100,
r: 50,
fill: 'red',
fillOpacity: 0.5,
}}
/>sector 的角度如何设置?
支持两种方式:
// 方式 1: 弧度值(推荐)
<sector
style={{
startAngle: 0,
endAngle: Math.PI / 2, // 90 度
}}
/>// 方式 2: 角度字符串
<sector
style={{
startAngle: '0 deg',
endAngle: '90 deg',
}}
/>
相关文档
---
Site/Docs/Tutorial/Shape Attrs.Zh
---
title: 绘图属性 - Style
order: 7
---
F2 底层使用了 G 绘图引擎。本篇列出了常见的绘图属性,更多关于绘图以及绘图属性的使用请至 G 中查看。
在 F2 中组件样式的定义全部直接使用 Style 统一的结构,例如 axis 的 label 样式、legend marker 样式、和其他自定义 shape 样式等等。
属性列表
位置属性
对于不同的图形,位置的几何意义也不同:
| 图形 | 位置说明 | 使用的属性 |
|------|----------|------------|
| Circle | 圆心位置 | cx/cy |
| Arc | 圆心位置 | cx/cy |
| Sector | 圆心位置 | cx/cy |
| Group | 左上角顶点位置 | x/y |
| Rect | 左上角顶点位置 | x/y |
| Image | 左上角顶点位置 | x/y |
| Text | 文本锚点位置 | x/y |
| Line | 包围盒左上角顶点位置 | x/y |
| Polyline | 包围盒左上角顶点位置 | x/y |
| Polygon | 包围盒左上角顶点位置 | x/y |
| 属性 | 类型 | 默认值 | 描述 |
|------|------|--------|------|
| anchor | [number, number] | [0, 0] | 锚点位置 |
通用属性
| 属性 | 类型 | 默认值 | 描述 |
|------|------|--------|------|
| zIndex | number | 0 | 控制图形显示层级 |
| clip | Clip | - | 创建元素的可显示区域,区域内的部分显示,区域外的隐藏。见裁剪 |
| visibility | string | - | 控制图形的可见性,见 MDN |
| opacity | number | 1 | 设置图形和图片透明度,范围从 0.0(完全透明)到 1.0(完全不透明) |
| fill | string \| Gradient \| Pattern | - | 填充色、渐变或纹理 |
| fillOpacity | number | 1 | 设置图形填充颜色的透明度,范围从 0.0 到 1.0 |
| stroke | string \| Gradient \| Pattern | - | 描边色、渐变或纹理 |
| strokeOpacity | number | 1 | 设置边颜色的透明度,范围从 0.0 到 1.0 |
| shadowType | string | - | 阴影类型,支持 'outer' 外阴影和 'inner' 内阴影 |
| shadowColor | string | - | 阴影颜色,见 MDN |
| shadowBlur | number | 0 | 阴影模糊程度,见 MDN |
| shadowOffsetX | number | 0 | 阴影水平偏移距离,见 MDN |
| shadowOffsetY | number | 0 | 阴影垂直偏移距离,见 MDN |
| filter | string | - | 滤镜,支持 blur、brightness、drop-shadow、contrast、grayscale、saturate、sepia、hue-rotate、invert 等,见 MDN |
| cursor | string | - | 鼠标样式,见 MDN |
线条属性
| 属性 | 类型 | 默认值 | 描述 |
|------|------|--------|------|
| lineCap | string | 'butt' | 线段末端样式,可选值:'butt'、'round'、'square',见 MDN |
| lineJoin | string | 'miter' | 线段连接处样式,可选值:'bevel'、'round'、'miter',见 MDN |
| lineWidth | number | 1 | 线段宽度,见 MDN |
| miterLimit | number | 10 | 斜接面限制比例,见 MDN |
| lineDash | number[] | [] | 虚线样式,如 [5, 5] 表示 5px 实线、5px 空白,见 setLineDash |
文本属性
| 属性 | 类型 | 默认值 | 描述 |
|------|------|--------|------|
| textAlign | string | 'start' | 文本水平对齐方式,可选值:'start'、'center'、'end'、'left'、'right' |
| textBaseline | string | 'alphabetic' | 文本垂直基线,可选值:'top'、'hanging'、'middle'、'alphabetic'、'ideographic'、'bottom' |
| fontStyle | string | 'normal' | 字体样式,可选值:'normal'、'italic'、'oblique' |
| fontSize | number | 12 | 字号(像素) |
| fontFamily | string | 'sans-serif' | 字体系列 |
| fontWeight | string | 'normal' | 字体粗细,可选值:'normal'、'bold'、'bolder'、'lighter'、'100'~'900' |
| fontVariant | string | 'normal' | 字体变体,可选值:'normal'、'small-caps' |
| lineHeight | number | - | 行高(像素) |
渐变色
F2 提供与 CSS 用法一致的渐变色使用方法,参见 MDN。
渐变效果包括线性和径向渐变、多个渐变叠加等:
<img src="https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*sXoJTKPWg70AAAAAAAAAAAAAARQnAQ" width="400" alt="gradient">
线性渐变
线性渐变指创建一个表示两种或多种颜色沿某一方向线性变化。渐变方向默认为从左到右(与 Canvas / SVG 保持一致),且可以多个渐变叠加。
// 基础线性渐变
<rect
style={{
x: 10,
y: 10,
width: 200,
height: 100,
fill: 'linear-gradient(90deg, blue, green 40%, red)',
}}
/><img src="https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*aU84RIJaH6AAAAAAAAAAAAAAARQnAQ" width="300" alt="linear gradient">
径向渐变
径向渐变指从图形中心发出的两种或者多种颜色之间的逐步过渡变化。
// 径向渐变
<circle
style={{
cx: 100,
cy: 100,
r: 80,
fill: 'radial-gradient(circle at center, red, blue, green 100%)',
}}
/><img src="https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*Z4QLTr3lC80AAAAAAAAAAAAAARQnAQ" width="300" alt="radial gradient">
渐变类型
| 类型 | 说明 | 示例 |
|------|------|------|
| linear-gradient(angle, ...) | 线性渐变,angle 为角度 | linear-gradient(90deg, red, blue) |
| radial-gradient(shape at position, ...) | 径向渐变 | radial-gradient(circle at center, red, blue) |
纹理
使用相同的图案填充图形,支持的 Pattern 可以是图片 URL、HTMLImageElement、HTMLCanvasElement、HTMLVideoElement 和 Rect 等,还可以指定重复方向。
<img src="https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*cRmFTItZOtYAAAAAAAAAAAAAARQnAQ" width="400" alt="pattern">
Pattern 类型定义
interface Pattern {
image: string | CanvasImageSource | Rect
repetition?: 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat'
transform?: string
}使用示例
// 使用纹理填充,在水平和垂直方向重复图片
<rect
style={{
x: 10,
y: 10,
width: 200,
height: 200,
fill: {
image: 'https://gw.alipayobjects.com/zos/rmsportal/ibtwzHXSxomqbZCPMLqS.png',
repetition: 'repeat',
transform: 'rotate(30deg)',
},
}}
/>repetition 参数说明
| 值 | 说明 |
|------|------|
| 'repeat' | 水平和垂直方向重复 |
| 'repeat-x' | 仅水平方向重复 |
| 'repeat-y' | 仅垂直方向重复 |
| 'no-repeat' | 不重复 |
裁剪
参考 CSS clip-path。该属性值可以定义可视区域,可以是任意图形,例如 Circle、Rect 等。同一个裁剪区域可以被多个图形共享使用,并且裁剪区域也会影响图形的拾取区域。
使用示例
// 圆形裁剪
<rect
style={{
x: 100,
y: 100,
width: 100,
height: 100,
fill: 'blue',
clip: {
type: 'circle',
style: {
cx: 150,
cy: 150,
r: 50,
},
},
}}
/>// 矩形裁剪
<rect
style={{
x: 100,
y: 100,
width: 200,
height: 200,
fill: 'red',
clip: {
type: 'rect',
style: {
x: 150,
y: 150,
width: 100,
height: 100,
},
},
}}
/>
Clip 类型定义
type Clip =
| {
type: 'circle'
style: CircleStyle
}
| {
type: 'rect'
style: RectStyle
}
| {
type: 'polygon'
style: PolygonStyle
}TypeScript 类型定义
interface ShapeStyle {
// 位置
anchor?: [number, number] // 通用属性
zIndex?: number
clip?: Clip
visibility?: 'visible' | 'hidden' | 'collapse'
opacity?: number
fill?: string | Gradient | Pattern
fillOpacity?: number
stroke?: string | Gradient | Pattern
strokeOpacity?: number
shadowType?: 'outer' | 'inner'
shadowColor?: string
shadowBlur?: number
shadowOffsetX?: number
shadowOffsetY?: number
filter?: string
cursor?: string
// 线条属性
lineCap?: 'butt' | 'round' | 'square'
lineJoin?: 'bevel' | 'round' | 'miter'
lineWidth?: number
miterLimit?: number
lineDash?: number[]
// 文本属性
textAlign?: 'start' | 'center' | 'end' | 'left' | 'right'
textBaseline?: 'top' | 'hanging' | 'middle' | 'alphabetic' | 'ideographic' | 'bottom'
fontStyle?: 'normal' | 'italic' | 'oblique'
fontSize?: number
fontFamily?: string
fontWeight?: 'normal' | 'bold' | 'bolder' | 'lighter' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900'
fontVariant?: 'normal' | 'small-caps'
lineHeight?: number
}
type Gradient = string // 'linear-gradient(...)' | 'radial-gradient(...)'
interface Pattern {
image: string | CanvasImageSource | Rect
repetition?: 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat'
transform?: string
}
常见问题
如何设置透明度?
使用 opacity 设置整体透明度,或使用 fillOpacity 和 strokeOpacity 分别设置填充和描边透明度:
// 整体透明度
<circle
style={{
cx: 100,
cy: 100,
r: 50,
fill: 'red',
opacity: 0.5,
}}
/>// 分别设置填充和描边透明度
<circle
style={{
cx: 100,
cy: 100,
r: 50,
fill: 'red',
fillOpacity: 0.5,
stroke: 'blue',
strokeOpacity: 0.8,
lineWidth: 2,
}}
/>
如何添加阴影?
使用阴影相关属性:
<rect
style={{
x: 100,
y: 100,
width: 100,
height: 100,
fill: 'blue',
shadowType: 'outer',
shadowColor: 'rgba(0, 0, 0, 0.5)',
shadowBlur: 10,
shadowOffsetX: 5,
shadowOffsetY: 5,
}}
/>如何设置虚线?
使用 lineDash 属性:
<line
style={{
x1: 10,
y1: 10,
x2: 200,
y2: 10,
stroke: '#000',
lineWidth: 2,
lineDash: [10, 5], // 10px 实线,5px 空白
}}
/>渐变色如何使用?
渐变色可以直接作为 fill 或 stroke 的值:
// 线性渐变填充
<rect
style={{
x: 10,
y: 10,
width: 200,
height: 100,
fill: 'linear-gradient(90deg, red 0%, yellow 50%, blue 100%)',
}}
/>// 径向渐变描边
<circle
style={{
cx: 100,
cy: 100,
r: 50,
stroke: 'radial-gradient(circle, white, black)',
lineWidth: 5,
}}
/>
如何控制图形层级?
使用 zIndex 属性,值越大越靠前:
<group>
<rect
style={{
x: 10,
y: 10,
width: 100,
height: 100,
fill: 'red',
zIndex: 1,
}}
/>
<rect
style={{
x: 50,
y: 50,
width: 100,
height: 100,
fill: 'blue',
zIndex: 2, // 会显示在红色矩形上方
}}
/>
</group>相关文档
---
Site/Docs/Tutorial/Understanding.En
---
title: Core Concepts
order: 1
---
To better use F2 for data visualization, we need to understand the composition of F2 charts and related terminology.
Chart Structure
F2 charts adopt a declarative component-based architecture. A complete chart is composed of multiple components:
Canvas (Canvas Container)
└── Chart (Chart Core)
├── Axis (Coordinate Axis)
├── Geometry (Geometry Mark)
├── Tooltip (Tooltip)
├── Legend (Legend)
└── Guide (Guide Mark)Chart Examples
Core Terminology
| Term | English | Description |
|------|---------|-------------|
| Coordinate Axis | Axis | Charts typically contain two axes. In Cartesian coordinates, these are the x-axis and y-axis; in polar coordinates, they are composed of angle and radius. Each axis consists of axis line, tick line, label, and grid. |
| Legend | Legend | An auxiliary element for charts, used to indicate different data types and ranges, assisting in reading charts and helping users filter data. |
| Geometry Mark | Geometry | Geometric shapes such as points, lines, and areas. The type of geometry mark determines the chart type and represents the actual visualization of data. |
| Graphic Attribute | Attribute | Corresponds to visual channels in visual encoding, including position, color, size, and shape. |
| Coordinate System | Coordinate | A 2D positioning system combining two position scales, describing how data is mapped to the graphic plane. |
| Tooltip | Tooltip | Displays data information in a tooltip when hovering over a point, helping users obtain specific data. |
| Guide Mark | Guide | Useful for drawing auxiliary lines, boxes, or text on charts, such as warning lines, maximum value lines, or highlighting specific ranges. |
Declarative Syntax
F2 uses declarative JSX syntax for more intuitive and concise code:
<Canvas context={context} pixelRatio={window.devicePixelRatio}>
<Chart data={data}>
{/ Coordinate axes /}
<Axis field="genre" />
<Axis field="sold" /> {/ Geometry mark - bar chart /}
<Interval x="genre" y="sold" color="genre" />
{/ Tooltip /}
<Tooltip />
{/ Legend /}
<Legend />
</Chart>
</Canvas>
Advantages of Declarative Syntax
- Intuitive: Clear component structure at a glance
- Concise: Avoid complex API call chains
- Composable: Components can be combined and nested flexibly
- Framework-friendly: Seamless integration with React, Vue
Component Details
Canvas - Canvas Container
Canvas is the root container of the chart, providing the rendering environment:
<Canvas context={context} pixelRatio={window.devicePixelRatio}>
{/ Child components /}
</Canvas>| Prop | Type | Default | Description |
|------|------|---------|-------------|
| context | CanvasRenderingContext2D | - | Required, Canvas 2D context |
| pixelRatio | number | window.devicePixelRatio | Device pixel ratio |
| width | number | - | Canvas width |
| height | number | - | Canvas height |
| animate | boolean | true | Whether to enable animation |
Chart - Chart Core
Chart is responsible for data processing and coordinate transformation:
<Chart data={data}>
{/ Geometry marks and components /}
</Chart>| Prop | Type | Default | Description |
|------|------|---------|-------------|
| data | Data[] | - | Required, data source |
| scale | ScaleConfig | - | Scale configuration |
| coord | CoordConfig | - | Coordinate system configuration |
Geometry - Geometry Mark
Geometry marks determine the chart type. F2 provides various built-in geometry marks:
| Geometry Mark | Component | Chart Type |
|---------------|-----------|------------|
| Interval | <Interval /> | Bar chart, column chart |
| Line | <Line /> | Line chart, curve chart |
| Point | <Point /> | Scatter plot, dot plot |
| Area | <Area /> | Area chart |
| Candlestick | <Candlestick /> | Candlestick chart |
// Bar chart
<Interval x="genre" y="sold" color="genre" />// Line chart
<Line x="date" y="value" color="type" />
// Scatter plot
<Point x="weight" y="height" color="gender" />
Graphic Attributes
Graphic attributes control the visual appearance of geometry marks:
| Attribute | Description | Example |
|-----------|-------------|---------|
| position | Position, maps fields to x or y axis | x="genre", y="sold" |
| color | Color, supports field or function | color="genre" or color={datum => datum.value > 100 ? 'red' : 'blue'} |
| size | Size, controls point size, line thickness, etc. | size={10} or size={datum => datum.value} |
| shape | Shape, controls the shape of geometry marks | shape="circle" or shape="hollowCircle" |
Coordinate System
Coordinate system describes how data is mapped to the plane:
| Type | Description | Configuration |
|------|-------------|---------------|
| rect | Cartesian coordinate system (default) | <coord type="rect" /> |
| polar | Polar coordinate system | <coord type="polar" /> |
| helix | Helix coordinate system | <coord type="helix" /> |
// Use polar coordinate system (pie chart, rose chart, etc.)
<Chart data={data} coord={{ type: 'polar' }}>
<Interval x="genre" y="sold" color="genre" coord="polar" />
</Chart>Scale
Scale is used to convert data into graphic attributes:
<Chart
data={data}
scale={{
sold: {
min: 0,
max: 500,
tickCount: 5,
},
genre: {
type: 'cat',
},
}}
{/ ... /}
</Chart>For detailed configuration, see: Scale
Data Format
F2 requires the data source to be a JSON array, where each element is a standard JSON object:
const data = [
{ genre: 'Sports', sold: 275, year: 2023 },
{ genre: 'Strategy', sold: 115, year: 2023 },
{ genre: 'Action', sold: 120, year: 2023 },
{ genre: 'Shooter', sold: 350, year: 2023 },
{ genre: 'Other', sold: 150, year: 2023 },
];For data processing, see: Data Processing
Complete Example
const data = [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 120 },
{ genre: 'Shooter', sold: 350 },
{ genre: 'Other', sold: 150 },
];const context = document.getElementById('container').getContext('2d');
const { props } = (
<Canvas context={context} pixelRatio={window.devicePixelRatio}>
<Chart
data={data}
scale={{
sold: {
min: 0,
tickInterval: 50,
},
}}
>
<Axis field="genre" />
<Axis field="sold" />
<Interval x="genre" y="sold" color="genre" />
<Tooltip />
<Legend />
</Chart>
</Canvas>
);
const canvas = new Canvas(props);
canvas.render();
Next Steps
- Learn Chart Grammar
- Understand Data Processing
- View Component API
- Learn Graphic Attributes
---
Site/Docs/Tutorial/Understanding.Zh
---
title: 核心概念
order: 1
---
为了更好地使用 F2 进行数据可视化,我们需要了解 F2 图表的组成以及相关术语。
图表结构
F2 图表采用声明式的组件化架构,一个完整的图表由多个组件组合而成:
Canvas (画布容器)
└── Chart (图表核心)
├── Axis (坐标轴)
├── Geometry (几何标记)
├── Tooltip (提示框)
├── Legend (图例)
└── Guide (辅助标记)图表示例
核心术语
| 术语 | 英文 | 描述 |
|------|------|------|
| 坐标轴 | Axis | 图表通常包含两个坐标轴。在直角坐标系下为 x 轴和 y 轴,在极坐标下由角度和半径构成。每个坐标轴由轴线(line)、刻度线(tickLine)、刻度文本(label)和网格线(grid)组成。 |
| 图例 | Legend | 图表辅助元素,用于标定不同数据类型及数据范围,辅助阅读图表并帮助用户筛选数据。 |
| 几何标记 | Geometry | 点、线、面等几何图形。几何标记的类型决定了图表类型,是数据可视化后的实际表现。 |
| 图形属性 | Attribute | 对应视觉编码中的视觉通道,包括位置(position)、颜色(color)、大小(size)、形状(shape)四种。 |
| 坐标系 | Coordinate | 将两种位置标度结合组成的 2 维定位系统,描述数据如何映射到图形所在平面。 |
| 提示信息 | Tooltip | 鼠标悬停时以提示框形式显示数据信息,帮助用户获取具体数据。 |
| 辅助标记 | Guide | 用于在图表上绘制辅助线、辅助框或文本,如预警线、最高值线等。 |
声明式语法
F2 采用声明式 JSX 语法,让代码更直观和简洁:
<Canvas context={context} pixelRatio={window.devicePixelRatio}>
<Chart data={data}>
{/ 坐标轴 /}
<Axis field="genre" />
<Axis field="sold" /> {/ 几何标记 - 柱状图 /}
<Interval x="genre" y="sold" color="genre" />
{/ 提示框 /}
<Tooltip />
{/ 图例 /}
<Legend />
</Chart>
</Canvas>
声明式的优势
- 直观: 组件结构清晰,一目了然
- 简洁: 避免复杂的 API 调用链
- 可组合: 组件可以灵活组合嵌套
- 框架友好: 与 React、Vue 无缝集成
组件详解
Canvas - 画布容器
Canvas 是图表的根容器,提供渲染环境:
<Canvas context={context} pixelRatio={window.devicePixelRatio}>
{/ 子组件 /}
</Canvas>| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| context | CanvasRenderingContext2D | - | 必填,Canvas 2D 上下文 |
| pixelRatio | number | window.devicePixelRatio | 设备像素比 |
| width | number | - | 画布宽度 |
| height | number | - | 画布高度 |
| animate | boolean | true | 是否开启动画 |
Chart - 图表核心
Chart 负责数据处理和坐标转换:
<Chart data={data}>
{/ 几何标记和组件 /}
</Chart>| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| data | Data[] | - | 必填,数据源 |
| scale | ScaleConfig | - | 度量配置 |
| coord | CoordConfig | - | 坐标系配置 |
Geometry - 几何标记
几何标记决定了图表的类型,F2 提供多种内置几何标记:
| 几何标记 | 组件 | 图表类型 |
|----------|------|----------|
| Interval | <Interval /> | 柱状图、条形图 |
| Line | <Line /> | 折线图、曲线图 |
| Point | <Point /> | 散点图、点图 |
| Area | <Area /> | 面积图 |
| Candlestick | <Candlestick /> | 蜡烛图(K线图) |
// 柱状图
<Interval x="genre" y="sold" color="genre" />// 折线图
<Line x="date" y="value" color="type" />
// 散点图
<Point x="weight" y="height" color="gender" />
图形属性
图形属性控制几何标记的视觉表现:
| 属性 | 说明 | 示例 |
|------|------|------|
| position | 位置,将字段映射到 x 或 y 轴 | x="genre", y="sold" |
| color | 颜色,支持字段或函数 | color="genre" 或 color={datum => datum.value > 100 ? 'red' : 'blue'} |
| size | 大小,控制点的大小、线的粗细等 | size={10} 或 size={datum => datum.value} |
| shape | 形状,控制几何标记的形状 | shape="circle" 或 shape="hollowCircle" |
坐标系
坐标系描述数据如何映射到平面:
| 类型 | 说明 | 配置 |
|------|------|------|
| rect | 直角坐标系(默认) | <coord type="rect" /> |
| polar | 极坐标系 | <coord type="polar" /> |
| helix | 螺旋坐标系 | <coord type="helix" /> |
// 使用极坐标系(饼图、玫瑰图等)
<Chart data={data} coord={{ type: 'polar' }}>
<Interval x="genre" y="sold" color="genre" coord="polar" />
</Chart>度量
度量(Scale)用于将数据转换为图形属性:
<Chart
data={data}
scale={{
sold: {
min: 0,
max: 500,
tickCount: 5,
},
genre: {
type: 'cat',
},
}}
{/ ... /}
</Chart>详细配置请参考:度量
数据格式
F2 要求数据源为 JSON 数组,数组的每个元素是一个标准 JSON 对象:
const data = [
{ genre: 'Sports', sold: 275, year: 2023 },
{ genre: 'Strategy', sold: 115, year: 2023 },
{ genre: 'Action', sold: 120, year: 2023 },
{ genre: 'Shooter', sold: 350, year: 2023 },
{ genre: 'Other', sold: 150, year: 2023 },
];数据处理相关内容请参考:数据处理
完整示例
const data = [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 120 },
{ genre: 'Shooter', sold: 350 },
{ genre: 'Other', sold: 150 },
];const context = document.getElementById('container').getContext('2d');
const { props } = (
<Canvas context={context} pixelRatio={window.devicePixelRatio}>
<Chart
data={data}
scale={{
sold: {
min: 0,
tickInterval: 50,
},
}}
>
<Axis field="genre" />
<Axis field="sold" />
<Interval x="genre" y="sold" color="genre" />
<Tooltip />
<Legend />
</Chart>
</Canvas>
);
const canvas = new Canvas(props);
canvas.render();
下一步
- 学习 图表语法
- 了解 数据处理
- 查看 组件 API
- 学习 图形属性
---
Site/Docs/Api/Chart/Guide/Guide.Zh
---
title: 标注 - Guide
order: 9
---
提示和标注,主要用于在图表上标识额外的标记注解。目前内置 PointGuide 点标注、TextGuide 文本标注、TagGuide 标注、ImageGuide 图片标注、RectGuide 矩形标注 和 LineGuide 线标注,也可以自定义标注。
- 点标注 PointGuide
- 文本标注 TextGuide
- 标签标注 TagGuide
- 图片标注 ImageGuide
- 矩形标注 RectGuide
- 辅助线标注 LineGuide
---
Site/Docs/Api/Chart/Guide/Image Guide.Zh
---
title: 图片标注 - ImageGuide
---
Usage 用法
import { Canvas, Chart, Line, ImageGuide } from '@antv/f2';const data = [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 120 },
{ genre: 'Shooter', sold: 350 },
{ genre: 'Other', sold: 150 },
];
// 黄色星形图标
const starIcon = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8cG9seWdvbiBwb2ludHM9IjEyLDIgMTUsOSAyMiw5IDE3LDE0IDE5LDIxIDEyLDE3IDUsMjEgNywxNCAyLDkgOSw5IiBmaWxsPSIjZmFhZDE0Ii8+Cjwvc3ZnPg==';
<Canvas context={context}>
<Chart data={data}>
<Line x="genre" y="sold" />
<ImageGuide
records={[data[3]]}
src={starIcon}
style={{ width: 36, height: 36 }}
/>
</Chart>
</Canvas>
TypeScript 类型定义
interface ImageGuideProps {
/ 标注位置的数据项,支持 1 个数据项或特殊值(如 'min', 'max', '50%') */
records: RecordItem[];
/ 图片地址 */
src: string;
/ 图片属性,会覆盖 style 中的同名属性 */
attrs?: ImageStyleProps;
/ 图片样式,支持对象或函数形式 */
style?: Partial<ImageStyleProps> | ((points: Point[], chart: Chart) => Partial<ImageStyleProps>);
/ x 轴偏移量,支持数字或带单位的字符串(如 '10px')*/
offsetX?: number | string;
/ y 轴偏移量,支持数字或带单位的字符串(如 '10px')*/
offsetY?: number | string;
/ 点击事件回调 */
onClick?: (event: { points: Point[] }) => void;
/ 动画配置,详见 动画文档 */
animation?: AnimationProps | ((points: Point[], chart: Chart) => AnimationProps);
}Props
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| records | Array<RecordItem> | - | 标注位置的数据项,支持特殊值(见下方说明) |
| src | string | - | 图片地址 |
| attrs | ImageStyleProps | - | 图片属性,会覆盖 style 中的同名属性 |
| style | ImageStyleProps \| Function | - | 图片样式,支持对象或函数形式 |
| offsetX | number \| string | 0 | x 轴偏移量 |
| offsetY | number \| string | 0 | y 轴偏移量 |
| onClick | Function | - | 点击事件回调,参数为 { points: Point[] } |
| animation | AnimationProps \| Function | - | 动画配置,详见 动画文档 |
注意:图片以中心点定位,偏移量是相对于中心点的偏移。
attrs vs style
style 是设置图片样式的主要方式。attrs 属性也可设置样式,但会与 style 合并,同名属性以 style 为准:
// 合并顺序
{ ...attrs, ...style } // style 覆盖 attrs建议:优先使用 style,attrs 仅在需要提供默认值时使用。
records 特殊值
records 的值可以使用特殊字符串来表示位置,无需计算具体数值:
| 值 | 含义 | 对应位置 |
|----|------|----------|
| 'min' | 最小值 | 0 |
| 'max' | 最大值 | 1 |
| 'median' | 中位值 | 0.5 |
| '50%' | 50% 位置 | 0.5 |
| '100%' | 100% 位置 | 1.0 |
style 属性
style 支持两种形式:
对象形式:静态样式
style={{ width: 24, height: 24 }}函数形式:动态样式,接收 points 和 chart 参数
style={(points, chart) => ({
width: points[0].y > 0.5 ? 30 : 20,
height: points[0].y > 0.5 ? 30 : 20,
})}支持的样式属性见 Shape 属性文档。
用法示例
基础用法
<Canvas context={context}>
<Chart data={data}>
<Line x="genre" y="sold" />
{data.map((item) => (
<ImageGuide
records={[item]}
src="https://gw.alipayobjects.com/zos/antfincdn/FLrTNDvlna/antv.png"
style={{ width: 24, height: 24 }}
/>
))}
</Chart>
</Canvas>使用偏移量
<ImageGuide
records={[{ genre: 'Sports', sold: 275 }]}
src="https://gw.alipayobjects.com/zos/antfincdn/FLrTNDvlna/antv.png"
style={{ width: 24, height: 24 }}
offsetY="-8px"
/>使用特殊值定位
// 红色奖杯图标(最高值)
const trophyIcon = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNiA4aDN2NGMwIDIuMiAxLjggNCA0IDRoNmMyLjIgMCA0LTEuOCA0LTR2LTRoM3Y0YzMuOSAwIDctMy4xIDctN2gtMnYybDQgM3YyLTQtMnYybDQtM3YtMmgtMWMtMy45IDAtNy0zLjEtNy03di00em01LTJoMTB2MkgxMVY2eiIgZmlsbD0iI2ZmNGQ0ZiIvPjxjaXJjbGUgY3g9IjE2IiBjeT0iMyIgcj0iMiIgZmlsbD0iI2ZmNGQ0ZiIvPjwvc3ZnPg==';
// 绿色向下箭头(最低值)
const arrowDownIcon = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTIgMTZsLTYtNmg0VjRoNHY2aDRsLTYgNnoiIGZpbGw9IiM1MmM0MWEiLz48L3N2Zz4=';<Canvas context={context}>
<Chart data={data}>
<Line x="genre" y="sold" />
{/ 标记全局最高销量(Shooter, 350) /}
<ImageGuide
records={[{ genre: 'Shooter', sold: 'max' }]}
src={trophyIcon}
style={{ width: 32, height: 32 }}
/>
{/ 标记全局最低销量(Strategy, 115) /}
<ImageGuide
records={[{ genre: 'Strategy', sold: 'min' }]}
src={arrowDownIcon}
style={{ width: 32, height: 32 }}
/>
</Chart>
</Canvas>
style 函数形式
<ImageGuide
records={[{ genre: 'Sports', sold: 275 }]}
src="https://gw.alipayobjects.com/zos/antfincdn/FLrTNDvlna/antv.png"
style={(points) => ({
width: points[0].y > 0.5 ? 32 : 24,
height: points[0].y > 0.5 ? 32 : 24,
})}
/>使用 onClick 事件
<ImageGuide
records={[{ genre: 'Sports', sold: 275 }]}
src="https://gw.alipayobjects.com/zos/antfincdn/FLrTNDvlna/antv.png"
style={{ width: 24, height: 24 }}
onClick={(ev) => {
console.log('点击位置:', ev.points);
}}
/>多图片标注组合
// 绿色小圆点
const dotIcon = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTIiIHZpZXdCb3g9IjAgMCAxMiAxMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48Y2lyY2xlIGN4PSI2IiBjeT0iNiIgcj0iNSIgZmlsbD0iIzUyYzQxYSIvPjwvc3ZnPg==';
// 黄色星形图标
const starIcon = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cG9seWdvbiBwb2ludHM9IjE2LDIgMjAsMTIgMzAsMTIgMjIsMTggMjUsMjggMTYsMjIgNywyOCAxMCwxOCAyLDEyIDEyLDEyIiBmaWxsPSIjZmFhZDE0Ii8+PC9zdmc+';<Canvas context={context}>
<Chart data={data}>
<Line x="genre" y="sold" color="type" />
{/ 在数据点上显示小圆点 /}
{data.map((item) => (
<ImageGuide
records={[item]}
src={dotIcon}
style={{ width: 12, height: 12 }}
/>
))}
{/ 在每个类别的最大值位置显示星形图标 /}
{data.map((item) => (
<ImageGuide
records={[{ genre: item.genre, sold: 'max' }]}
src={starIcon}
style={{ width: 32, height: 32 }}
offsetY="-10px"
/>
))}
</Chart>
</Canvas>
使用动画
<ImageGuide
records={[{ genre: 'Sports', sold: 275 }]}
src="https://gw.alipayobjects.com/zos/antfincdn/FLrTNDvlna/antv.png"
style={{ width: 24, height: 24 }}
animation={{
appear: {
property: ['opacity'],
duration: 1000,
easing: 'easeOut',
start: {
opacity: 0,
},
end: {
opacity: 1,
},
}
}}
/>更多动画配置详见 动画文档。
---
Site/Docs/Api/Chart/Guide/Line Guide.Zh
---
title: 辅助线标注 - LineGuide
---
Usage 用法
import { Canvas, Chart, Line, LineGuide } from '@antv/f2';const data = [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 120 },
{ genre: 'Shooter', sold: 350 },
{ genre: 'Other', sold: 150 },
];
<Canvas context={context}>
<Chart data={data}>
<Line x="genre" y="sold" />
{data.map((item) => (
<LineGuide
records={[
{ genre: item.genre, sold: 'min' },
{ genre: item.genre, sold: item.sold },
]}
style={{ stroke: '#f00', lineWidth: 2 }}
/>
))}
</Chart>
</Canvas>
TypeScript 类型定义
interface LineGuideProps {
/ 标注位置的数据项或比例值(需要 2 个点来定义线) */
records: RecordItem[];
/ x 轴偏移量,支持数字、字符串或数组(为数组时可为两个端点分别设置不同偏移) */
offsetX?: number | string | (number | string)[];
/ y 轴偏移量,支持数字、字符串或数组(为数组时可为两个端点分别设置不同偏移) */
offsetY?: number | string | (number | string)[];
/ 线样式,支持对象或函数形式(函数接收 points 和 chart 参数)*/
style?: Partial<LineStyleProps> | ((points: Point[], chart: Chart) => Partial<LineStyleProps>);
/ 动画配置,详见 动画文档 */
animation?: AnimationProps | ((points: Point[], chart: Chart) => AnimationProps);
}Props
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| records | Array<RecordItem> | - | 标注位置的数据项或比例值,需要 2 个点来定义线,支持特殊值(见下方说明) |
| offsetX | number \| string \| Array | 0 | x 轴偏移量,支持数组形式为两个端点分别设置偏移 |
| offsetY | number \| string \| Array | 0 | y 轴偏移量,支持数组形式为两个端点分别设置偏移 |
| style | LineStyleProps \| Function | - | 线样式,支持对象或函数形式 |
| animation | AnimationProps \| Function | - | 动画配置,详见 动画文档 |
records 特殊值
records 的值可以使用特殊字符串来表示位置,无需计算具体数值:
| 值 | 含义 | 对应位置 |
|----|------|----------|
| 'min' | 最小值 | 0 |
| 'max' | 最大值 | 1 |
| 'median' | 中位值 | 0.5 |
| '50%' | 50% 位置 | 0.5 |
| '100%' | 100% 位置 | 1.0 |
注意:x 轴和 y 轴都支持这些特殊值。
style 属性
style 支持两种形式:
对象形式:静态样式
style={{ stroke: '#f00', lineWidth: 2, lineDash: [4, 4] }}函数形式:函数接收 points(坐标数组)和 chart(图表实例)参数
style={(points, chart) => ({
stroke: '#f00',
lineWidth: 2,
lineDash: [4, 4],
})}支持的样式属性见 Shape 属性文档。
用法示例
水平参考线
使用 min/max 配合百分比位置,绘制横跨整个图表的水平参考线:
<Canvas context={context}>
<Chart data={data}>
<Line x="genre" y="sold" />
{/ 在 y 轴 50% 位置绘制水平参考线 /}
<LineGuide
records={[
{ genre: 'min', sold: '50%' },
{ genre: 'max', sold: '50%' },
]}
style={{ stroke: '#999', lineWidth: 1, lineDash: [4, 4] }}
/>
</Chart>
</Canvas>从最小值画线到实际值
<Canvas context={context}>
<Chart data={data}>
<Line x="genre" y="sold" />
{data.map((item) => (
<LineGuide
records={[
{ genre: item.genre, sold: 'min' },
{ genre: item.genre, sold: item.sold },
]}
style={{ stroke: 'rgba(0, 0, 0, 0.25)', lineWidth: '2px' }}
/>
))}
</Chart>
</Canvas>使用数组偏移
offsetX 和 offsetY 支持数组形式,可为两个端点分别设置不同的偏移量:
<Canvas context={context}>
<Chart data={data}>
<Line x="genre" y="sold" />
{data.map((item) => (
<LineGuide
records={[
{ genre: item.genre, sold: 'min' },
{ genre: item.genre, sold: item.sold },
]}
// 第一个点向下偏移 120px,第二个点不偏移
offsetY={['120px', 0]}
style={{ stroke: '#f00', lineWidth: 2 }}
/>
))}
</Chart>
</Canvas>style 函数形式
<Canvas context={context}>
<Chart data={data}>
<Line x="genre" y="sold" />
<LineGuide
records={[
{ genre: 'Sports', sold: 'min' },
{ genre: 'Sports', sold: 'max' },
]}
style={(points, chart) => {
// Canvas 坐标系中 y 轴向下,points[0].y > points[1].y 表示上升
const isRising = points[0].y > points[1].y;
return {
stroke: isRising ? 'green' : 'red',
lineWidth: 2,
};
}}
/>
</Chart>
</Canvas>虚线样式
<Canvas context={context}>
<Chart data={data}>
<Line x="genre" y="sold" />
<LineGuide
records={[
{ genre: 'Sports', sold: 'min' },
{ genre: 'Sports', sold: 'max' },
]}
style={{ stroke: '#999', lineWidth: 1, lineDash: [4, 4] }}
/>
</Chart>
</Canvas>多条辅助线组合
横线与竖线组合,标注平均值线与峰值点:
<Canvas context={context}>
<Chart data={data}>
<Line x="genre" y="sold" />
{/ 水平参考线:50% 位置 /}
<LineGuide
records={[
{ genre: 'min', sold: '50%' },
{ genre: 'max', sold: '50%' },
]}
style={{ stroke: '#999', lineWidth: 1, lineDash: [4, 4] }}
/>
{/ 竖线:标注最大值点 /}
{data.filter((item) => item.sold > 300).map((item) => (
<LineGuide
records={[
{ genre: item.genre, sold: 'min' },
{ genre: item.genre, sold: item.sold },
]}
style={{ stroke: '#f00', lineWidth: 2 }}
/>
))}
</Chart>
</Canvas>使用动画
线条从下往上生长的动效:
<LineGuide
records={[
{ genre: 'Sports', sold: 'min' },
{ genre: 'Sports', sold: 275 },
]}
style={{ stroke: '#f00', lineWidth: 2 }}
animation={(points, chart) => ({
appear: {
duration: 800,
easing: 'easeOut',
property: ['y2'], // 支持端点坐标动画:x1, y1, x2, y2
start: { y2: points[0].y }, // 从起点开始
end: { y2: points[1].y }, // 生长到终点
}
})}
/>更多动画配置详见 动画文档。
---
Site/Docs/Api/Chart/Guide/Point Guide.Zh
---
title: 点标注 - PointGuide
---
Usage 用法
import { Canvas, Chart, Line, PointGuide } from '@antv/f2';const data = [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 120 },
{ genre: 'Shooter', sold: 350 },
{ genre: 'Other', sold: 150 },
];
<Canvas context={context}>
<Chart data={data}>
<Line x="genre" y="sold" />
{data.map((item) => (
<PointGuide
records={[item]}
offsetX={0}
offsetY={0}
style={{ fill: '#f00' }}
/>
))}
</Chart>
</Canvas>
TypeScript 类型定义
interface PointGuideProps {
/ 标注位置的数据项或比例值 */
records: RecordItem[];
/ x 轴偏移量,支持数字或带单位的字符串(如 '10px')*/
offsetX?: number | string;
/ y 轴偏移量,支持数字或带单位的字符串(如 '10px')*/
offsetY?: number | string;
/ 圆形样式,支持对象或函数形式 */
style?: Partial<CircleStyleProps> | ((points: Point[], chart: Chart) => Partial<CircleStyleProps>);
/ 动画配置,详见 动画文档 */
animation?: AnimationProps | ((points: Point[], chart: Chart) => AnimationProps);
/ 点击事件回调 */
onClick?: (ev: Event) => void;
/ 是否显示,默认 true */
visible?: boolean;
/ 是否精确定位(用于分组柱状图中精确定位到每个子柱子) */
precise?: boolean;
}/ 画布坐标点 */
interface Point {
x: number;
y: number;
}
/ 数据记录 */
type RecordItem = Record<string, string | number>;
Props
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| records | Array<RecordItem> | - | 标注位置的数据项或比例值,支持特殊值(见下方说明) |
| offsetX | number \| string | 0 | x 轴偏移量 |
| offsetY | number \| string | 0 | y 轴偏移量 |
| style | CircleStyleProps \| Function | 见下方 | 圆形样式,支持对象或函数形式 |
| animation | AnimationProps \| Function | - | 动画配置,详见 动画文档 |
| onClick | (ev: Event) => void | - | 点击事件回调 |
| visible | boolean | true | 是否显示标注 |
| precise | boolean | - | 是否精确定位(用于分组柱状图中精确定位到每个子柱子) |
默认样式值
{
fill: '#fff',
r: 3,
lineWidth: 2,
stroke: '#1890ff',
}records 特殊值
records 的值可以使用特殊字符串来表示位置,无需计算具体数值:
| 值 | 含义 | 对应位置 |
|----|------|----------|
| 'min' | 最小值 | 0 |
| 'max' | 最大值 | 1 |
| 'median' | 中位值 | 0.5 |
| '0%' | 0% 位置 | 0.0 |
| '50%' | 50% 位置 | 0.5 |
| '100%' | 100% 位置 | 1.0 |
示例:标注每个 x 轴位置的 y 轴最小值
{data.map((item) => (
<PointGuide
records={[{ genre: item.genre, sold: 'min' }]}
style={{ stroke: '#262626' }}
/>
))}style 属性
style 支持两种形式:
对象形式:静态样式
style={{ fill: '#f00', stroke: '#000', lineWidth: 2 }}函数形式:动态样式,根据位置或数据计算样式
style={(points, chart) => ({
fill: points[0].y > 0.5 ? '#f00' : '#00f'
})}函数接收两个参数:
- points: Point[] - 转换后的画布坐标点数组
- chart: Chart - 图表实例,可获取图表布局信息等
支持的样式属性见 Shape 属性文档。
用法示例
使用特殊值标注
<Canvas context={context}>
<Chart data={data}>
<Line x="genre" y="sold" />
{data.map((item) => (
<PointGuide
records={[{ genre: item.genre, sold: 'min' }]}
style={{ stroke: '#262626' }}
/>
))}
{data.map((item) => (
<PointGuide
records={[{ genre: item.genre, sold: 'max' }]}
style={{ stroke: '#82DC95' }}
/>
))}
</Chart>
</Canvas>标注百分比位置
<Canvas context={context}>
<Chart data={data}>
<Line x="genre" y="sold" />
{data.map((item) => (
<PointGuide
records={[{ genre: item.genre, sold: '100%' }]}
style={{ stroke: 'blue' }}
/>
))}
{data.map((item) => (
<PointGuide
records={[{ genre: item.genre, sold: '50%' }]}
style={{ stroke: 'red' }}
/>
))}
</Chart>
</Canvas>style 函数形式
<Canvas context={context}>
<Chart data={data}>
<Line x="genre" y="sold" />
{data.map((item) => (
<PointGuide
records={[item]}
style={(points, chart) => {
const y = points[0].y;
const { top, bottom } = chart.layout;
const normalizedY = (y - bottom) / (top - bottom);
return {
fill: normalizedY > 0.7 ? 'red' : 'gray',
r: normalizedY > 0.7 ? 6 : 4,
};
}}
/>
))}
</Chart>
</Canvas>多标注组合
使用多个 map 分别生成多个标注:
<Canvas context={context}>
<Chart data={data}>
<Line x="genre" y="sold" />
{data.map((item) => (
<PointGuide
records={[{ genre: item.genre, sold: 'min' }]}
style={{ stroke: '#262626' }}
/>
))}
{data.map((item) => (
<PointGuide
records={[{ genre: item.genre, sold: 'median' }]}
style={{ stroke: '#FF6797' }}
/>
))}
{data.map((item) => (
<PointGuide
records={[{ genre: item.genre, sold: 'max' }]}
style={{ stroke: '#82DC95' }}
/>
))}
</Chart>
</Canvas>使用动画
<Canvas context={context}>
<Chart data={data}>
<Line x="genre" y="sold" />
{data.map((item) => (
<PointGuide
records={[item]}
style={{ fill: 'red', r: 6 }}
animation={{
appear: {
duration: 450,
}
}}
/>
))}
</Chart>
</Canvas>更多动画配置详见 动画文档。
---
Site/Docs/Api/Chart/Guide/Rect Guide.Zh
---
title: 矩形标注 - RectGuide
---
Usage 用法
import { Canvas, Chart, Line, RectGuide } from '@antv/f2';const data = [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 120 },
{ genre: 'Shooter', sold: 350 },
{ genre: 'Other', sold: 150 },
];
<Canvas context={context}>
<Chart data={data}>
<Line x="genre" y="sold" />
<RectGuide
records={[data[0], data[1]]}
style={{ fill: 'yellow', fillOpacity: 0.5 }}
offsetX={0}
offsetY={0}
/>
</Chart>
</Canvas>
TypeScript 类型定义
interface RectGuideProps {
/ 矩形两个顶点对应的位置(第一个点为左上角或右下角,第二个点为对角顶点) */
records: RecordItem[];
/ x 轴偏移量,支持数字或带单位的字符串(如 '10px')*/
offsetX?: number | string;
/ y 轴偏移量,支持数字或带单位的字符串(如 '10px')*/
offsetY?: number | string;
/ 矩形样式,支持对象或函数形式 */
style?: Partial<RectStyleProps> | ((points: Point[], chart: Chart) => Partial<RectStyleProps>);
/ 动画配置,详见 动画文档 */
animation?: AnimationProps | ((points: Point[], chart: Chart) => AnimationProps);
/ 点击事件回调 */
onClick?: (ev) => void;
/ 是否显示,默认 true */
visible?: boolean;
/ 是否精确定位(用于 dodge 调整时的位置计算) */
precise?: boolean;
}interface Point {
x: number;
y: number;
}
Props
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| records | Array<RecordItem> | - | 矩形两个顶点对应的位置,需要 2 个点来定义矩形,支持特殊值(见下方说明) |
| offsetX | number \| string | 0 | x 轴偏移量 |
| offsetY | number \| string | 0 | y 轴偏移量 |
| style | RectStyleProps \| Function | - | 矩形样式,支持对象或函数形式 |
| animation | AnimationProps \| Function | - | 动画配置,详见 动画文档 |
| onClick | (ev) => void | - | 点击事件回调 |
| visible | boolean | true | 是否显示 |
| precise | boolean | - | 是否精确定位(用于 dodge 调整时的位置计算) |
records 特殊值
records 的值可以使用特殊字符串来表示位置,无需计算具体数值:
| 值 | 含义 | 对应位置 |
|----|------|----------|
| 'min' | 最小值 | 0 |
| 'max' | 最大值 | 1 |
| 'median' | 中位值 | 0.5 |
| '50%' | 50% 位置 | 0.5 |
| '100%' | 100% 位置 | 1.0 |
示例:标记从最小值到最大值的矩形区域
<RectGuide
records={[
{ genre: 'Sports', sold: 'min' },
{ genre: 'Sports', sold: 'max' },
]}
/>style 属性
style 支持两种形式:
对象形式:静态样式
style={{ fill: 'yellow', fillOpacity: 0.5, stroke: 'red', lineWidth: 2 }}函数形式:动态样式,根据位置或数据计算样式
函数签名:(points: Point[], chart: Chart) => RectStyleProps
- points: 矩形两个顶点的画布像素坐标数组,每个点包含 x 和 y 属性
- chart: 图表实例,可访问图表配置、布局等信息
style={(points, chart) => {
const height = Math.abs(points[1].y - points[0].y);
return {
fill: height > 100 ? 'red' : 'green',
fillOpacity: 0.3,
stroke: height > 100 ? 'darkred' : 'darkgreen',
};
}}支持的样式属性见 Shape 属性文档。
用法示例
标记两个数据点之间的区域
<Canvas context={context}>
<Chart data={data}>
<Line x="genre" y="sold" />
<RectGuide
records={[data[0], data[1]]}
style={{ fill: 'yellow', fillOpacity: 0.5 }}
offsetX="-24px"
offsetY="24px"
/>
</Chart>
</Canvas>标记最小值到最大值的区域
<Canvas context={context}>
<Chart data={data}>
<Line x="genre" y="sold" />
<RectGuide
records={[
{ genre: 'Sports', sold: 'min' },
{ genre: 'Sports', sold: 'max' },
]}
style={{ fill: 'rgba(255, 0, 0, 0.2)' }}
/>
</Chart>
</Canvas>style 函数形式
<RectGuide
records={[data[0], data[1]]}
style={(points, chart) => {
// points 是画布像素坐标
const height = Math.abs(points[1].y - points[0].y);
return {
fill: height > 100 ? 'red' : 'green',
fillOpacity: 0.3,
stroke: height > 100 ? 'darkred' : 'darkgreen',
};
}}
/>半透明填充区域
<RectGuide
records={[
{ genre: 'Sports', sold: 'min' },
{ genre: 'Sports', sold: 'max' },
]}
style={{
fill: 'blue',
fillOpacity: 0.1,
stroke: 'blue',
lineWidth: 1,
lineDash: [4, 4],
}}
/>多个矩形区域组合
<Canvas context={context}>
<Chart data={data}>
<Line x="genre" y="sold" />
{/ 高值区域标记 /}
<RectGuide
records={[
{ genre: 'Sports', sold: '50%' },
{ genre: 'Sports', sold: 'max' },
]}
style={{ fill: 'red', fillOpacity: 0.1 }}
/>
{/ 低值区域标记 /}
<RectGuide
records={[
{ genre: 'Sports', sold: 'min' },
{ genre: 'Sports', sold: '50%' },
]}
style={{ fill: 'green', fillOpacity: 0.1 }}
/>
</Chart>
</Canvas>使用动画
<RectGuide
records={[
{ genre: 'Sports', sold: 'min' },
{ genre: 'Sports', sold: 'max' },
]}
style={{ fill: 'yellow', fillOpacity: 0.5 }}
animation={{
appear: {
duration: 450,
easing: 'linear',
}
}}
/>更多动画配置详见 动画文档。
点击事件
<RectGuide
records={[
{ genre: 'Sports', sold: 'min' },
{ genre: 'Sports', sold: 'max' },
]}
style={{ fill: 'yellow', fillOpacity: 0.5 }}
onClick={(ev) => {
console.log('RectGuide clicked:', ev);
}}
/>条件显示
通过 visible 属性控制显示/隐藏:
<RectGuide
records={[
{ genre: 'Sports', sold: 'min' },
{ genre: 'Sports', sold: 'max' },
]}
style={{ fill: 'yellow', fillOpacity: 0.5 }}
visible={showRegion}
/>使用 chart 实例计算样式
通过 chart 参数访问图表布局信息,动态计算样式:
<RectGuide
records={[
{ genre: 'Sports', sold: 'min' },
{ genre: 'Action', sold: 'max' },
]}
style={(points, chart) => {
// points 已是画布像素坐标
const rectWidth = Math.abs(points[1].x - points[0].x);
return {
fill: rectWidth > 200 ? 'blue' : 'orange',
fillOpacity: 0.3,
};
}}
/>---
Site/Docs/Api/Chart/Guide/Tag Guide.Zh
---
title: 标签标注 - TagGuide
---
Usage 用法
import { Canvas, Chart, Interval, TagGuide } from '@antv/f2';const data = [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 120 },
{ genre: 'Shooter', sold: 350 },
{ genre: 'Other', sold: 150 },
];
<Canvas context={context}>
<Chart data={data}>
<Interval x="genre" y="sold" />
<TagGuide
records={[{ genre: 'Sports', sold: 350 }]}
content="最高销量"
direct="tr"
background={{ fill: '#fff' }}
textStyle={{ fill: '#000' }}
/>
</Chart>
</Canvas>
TypeScript 类型定义
interface TagGuideProps {
/ 标注位置的数据项或比例值 */
records: RecordItem[];
/ 文本内容 */
content?: string;
/ x 轴偏移量,支持数字或带单位的字符串(如 '10px')*/
offsetX?: number | string;
/ y 轴偏移量,支持数字或带单位的字符串(如 '10px')*/
offsetY?: number | string;
/ 箭头方向 */
direct?: 'tl' | 'tc' | 'tr' | 'cl' | 'cr' | 'bl' | 'bc' | 'br';
/ 箭头的边长 */
side?: string | number;
/ 是否自动调整方向避免超出画布 */
autoAdjust?: boolean;
/ 背景容器样式,支持 rect 组件属性 */
background?: Partial<RectStyleProps>;
/ 文本样式,支持 text 组件属性 */
textStyle?: Partial<TextStyleProps>;
/ 是否精确定位(用于分组柱状图),详见下方说明 */
precise?: boolean;
/ 是否显示标注 */
visible?: boolean;
/ 点击事件回调 */
onClick?: (ev: Event) => void;
/ 动画配置,详见 动画文档 */
animation?: AnimationProps | ((points: Point[], chart: Chart) => AnimationProps);
}Props
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| records | Array<RecordItem> | - | 标注位置的数据项或比例值,支持特殊值(见下方说明) |
| content | string | - | 文本内容 |
| offsetX | number \| string | 0 | x 轴偏移量 |
| offsetY | number \| string | 0 | y 轴偏移量 |
| direct | 'tl' \| 'tc' \| 'tr' \| 'cl' \| 'cr' \| 'bl' \| 'bc' \| 'br' | 'tl' | 箭头方向(见下方说明) |
| side | string \| number | '8px' | 箭头的边长 |
| autoAdjust | boolean | true | 是否自动调整标签方向,避免超出画布 |
| background | RectStyleProps | - | 背景容器样式,支持 rect 组件属性(见下方说明) |
| textStyle | TextStyleProps | - | 文本样式,支持 text 组件属性 |
| precise | boolean | false | 是否精确定位,用于分组柱状图中精确定位到每个子柱子(见下方说明) |
| visible | boolean | true | 是否显示标注 |
| onClick | Function | - | 点击事件回调 |
| animation | AnimationProps \| Function | - | 动画配置,详见 动画文档 |
records 特殊值
records 的值可以使用特殊字符串来表示位置,无需计算具体数值:
| 值 | 含义 | 对应位置 |
|----|------|----------|
| 'min' | 最小值 | 0 |
| 'max' | 最大值 | 1 |
| 'median' | 中位值 | 0.5 |
| '50%' | 50% 位置 | 0.5 |
| '100%' | 100% 位置 | 1.0 |
direct 方向说明
direct 属性控制标签相对于标注点的方向:
| 值 | 含义 | 图示 |
|----|------|------|
| tl | top-left,标签在左上方 | ↖ |
| tc | top-center,标签在上方居中 | ↑ |
| tr | top-right,标签在右上方 | ↗ |
| cl | center-left,标签在左侧居中 | ← |
| cr | center-right,标签在右侧居中 | → |
| bl | bottom-left,标签在左下方 | ↙ |
| bc | bottom-center,标签在下方居中 | ↓ |
| br | bottom-right,标签在右下方 | ↘ |
background 属性
background 用于设置标签背景容器的样式,支持 rect 组件属性:
background={{
fill: '#fff',
stroke: '#1677FF',
strokeWidth: 2,
radius: '8px',
padding: ['8px', '12px'],
}}支持的属性见 Rect 属性文档。
precise 精确定位模式
在分组柱状图中使用 precise 属性,可以让标注精确定位到每个子柱子的中心位置,而不是分组位置:
<Canvas context={context}>
<Chart data={data}>
<Interval x="月份" y="销量" color="城市" adjust={{ type: 'dodge' }} />
{data.map((item) => (
<TagGuide
records={[item]}
precise
content={${item.销量}}
direct="tc"
/>
))}
</Chart>
</Canvas>适用场景:当使用 adjust="dodge" 分组调整时,设置 precise={true} 可确保标注准确对应每个子柱子。
默认样式
{
container: {
fill: '#1677FF',
radius: '4px',
padding: ['4px', '8px'],
},
text: {
fontSize: '22px',
fill: '#fff',
},
arrow: {
fill: '#1677FF',
},
}用法示例
基础用法
<Canvas context={context}>
<Chart data={data}>
<Interval x="genre" y="sold" />
<TagGuide
records={[{ genre: 'Shooter', sold: 350 }]}
content="最高销量"
direct="tr"
/>
</Chart>
</Canvas>;自定义样式
<TagGuide
records={[{ genre: 'Shooter', sold: 350 }]}
content="最高销量"
direct="tl"
background={{
fill: '#fff',
stroke: '#1677FF',
strokeWidth: 2,
radius: '8px',
padding: ['8px', '12px'],
}}
textStyle={{
fill: '#1677FF',
fontSize: '24px',
fontWeight: 'bold',
}}
/>不同方向标注
{/ 右上方向 /}
<TagGuide records={[item]} content="右上" direct="tr" />
{/ 下方居中 /}
<TagGuide records={[item]} content="下方" direct="bc" />
{/ 左侧居中 /}
<TagGuide records={[item]} content="左侧" direct="cl" />使用特殊值
{/ 标注最大值 /}
<TagGuide
records={[{ genre: 'Sports', sold: 'max' }]}
content="最大值"
direct="tc"
background={{ fill: 'green' }}
/>禁用自动调整
<TagGuide
records={[item]}
content="固定方向"
direct="tl"
autoAdjust={false}
/>自定义箭头大小
<TagGuide
records={[item]}
content="大箭头"
direct="tr"
side="12px"
/>多标签组合
使用多个 map 分别生成多个标签:
<Canvas context={context}>
<Chart data={data}>
<Interval x="genre" y="sold" />
{data.map((item) => (
<TagGuide
records={[{ genre: item.genre, sold: 'max' }]}
content="Max"
direct="tc"
background={{ fill: 'red' }}
/>
))}
{data.map((item) => (
<TagGuide
records={[{ genre: item.genre, sold: 'min' }]}
content="Min"
direct="bc"
background={{ fill: 'green' }}
/>
))}
</Chart>
</Canvas>;配合 offset 使用
<TagGuide
records={[item]}
content="偏移标签"
direct="tr"
offsetX={20}
offsetY={-30}
/>使用动画
<TagGuide
records={[item]}
content="标签"
direct="tr"
animation={{
appear: {
duration: 450,
easing: 'linear',
}
}}
/>更多动画配置详见 动画文档。
分组柱状图精确定位
在分组柱状图中使用 precise 属性,让标注精确定位到每个子柱子:
import { Canvas, Chart, Interval, TagGuide, Axis } from '@antv/f2';const data = [
{ name: 'London', 月份: 'Jan.', 月均温度: 5.2 },
{ name: 'London', 月份: 'Feb.', 月均温度: 6.8 },
{ name: 'Beijing', 月份: 'Jan.', 月均温度: -3.9 },
{ name: 'Beijing', 月份: 'Feb.', 月均温度: 2.1 },
];
<Canvas context={context}>
<Chart data={data}>
<Axis field="月份" />
<Axis field="月均温度" min={-10} />
<Interval x="月份" y="月均温度" color="name" adjust={{ type: 'dodge', marginRatio: 0.05 }} />
{data.map((item) => (
<TagGuide
records={[item]}
precise
content={${item['月均温度']}°C}
direct={item['月均温度'] >= 0 ? 'tc' : 'bc'}
background={(points) => {
const colorMap = { 'London': '#1677FF', 'Beijing': '#22C678' };
return { fill: colorMap[item.name] };
}}
textStyle={{ fontSize: '20px', fill: '#fff' }}
/>
))}
</Chart>
</Canvas>
说明:
- min={-10}:Y 轴底部预留空间,避免负数标签遮挡 X 轴刻度
- direct 根据数值正负动态调整:正数标签向上(tc),负数标签向下(bc)
- background 函数让标签背景色与对应柱子颜色一致
点击事件
<TagGuide
records={[item]}
content="点击我"
direct="tr"
onClick={(e) => {
console.log('标签被点击', e);
}}
/>根据条件控制显示
通过 visible 属性动态控制标签显示:
{data.map((item) => (
<TagGuide
records={[item]}
content={item.sold}
direct="tc"
visible={item.sold > 200}
/>
))}---
Site/Docs/Api/Chart/Guide/Text Guide.Zh
---
title: 文本标注 - TextGuide
---
Usage 用法
import { Canvas, Chart, Interval, TextGuide } from '@antv/f2';const data = [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 120 },
{ genre: 'Shooter', sold: 350 },
{ genre: 'Other', sold: 150 },
];
<Canvas context={context}>
<Chart data={data}>
<Interval x="genre" y="sold" />
{data.map((item) => (
<TextGuide
records={[item]}
content={${item.sold}}
style={{ fill: '#000', fontSize: '24px', textAlign: 'center', textBaseline: 'bottom' }}
/>
))}
</Chart>
</Canvas>
TypeScript 类型定义
interface TextGuideProps {
/ 标注位置的数据项或比例值 */
records: RecordItem[];
/ 文本内容 */
content: string | number;
/ x 轴偏移量,支持数字或带单位的字符串(如 '10px')*/
offsetX?: number | string;
/ y 轴偏移量,支持数字或带单位的字符串(如 '10px')*/
offsetY?: number | string;
/ 文本样式,支持对象或函数形式(函数接收 points 和 chart 参数)*/
style?: Partial<TextStyleProps> | ((points: Point[], chart: Chart) => Partial<TextStyleProps>);
/ 动画配置,详见 动画文档 */
animation?: AnimationProps | ((points: Point[], chart: Chart) => AnimationProps);
}Props
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| records | Array<RecordItem> | - | 标注位置的数据项或比例值,支持特殊值(见下方说明) |
| content | string \| number | - | 文本内容 |
| offsetX | number \| string | 0 | x 轴偏移量 |
| offsetY | number \| string | 0 | y 轴偏移量 |
| style | TextStyleProps \| Function | - | 文本样式,支持对象或函数形式 |
| animation | AnimationProps \| Function | - | 动画配置,详见 动画文档 |
records 特殊值
records 的值可以使用特殊字符串来表示位置,无需计算具体数值:
| 值 | 含义 | 对应位置 |
|----|------|----------|
| 'min' | 最小值 | 0 |
| 'max' | 最大值 | 1 |
| 'median' | 中位值 | 0.5 |
| '50%' | 50% 位置 | 0.5 |
| '100%' | 100% 位置 | 1.0 |
示例:
// 在每个 x 轴位置标注 y 轴最小值
{data.map((item) => (
<TextGuide records={[{ genre: item.genre, sold: 'min' }]} content="Min" />
))}// 标注 y 轴 50% 位置
{data.map((item) => (
<TextGuide records={[{ genre: item.genre, sold: '50%' }]} content="50%" />
))}
style 属性
style 支持两种形式:
对象形式:静态样式
style={{ fill: '#000', fontSize: '24px', textAlign: 'center' }}函数形式:动态样式,根据位置或数据计算样式
style={(points) => ({
fill: points[0].y > 100 ? '#f00' : '#00f'
})}位置与对齐
textAlign 和 textBaseline 是控制文本相对于标注基准点(points[0])对齐位置的关键属性:
- textAlign - 控制文本相对于基准点 X 坐标的对齐方式
- textBaseline - 控制文本相对于基准点 Y 坐标的对齐方式
例如 textAlign: 'center' + textBaseline: 'bottom' 表示文本中心线与基准点 X 坐标齐平、文本底线与基准点 Y 坐标齐平,即文本位于基准点上方。
#### 文本对齐(textAlign)
textAlign 控制文本的哪条垂直参考线(左边缘、中心线、右边缘)与基准点 X 坐标对齐:
| 值 | 说明 |
|----|------|
| 'start' | 文本起始位置与基准点 X 坐标齐平(默认,从左到右时等于 left) |
| 'center' | 文本中心线与基准点 X 坐标齐平 |
| 'end' | 文本结束位置与基准点 X 坐标齐平(从左到右时等于 right) |
| 'left' | 文本左边缘与基准点 X 坐标齐平 |
| 'right' | 文本右边缘与基准点 X 坐标齐平 |
#### 文本基线对齐(textBaseline)
textBaseline 控制文本的哪条水平参考线(顶线、中线、底线、字母基线)与基准点 Y 坐标对齐:
| 值 | 说明 |
|----|------|
| 'top' | 文本顶线与基准点 Y 坐标齐平 |
| 'middle' | 文本中线与基准点 Y 坐标齐平(默认) |
| 'bottom' | 文本底线与基准点 Y 坐标齐平 |
| 'alphabetic' | 字母基线与基准点 Y 坐标齐平 |
| 'hanging' | 悬挂基线与基准点 Y 坐标齐平 |
典型组合示例:
// 文本位于数据点上方(底部紧贴)
<TextGuide
records={[item]}
content={item.sold}
style={{ textAlign: 'center', textBaseline: 'bottom' }}
/>// 文本中心与数据点重合
<TextGuide
records={[item]}
content={item.sold}
style={{ textAlign: 'center', textBaseline: 'middle' }}
/>
// 文本位于数据点下方(顶部紧贴)
<TextGuide
records={[item]}
content={item.sold}
style={{ textAlign: 'center', textBaseline: 'top' }}
/>
支持的样式属性见 Shape 属性文档。
用法示例
折线图数据点标注
在折线图中,records={[item]} 的基准点 points[0] 就是折线图上该数据点的位置:
<Canvas context={context}>
<Chart data={data}>
<Line x="genre" y="sold" />
{data.map((item) => (
<TextGuide
records={[item]}
content={item.sold}
style={{
fill: '#000',
fontSize: '24px',
textAlign: 'center',
textBaseline: 'bottom',
}}
/>
))}
</Chart>
</Canvas>使用特殊值标注
<Canvas context={context}>
<Chart data={data}>
<Interval x="genre" y="sold" />
{data.map((item) => (
<TextGuide
records={[{ genre: item.genre, sold: 'min' }]}
content="最小值"
style={{ fill: 'red', fontSize: '20px', textAlign: 'center' }}
/>
))}
</Chart>
</Canvas>使用偏移量
<TextGuide
records={[item]}
content={item.sold}
offsetX={10}
offsetY="-10px"
style={{ textAlign: 'center', textBaseline: 'bottom' }}
/>style 函数形式
函数接收 points(坐标数组)和 chart(图表实例)参数:
<TextGuide
records={[item]}
content={item.sold}
style={(points, chart) => ({
fill: item.sold > 200 ? 'red' : 'black',
fontSize: item.sold > 200 ? '28px' : '20px',
textAlign: 'center',
})}
/>多标注组合
使用多个 map 分别生成多个标注:
<Canvas context={context}>
<Chart data={data}>
<Interval x="genre" y="sold" />
{data.map((item) => (
<TextGuide
records={[{ genre: item.genre, sold: 'min' }]}
content="Min"
style={{ fill: 'green', textAlign: 'center' }}
/>
))}
{data.map((item) => (
<TextGuide
records={[{ genre: item.genre, sold: 'max' }]}
content="Max"
style={{ fill: 'red', textAlign: 'center' }}
/>
))}
</Chart>
</Canvas>使用动画
<TextGuide
records={[item]}
content={item.sold}
animation={{
appear: {
duration: 600,
easing: 'ease-in',
property: ['opacity'],
start: { opacity: 0 },
end: { opacity: 1 },
}
}}
/>更多动画配置详见 动画文档。
---
Site/Docs/Api/Chart/Area.Zh
---
title: 面积 - Area
order: 5
---
用于绘制区域图(面积图)、层叠区域图、区间区域图等, 继承自 几何标记 Geometry
Usage
import { Canvas, Chart, Area } from '@antv/f2';
const data = [
{ genre: 'Sports', sold: 5 },
{ genre: 'Strategy', sold: 10 },
{ genre: 'Action', sold: 20 },
{ genre: 'Shooter', sold: 20 },
{ genre: 'Other', sold: 40 },
];<Canvas context={context}>
<Chart data={data}>
<Area x="genre" y="sold" />
</Chart>
</Canvas>;
Props
Area 组件继承自 Geometry,支持以下属性(包含继承的通用属性和 Area 特有属性):
属性概览
| 属性名 | 类型 | 必填 | 默认值 | 描述 |
|--------|------|------|--------|------|
| x | string | 是 | - | x 轴的数据映射字段名 |
| y | string | 是 | - | y 轴的数据映射字段名 |
| color | string \| object \| array | 否 | - | 颜色映射,详见下方 |
| size | string \| object \| array \| number | 否 | - | 大小映射,详见下方 |
| viewClip | boolean | 否 | false | 是否只显示图表区域内(两轴之间)的部分 |
| adjust | string | 否 | - | 数据调整方式,可选值见下方 |
| startOnZero | boolean | 否 | false | y 轴是否需要从 0 开始 |
| animation | object | 否 | - | 动画配置,详见下方 |
| style | object | 否 | - | 图形样式,详见下方 |
| connectNulls | boolean | 否 | false | 是否连接空值 |
---
color 属性
color 支持多种配置格式:
| 格式 | 类型 | 说明 | 示例 |
|------|------|------|------|
| 固定值 | string | 直接指定颜色值 | <Area color="#1890FF" /> |
| 字段映射 | string | 根据数据字段自动映射 | <Area color="category" /> |
| 数组形式 | [string, string[]] | [字段, 颜色数组] | <Area color={["cat", ["red", "blue"]]} /> |
| 对象形式 | object | 详细配置,属性见下表 | <Area color={{ field: "cat", range: ["red", "blue"] }} /> |
| 类型指定 | object | 指定映射类型,属性见下表 | <Area color={{ type: "linear", field: "val" }} /> |
#### color 对象格式
| 属性 | 类型 | 必填 | 默认值 | 描述 |
|------|------|------|--------|------|
| field | string | 是 | - | 映射的数据字段名 |
| range | string[] | 否 | - | 颜色范围数组 |
| callback | (value: any, record?: any) => string | 否 | - | 自定义颜色函数。value 为 field 指定字段在数据中的值,record 为完整数据对象 |
#### color 类型格式
| 属性 | 类型 | 必填 | 默认值 | 描述 |
|------|------|------|--------|------|
| type | 'linear' \| 'category' | 是 | - | 映射类型,可选值见下表 |
| field | string | 是 | - | 映射的数据字段名 |
| range | string[] | 否 | - | 颜色范围数组 |
#### color 映射类型
| type 值 | 描述 |
|----------|------|
| linear | 线性渐变映射,颜色会渐变 |
| category | 分类映射,颜色离散分配 |
---
size 属性
size 支持多种配置格式:
| 格式 | 类型 | 说明 | 示例 |
|------|------|------|------|
| 固定值 | number | 直接指定大小 | <Area size={4} /> |
| 字段映射 | string | 根据数据字段自动映射 | <Area size="value" /> |
| 数组形式 | [string, number[]] | [字段, 大小数组] | <Area size={["val", [2, 4, 6]]} /> |
| 对象形式 | object | 详细配置,属性见下表 | <Area size={{ field: "val", range: [2, 10] }} /> |
| 类型指定 | object | 指定映射类型,属性见下表 | <Area size={{ type: "linear", field: "val" }} /> |
#### size 对象格式
| 属性 | 类型 | 必填 | 默认值 | 描述 |
|------|------|------|--------|------|
| field | string | 是 | - | 映射的数据字段名 |
| range | number[] | 否 | - | 大小范围数组 |
| callback | (value: any, record?: any) => number | 否 | - | 自定义大小函数。value 为 field 指定字段在数据中的值,record 为完整数据对象 |
#### size 类型格式
| 属性 | 类型 | 必填 | 默认值 | 描述 |
|------|------|------|--------|------|
| type | 'linear' \| 'category' | 是 | - | 映射类型,同 color 映射类型 |
| field | string | 是 | - | 映射的数据字段名 |
| range | number[] | 否 | - | 大小范围数组 |
---
style 属性
Area 组件支持的常用样式属性:
| 属性名 | 类型 | 默认值 | 描述 |
|--------|------|--------|------|
| fill | string | - | 填充颜色,支持渐变和纹理 |
| fillOpacity | number | 1 | 填充透明度,范围 0-1 |
| stroke | string | - | 描边颜色(边框颜色) |
| strokeWidth | number | - | 描边宽度(边框宽度) |
| strokeOpacity | number | 1 | 描边透明度,范围 0-1 |
| opacity | number | 1 | 整体透明度,范围 0-1 |
| lineCap | 'butt' \| 'round' \| 'square' | 'butt' | 边框线条端点样式 |
| lineJoin | 'bevel' \| 'round' \| 'miter' | 'miter' | 边框线条连接样式 |
| shadowColor | string | - | 阴影颜色 |
| shadowBlur | number | 0 | 阴影模糊程度 |
| cursor | string | - | 鼠标样式 |
使用示例:
// 设置填充颜色
<Area
x="genre"
y="sold"
style={{
fill: '#1890FF',
fillOpacity: 0.6
}}
/>// 带边框的面积图
<Area
x="genre"
y="sold"
style={{
fill: '#1890FF',
fillOpacity: 0.3,
stroke: '#0050B3',
strokeWidth: 2
}}
/>// 渐变填充
<Area
x="genre"
y="sold"
style={{
fill: 'linear-gradient(180deg, #1890FF, #0050B3)',
fillOpacity: 0.8
}}
/>// 半透明 + 阴影效果
<Area
x="genre"
y="sold"
style={{
fill: '#1890FF',
fillOpacity: 0.4,
shadowColor: 'rgba(0, 0, 0, 0.2)',
shadowBlur: 15
}}
/>更多样式属性(如渐变、纹理、裁剪等)请参考:绘图属性完整文档
---
adjust 属性
数据调整方式可选值:
| 值 | 描述 |
|-----|------|
| stack | 层叠,将同一个分类的数据值累加起来 |
| dodge | 分组散开,将同一个分类的数据进行分组均匀分布 |
| symmetric | 数据对称,使生成的图形居中对齐 |
---
animation 属性
动画配置按阶段划分,三个阶段(appear/update/leave)支持相同的属性结构:
| 阶段 | 属性 | 类型 | 必填 | 默认值 | 描述 |
|------|------|------|------|--------|------|
| appear | easing | string \| function | 否 | 'linear' | 缓动函数,可选值见下方 |
| (元素进场) | duration | number | 否 | 300 | 动画时长 (ms) |
| | delay | number | 否 | 0 | 延迟时间 (ms) |
| | property | string[] | 否 | - | 变化的属性数组,如 ['x', 'y'] |
| | start | object | 否 | - | 起始状态,结构见下表 |
| | end | object | 否 | - | 结束状态,结构见下表 |
| update | easing | string \| function | 否 | 'linear' | 缓动函数,可选值见下方 |
| (数据更新) | duration | number | 否 | 300 | 动画时长 (ms) |
| | delay | number | 否 | 0 | 延迟时间 (ms) |
| | property | string[] | 否 | - | 变化的属性数组,如 ['x', 'y'] |
| | start | object | 否 | - | 起始状态,结构见下表 |
| | end | object | 否 | - | 结束状态,结构见下表 |
| leave | easing | string \| function | 否 | 'linear' | 缓动函数,可选值见下方 |
| (元素离场) | duration | number | 否 | 300 | 动画时长 (ms) |
| | delay | number | 否 | 0 | 延迟时间 (ms) |
| | property | string[] | 否 | - | 变化的属性数组,如 ['x', 'y'] |
| | start | object | 否 | - | 起始状态,结构见下表 |
| | end | object | 否 | - | 结束状态,结构见下表 |
注意: 三个阶段的属性结构完全相同,可根据需要单独配置某个阶段。例如只配置 appear 阶段可实现进场动画。#### 动画状态对象 (start/end)
| 属性 | 类型 | 描述 |
|------|------|------|
| fillOpacity | number | 填充透明度,范围 0-1 |
| opacity | number | 整体透明度,范围 0-1 |
| x | number | x 坐标 |
| y | number | y 坐标 |
| stroke | string | 描边颜色 |
| lineWidth | number | 线宽 |
#### 缓动函数 (easing)
| 值 | 描述 |
|-----|------|
| 'linear' | 线性 |
| 'ease-in' / 'in' | 加速 |
| 'ease-out' / 'out' | 减速 |
| 'ease-in-out' / 'in-out' | 先加速后减速 |
| 'ease-out-in' / 'out-in' | 先减速后加速 |
更多缓动函数可见:easing 函数源码
#### 动画配置示例
默认动画配置(组件内置):
// Area 组件默认使用从左到右的擦除效果
<Area x="genre" y="sold" />
// 内置配置: { appear: { easing: 'quadraticOut', duration: 450 }, update: { easing: 'linear', duration: 450 } }自定义进场动画:
// 淡入效果
<Area
x="genre"
y="sold"
animation={{
appear: {
easing: 'ease-out',
duration: 1000,
property: ['opacity'],
start: { opacity: 0 },
end: { opacity: 1 }
}
}}
/>从底部生长效果:
// 区域从底部向上生长
<Area
x="genre"
y="sold"
animation={{
appear: {
easing: 'ease-out',
duration: 800,
property: ['y'],
start: { y: 0 }, // 从基线开始
end: { y: 1 } // 生长到目标位置
}
}}
/>配置多个动画阶段:
<Area
x="genre"
y="sold"
animation={{
appear: {
easing: 'ease-out',
duration: 800,
property: ['fillOpacity'],
start: { fillOpacity: 0 },
end: { fillOpacity: 0.6 }
},
update: {
easing: 'linear',
duration: 450,
property: ['points']
},
leave: {
easing: 'ease-in',
duration: 500,
property: ['opacity'],
end: { opacity: 0 }
}
}}
/>禁用动画:
<Area
x="genre"
y="sold"
animation={false}
/>---
方法
几何标记统一方法 详见:几何标记
---
Site/Docs/Api/Chart/Axis.Zh
---
title: 坐标轴 - Axis
order: 6
---
坐标轴配置。F2 的坐标轴的组成如下:
| 术语 | 英文 | 对应属性 |
| ------------ | -------- | ------------ |
| 坐标轴文本 | label | style.label |
| 坐标轴线 | line | style.line |
| 坐标轴刻度线 | tickLine | style.tickLine |
| 坐标轴网格线 | grid | style.grid |
TypeScript 类型定义
interface AxisProps {
visible?: boolean;
field: string;
position?: 'top' | 'right' | 'bottom' | 'left';
formatter?: (value: any) => string | number;
type?: 'identity' | 'linear' | 'cat' | 'timeCat';
tickCount?: number;
range?: [number, number];
mask?: string;
min?: number;
max?: number;
nice?: boolean;
ticks?: Array<string | number>;
style?: StyleProps;
grid?: 'arc' | 'line';
labelAutoRotate?: boolean;
labelAutoHide?: boolean;
safetyDistance?: number | string;
}interface StyleProps {
label?: TextStyleProps | LabelCallback;
line?: LineStyleProps;
tickLine?: TickLineProps;
grid?: LineStyleProps | GridCallback;
labelOffset?: number | string;
symbol?: MarkerStyleProps | MarkerStyleProps[];
width?: number | string;
height?: number | string;
}
interface Tick {
/ 归一化值 (0-1) */
value: number;
/ 显示文本 */
text: string;
/ 原始值 */
tickValue: string | number;
}
interface TickLineProps {
length?: number;
stroke?: string;
lineWidth?: number | string;
lineDash?: Array<string | number>;
}
interface MarkerStyleProps {
/ 标记类型 */
symbol?: 'circle' | 'square' | 'arrow';
/ 标记半径 */
radius?: string | number;
}
Usage
import { Canvas, Chart, Interval, Axis } from '@antv/f2';const data = [
{ genre: 'Sports', sold: 5 },
{ genre: 'Strategy', sold: 10 },
{ genre: 'Action', sold: 20 },
{ genre: 'Shooter', sold: 20 },
{ genre: 'Other', sold: 40 },
];
<Canvas context={context}>
<Chart data={data}>
<Axis field="genre" />
<Axis field="sold" />
<Interval x="genre" y="sold" />
</Chart>
</Canvas>;
Props
部分属性可参考 scale 图表度量,度量详细介绍可见:度量
基础配置
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| field | string | - | 坐标轴的数据字段(必填) |
| visible | boolean | true | 是否显示该坐标轴 |
| position | 'top' \| 'right' \| 'bottom' \| 'left' | 自动判断 | 坐标轴显示位置 |
度量配置
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| type | 'identity' \| 'linear' \| 'cat' \| 'timeCat' | - | 度量类型 |
| tickCount | number | - | 坐标轴刻度点个数 |
| range | [number, number] | - | 输出范围 [min, max],值域 0-1 |
| mask | string | - | 时间格式化 mask |
| min | number | - | 数值范围最小值 |
| max | number | - | 数值范围最大值 |
| nice | boolean | true | 优化数值范围使刻度均匀分布 |
| ticks | Array<string \| number> | - | 自定义刻度值 |
| formatter | (value: any) => string \| number | - | 格式化刻度点文本 |
标签自动处理
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| labelAutoRotate | boolean | false | 自动旋转标签以防止重叠 |
| labelAutoHide | boolean | false | 自动隐藏重叠标签 |
| safetyDistance | number \| string | 2 | 重叠检测安全边距 |
样式配置(style)
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| style.label | TextStyleProps \| LabelCallback | #808080, 20px | 标签样式 |
| style.line | LineStyleProps | #E8E8E8, 1px | 坐标轴线样式 |
| style.tickLine | TickLineProps | #E8E8E8 | 刻度线样式 |
| style.grid | LineStyleProps \| GridCallback | #E8E8E8, 1px | 网格线样式(默认虚线) |
| style.labelOffset | number \| string | '15px' | 标签偏移距离 |
| style.symbol | MarkerStyleProps \| MarkerStyleProps[] | - | 轴箭头/圆点标记 |
| style.width | number \| string | - | 组件宽度 |
| style.height | number \| string | - | 组件高度 |
极坐标配置
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| grid | 'arc' \| 'line' | - | 极坐标网格线类型 |
默认样式值
来源:packages/f2/src/theme.ts
const defaultStyle = {
labelOffset: '15px',
line: { stroke: '#E8E8E8', lineWidth: '1px' },
symbol: { fill: '#E8E8E8', radius: '10px' },
tickLine: { stroke: '#E8E8E8' },
label: { fill: '#808080', fontSize: '20px' },
grid: { stroke: '#E8E8E8', lineWidth: '1px', lineDash: ['4px'] },
};用法示例
格式化刻度值
<Axis
field="sold"
formatter={(value) => value.toFixed(2) + '%'}
/>自定义标签样式(函数形式)
<Axis
field="value"
formatter={(v) => v.toFixed(2) + '%'}
style={{
label: (text, index, ticks) => {
// text: formatter 处理后的文本,如 "-0.48%"
// ticks: 所有刻度数组,ticks[index].tickValue 是原始值
const number = parseFloat(text);
if (number > 0) {
return { text: '+' + text, fill: '#F5222D' };
} else if (number === 0) {
return { fill: '#000', fontWeight: 'bold' };
} else {
return { fill: '#52C41A' };
}
},
}}
/>使用 ticks 数组数据
<Axis
field="value"
style={{
label: (text, index, ticks) => {
const total = ticks.length;
const isFirst = index === 0;
const isLast = index === total - 1; if (isFirst || isLast) {
return { fill: '#1890FF', fontWeight: 'bold' };
}
return { fill: '#808080' };
},
}}
/>
注意:ticks[index].value是归一化值(0-1),原始值请使用ticks[index].tickValue。
自定义网格线(函数形式)
<Axis
field="value"
style={{
grid: (text, index, total) => {
// text: 格式化后的文本,index: 当前索引,total: 刻度总数
if (index === total - 1) {
return { stroke: 'rgb(113, 113, 112)', strokeOpacity: 1, lineDash: null };
}
return { stroke: 'rgb(220, 220, 220)', strokeOpacity: 0.4, lineDash: null };
},
}}
/>自动处理标签
<Axis
field="month"
labelAutoRotate={true}
labelAutoHide={true}
/>注意:safetyDistance默认值为2,通常无需手动设置。
坐标轴箭头标记
<Axis
field="value"
style={{
line: {},
// symbol 数组:[最大值端, 最小值端]
// 单箭头:[{ type: 'arrow' }],双端:[{ type: 'arrow' }, { type: 'circle' }]
symbol: [{ type: 'arrow' }],
}}
/>旋转标签
旋转标签用于解决标签重叠问题,但会降低可读性。
#### ⚠️ 使用优先级
1. labelAutoRotate(推荐)
2. 旋转 45°
3. 旋转 90°(谨慎)#### 自动旋转
<Axis field="month" labelAutoRotate={true} />#### 手动旋转 45°
<Axis
field="month"
style={{
label: { transform: 'rotate(-45deg)', align: 'end', textBaseline: 'middle' },
}}
/>#### 手动旋转 90°
<Axis
field="year"
style={{
label: { transform: 'rotate(-90deg)', align: 'end', textBaseline: 'middle' },
}}
/>---
Site/Docs/Api/Chart/Candlestick.Zh
---
title: K 线图 - Candlestick
order: 5
---
用于 K 线图, 继承自 几何标记 Geometry
Usage
import { Axis, Candlestick, Canvas, Chart, jsx } from '@antv/f2';const data = [
{
time: '2017-10-24',
// 格式为:[open, close, lowest, highest]
value: [20, 34, 10, 38],
},
{
time: '2017-10-25',
value: [40, 35, 30, 50],
},
{
time: '2017-10-26',
value: [31, 38, 33, 44],
},
{
time: '2017-10-27',
value: [38, 15, 5, 42],
},
];
const { props } = (
<Canvas context={context}>
<Chart data={data}>
<Axis field="time" />
<Axis field="value" />
<Candlestick x="time" y="value" />
</Chart>
</Canvas>
);
数据结构说明
y 轴字段格式为:[open, close, lowest, highest] 分别代表:[开盘价, 收盘价, 最低价, 最高价]
Props
Candlestick 组件继承自 Geometry,支持以下属性(包含继承的通用属性和 Candlestick 特有属性):
属性概览
| 属性名 | 类型 | 必填 | 默认值 | 描述 |
|--------|------|------|--------|------|
| x | string | 是 | - | x 轴的数据映射字段名 |
| y | string | 是 | - | y 轴的数据映射字段名 |
| color | object | 否 | { range: ['#E62C3B', '#0E9976', '#999999'] } | 涨跌颜色,详见下方 |
| sizeRatio | number | 否 | 0.5 | 矩形大小比例,范围 [0, 1] |
| viewClip | boolean | 否 | false | 是否只显示图表区域内(两轴之间)的部分 |
| startOnZero | boolean | 否 | false | y 轴是否需要从 0 开始 |
| animation | object | 否 | - | 动画配置,详见下方 |
| style | object | 否 | - | 图形样式,详见下方 |
---
color 属性
Candlestick 的 color 用于设置「涨」、「跌」、「平盘」三种状态的颜色。
仅支持对象形式,通过 range 属性指定三种颜色:
| 属性 | 类型 | 必填 | 默认值 | 描述 |
|------|------|------|--------|------|
| range | [string, string, string] | 否 | ['#E62C3B', '#0E9976', '#999999'] | [上涨颜色, 下跌颜色, 平盘颜色] |
注意:Candlestick 的 color 仅支持range属性,不支持field、callback等其他属性。组件会根据价格变动自动选择对应的颜色。
// 自定义涨跌颜色
<Candlestick
x="time"
y="value"
color={{ range: ['#ff4d4f', '#52c41a', '#d9d9d9'] }} // 红涨、绿跌、灰平
/>---
sizeRatio 属性
矩形的大小比例,范围 [0, 1],默认为 0.5,表示矩形的宽度占可用空间的 50%。
| 值 | 效果 |
|-----|------|
| 0.5 (默认) | 矩形宽度和空白处各占 50% |
| 0.8 | 矩形更宽,空白更窄 |
| 1.0 | 矩形占满整个空间,无间隙 |
<Candlestick x="time" y="value" sizeRatio={0.8} />---
style 属性
Candlestick 组件支持的常用样式属性:
| 属性名 | 类型 | 默认值 | 描述 |
|--------|------|--------|------|
| fill | string | - | 填充颜色(K线实体颜色) |
| fillOpacity | number | 1 | 填充透明度,范围 0-1 |
| stroke | string | - | 描边颜色(K线影线颜色) |
| strokeWidth | number | 2 | 描边宽度(影线宽度) |
| strokeOpacity | number | 1 | 描边透明度,范围 0-1 |
| radius | string \| number[] | '2px' | 实体矩形圆角半径 |
| lineCap | 'butt' \| 'round' \| 'square' | 'round' | 影线端点样式 |
| opacity | number | 1 | 整体透明度,范围 0-1 |
| shadowColor | string | - | 阴影颜色 |
| shadowBlur | number | 0 | 阴影模糊程度 |
| cursor | string | - | 鼠标样式 |
使用示例:
// 自定义涨跌颜色
<Candlestick
x="time"
y="value"
color={{ range: ['#E62C3B', '#0E9976', '#999999'] }}
/>
// color 属性已控制涨跌色,style 可用于其他样式// 设置圆角矩形
<Candlestick
x="time"
y="value"
style={{
radius: '2px'
}}
/>// 调整影线宽度
<Candlestick
x="time"
y="value"
style={{
strokeWidth: 1, // 更细的影线
strokeOpacity: 0.8
}}
/>// 半透明效果
<Candlestick
x="time"
y="value"
style={{
fillOpacity: 0.7,
strokeOpacity: 0.8,
opacity: 0.9
}}
/>// 渐变填充(K线实体)
<Candlestick
x="time"
y="value"
style={{
fill: 'linear-gradient(180deg, rgba(230, 44, 59, 0.8), rgba(230, 44, 59, 0.4))',
stroke: '#E62C3B'
}}
/>// 带阴影效果
<Candlestick
x="time"
y="value"
style={{
shadowColor: 'rgba(0, 0, 0, 0.2)',
shadowBlur: 6
}}
/>更多样式属性(如渐变、纹理、裁剪等)请参考:绘图属性完整文档
> 注意: Candlestick 的color属性专门用于控制涨跌颜色,style.fill会覆盖此设置。建议使用color属性设置涨跌色,style仅用于其他样式效果(如圆角、阴影、透明度等)。
---
animation 属性
动画配置按阶段划分,三个阶段(appear/update/leave)支持相同的属性结构:
| 阶段 | 属性 | 类型 | 必填 | 默认值 | 描述 |
|------|------|------|------|--------|------|
| appear | easing | string \| function | 否 | 'linear' | 缓动函数,可选值见下方 |
| (元素进场) | duration | number | 否 | 300 | 动画时长 (ms) |
| | delay | number | 否 | 0 | 延迟时间 (ms) |
| | property | string[] | 否 | - | 变化的属性数组 |
| | start | object | 否 | - | 起始状态,结构见下表 |
| | end | object | 否 | - | 结束状态,结构见下表 |
| update | easing | string \| function | 否 | 'linear' | 缓动函数,可选值见下方 |
| (数据更新) | duration | number | 否 | 300 | 动画时长 (ms) |
| | delay | number | 否 | 0 | 延迟时间 (ms) |
| | property | string[] | 否 | - | 变化的属性数组 |
| | start | object | 否 | - | 起始状态,结构见下表 |
| | end | object | 否 | - | 结束状态,结构见下表 |
| leave | easing | string \| function | 否 | 'linear' | 缓动函数,可选值见下方 |
| (元素离场) | duration | number | 否 | 300 | 动画时长 (ms) |
| | delay | number | 否 | 0 | 延迟时间 (ms) |
| | property | string[] | 否 | - | 变化的属性数组 |
| | start | object | 否 | - | 起始状态,结构见下表 |
| | end | object | 否 | - | 结束状态,结构见下表 |
注意: 三个阶段的属性结构完全相同,可根据需要单独配置某个阶段。Candlestick 由影线(line)和实体(rect)两部分组成,动画会同时作用于这两部分。
#### 动画状态对象 (start/end)
| 属性 | 类型 | 描述 |
|------|------|------|
| fillOpacity | number | 填充透明度,范围 0-1 |
| opacity | number | 整体透明度,范围 0-1 |
| x | number | x 坐标 |
| y | number | y 坐标 |
| stroke | string | 描边颜色 |
| lineWidth | number | 线宽 |
| height | number | 矩形高度(Candlestick 特有) |
#### 缓动函数 (easing)
| 值 | 描述 |
|-----|------|
| 'linear' | 线性 |
| 'ease-in' / 'in' | 加速 |
| 'ease-out' / 'out' | 减速 |
| 'ease-in-out' / 'in-out' | 先加速后减速 |
| 'ease-out-in' / 'out-in' | 先减速后加速 |
更多缓动函数可见:easing 函数源码
#### 动画配置示例
默认动画配置(组件内置):
// Candlestick 组件默认使用从底部向上生长的效果
<Candlestick x="time" y="value" />
// 内置配置: { appear: { easing: 'linear', duration: 300, property: ['y', 'height'], start: { y: y0, height: 0 } } }自定义生长动画:
// 使用减速效果,更自然的生长感
<Candlestick
x="time"
y="value"
animation={{
appear: {
easing: 'ease-out',
duration: 600,
property: ['y', 'height'],
start: { height: 0 }
}
}}
/>淡入效果:
// K线淡入显示
<Candlestick
x="time"
y="value"
animation={{
appear: {
easing: 'ease-out',
duration: 800,
property: ['opacity'],
start: { opacity: 0 },
end: { opacity: 1 }
}
}}
/>仅影线动画:
// 只对上下影线应用动画
<Candlestick
x="time"
y="value"
animation={{
appear: {
easing: 'linear',
duration: 500,
property: ['y1', 'y2'], // 影线的 y1, y2 属性
start: { y1: 0, y2: 0 }
}
}}
/>配置多个动画阶段:
<Candlestick
x="time"
y="value"
animation={{
appear: {
easing: 'ease-out',
duration: 600,
property: ['y', 'height'],
start: { height: 0 }
},
update: {
easing: 'linear',
duration: 300,
property: ['x', 'y', 'width', 'height']
},
leave: {
easing: 'ease-in',
duration: 300,
property: ['opacity', 'height'],
end: { opacity: 0, height: 0 }
}
}}
/>禁用动画:
<Candlestick
x="time"
y="value"
animation={false}
/>方法
---