Skip to content

React ​

bash
npm install @kumochart-sdk/core @kumochart-sdk/react

适配包是内核之上的一层薄封装:一个在 JSX 中使用的组件,以及一个用于自定义场景的 Hook。其余一切都通过图表实例完成。支持 React 18.3 和 19,兼容 StrictMode,并且已标记为 'use client',可以直接在 Next.js 的服务端组件中引入。

可以在 React 示例中查看实际效果(源码)。

组件 ​

tsx
import { useMemo, useRef, useState } from 'react';
import { TradingChart } from '@kumochart-sdk/react';
import {
  darkTheme,
  type BarInput,
  type Chart,
  type OrderInput,
  type PriceDragEvent
} from '@kumochart-sdk/core';

export function Terminal({ bars }: { bars: BarInput[] }) {
  const chart = useRef<Chart>(null);
  const [orders, setOrders] = useState<OrderInput[]>([
    { id: 'o-1', side: 'buy', price: 101.5, label: 'LIMIT' }
  ]);
  const options = useMemo(() => ({ locale: 'zh-CN', theme: darkTheme }), []);

  function onReady(instance: Chart) {
    instance.indicators.add({ type: 'MACD' });
    socket.onmessage = (message) => instance.data.update(JSON.parse(message.data));
  }

  function onOrderDrag({ id, phase, price }: PriceDragEvent) {
    if (phase === 'end') {
      setOrders((current) =>
        current.map((order) => (order.id === id ? { ...order, price } : order))
      );
    }
  }

  return (
    <TradingChart
      ref={chart}
      style={{ height: 520 }}
      data={bars}
      orders={orders}
      options={options}
      onReady={onReady}
      onOrderDrag={onOrderDrag}
      onLoadMore={({ before }) => loadOlder(before)}
    />
  );
}

Props ​

Prop生效方式
options传入新对象时调用 chart.applyOptions()
data传入新数组时调用 chart.data.set()
interval与 data 一起传给 chart.data.set(),如 '1m'
timeframe调用 chart.data.setTimeframe(),如 '15m';null 显示源周期
transform调用 chart.data.setTransform(),如 { type: 'renko' };null 显示周期本身的 K 线;传入相同的值不会重建
orders传入新数组时调用 chart.orders.set()
markers传入新数组时调用 chart.markers.set()
alerts传入新数组时调用 chart.alerts.set()
configure图表创建后、其他属性生效前执行一次:在这里注册扩展功能、自定义类型或插件
className作用于图表的容器元素
style合并在默认的 width: 100%; height: 100% 之上

和 React 的 state 一样,props 按引用比较。修改数组时请以不可变的方式替换;options 请用 useMemo 或模块级常量保持稳定:内联的对象字面量每次渲染都是新对象,会被反复应用。

实时 K 线请用 chart.data.update()、逐笔成交请用 chart.data.addTrades() 推送,不要重建 data 数组;切换品种时再传入新数组。设置了 interval 后,切换周期请通过 timeframe 属性,而不是重新加载数据(见周期与回放)。周期请用字符串传入,或者像 options 一样保持对象引用稳定。

指标、子图、画线和视图都可以由用户编辑,并通过 chart.saveState() 保存;请通过图表实例管理它们。

事件 ​

每个图表事件都对应一个 on* prop:onCrosshairMove、onVisibleRangeChange、onLoadMore、onClick、onDoubleClick、onContextMenu、onSelectionChange、onPaneResize、onDrawingsChange、onToolChange、onOrderDrag、onAlertDrag、onButtonClick、onAlertTrigger、onReplay。onReady 会在图表创建完成、props 已应用之后传入图表实例。

事件处理函数每次渲染都可以是新函数,组件始终调用最新的那个,且不会重新订阅。没有传处理函数的事件不会被订阅,所以不用 crosshairMove 就不会有任何开销。

获取实例 ​

通过 ref 可以拿到图表实例(创建之前和卸载之后为 null),onReady 也会传入它。

Hook ​

useTradingChart() 在你渲染的任意元素中创建图表,并在元素移除时销毁。它返回一个回调 ref 和图表实例:

tsx
import { useEffect, useMemo } from 'react';
import { darkTheme, lightTheme, type BarInput } from '@kumochart-sdk/core';
import { useTradingChart } from '@kumochart-sdk/react';

function Chart({ bars, dark }: { bars: BarInput[]; dark: boolean }) {
  const options = useMemo(() => ({ theme: dark ? darkTheme : lightTheme }), [dark]);
  const [ref, chart] = useTradingChart(options);

  useEffect(() => {
    chart?.data.set(bars);
  }, [chart, bars]);

  return <div ref={ref} className="chart" />;
}

元素挂载时才会创建图表,即使它比组件本身晚出现也没问题;在此之前 chart 为 null。

服务端渲染 ​

图表依赖 DOM,所以服务端不会创建任何东西:组件只渲染一个空的 <div>,图表在 hydration 之后出现。不需要再用 dynamic(() => import(...), { ssr: false }) 包一层。

基于 MIT 许可证发布。