mcpField
K
klinecharts

klinecharts

github.com/klinechartsDevelopment4.3k153 installsUpdated 1w ago
Repository

About klinecharts

A developer guide skill for integrating the `klinecharts` JavaScript charting library. It covers data loading, framework lifecycle, indicators, overlays, migration, and troubleshooting.

Key features

  1. 01Minimal chart setup
  2. 02REST and streaming data loading guidance
  3. 03React and Vue integration patterns
  4. 04Indicators and drawing overlays
  5. 05v9-to-v10 migration guidance
  6. 06Troubleshooting chart and data issues

Use cases

  1. 01Add a candlestick chart to a web project
  2. 02Connect chart data to a backend
  3. 03Upgrade an integration from v9 to v10
  4. 04Diagnose blank charts or stale data

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/klinecharts/klinechart --skill klinecharts

After installing, type/klinechartsin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

api-reference.md
examples.md
prompts.md

Details

From the project README

KLineChart Integration Guide

Helps developers integrate KLineChart (npm: klinecharts, currently v10) into their projects.

Route by scenario

User needStart here
First integration, quick chart→ Minimal example
Real backend (REST/WebSocket)→ Data loading
React / Vue / other frameworks→ Framework integration
Indicators / drawing tools→ Indicators and overlays
Upgrading from v9→ v9 → v10 migration
Blank chart / data not updating→ Troubleshooting

Check klinecharts in package.json if the version is unclear. v10 no longer uses applyNewData / updateData.

Minimal example

import { init, dispose } from 'klinecharts'

const chart = init('chart') // HTMLElement or id; container needs width and height
chart.setSymbol({ ticker: 'BTCUSDT', pricePrecision: 2, volumePrecision: 0 })
chart.setPeriod({ span: 1, type: 'day' })
chart.setDataLoader({
  getBars: ({ callback }) => {
    callback([
      { timestamp: 1517846400000, open: 7424.6, high: 7511.3, low: 6032.3, close: 7310.1, volume: 224461 },
    ])
  }
})
// cleanup: dispose('chart')

Required order: init → setSymbol → setPeriod → setDataLoader

Data model

// KLineData — all price/volume fields must be numbers
{ timestamp: number, open: number, high: number, low: number, close: number, volume?: number, turnover?: number }

// Period
{ span: 5, type: 'minute' }  // 5-minute bars; type: second | minute | hour | day | week | month | year

// SymbolInfo
{ ticker: string, pricePrecision: number, volumePrecision: number }

timestamp must be in milliseconds. turnover is only required for EMV and AVP indicators.

Data loading (setDataLoader)

v10 uses setDataLoader instead of legacy data APIs. getBars may be async, but must always call callback.

chart.setDataLoader({
  getBars: ({ type, timestamp, symbol, period, callback }) => {
    // type: 'init' | 'forward' | 'backward'
    // init: first load, timestamp = null
    // forward: scrolled to left edge, timestamp = leftmost bar time
    // backward: scrolled to right edge, timestamp = rightmost bar time
    callback(bars, { forward: true, backward: false })
  },
  subscribeBar: ({ symbol, period, callback }) => {
    // fires after init; call callback with one KLineData per push
    // same timestamp → update last bar; larger timestamp → append
  },
  unsubscribeBar: ({ symbol, period }) => {
    // tear down WebSocket/polling on symbol/period change or dispose
  }
})

Rules:

  • Always call callback from getBars, even on failure (pass [])
  • Bars sorted ascending by timestamp, no duplicates
  • subscribeBar pushes one bar at a time, not an array
  • more controls pagination: boolean or { forward?, backward? }

Changing period or symbol: chart.setPeriod(...) or chart.setSymbol(...) reloads automatically.

Framework integration

The container must have explicit width and height. Call init on mount, dispose on unmount, and chart.resize() on size changes.

// React pattern
useEffect(() => {
  const chart = init(containerRef.current!)
  chart.setSymbol({ ticker: 'TEST', pricePrecision: 2, volumePrecision: 0 })
  chart.setPeriod({ span: 1, type: 'day' })
  chart.setDataLoader(loader)
  const ro = new ResizeObserver(() => chart.resize())
  ro.observe(containerRef.current!)
  return () => { ro.disconnect(); dispose(containerRef.current!) }
}, [])

CDN: klinecharts.init(...) / klinecharts.dispose(...)

Indicators and overlays

chart.createIndicator('MACD')  // separate pane
chart.createIndicator({ name: 'MA', paneId: 'candle_pane' }, true)  // stack on main chart

chart.createOverlay('segment')  // interactive drawing
chart.createOverlay({ name: 'priceLine', points: [{ timestamp, value }] })  // programmatic

Built-in indicators stackable on the main chart: BBI, BOLL, EMA, MA, SAR, SMA

Runtime lookup: getSupportedIndicators() / getSupportedOverlays()

Custom types: registerIndicator(...) / registerOverlay(...) — register before init.

Common instance APIs

MethodPurpose
setStyles(partial)Update styles (shallow merge)
setLayoutOptions(partial)Update defaults for subsequently created panes and y-axes
getLayoutOptions()Get the complete current default layout options
setPaneOptions(opts)Pane height/state
overrideYAxis(opts)Y-axis position/ticks
subscribeAction(type, cb)Crosshair, click, etc.
scrollToRealTime()Scroll to latest bar
getDataList()Current bar data
resetData()Reload data
getConvertPictureUrl()Export image

Action types: onCrosshairChange, onCandleBarClick, onZoom, onScroll, onVisibleRangeChange, onPaneDrag

Initial layout

init(container, {
  layout: {
    barSpaceLimit: { min: 2, max: 40 },
    pane: { minHeight: 120 },
    yAxis: { position: 'right' }
  },
  locale: 'zh-CN',
  timezone: 'Asia/Shanghai',
  styles: 'dark'
})

To change layout defaults after initialization, use setLayoutOptions(partial). It merges incrementally and only affects panes and y-axes created afterward; use setPaneOptions, overrideYAxis, or overrideXAxis for existing chart elements. Use getLayoutOptions() to read the complete current defaults.

v9 → v10 migration

v9 (removed)v10
applyNewData(data)getBars with type 'init'
updateData(bar)subscribeBar callback
applyMoreData(data, more)getBars 'forward' / 'backward'
setLoadDataCallbacksetDataLoader
setPriceVolumePrecisionsetSymbol({ pricePrecision, volumePrecision })
setCustomApisetFormatter
indicator calc returns arraycalc returns Record<timestamp, value>

Troubleshooting

  1. No data — called setSymbol/setPeriod/setDataLoader in order? did getBars call callback? is timestamp in ms?
  2. Pagination broken — are more.forward / more.backward correct in callback?
  3. Realtime not updating — does subscribeBar push one bar? is timestamp ≥ last bar?
  4. Stale data after symbol switch — does unsubscribeBar close the old subscription?
  5. Blank container — is width/height 0? was resize called?

Further reading

Comments

Markdown supported