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
- 01Minimal chart setup
- 02REST and streaming data loading guidance
- 03React and Vue integration patterns
- 04Indicators and drawing overlays
- 05v9-to-v10 migration guidance
- 06Troubleshooting chart and data issues
Use cases
- 01Add a candlestick chart to a web project
- 02Connect chart data to a backend
- 03Upgrade an integration from v9 to v10
- 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 klinechartsAfter installing, type/klinechartsin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
api-reference.mdexamples.mdprompts.mdDetails
From the project READMEKLineChart Integration Guide
Helps developers integrate KLineChart (npm: klinecharts, currently v10) into their projects.
Route by scenario
| User need | Start 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
callbackfromgetBars, even on failure (pass[]) - Bars sorted ascending by
timestamp, no duplicates subscribeBarpushes one bar at a time, not an arraymorecontrols pagination:booleanor{ 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
| Method | Purpose |
|---|---|
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' |
setLoadDataCallback | setDataLoader |
setPriceVolumePrecision | setSymbol({ pricePrecision, volumePrecision }) |
setCustomApi | setFormatter |
indicator calc returns array | calc returns Record<timestamp, value> |
Troubleshooting
- No data — called setSymbol/setPeriod/setDataLoader in order? did getBars call callback? is timestamp in ms?
- Pagination broken — are
more.forward/more.backwardcorrect in callback? - Realtime not updating — does subscribeBar push one bar? is timestamp ≥ last bar?
- Stale data after symbol switch — does unsubscribeBar close the old subscription?
- Blank container — is width/height 0? was resize called?
Further reading
- Copy-paste prompts: prompts.md
- Full examples: examples.md
- API reference: api-reference.md
- Official docs: https://klinecharts.com/guide/data-integration