普通视图

发现新文章,点击刷新页面。
今天 — 2026年4月29日首页

React 图表库选型指南:Recharts、ECharts、Nivo、Lightweight Charts 深度对比

作者 GeraldChen
2026年4月28日 16:58

选图表库之前,先明确你最需要哪种图表——因为不同库的设计重心差异很大,没有一个"全能冠军"。

这篇文章针对三种最常用的图表类型:K 线图(金融场景核心)、柱状图(通用仪表盘标配)、Treemap(层级数据展示),逐一给出各主流库的真实能力评估,以及具体的选型建议。数据来自 2026 年 4 月的 npm/GitHub 公开数据。

市场格局:七个主流选项

定位 GitHub Stars 周下载量
Recharts React 声明式图表 27k 3.6M
Apache ECharts (echarts-for-react) 功能最全的配置式图表 64k 800k
Nivo 精致动画 + 无障碍 13.6k 450k
TradingView Lightweight Charts 专业金融/K线 15k 560k
Visx (Airbnb) D3 原语封装 20k 300k
Victory React Native 兼容(主要卖点) 11.2k 272k
Chart.js (react-chartjs-2) 通用 Canvas 图表 Chart.js 65k react-chartjs-2 ~2.5M / chart.js ~4.1M

Victory 的核心卖点是 React Native 兼容——同一套组件可以同时用于 Web 和 React Native App。纯 Web 场景下,Recharts 或 Nivo 通常是更好的选择;本文后续章节不展开 Victory,专注于 Web 场景更常用的库。

综合对比表

维度 Recharts ECharts Nivo Lightweight Charts Visx Chart.js
K 线图 变通实现 原生支持 不支持 专为此设计 需组合 需插件
柱状图 完整 最完整 完整 + Canvas 版 仅基础 完全自定义 完整
Treemap 基础支持 支持 + 层级钻取 三渲染模式 不支持 @visx/hierarchy 不支持
渲染方式 SVG Canvas / WebGL SVG + Canvas Canvas SVG + Canvas Canvas
大数据性能 1k+ 有感知卡顿 百万级数据点 Canvas 版较好 金融实时优化 取决于实现 百万级
Bundle(gzip) ~50 KB 按需 ~80-130 KB ~82 KB ~12 KB(gzip) ~30-50 KB ~66 KB
学习曲线 中高 中(金融专用) 高(需 D3 知识)
TypeScript v3 后良好 良好 良好 优秀(TS 编写) 优秀(TS 编写) 良好
SSR 支持 有限制 有限制 原生支持 不支持 需配置 不支持
维护状态 活跃 非常活跃 活跃 非常活跃 更新节奏慢 活跃

K 线图:哪个库真正好用?

TradingView Lightweight Charts — 唯一专业选择

如果 K 线图是项目的核心需求,Lightweight Charts 是唯一不需要妥协的选择。

它是专为金融时序数据设计的,K 线(Candlestick)、折线(Line)、面积(Area)、成交量柱(Histogram)都是第一公民。数据格式极简:

import { createChart } from "lightweight-charts";

const chart = createChart(document.getElementById("chart"), {
  width: 800,
  height: 400,
});

const candleSeries = chart.addCandlestickSeries({
  upColor: "#26a69a",
  downColor: "#ef5350",
  borderVisible: false,
  wickUpColor: "#26a69a",
  wickDownColor: "#ef5350",
});

candleSeries.setData([
  { time: "2024-01-01", open: 100, high: 110, low: 95, close: 105 },
  { time: "2024-01-02", open: 105, high: 115, low: 100, close: 98 },
  { time: "2024-01-03", open: 98, high: 108, low: 92, close: 103 },
]);

在 React 中使用(useRef + useEffect 模式):

import { useEffect, useRef } from "react";
import { createChart, IChartApi } from "lightweight-charts";

interface CandleData {
  time: string;
  open: number;
  high: number;
  low: number;
  close: number;
}

export function CandlestickChart({ data }: { data: CandleData[] }) {
  const containerRef = useRef<HTMLDivElement>(null);
  const chartRef = useRef<IChartApi | null>(null);

  useEffect(() => {
    if (!containerRef.current) return;

    const chart = createChart(containerRef.current, {
      layout: { background: { color: "#1a1a2e" }, textColor: "#d1d4dc" },
      grid: { vertLines: { color: "#2a2a3c" }, horzLines: { color: "#2a2a3c" } },
      width: containerRef.current.clientWidth,
      height: 400,
    });

    const series = chart.addCandlestickSeries();
    series.setData(data);
    chart.timeScale().fitContent();

    chartRef.current = chart;

    const handleResize = () => {
      if (containerRef.current) {
        chart.applyOptions({ width: containerRef.current.clientWidth });
      }
    };
    window.addEventListener("resize", handleResize);

    return () => {
      window.removeEventListener("resize", handleResize);
      chart.remove();
    };
  }, [data]);

  return <div ref={containerRef} />;
}

v5(2026 年 4 月最新)base bundle 35 KB(未压缩),gzip 后约 12 KB,是所有图表库里最小的。Canvas 渲染,实时 tick 级更新(每秒数百次数据刷新)依然流畅。

局限:只做金融图表。如果仪表盘还需要饼图、热力图、散点图,需要引入另一个库。

Apache ECharts — K 线 + 量价混合场景

量价图(K 线 + 柱状成交量)在金融产品里极常见,ECharts 的 candlestick series 和 bar series 可以直接叠加在同一个图表实例里:

import * as echarts from "echarts/core";
import { CandlestickChart, BarChart } from "echarts/charts";
import { GridComponent, TooltipComponent, DataZoomComponent } from "echarts/components";
import { CanvasRenderer } from "echarts/renderers";

echarts.use([CandlestickChart, BarChart, GridComponent, TooltipComponent, DataZoomComponent, CanvasRenderer]);

const option = {
  xAxis: { data: dates },
  yAxis: [
    { scale: true },           // K 线坐标轴
    { scale: true, show: false }, // 成交量坐标轴(隐藏)
  ],
  series: [
    {
      type: "candlestick",
      data: klineData, // [open, close, low, high]
      yAxisIndex: 0,
    },
    {
      type: "bar",
      data: volumeData,
      yAxisIndex: 1,
      itemStyle: {
        color: (params: any) => params.data[1] >= params.data[0] ? "#26a69a" : "#ef5350",
      },
    },
  ],
  dataZoom: [{ type: "inside" }, { type: "slider" }],
};

内置的 dataZoom 组件(鼠标滚轮缩放、滑动条范围选择)在金融场景里非常实用,无需额外开发。

Recharts — K 线图的陷阱

Recharts 官方示例展示了用 <Bar> + <ErrorBar> 模拟 K 线图,但这只是近似实现:

// 这种实现的问题:
// 1. 阳线/阴线颜色需要用 Cell 逐个设置,数据量大时性能差
// 2. 影线(上下 wick)和实体颜色联动逻辑需要手写
// 3. 没有金融图表需要的十字光标、价格标签等组件
// 4. 代码量是 Lightweight Charts 的 3-5 倍

如果项目只是偶尔展示一个 K 线图,可以接受这种实现。但如果 K 线图是核心功能,维护成本会很高。


柱状图:Recharts 为什么是默认选择

Recharts — React 友好的首选

Recharts 是下载量最高的 React 专属图表库(3.6M 周下载),核心原因是它与 React 的组合方式高度一致:

import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, Cell, LabelList } from "recharts";

const data = [
  { month: "Jan", revenue: 4200, cost: 2400 },
  { month: "Feb", revenue: 3800, cost: 1900 },
  { month: "Mar", revenue: 5100, cost: 2800 },
  { month: "Apr", revenue: 4700, cost: 2200 },
];

// 堆叠柱状图
export function StackedBar() {
  return (
    <BarChart width={600} height={300} data={data}>
      <CartesianGrid strokeDasharray="3 3" />
      <XAxis dataKey="month" />
      <YAxis />
      <Tooltip />
      <Legend />
      <Bar dataKey="revenue" stackId="a" fill="#6366f1" />
      <Bar dataKey="cost" stackId="a" fill="#f43f5e" />
    </BarChart>
  );
}

// 单个柱子自定义颜色(Cell)
export function CustomColorBar() {
  const colors = ["#6366f1", "#8b5cf6", "#a78bfa", "#c4b5fd"];
  return (
    <BarChart width={600} height={300} data={data}>
      <Bar dataKey="revenue">
        {data.map((_, index) => (
          <Cell key={index} fill={colors[index % colors.length]} />
        ))}
        <LabelList dataKey="revenue" position="top" />
      </Bar>
    </BarChart>
  );
}

stackId 实现堆叠、Cell 自定义颜色、LabelList 显示数值标签,都是声明式写法,不需要记配置项路径。

限制:SVG 渲染,数据量超过 1000 个数据点时会有感知卡顿。柱状图 bar 数量很多(如时序数据按分钟统计 24 小时 = 1440 个点)时,应考虑切换到 ECharts 或 Chart.js。

Apache ECharts — 大数据 + 高级交互

数据量超 1 万,或者需要 brush 选择、动态排序等高级交互时,ECharts 是更合适的选择:

// 动态排序柱状图(ECharts 内置功能,Recharts 需要自实现)
const option = {
  xAxis: { max: "dataMax" },
  yAxis: { type: "category", data: categories, animationEasing: "linear" },
  series: [{
    type: "bar",
    data: values,
    realtimeSort: true,  // 实时排序动画
    label: { show: true, position: "right" },
  }],
  animationDuration: 0,
  animationDurationUpdate: 2000,
};

ECharts v6(2025 年 7 月发布)新增矩阵坐标系,进一步扩展了柱状图的展示能力。

Nivo — 视觉精致和无障碍

如果产品有无障碍要求(WCAG 2.1 AA),Nivo 是主流 React 图表库中开箱即用无障碍支持最完整的选择之一。动画效果基于 @react-spring,过渡效果最精致:

import { ResponsiveBar } from "@nivo/bar";

<ResponsiveBar
  data={data}
  keys={["revenue", "cost"]}
  indexBy="month"
  margin={{ top: 50, right: 130, bottom: 50, left: 60 }}
  padding={0.3}
  colors={{ scheme: "nivo" }}
  animate={true}          // 基于 @react-spring 的动画
  motionConfig="gentle"   // 动画缓动配置
  role="application"      // 无障碍 ARIA
  ariaLabel="Revenue and cost by month"
/>

数据量大时切换到 <BarCanvas>,用 Canvas 渲染替代 SVG,API 保持一致。


Treemap:Nivo 领先

Nivo @nivo/treemap — 三渲染模式

Nivo 的 Treemap 支持 SVG、Canvas、HTML 三种渲染方式,通过 nodeComponent 可以完全自定义每个节点:

import { ResponsiveTreeMap } from "@nivo/treemap";

const data = {
  name: "root",
  children: [
    {
      name: "Frontend",
      children: [
        { name: "React", size: 85000 },
        { name: "Vue", size: 42000 },
        { name: "Angular", size: 38000 },
      ],
    },
    {
      name: "Backend",
      children: [
        { name: "Node.js", size: 62000 },
        { name: "Python", size: 71000 },
      ],
    },
  ],
};

<ResponsiveTreeMap
  data={data}
  identity="name"
  value="size"
  valueFormat=".02s"
  margin={{ top: 10, right: 10, bottom: 10, left: 10 }}
  labelSkipSize={12}
  labelTextColor={{ from: "color", modifiers: [["darker", 1.2]] }}
  parentLabelPosition="left"
  parentLabelTextColor={{ from: "color", modifiers: [["darker", 2]] }}
  colors={{ scheme: "tableau10" }}
/>

如果需要完全自定义每个格子的渲染,Nivo 提供 nodeComponent prop,可以传入自定义 React 组件来控制节点的外观和交互——比如在格子里加 sparkline、progress bar 或任意 SVG 元素。

Apache ECharts — 层级钻取

如果 Treemap 需要支持点击父节点放大(drill-down)和面包屑导航,ECharts 内置了这个功能:

const option = {
  series: [{
    type: "treemap",
    data: hierarchicalData,
    leafDepth: 1,     // 默认显示到第几层
    drillDownIcon: "▶",
    breadcrumb: { show: true },  // 显示层级导航
    levels: [
      { itemStyle: { borderWidth: 3, gapWidth: 3 } },
      { itemStyle: { borderWidth: 2, gapWidth: 2 } },
      { colorSaturation: [0.35, 0.5] },
    ],
  }],
};

性能对比:何时 SVG 不够用?

渲染方式决定了性能上限:

渲染方式 适用数据量 特点
SVG < 1000 数据点 DOM 节点多,但可 CSS 控制、支持 SSR
Canvas 2D < 100 万数据点 性能强,无法 CSS 控制单个元素
WebGL > 100 万数据点 极限性能,ECharts GL 支持

Recharts 使用 SVG,数据点超过 1000 时页面渲染帧率明显下降。ECharts 默认用 Canvas,即使 10 万个数据点也能流畅渲染。

参考基准(MacBook Pro M3,Chrome 122,柱状图,默认配置):

数据量 Recharts (SVG) ECharts (Canvas) Chart.js (Canvas)
500 点 流畅 流畅 流畅
2000 点 轻微卡顿 流畅 流畅
10000 点 明显卡顿 流畅 流畅
100000 点 无法使用 流畅 基本流畅

以上为参考数据,实际表现与数据结构、动画配置、图表类型相关,建议在目标设备上自行基准测试。


Bundle Size 对比

按需引入是关键。ECharts 全量包 ~340 KB(gzip),按需只引入用到的组件可显著减少体积——以 BarChart + Tooltip + Grid + DataZoom 组合为例,约 80-130 KB(gzip,实际取决于组件组合,建议用 bundlejs.com 实测):

// 按需引入 ECharts(推荐写法)
import * as echarts from "echarts/core";
import { BarChart, CandlestickChart } from "echarts/charts";
import {
  TitleComponent,
  TooltipComponent,
  GridComponent,
  DataZoomComponent,
} from "echarts/components";
import { CanvasRenderer } from "echarts/renderers";

echarts.use([
  BarChart,
  CandlestickChart,
  TitleComponent,
  TooltipComponent,
  GridComponent,
  DataZoomComponent,
  CanvasRenderer,
]);

Recharts v3 已设置 sideEffects: false 并提供 ES Module 输出,Vite/Webpack 5 下可 tree-shake,但其核心依赖(d3、victory-vendor 等)体积较大,实际收益有限,整包 gzip 仍约 50 KB。


选型决策树

需要 K 线图?
  ├── K 线是核心功能 → Lightweight Charts(专业、最小体积)
  └── K 线 + 其他图表混合 → Apache ECharts(一库全搞定)

不需要 K 线图:
  ├── 数据量 > 1 万 → Apache ECharts(Canvas 性能)
  ├── 需要 Treemap + 精致动画 → Nivo
  ├── 视觉高度定制(有 D3 经验)→ Visx
  └── 通用仪表盘,快速开发 → Recharts

场景推荐速查

场景 推荐 理由
纯金融 K 线图 Lightweight Charts 专业设计,gzip ~12 KB,Canvas 性能最优
K 线 + 量价柱状图混合 Apache ECharts 原生支持叠加,内置 dataZoom
通用业务仪表盘 Recharts 学习成本最低,社区最大
数据量 10k+ Apache ECharts Canvas/WebGL 渲染
Treemap + 层级钻取 Apache ECharts 内置 drill-down,面包屑导航
Treemap + 自定义节点 Nivo nodeComponent 完全自定义
无障碍(WCAG 2.1 AA) Nivo 开箱无障碍支持最完整的选择之一
极致定制化 Visx D3 原语,完全控制
快速原型 Chart.js 文档最多,社区问答最丰富

结论

没有一个图表库适合所有场景。实际项目中最常见的两种组合方案:

方案 A(金融/交易类产品):Lightweight Charts(K 线) + Recharts 或 ECharts(其他图表)

方案 B(通用 SaaS 仪表盘):Apache ECharts(主力,性能好功能全) 或 Recharts + Nivo(React 友好 + 精致视觉,适合数据量不大的场景)

如果只能选一个并且对性能有要求,Apache ECharts 是覆盖最广的单一选择:K 线、柱状图、Treemap 全部原生支持,Canvas 渲染不怕大数据,按需引入后体积可控。如果团队 React 经验丰富且数据量有限,Recharts 的开发体验更接近 React 惯例,上手成本最低。


原文链接chenguangliang.com/posts/blog1…

❌
❌