开源一个 React 股票 K 线图组件,传个股票代码就能画图

前端做金融图表的坑,我替你踩过了。

背景

说来话长,但我尽量说短。

某天产品跑过来跟我说:"在页面上加个 K 线图吧,应该不难。"

我当时心想,2025 年了,这东西还需要自己写?npm 上肯定一堆现成的。

结果我打开 npm 搜了一圈,发现情况不太乐观:

  • 有些组件功能倒是全,但那是人家商业产品,开源版阉割得差不多了,想用完整功能得掏钱
  • 有些看起来还行,点进去一看,最后一次 commit 是两年前,依赖的 React 版本还停留在 16
  • 还有一些纯 Canvas 手撸的,佩服是佩服,但接入成本太高,文档还是英文半成品

纠结了一下午,我决定自己写一个。

直接看东西

项目叫 kline-charts-react,已经发到 npm 上了。

GitHub | npm | 在线演示

最简单的用法,五行代码搞定:

tsx 复制代码
import { KLineChart } from 'kline-charts-react';
import 'kline-charts-react/style.css';

function App() {
  return <KLineChart symbol="sh600519" height={600} />;
}

没错,一个 symbol 属性就完事了。数据获取、指标计算、图表渲染,组件内部全包了。

"那数据是从哪来的?不会要我自己对接接口吧?"

不需要,往下看。

功能概览

目标是做到雪球 K 线图那种体验。目前做到了大概八成:

多周期:分时走势、五日分时、日 K、周 K、月 K,还有 1 分钟到 60 分钟的分钟线。炒短线的朋友可以放心了。

技术指标:支持 15 种 ------ MA、BOLL、MACD、KDJ、RSI、WR、BIAS、CCI、ATR、OBV、ROC、DMI、SAR、KC。所有指标都在浏览器端计算,不需要服务端返回。说实话,写这些计算公式的过程挺上头的,特别是 DMI 和 SAR,逻辑绕得我差点怀疑人生。

交互体验:滚轮缩放、拖拽平移、十字准线跟随、Tooltip 信息展示、缩放的撤销/重做、一键全屏、导出 PNG 图片。

外观:浅色和深色两套内置主题,也可以传自定义的颜色配置进去。

复权支持:不复权、前复权、后复权三种模式可切换,默认前复权。

数据层 ------ 聊聊 stock-sdk

做图表组件,绑定什么数据源是个问题。

前端圈搞股票数据一直比较尴尬 ------ 好用的库几乎全是 Python 的。tushare、akshare、baostock,想用的话你得起个 Python 服务,前端再请求这个服务。链路长,维护烦。

为了解决这个痛点,我做了 stock-sdk,一个纯前端/Node.js 的股票行情 SDK。

核心思路就一句话:前端工程师获取股票数据,不应该需要 Python。

stock-sdk 的几个亮点:

  • 零依赖、体积小,TypeScript 写的,打包压缩后不到 20KB
  • 浏览器和 Node.js 都行,ESM 和 CJS 双格式输出
  • 覆盖面广,A 股、港股、美股、公募基金,实时行情和历史 K 线都能取
  • 自带指标计算,MA、MACD、BOLL、KDJ、RSI 等主流技术指标直接调用
  • 类型提示完善,TS 项目用起来体验很好,字段名不用猜

简单示意:

ts 复制代码
import { StockSDK } from 'stock-sdk';

const sdk = new StockSDK();

// 拉几只股票的实时报价
const quotes = await sdk.getSimpleQuotes(['sh600519', 'sz000858']);
quotes.forEach(q => {
  console.log(`${q.name}: ${q.price} (${q.changePercent}%)`);
});

// 拉日 K 线数据
const kline = await sdk.getKline('sh600519', { period: 'daily', adjust: 'qfq' });

kline-charts-react 底层就集成了 stock-sdk,传一个股票代码进去,组件会自动请求数据、计算指标、渲染图表,整条链路在浏览器端闭环,不依赖任何后端服务。

stock-sdk 本身也是独立的 npm 包,不画图的场景一样能用 ------ 做个行情 Dashboard、写个 Node 定时任务抓数据之类的,都没问题。

更多用法参考官方文档:stock-sdk.linkdiary.cn

当然了,如果你们公司有现成的行情接口,组件也支持自定义数据源,完全可以绕过 stock-sdk。

技术选型

图表渲染这块我选了 ECharts。

有人可能觉得 ECharts 太重了,但实际上组件里用了按需引入 ------ 只注册了 CandlestickChart、LineChart、BarChart、ScatterChart 这几个模块,并不是把整个 ECharts 都打进去。

而且 ECharts 的优势很明显:渲染性能好、交互事件体系成熟、响应式适配开箱即用。自己从 Canvas 开始画当然也行,但工期不允许。

关于包体积,组件自身(不含 echarts 和 react)构建产物 77KB ,gzip 后约 19KB。echarts 走 peerDependency,项目里已有的话不会重复打包。

设计上的一些考量

1. 开箱即用 vs 高度可配

默认情况下传个 symbol 就能渲染,零配置。但所有细节都暴露了 props:

tsx 复制代码
<KLineChart
  symbol="sh600519"
  period="weekly"
  adjust="qfq"
  theme="dark"
  indicators={['ma', 'volume', 'kdj', 'rsi']}
  indicatorOptions={{
    ma: { periods: [5, 10, 20, 60] },
  }}
  maxSubPanes={3}
  height={700}
/>

想用哪些指标、均线取几日、副图显示几个、用什么主题,随便调。

2. 自定义数据源

如果你有自己的行情 API,通过 dataProvider 可以完全替换内置的数据获取逻辑:

tsx 复制代码
const myProvider = {
  getKline: async (params, signal) => {
    const res = await fetch(`/api/kline?symbol=${params.symbol}&period=${params.period}`, { signal });
    return res.json();
  },
  getTimeline: async (params, signal) => {
    const res = await fetch(`/api/timeline?symbol=${params.symbol}`, { signal });
    return res.json();
  },
};

<KLineChart symbol="sh600519" dataProvider={myProvider} />

数据结构很直观 ------ K 线是 { date, open, close, high, low, volume, amount },分时是 { time, price, volume, amount, avgPrice }。传进来原始数据就行,MA、MACD 这些指标组件内部会自己算。

3. 外部控制

通过 ref 可以在组件外部调用方法,适合需要和外部 UI 联动的场景:

tsx 复制代码
const chartRef = useRef<KLineChartRef>(null);

// 手动刷新
chartRef.current?.refresh();

// 导出成图片
const dataUrl = chartRef.current?.exportImage('png');

// 程序化切换到周 K
chartRef.current?.setPeriod('weekly');

// 拿到底层 ECharts 实例
const instance = chartRef.current?.getEchartsInstance();

4. 分时自动刷新

盯盘场景下,分时图需要定时刷新。组件内置了轮询机制,还支持限制只在交易时段刷新:

tsx 复制代码
<KLineChart
  symbol="sh600519"
  period="timeline"
  autoRefresh={{ intervalMs: 5000, onlyTradingTime: true }}
/>

安装方式

bash 复制代码
yarn add kline-charts-react

# peer dependencies 也别忘了装
yarn add react react-dom echarts

echarts 是 peerDependency,你项目里已经有的话就不用重复安装了。

还有哪些不足

几个目前没做好的地方,先摆出来:

  • 手机端:触屏的捏合缩放、双指拖动这些还没有专门适配
  • 图片导出:导出的图片不包含左上角的指标数值标签(那部分是 DOM 元素,不在 Canvas 上)
  • WebSocket:暂时只有轮询,还没对接实时推送

这些都在计划中,后面会陆续补上。

写在最后

本来只是想解决手头的需求,没想到越写越多,最后索性做成了一个完整的组件库发了出来。

如果你正好有在 React 项目中展示 K 线图的需求,不妨装上试试。遇到问题欢迎在 GitHub 提 issue,PR 更好。

顺手点个 Star 就更好了,我写那些技术指标公式真的掉了不少头发。


相关推荐
木斯佳1 分钟前
前端八股文面经大全: 美团财务科技前端一面 (2026-04-09)·面经深度解析
前端·实习面经·前端初级
天外天-亮1 分钟前
Vue2.0 + jsmind:开发思维导图
javascript·vue.js·jsmind
LIO4 分钟前
React 零基础入门,一篇搞懂核心用法(适合新手)
前端·react.js
TeamDev18 分钟前
JxBrowser 8.18.2 版本发布啦!
java·前端·跨平台·桌面应用·web ui·jxbrowser·浏览器控件
netkiller-BG7NYT19 分钟前
yoloutils - Openclaw Agent Skill
前端·webpack·node.js
北城笑笑23 分钟前
FPGA 51,基于 ZYNQ 7Z010 的 FPGA 高速路由转发加速系统架构设计(Xilinx ZYNQ-MINI 7Z010 CLG400 -1)
前端·fpga开发·系统架构·fpga
蜡台27 分钟前
JavaScript async和awiat 使用
开发语言·前端·javascript·async·await
tzy23330 分钟前
AI 对话的流式输出详解——不止于SSE
javascript·ai·llm·sse·readablestream
挖稀泥的工人32 分钟前
能够插入 DOM 的输入框
前端·javascript·vue.js
xiaotao13135 分钟前
第十五章:企业级部署方案
前端·vite·前端打包