Victory logo

Victory

基于 D3 的 React 图表库,业界唯一成熟的 Web + React Native 跨平台数据可视化解决方案。

可视化图表ReactReact Native

Victory 是唯一同时支持 Web(SVG)和 React Native(Skia GPU)的成熟 React 图表库,Web 端基于 D3 数学计算和 SVG 渲染,Native 端使用 Skia GPU 加速实现 60+ FPS 动画,是跨平台数据可视化的首选方案。

Victory

基于 D3 的 React 图表库,业界唯一成熟的 Web + React Native 跨平台数据可视化解决方案。

技术简介说明

Victory 是由 Formidable Labs 创建、现由 Nearform 维护的 React 图表库。其核心定位是提供一套统一的组件 API 同时支持 Web(SVG 渲染)和 React Native(Skia GPU 渲染),这使得 Victory 在 React 生态中占据了一个独特的生态位——当项目需要同时在 Web 和移动端(iOS/Android)展示一致的图表体验时,Victory 几乎是唯一成熟的开源选择。

Victory 的架构基于 D3.js 做数学计算(scales、domains、path 生成),但不依赖 D3 的 DOM 操作。Web 端使用纯 SVG 渲染,React Native 端(Victory Native XL, v40+)使用 @shopify/react-native-skia 做 GPU 加速渲染,配合 react-native-reanimated 实现独立 JS 线程的 60+ FPS 动画。这种架构让 Victory Native XL 在低端设备上也能达到流畅的图表交互体验。

Victory 项目分为两条产品线:victory(Web 端,当前 v37.x)和 victory-native-xl(React Native 端,当前 v41.x)。Web 端处于稳定维护模式,以 bug 修复和类型改进为主;React Native 端则是当前最活跃的发展方向,基于 Skia 的重写带来了显著的性能提升和全新的功能规划。

基本信息

快速上手

安装

Web 端

# npm
npm install victory
 
# yarn
yarn add victory
 
# pnpm
pnpm add victory

Web 端为单包安装,所有图表组件包含在 victory 包中。

React Native 端

# 安装 Victory Native XL
pnpm add victory-native
 
# 安装 peer dependencies(必需)
pnpm add @shopify/react-native-skia
pnpm add react-native-reanimated
pnpm add react-native-gesture-handler

重要:Victory Native XL (v40+) 需要安装上述三个 peer dependencies,缺一不可。

基础配置

Web 端

Victory Web 端零配置即可使用,无需 Provider 或全局设置。通过 VictoryTheme 设置全局主题:

import { VictoryTheme } from 'victory'
 
// 使用内置主题
<VictoryChart theme={VictoryTheme.material}>

React Native 端

需要在 App 根组件配置 GestureHandlerRootView

import { GestureHandlerRootView } from 'react-native-gesture-handler'
 
export default function App() {
  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      <YourApp />
    </GestureHandlerRootView>
  )
}

最小示例

Web 端

import {
  VictoryChart,
  VictoryLine,
  VictoryBar,
  VictoryAxis,
  VictoryTooltip,
  VictoryVoronoiContainer,
} from 'victory'
 
const data = [
  { x: 1, y: 2 },
  { x: 2, y: 3 },
  { x: 3, y: 5 },
  { x: 4, y: 4 },
  { x: 5, y: 6 },
]
 
export default function App() {
  return (
    <VictoryChart
      // 使用 Voronoi 容器实现 hover 交互
      containerComponent={
        <VictoryVoronoiContainer
          voronoiDimension="x"
          labels={({ datum }) => `y: ${datum.y}`}
          labelComponent={<VictoryTooltip />}
        />
      }
    >
      <VictoryAxis
        label="X 轴"
      />
      <VictoryAxis
        dependentAxis
        label="Y 轴"
      />
      <VictoryLine
        data={data}
        style={{
          data: { stroke: '#8884d8', strokeWidth: 3 },
        }}
      />
    </VictoryChart>
  )
}

React Native 端

import { CartesianChart, Line } from 'victory-native'
import { useSharedValue } from 'react-native-reanimated'
 
const DATA = (length: number = 10) =>
  Array.from({ length }, (_, index) => ({
    x: index + 1,
    y: Math.random() * 10,
  }))
 
export function MyChart() {
  const data = useSharedValue(DATA())
  
  return (
    <CartesianChart data={data} xKey="x" yKeys={['y']}>
      {({ points }) => (
        <Line points={points.y} color="red" />
      )}
    </CartesianChart>
  )
}

核心概念与架构

Web 端架构

用户数据输入
  ↓
D3 Scales 计算 (d3-scale, d3-shape)
  ↓
React 组件渲染 (VictoryChart → VictoryLine/Bar/Pie...)
  ↓
SVG 元素输出
  ↓
React Reconciliation
  ↓
DOM 更新

Web 端核心组件层次:

VictoryChart (图表容器,管理坐标系)
├── VictoryAxis / VictoryAxis (坐标轴)
├── VictoryLine / VictoryBar / VictoryArea (数据组件)
├── VictoryScatter (散点)
├── VictoryPie (饼图,独立容器)
├── VictoryGroup (组件分组)
├── VictoryStack (堆叠图表)
└── Container Components
    ├── VictoryZoomContainer (缩放)
    ├── VictoryVoronoiContainer (Voronoi hover)
    ├── VictorySelectionContainer (区域选择)
    └── VictoryCursorContainer (光标追踪)

React Native 端架构(Victory Native XL)

用户数据输入 (SharedValue)
  ↓
Skia GPU 渲染 (React Native Skia)
  ↓
Reanimated 动画 (独立 JS 线程)
  ↓
Gesture Handler 手势交互

React Native XL 的核心架构变化:

  • 渲染层:从 SVG 转向 React Native Skia(GPU 加速)
  • 动画层:从内置动画转向 Reanimated(独立 JS 线程,不阻塞 UI)
  • 交互层:使用 React Native Gesture Handler(原生手势识别)

数据绑定模型

// Web 端:通过 data prop
<VictoryBar data={[{ x: 'A', y: 1 }, { x: 'B', y: 2 }]} />
 
// React Native XL:通过 xKey/yKeys
<CartesianChart data={data} xKey="x" yKeys={['y']}>
  {({ points }) => <Line points={points.y} />}
</CartesianChart>

组合模式

Victory 强调组件组合而非配置:

// Web 端组合示例
<VictoryChart>
  <VictoryStack>
    <VictoryBar data={data1} style={{ data: { fill: 'red' } }} />
    <VictoryBar data={data2} style={{ data: { fill: 'blue' } }} />
  </VictoryStack>
</VictoryChart>

核心特性

  • 跨平台统一:唯一成熟的 Web + React Native 统一 API 方案,一套代码在 Web、iOS、Android 上运行
  • D3 驱动计算:使用 D3 的 scales、shapes 做数学计算,确保数据映射的准确性
  • GPU 加速渲染(React Native):Victory Native XL 使用 Skia 实现 GPU 加速,低端设备可达 100+ FPS
  • 组合式 API:通过组件组合(VictoryStackVictoryGroupcreateContainer)而非复杂配置构建图表
  • 容器交互系统createContainer 支持组合多种交互行为(zoom + tooltip + selection)
  • 主题系统:内置多套主题(materialgrayscaleclean),支持完全自定义
  • 动画支持:Web 端内置动画;Native 端使用 Reanimated 实现流畅过渡
  • TypeScript 支持:完整的 TypeScript 类型定义,v37.3.3+ 升级至 TypeScript 5.7.2
  • 事件系统:丰富的 events prop 支持点击、hover、拖拽等交互
  • 可组合图表:轻松实现堆叠图、分组图、多 Y 轴等复杂图表组合
  • Clean Theme:v37.3.0+ 引入的 Clean Theme 新主题系统,更现代的默认样式

生态图

关键依赖

Web 端

依赖用途
d3-scale比例尺计算
d3-shape图形路径生成
d3-interpolate值插值
d3-voronoiVoronoi 图(hover 交互)
d3-array数组工具
fast-deep-equal深比较(性能优化)
react-fast-compareReact 优化比较

React Native 端(Victory Native XL)

依赖用途
@shopify/react-native-skiaGPU 加速渲染
react-native-reanimated动画引擎(独立 JS 线程)
react-native-gesture-handler手势交互
d3-scale比例尺计算
d3-shape图形路径生成

相关工具

工具说明
victory-nativeReact Native 图表组件(v40+ 为 XL 版)
createContainer组合多种交互容器
victory-cli服务端生成图表图片

社区生态

  • npm 周下载量:~440K(Web)
  • GitHub Stars:~11,200(Web)+ ~3,500(Native XL)
  • GitHub Issues:~84 个 open issues(Web)
  • Discussions:GitHub Discussions 活跃
  • Shopify 工程博客:Shopify 持续发布 Skia/Reanimated 相关技术文章
  • Formidable Labs 支持:虽已由 Nearform 维护,Formidable 仍有影响力

适用场景

  • Web + React Native 跨平台项目:Victory 最核心的价值——需要同一套图表代码在 Web 和移动端运行
  • React Native 移动应用:Victory Native XL 是 React Native 生态中最成熟的图表库
  • 高性能移动端图表:Skia GPU 渲染在低端设备上可达 100+ FPS,适合性能敏感的移动应用
  • 需要复杂交互的图表createContainer 组合 zoom、tooltip、selection 等多种交互
  • 堆叠/分组图表VictoryStackVictoryGroup 组件使复杂组合图表简单易用
  • 企业级数据应用:Formidable Labs / Nearform 维护,有商业支持背景
  • 实时数据可视化(移动端):Victory Native XL 的 Reanimated 动画和 Streaming Data 规划适合实时数据场景

开发与工程化

开发流程

Web 端

# 克隆仓库
git clone https://github.com/FormidableLabs/victory.git
cd victory
 
# 安装依赖
pnpm install
 
# 启动开发环境
pnpm start
 
# 运行测试
pnpm test
 
# 类型检查
pnpm typecheck
 
# 构建
pnpm build

React Native 端

# 克隆仓库
git clone https://github.com/FormidableLabs/victory-native-xl.git
cd victory-native-xl
 
# 安装依赖
pnpm install
 
# 启动示例应用
cd apps/example
pnpm start

构建配置

Web 端输出格式:

dist/
├── victory.js          # UMD
├── victory.min.js      # UMD 压缩
├── victory.es.js       # ES Module
├── victory.cjs.js      # CommonJS
└── index.d.ts          # TypeScript 类型

React Native 端输出为 ES Module,供 Metro bundler 处理。

工程化最佳实践

  1. 使用 createContainer 组合交互

    const ZoomVoronoi = createContainer('zoom', 'voronoi')
    <VictoryChart containerComponent={<ZoomVoronoi />} />
  2. 锁定依赖版本:Victory 的 minor 版本可能引入 breaking changes

  3. React Native 端确保 peer deps 版本匹配:Skia 和 Reanimated 的版本需要与 Victory Native XL 兼容

  4. Bundle size 分析:Web 端支持 tree-shaking,使用 named imports

  5. CI/CD 集成:运行 pnpm test + pnpm typecheck + pnpm build 确保质量

性能与安全

性能特点

平台数据量帧率备注
Web (SVG)< 500 点流畅适合中小数据量
Web (SVG)500-2,000 点一般考虑数据降采样
Native (Skia)< 5,000 点100+ FPSGPU 加速
Native (Skia)5,000-20,000 点60+ FPS流畅动画
Native (Skia)20,000+ 点30-60 FPS仍可接受

性能优化建议

  1. Web 端大数据量

    // 使用 downsample 或限制渲染数据量
    const downsampledData = useMemo(() => lttb(rawData, 500), [rawData])
  2. React Native 端使用 SharedValue

    // 使用 shared value 避免 JS 线程阻塞
    const data = useSharedValue(rawData)
    <CartesianChart data={data} xKey="x" yKeys={['y']}>
  3. 关闭不需要的动画

    <VictoryLine animate={false} />
  4. 使用 events prop 替代全局事件

    // 精确控制事件触发范围,避免不必要的重渲染
    events={[{
      target: 'data',
      eventHandlers: {
        onMouseEnter: () => [{ target: 'data', mutation: ... }]
      }
    }]}
  5. 使用 VictoryClipContainer 裁剪优化

    // 避免渲染超出坐标系的元素
    <VictoryChart clipContainerComponent={<VictoryClipContainer />} />

安全注意事项

  • SVG 渲染不直接执行用户代码,XSS 风险较低
  • 自定义 labelComponent 时避免使用 dangerouslySetInnerHTML
  • 事件处理器中注意数据验证

已知性能瓶颈

  • Web 端 SVG 渲染在超过 2,000 数据点时性能下降明显
  • createContainer 组合多种交互时事件处理开销增加
  • Web 端缺少 Canvas 渲染选项(与 Chart.js / Nivo Canvas 相比劣势)
  • React Native 端 Skia 依赖较大,增加 App 安装包体积

技术对比

维度VictoryRechartsNivovisxChart.js
GitHub Stars~11,200~25,600~14,000~19,000~65,000
周下载量~440K~9M~650K~3M~5M
渲染方式SVG (Web) / Skia (Native)SVGSVG/Canvas/HTMLSVGCanvas
跨平台✅ Web + RN❌ 仅 Web❌ 仅 Web❌ 仅 Web❌ 仅 Web
React Native✅ 成熟支持
D3 依赖部分(计算)部分(计算)部分(计算)部分(计算)❌ 无
学习曲线中等中等
自定义能力中高中高极高
动画内置 / Reanimated (Native)内置react-spring需自建内置
TypeScript✅ (社区)
商业维护Nearform社区个人Airbnb社区

选型建议

  • Web + React Native 统一方案 → Victory(唯一选择)
  • 纯 Web 后台图表 → Recharts(社区最大,教程最多)
  • 视觉效果优先 → Nivo(动画和图表类型最丰富)
  • 极致自定义 → visx(底层原语)
  • 非 React 项目 → Chart.js / ECharts

最佳实践

生产环境推荐模式

  1. Web 端使用 createContainer 组合交互

    import { createContainer, VictoryZoomContainer, VictoryVoronoiContainer } from 'victory'
     
    // 组合 zoom + tooltip
    const InteractiveContainer = createContainer('zoom', 'voronoi')
     
    <VictoryChart
      containerComponent={
        <InteractiveContainer
          voronoiDimension="x"
          labels={({ datum }) => `${datum.y}`}
        />
      }
    >
  2. 主题统一管理

    // themes/victory-theme.ts
    export const customTheme = {
      axis: {
        style: {
          axis: { stroke: '#777' },
          ticks: { stroke: '#777' },
          tickLabels: { fill: '#333', fontSize: 12 },
        },
      },
      // ...
    }
     
    // 全局使用
    <VictoryChart theme={customTheme}>
  3. React Native 端数据流管理

    // 使用 Reanimated SharedValue 确保流畅
    function RealtimeChart() {
      const data = useSharedValue(generateData())
      
      useEffect(() => {
        const interval = setInterval(() => {
          data.value = generateData()  // 不触发 React 重渲染
        }, 100)
        return () => clearInterval(interval)
      }, [])
      
      return (
        <CartesianChart data={data} xKey="x" yKeys={['y']}>
          {({ points }) => <Line points={points.y} />}
        </CartesianChart>
      )
    }
  4. 堆叠图表

    <VictoryChart>
      <VictoryStack colorScale="warm">
        <VictoryBar data={data1} />
        <VictoryBar data={data2} />
        <VictoryBar data={data3} />
      </VictoryStack>
    </VictoryChart>

常见陷阱

陷阱说明解决方案
React Native 迁移 v36→v40+不兼容升级,API 大改参考官方迁移指南,预留充足时间
peer dependencies 遗漏RN 端忘记安装 Skia/Reanimated文档化安装步骤,CI 检查
Web 端大数据量卡顿SVG 节点过多数据降采样或切换 Canvas 方案
createContainer 参数顺序组合容器参数顺序影响行为先 zoom 后 voronoi,参考文档
主题覆盖不完整部分组件样式未受主题控制使用 style prop 补充
Next.js 15 hydration 错误v37.3.3 已修复,但需确认版本升级到最新版本

技术局限与边界

已知限制

  1. Web 端仅支持 SVG 渲染:无 Canvas 渲染选项,不适合超大规模数据集
  2. 社区规模较小:相比 Recharts(900 万周下载量),Victory 的社区资源和教程较少
  3. React Native 迁移成本高:v36 → v40+ (XL) 是不兼容升级,需安装新依赖并重写部分代码
  4. Web 端处于维护模式:v37.x 以 bug 修复为主,新功能开发集中在 React Native 端
  5. 无正式公开路线图:Web 端未来发展方向不明确
  6. Skia 依赖体积:React Native 端新增 Skia 依赖,显著增加 App 安装包体积
  7. 图表类型不如 Nivo 丰富:缺少 Sankey、Chord、Heatmap 等高级可视化

不适用场景

  • 纯 Web 项目且需要丰富图表类型 → Nivo 更合适
  • 需要 Canvas 高性能渲染(Web) → Chart.js / Nivo Canvas
  • 快速原型开发 → Recharts 学习曲线更低
  • 非 React 项目 → 选择 ECharts / Chart.js / D3

迁移注意事项

  • 从 v36 迁移到 v40+ (React Native):这是最大的迁移挑战
    • 渲染引擎从 SVG 变为 Skia
    • 动画系统从内置变为 Reanimated
    • 需要新增三个 peer dependencies
    • API 有显著变化,需参考官方迁移指南
  • 从 Recharts 迁移到 Victory Web:数据格式兼容,组件 API 需重写
  • 从 Victory Web 迁移到 Victory Native XL:API 完全不同,需要重写
  • 从 Victory 迁移到其他库:数据层迁移成本低

学习资源

2026 年现状

最新版本

  • Web 端:v37.3.6(2025 年 1 月 14 日)— 维护模式
  • React Native 端:v41.26.0(2026 年 6 月)— 活跃开发

近期重要更新

Web 端 (v37.x)

版本主要变更
v37.3.6修复 zoom 裁剪 bug
v37.3.5修复 props.groupComponent 未定义错误
v37.3.4修复 cursor 渲染回归
v37.3.3修复 Next.js 15 hydration 错误、TypeScript 5.7.2
v37.3.0Clean Theme 新主题系统
v37.2.0Clean theme 应用、delay prop

React Native 端(Victory Native XL)

活跃开发中,持续发布新版本。v41.26.0(2026 年 6 月)为当前最新版。

发展趋势

  1. React Native 端是主要方向:Victory 的未来发展重心在 React Native XL
  2. WebGPU + Skia 生态:Shopify 持续投入 WebGPU + Skia 技术栈,Victory Native XL 直接受益
  3. Web 端稳定维护:v37.x 保持 bug 修复和类型改进
  4. 规划中功能(React Native):Windowing/Brushing、Polar Chart Events、Streaming Data、水平柱状图等
  5. Nearform 维护:项目已从 Formidable Labs 过渡到 Nearform 主要维护

社区活跃度

  • Web 端:~11,200 Stars,~440K 周下载量,~84 open issues
  • Native 端:~3,500 Stars,活跃 issue 和 Discussions
  • Web 端 commit 频率较低(维护模式),Native 端频繁发布
  • 2026 年横评文章中仍被推荐为 React Native 图表首选

总体评估

Victory 在 React 图表库生态中的定位清晰且独特:跨平台(Web + React Native)图表方案的首选。Web 端虽处于维护模式但质量稳定,React Native 端(Victory Native XL)基于 Skia 的重写带来了显著的性能提升和光明的技术前景。如果项目需要同时支持 Web 和 React Native 的图表渲染,Victory 几乎是唯一成熟的开源选择。对于纯 Web 项目,需要根据具体需求在 Recharts(简单实用)、Nivo(视觉丰富)和 visx(极致灵活)之间权衡。