npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

kline-charts-react

v0.1.0

Published

Professional stock K-line chart React component with built-in data source, powered by ECharts and stock-sdk

Readme

KLine Charts


功能特性

  • 🚀 零配置数据 - 内置 stock-sdk,传入股票代码自动获取数据
  • 🔌 可插拔数据源 - 支持自定义 DataProvider(解决跨域/接入自有行情源/SSR)
  • 🌍 多市场支持 - A 股、港股、美股
  • 📊 丰富周期 - 分时、五日、日 K、周 K、月 K、分钟级 K 线
  • 📈 技术指标 - MA/MACD/BOLL/KDJ/RSI/WR/BIAS/CCI/ATR/OBV/ROC/DMI/SAR/KC
  • 🎯 交互完善 - 缩放、平移、十字准线、Tooltip、撤销/重做
  • 🖥️ 全屏模式 - 一键全屏展示
  • 🔄 自动刷新 - 分时模式支持自动刷新数据
  • 🎨 高度可定制 - 主题、颜色、指标参数均可配置
  • 📱 响应式设计 - 自适应容器尺寸
  • 📦 轻量体积 - Tree-shaking 友好,按需引入 ECharts 组件

安装

npm install kline-charts-react

# 或使用 yarn
yarn add kline-charts-react

# 或使用 pnpm
pnpm add kline-charts-react

Peer Dependencies

npm install react react-dom echarts

快速开始

import { KLineChart } from 'kline-charts-react';
import 'kline-charts-react/style.css';

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

基础用法

切换股票

<KLineChart
  symbol="sz000001"  // 平安银行
  market="A"         // A 股(默认)
/>

指定周期

<KLineChart
  symbol="sh600519"
  defaultPeriod="weekly"  // 非受控模式下默认显示周 K
/>

可选周期:timeline | timeline5 | 1 | 5 | 15 | 30 | 60 | daily | weekly | monthly

受控 / 非受控

periodadjustindicators 支持受控模式;defaultPerioddefaultAdjustdefaultIndicators 用于非受控默认值。

// 非受控
<KLineChart
  symbol="sh600519"
  defaultPeriod="daily"
  defaultAdjust="qfq"
  defaultIndicators={['ma', 'volume', 'macd']}
/>
// 受控
function App() {
  const [period, setPeriod] = useState<PeriodType>('daily');

  return (
    <KLineChart
      symbol="sh600519"
      period={period}
      onPeriodChange={setPeriod}
    />
  );
}

配置技术指标

<KLineChart
  symbol="sh600519"
  indicators={['ma', 'volume', 'macd', 'kdj']}
  indicatorOptions={{
    ma: { periods: [5, 10, 20, 60] },
    macd: { short: 12, long: 26, signal: 9 },
  }}
/>

深色主题

<KLineChart
  symbol="sh600519"
  theme="dark"
/>

自动刷新(分时模式)

<KLineChart
  symbol="sh600519"
  period="timeline"
  autoRefresh={{ intervalMs: 5000, onlyTradingTime: true }}
/>

自定义数据源

解决跨域问题或接入自有行情源:

import { KLineChart, type KLineDataProvider } from 'kline-charts-react';

const customProvider: KLineDataProvider = {
  // K 线数据(必须实现)
  getKline: async (params, signal) => {
    // params: { symbol, market, period, adjust, cursor?, limit? }
    // cursor/limit 仅在「向左滚动加载更多历史」时传入,见下方「无限滚动加载历史」
    const res = await fetch(`/api/kline?symbol=${params.symbol}&period=${params.period}`, { signal });
    return res.json(); // 返回 KlineData[]
  },
  // 分时数据(可选,period 为 'timeline' / 'timeline5' 时使用)
  getTimeline: async (params, signal) => {
    // params.period: 'timeline'(单日,默认)| 'timeline5'(五日)
    const days = params.period === 'timeline5' ? 5 : 1;
    const res = await fetch(`/api/timeline?symbol=${params.symbol}&days=${days}`, { signal });
    const json = await res.json();
    // 推荐返回 { data, prevClose }:prevClose(昨收)用于分时图的涨跌着色与昨收参考线
    return { data: json.data, prevClose: json.prevClose };
    // 也兼容直接 return TimelineData[](此时无昨收线)
  },
};

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

KlineData 数据结构

getKline 需要返回 KlineData[],每条数据的字段如下:

interface KlineData {
  date: string;              // 日期/时间,如 "2024-01-15" 或 "2024-01-15 09:35"
  open: number | null;       // 开盘价
  close: number | null;      // 收盘价
  high: number | null;       // 最高价
  low: number | null;        // 最低价
  volume: number | null;     // 成交量
  amount: number | null;     // 成交额
  changePercent?: number;    // 涨跌幅(可选)
  change?: number;           // 涨跌额(可选)
  amplitude?: number;        // 振幅(可选)
  turnoverRate?: number;     // 换手率(可选)
}

TimelineData 数据结构

getTimeline 推荐返回 TimelineResult{ data, prevClose }),其中 data 为分时序列、prevClose 为昨收价;也兼容直接返回 TimelineData[]

interface TimelineData {
  time: string;       // 时间:"09:30" 或 "2024-01-15 09:30" 均可(渲染层两种都支持;
                      // 内置源:A 股单日分时为 HH:mm,港/美股单日与所有五日分时带日期前缀)
  price: number;      // 当前价格
  volume: number;     // 累计成交量(按交易日累计)
  amount: number;     // 累计成交额(按交易日累计)
  avgPrice: number;   // 均价
}

interface TimelineResult {
  data: TimelineData[];
  prevClose?: number | null;  // 昨收价:用于分时图涨跌着色与昨收参考线,缺省则不绘制昨收线
}

技术指标(MA、MACD、KDJ 等)会由组件自动根据 K 线数据计算,无需在数据源中提供。 未实现 getTimeline 的自定义数据源:分时/五日分时会退化为「调用 getKline 拿分钟数据 + 组件内聚合 VWAP」,此时无昨收基准。

无限滚动加载历史(loadMore)

日/周/月 K 向左滚动到最左侧时,组件会调用 getKline 并带上 cursor(当前最早一根的 date)与 limit(默认 180,可用 requestOptions.loadMoreLimit 配置)请求更早的历史:

const provider: KLineDataProvider = {
  getKline: async ({ symbol, period, cursor, limit }, signal) => {
    const qs = cursor ? `&before=${cursor}&limit=${limit}` : '';
    const res = await fetch(`/api/kline?symbol=${symbol}&period=${period}${qs}`, { signal });
    return res.json();
  },
};

⚠️ 内置数据源不支持增量加载历史:默认 provider 一次性返回全部历史并忽略 cursor/limit,向左滚动不会加载更多(首次触发后自动停止探测)。 无限滚动仅在自定义 dataProvider 实现了基于 cursor 的分页时生效。

分页返回的顺序不限(newest-first / oldest-first 均可):组件会去重并按日期 升序归并后再渲染。

使用 Ref 控制图表

import { useRef } from 'react';
import { KLineChart, type KLineChartRef } from 'kline-charts-react';

function App() {
  const chartRef = useRef<KLineChartRef>(null);

  const handleRefresh = () => {
    chartRef.current?.refresh();
  };

  const handleExport = () => {
    const dataUrl = chartRef.current?.exportImage('png');
    // 下载图片...
  };

  return (
    <>
      <button onClick={handleRefresh}>刷新</button>
      <button onClick={handleExport}>导出图片</button>
      <KLineChart ref={chartRef} symbol="sh600519" />
    </>
  );
}

unstable 二级导出

主入口只保留稳定导出。如果你明确需要内部 hooks / 子组件,请从 kline-charts-react/unstable 引入:

import { useKlineData, Toolbar } from 'kline-charts-react/unstable';

API 文档

KLineChartProps

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | symbol | string | 必填 | 股票代码,如 sh600519sz000001 | | market | 'A' \| 'HK' \| 'US' | 'A' | 市场类型 | | period | PeriodType | - | 当前 K 线周期(受控) | | defaultPeriod | PeriodType | 'daily' | 非受控模式下默认周期 | | adjust | '' \| 'qfq' \| 'hfq' | - | 当前复权类型(受控) | | defaultAdjust | '' \| 'qfq' \| 'hfq' | 'qfq' | 非受控模式下默认复权 | | height | number \| string | 500 | 图表高度 | | width | number \| string | '100%' | 图表宽度 | | theme | 'light' \| 'dark' \| ThemeConfig | 'light' | 主题配置 | | indicators | IndicatorType[] | - | 当前启用的技术指标(受控) | | defaultIndicators | IndicatorType[] | ['ma', 'volume', 'macd'] | 非受控模式下默认指标 | | indicatorOptions | IndicatorOptions | - | 指标参数配置 | | showToolbar | boolean | true | 是否显示工具栏 | | showPeriodSelector | boolean | true | 是否显示周期切换 | | showIndicatorSelector | boolean | true | 是否显示指标切换 | | maxSubPanes | number | 3 | 最多显示几个副图,0 表示不显示副图 | | visibleCount | number | 60 | 初始可见 K 线数量(关闭缩放的周期不生效,显示全部) | | showDataZoomSlider | boolean \| Partial<Record<PeriodType, boolean>> | true | 是否启用缩放(滚轮 + 底部滑块),可按周期设置,如 { timeline: false };关闭后该周期无缩放/平移、visibleCount 与滚动加载历史均不生效 | | dataProvider | KLineDataProvider | - | 自定义数据源(请用 useMemo 保持引用稳定) | | sdkOptions | SDKOptions | - | stock-sdk 配置 | | requestOptions | RequestOptions | - | 请求控制配置(见下表) | | autoRefresh | boolean \| AutoRefreshOptions | - | 自动刷新配置 | | echartsOption | EChartsOption | - | 自定义 ECharts 配置 | | echartsOptionMerge | EChartsOptionMergeOptions | - | ECharts Option 合并策略 | | panes | PaneConfig[] | - | 自定义面板布局,支持单副图多指标;主图面板的 id 必须为 'main' | | onDataLoad | (data: KlineWithIndicators[]) => void | - | 数据加载回调(仅 K 线周期触发,数据已附带指标字段) | | onPeriodChange | (period: PeriodType) => void | - | 周期切换回调 | | onAdjustChange | (adjust: AdjustType) => void | - | 复权切换回调 | | onIndicatorsChange | (indicators: IndicatorType[]) => void | - | 指标切换回调 | | onVisibleRangeChange | ({ start, end }) => void | - | 当前 dataZoom 可见范围变化 | | onError | (error: Error) => void | - | 错误回调 |

RequestOptions

| 字段 | 类型 | 默认值 | 说明 | |------|------|--------|------| | debounceMs | number | 150 | 参数变化后的请求防抖时间 | | abortOnChange | boolean | true | 参数变化时是否中止上一次请求(内置数据源的网络层不支持中止,仅丢弃过期结果) | | dedupe | boolean | true | 相同请求(同数据源 + 同参数)是否走缓存与去重 | | loadMoreLimit | number | 180 | 滚动加载历史时每次请求的条数(传给 getKlinelimit) |

KLineChartRef

| 方法 | 说明 | |------|------| | refresh() | 刷新数据 | | setPeriod(period) | 切换周期 | | setAdjust(adjust) | 切换复权 | | setIndicators(indicators) | 切换指标 | | zoomTo(start, end) | 缩放到指定范围 | | resetZoom() | 重置缩放 | | getVisibleRange() | 获取当前可见范围 { start, end } | | getEchartsInstance() | 获取 ECharts 实例,未初始化时返回 null | | exportImage(type?) | 导出图片(png/jpeg),图表实例未就绪时返回 null | | getData() | 获取当前 K 线数据(KlineWithIndicators[],已附带指标字段) |

PeriodType

type PeriodType =
  | 'timeline'   // 分时
  | 'timeline5'  // 五日分时
  | '1'          // 1分钟
  | '5'          // 5分钟
  | '15'         // 15分钟
  | '30'         // 30分钟
  | '60'         // 60分钟
  | 'daily'      // 日K
  | 'weekly'     // 周K
  | 'monthly';   // 月K

内置数据源的市场 × 周期支持

| 周期 | A 股 | 港股 | 美股 | 说明 | |------|:---:|:---:|:---:|------| | 分时 timeline | ✅ | ✅ | ✅ | A 股走行情分时接口(自带昨收);港/美股由 1 分钟数据聚合,昨收取自日 K | | 五日分时 timeline5 | ✅ | ✅ | ✅ | 由 1 分钟数据按交易日聚合(VWAP 均价按日重置),昨收取自窗口前最近交易日的日 K 收盘 | | 分钟 1/5/15/30/60 | ✅ | ✅ | ✅ | 按市场路由到对应分钟 K 线端点 | | 日/周/月 | ✅ | ✅ | ✅ | 支持前复权/后复权/不复权 |

使用自定义 dataProvider 时不受上表限制,支持范围由你的数据源决定。

代码格式(内置数据源):A 股带市场前缀如 sh600519 / sz000001;港股用 5 位 数字如 00700;美股需带交易所前缀,如 105.AAPL(105=纳斯达克、106=NYSE、107=AMEX)。

IndicatorType

type IndicatorType =
  // 主图指标
  | 'ma'      // 移动平均线
  | 'boll'    // 布林带
  | 'sar'     // 抛物线转向(SAR)
  | 'kc'      // 肯特纳通道(KC)
  // 副图指标
  | 'volume'  // 成交量
  | 'macd'    // MACD
  | 'kdj'     // KDJ
  | 'rsi'     // RSI
  | 'wr'      // WR(威廉指标)
  | 'bias'    // BIAS(乖离率)
  | 'cci'     // CCI(顺势指标)
  | 'atr'     // ATR(平均真实波幅)
  | 'obv'     // OBV(能量潮)
  | 'roc'     // ROC(变动率)
  | 'dmi';    // DMI(趋向指标)

主图指标说明

  • MA - 移动平均线,显示不同周期的均线
  • BOLL - 布林带,由上轨、中轨、下轨组成的通道
  • SAR - 抛物线转向,以点状显示趋势反转信号
  • KC - 肯特纳通道,基于 EMA 和 ATR 的通道指标

副图指标说明

  • OBV - 能量潮,通过成交量变化预测价格趋势
  • ROC - 变动率,衡量价格变化的速度
  • DMI - 趋向指标,包含 +DI、-DI、ADX、ADXR 四条线

主题定制

内置主题

// 浅色主题(默认)
<KLineChart theme="light" />

// 深色主题
<KLineChart theme="dark" />

自定义主题

<KLineChart
  theme={{
    backgroundColor: '#1a1a2e',
    textColor: '#eaeaea',
    upColor: '#26a69a',
    downColor: '#ef5350',
    gridLineColor: '#2a2a4a',
    // ... 更多配置
  }}
/>

处理跨域

内置数据源(stock-sdk v2)请求东方财富 / 雪球等多个行情端点,这些端点通常允许 浏览器直连,多数场景无需任何代理配置(本仓库 playground 即为直连)。

如果你的部署环境仍遇到跨域拦截(例如目标端点策略变化、内网安全网关拦截),推荐:

自定义 DataProvider(推荐)

用自己的后端聚合/代理行情数据,前端只对同源接口取数——这同时解决跨域、鉴权与 数据合规问题:

<KLineChart
  symbol="sh600519"
  dataProvider={myDataProvider}  // 实现见上方「自定义数据源」
/>

说明:sdkOptions.baseUrl 在 stock-sdk v2 中只影响腾讯快照行情端点, 不会改写 K 线 / 分时等其余多数据源(eastmoney / xueqiu)的请求地址, 不能用作跨域网关方案;旧版针对 qt.gtimg.cn/qt 单目标代理同样已失效。 需要收口出网流量时请使用方案 1(自定义 DataProvider)。

目录结构

kline-charts-react/
├── src/
│   ├── components/           # 子组件
│   │   ├── Loading/          # 加载状态
│   │   ├── PeriodSelector/   # 周期切换
│   │   ├── IndicatorSelector/# 指标选择器
│   │   ├── Toolbar/          # 工具栏
│   │   ├── IndicatorDisplay/ # 主图指标数值
│   │   └── SubPaneTitle/     # 副图标题
│   ├── hooks/                # React Hooks
│   │   ├── useKlineData.ts   # 数据获取 & 指标计算
│   │   ├── useEcharts.ts     # ECharts 实例管理
│   │   └── useZoomHistory.ts # 缩放历史
│   ├── utils/                # 工具函数
│   │   ├── indicators.ts     # 技术指标计算
│   │   ├── optionBuilder.ts  # K 线 ECharts 配置
│   │   ├── timelineBuilder.ts# 分时图 ECharts 配置
│   │   ├── formatters.ts     # 数据格式化
│   │   └── cache.ts          # 数据缓存
│   ├── types/                # 类型定义
│   ├── KLineChart.tsx        # 主组件
│   └── index.ts              # 入口
├── playground/               # 调试环境
└── dist/                     # 构建产物

开发

# 安装依赖
yarn install

# 启动开发调试(直连本地源码,支持热更新)
yarn dev

# 构建组件库
yarn build

# 构建 playground 生产版本
yarn build:playground

# 代码检查
yarn lint

# 类型检查
yarn typecheck

# 单元测试
yarn test:run

# 打包校验
yarn pack:check

开发模式说明

  • yarn dev 会启动 playground,直接引用 src/ 下的源码,修改源码后自动热更新
  • playground/ 通过本地 file:.. 依赖引用当前仓库,避免和 npm 上的历史版本漂移
  • CI 会执行 linttypechecktest:runbuildbuild:playgroundpack:check

已知限制

  • 导出图片exportImage() 导出的图片仅包含 ECharts 图表内容,不包含左上角的指标数值文字(这部分是用 React 渲染在图表外部的)
  • 成交量单位:内置数据源的 volume 原样透传上游数值,不同市场/端点的单位可能不同(股 vs 手)。若用于自定义计算或展示换算,请先用真实数据校准
  • 自动刷新与节假日autoRefresh.onlyTradingTime 仅按「星期 + 交易时段」判断,不含法定节假日/半日市日历——休市日(非周末)仍会按周期发起刷新
  • 请求中止:内置数据源(stock-sdk v2)的接口不支持逐请求 AbortSignal,requestOptions.abortOnChange 对它只在结果层丢弃过期数据,不会真正取消网络请求;自定义 provider 透传 signal 即可获得真正的中止
  • 无限滚动:内置数据源不支持 cursor/limit 增量分页,向左滚动加载更多历史仅对实现了分页的自定义 provider 生效
  • onDataLoad:仅 K 线周期触发;分时/五日分时的数据经由 getTimeline 通道,不回调 onDataLoad
  • 同参数刷新失败的提示:手动/自动刷新(参数不变)失败时会保留旧图、不弹内置错误层(避免遮挡与闪烁),仅触发 onError 回调——需要显式提示时请在 onError 里自行展示

License

MIT © 2025-present chengzuopeng