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

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

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

市场格局:七个主流选项

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

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

综合对比表

维度RechartsEChartsNivoLightweight ChartsVisxChart.js
K 线图变通实现原生支持不支持专为此设计需组合需插件
柱状图完整最完整完整 + Canvas 版仅基础完全自定义完整
Treemap基础支持支持 + 层级钻取三渲染模式不支持@visx/hierarchy不支持
渲染方式SVGCanvas / WebGLSVG + CanvasCanvasSVG + CanvasCanvas
大数据性能1k+ 有感知卡顿百万级数据点Canvas 版较好金融实时优化取决于实现百万级
Bundle(gzip)~50 KB按需 ~80-130 KB~82 KB~12 KB(gzip)~30-50 KB~66 KB
学习曲线中高中(金融专用)高(需 D3 知识)
TypeScriptv3 后良好良好良好优秀(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 元素。具体 API 参考 nivo.rocks/treemap 的 nodeComponent 文档。

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 EChartsCanvas/WebGL 渲染
Treemap + 层级钻取Apache ECharts内置 drill-down,面包屑导航
Treemap + 自定义节点NivonodeComponent 完全自定义
无障碍(WCAG 2.1 AA)Nivo开箱无障碍支持最完整的选择之一
极致定制化VisxD3 原语,完全控制
快速原型Chart.js文档最多,社区问答最丰富

结论

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

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

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

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