Skip to content

SiMahfud/klinechartpro

Β 
Β 

Repository files navigation

KLineChart Pro

License KLineChart

A professional-grade, TradingView-inspired charting component built on KLineChart, powered by SolidJS. Features 25 built-in drawing tools, bar replay, keyboard shortcuts, multi-chart type support, multi-symbol comparison overlays, price alerts, chart templates, and a complete custom tool API.

πŸ”— Repository: github.com/SiMahfud/klinechartpro
πŸ“¦ Forked from klinecharts/pro


✨ Features

Core

  • πŸ“Š Built on KLineChart with SolidJS rendering
  • 🎨 Light & Dark themes with CSS custom properties
  • 🌐 5 locales: Chinese, English, Indonesian, Japanese, Korean
  • πŸ’Ύ Data persistence via localStorage (symbols, periods, indicators, drawings)
  • πŸ”” Price alert system with browser notifications
  • πŸ“ˆ Multi-symbol comparison mode
  • ⚑ Performance monitoring panel (FPS, memory, WS latency)
  • β™Ώ Full modal accessibility (focus trap, keyboard nav, ARIA)
  • πŸ“± Responsive layout with mobile support

Chart Types (6 types)

Type Key Description
Candles candle_solid Standard filled candlestick (default)
Hollow Candles candle_stroke All candles outlined
Up Hollow candle_up_stroke Up candles hollow, down filled
Down Hollow candle_down_stroke Down candles hollow, up filled
OHLC Bars ohlc Traditional open-high-low-close bars
Area area Filled area chart

Drawing Tools (25 built-in)

Category Tools
Lines Horizontal/Vertical (straight, ray, segment), Trend Line, Ray, Segment, Arrow, Price Line
Channels Price Channel, Parallel Line
Shapes Circle, Rectangle, Parallelogram, Triangle
Fibonacci Line, Segment, Circle, Spiral, Fan, Extension
Gann Gann Box
Waves XABCD, ABCD, 3-Wave, 5-Wave, 8-Wave, Any Wave
Trading Long Position, Short Position, Measure Tool
Annotation Volume Profile (FRVP), Price Range, Text Note, Anchored VWAP, Price Label

Technical Indicators (26 built-in)

Main chart: MA, EMA, SMA, BOLL, SAR, BBI
Sub chart: VOL, MACD, KDJ, RSI, BIAS, BRAR, CCI, DMI, CR, PSY, DMA, TRIX, OBV, VR, WR, MTM, EMV, ROC, PVT, AO

Advanced Features

Feature Description
⏯ Bar Replay Step through historical data bar by bar with play/pause/speed controls
⌨️ Keyboard Shortcuts Configurable hotkeys for all chart operations
🌳 Object Tree Manage all drawings β€” toggle visibility, select, delete
πŸ’Ύ Chart Templates Save/load indicator + style presets via localStorage
🏷️ Price Labels Custom price markers on Y-axis
πŸ”— Crosshair Sync Synchronize crosshair across multiple chart instances
🎨 Style Editor Edit drawing properties (color, width, style) via right-click
πŸ“‹ Context Menu Right-click overlay menu with Edit/Hide/Delete/Alert/Performance actions
πŸ“Š Chart Type Selector Switch between 6 chart types from the toolbar
πŸ–₯️ Multi-Chart Layout onLayoutClick callback for parent-managed split views

πŸ“¦ Installation

Using npm

npm install klinecharts @simahfud/klinecharts-pro

Using unpkg or jsDelivr (CDN)

The library is published as a UMD bundle, so you can load it directly via <script> tags:

<!-- KLineChart (dependency, must be loaded first) -->
<script src="https://unpkg.com/klinecharts/dist/klinecharts.min.js"></script>

<!-- KLineChart Pro -->
<!-- using unpkg -->
<script src="https://unpkg.com/@simahfud/klinecharts-pro/dist/klinecharts-pro.umd.js"></script>
<!-- OR using jsDelivr -->
<script src="https://cdn.jsdelivr.net/npm/@simahfud/klinecharts-pro/dist/klinecharts-pro.umd.js"></script>

<!-- CSS styles (required) -->
<link rel="stylesheet" href="https://unpkg.com/@simahfud/klinecharts-pro/dist/klinecharts-pro.css" />

After loading, the global variable klinechartspro is available:

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="https://unpkg.com/@simahfud/klinecharts-pro/dist/klinecharts-pro.css" />
</head>
<body>
  <div id="chart-container" style="width:100%;height:600px;"></div>

  <script src="https://unpkg.com/klinecharts/dist/klinecharts.min.js"></script>
  <script src="https://unpkg.com/@simahfud/klinecharts-pro/dist/klinecharts-pro.umd.js"></script>
  <script>
    // Access via global: klinechartspro
    const { KLineChartPro, DefaultDatafeed } = klinechartspro

    const chart = new KLineChartPro({
      container: document.getElementById('chart-container'),
      symbol: { ticker: 'AAPL', name: 'Apple Inc.', market: 'stocks' },
      period: { multiplier: 1, timespan: 'day', text: 'D' },
      datafeed: new DefaultDatafeed('YOUR_POLYGON_API_KEY'),
      theme: 'dark',
      locale: 'en-US'
    })
  </script>
</body>
</html>

πŸ’‘ Note: For your fork, after running npm run build-core, the dist/ folder will contain your customized UMD/ES bundles. You can self-host these files or publish to npm to use via CDN.

Building from source

git clone https://github.com/SiMahfud/klinechartpro.git
cd klinechartpro
npm install
npm run build-core   # β†’ dist/klinecharts-pro.umd.js + klinecharts-pro.js + klinecharts-pro.css

πŸš€ Quick Start

import { KLineChartPro, DefaultDatafeed } from '@simahfud/klinecharts-pro'

const chart = new KLineChartPro({
  container: 'chart-container',
  symbol: { ticker: 'AAPL', name: 'Apple Inc.', market: 'stocks' },
  period: { multiplier: 1, timespan: 'day', text: 'D' },
  datafeed: new DefaultDatafeed('YOUR_POLYGON_API_KEY'),
  theme: 'dark',
  locale: 'en-US'
})

// Wait for chart to be ready before calling methods
await chart.ready()
console.log('Chart initialized:', chart.getSymbol())

Constructor Options

const chart = new KLineChartPro({
  container: 'chart-container',       // Required: DOM element or selector
  symbol: { ticker: 'AAPL' },         // Required: Initial symbol
  period: { multiplier: 1, timespan: 'day', text: 'D' },  // Required
  datafeed: myDatafeed,               // Required: Datafeed implementation
  theme: 'dark',                      // 'dark' | 'light'
  locale: 'en-US',                    // 'en-US' | 'zh-CN' | 'id-ID' | 'ja-JP' | 'ko-KR'
  drawingBarVisible: true,            // Show drawing toolbar
  mainIndicators: ['MA', 'EMA'],      // Initial main indicators
  subIndicators: ['VOL', 'MACD'],     // Initial sub indicators
  chartType: 'candle_solid',          // Initial chart type
  renkoBrickSize: 10,                 // Renko brick size
  rangeBarSize: 10,                   // Range bar size
  onSettingsChange: (settings) => {}, // Called on settings change
  onDrawingsChange: (ticker, d) => {},// Called on drawings change
  onLayoutClick: () => {},            // Called when Layout button is clicked
})

πŸ”§ API Reference

Core Methods

// Theme
chart.setTheme('dark')          // 'dark' | 'light'
chart.getTheme()

// Locale
chart.setLocale('en-US')        // 'en-US' | 'zh-CN' | 'id-ID' | 'ja-JP' | 'ko-KR'
chart.getLocale()

// Symbol & Period
chart.setSymbol({ ticker: 'MSFT', name: 'Microsoft' })
chart.getSymbol()
chart.setPeriod({ multiplier: 5, timespan: 'minute', text: '5m' })
chart.getPeriod()

// Timezone
chart.setTimezone('Asia/Jakarta')
chart.getTimezone()

// Styles (deep partial merge)
chart.setStyles({ candle: { bar: { upColor: '#26A69A' } } })
chart.getStyles()

Chart Type

// Switch chart type
chart.setChartType('ohlc')        // candle_solid | candle_stroke | candle_up_stroke | candle_down_stroke | ohlc | area
chart.getChartType()              // Returns current type

Bar Replay

// Start replay using current chart data
chart.startReplay('current')

// Or start replay loading custom historical data
chart.startReplay('custom')

// Stop and restore original data
chart.stopReplay()

Programmatic control via BarReplayManager:

import { BarReplayManager } from '@simahfud/klinecharts-pro'

const replay = new BarReplayManager(chartWidget, datafeed)

replay.setHandlers({
  onStep: (index, total, bar) => console.log(`${index}/${total}`),
  onPlay: () => console.log('Playing'),
  onPause: () => console.log('Paused'),
  onEnd: () => console.log('Replay ended'),
  onStatusChange: (status) => console.log('Status:', status)
})

await replay.start({ dataSource: 'current', speed: 500, startFrom: 0 })

// Controls
replay.play()           // Auto-advance
replay.pause()          // Pause
replay.stepForward()    // Next bar
replay.stepBackward()   // Previous bar
replay.seekTo(50)       // Jump to index
replay.setSpeed(100)    // 100ms per bar

// State
replay.getStatus()      // 'idle' | 'playing' | 'paused' | 'ended'
replay.getIndex()       // Current position
replay.getTotal()       // Total bars

// Cleanup
replay.stop()           // Restore original data
replay.destroy()        // Full cleanup

Object Tree & Style Editor

// Open Object Tree modal (lists all overlays)
chart.showObjectTree()

// Open Style Editor for a specific overlay
chart.showStyleEditor('overlay_id_123')

Keyboard Shortcuts

import { KeyboardShortcutManager } from '@simahfud/klinecharts-pro'

const shortcuts = new KeyboardShortcutManager(containerElement)

shortcuts.register({ key: 'ctrl+z', description: 'Undo', callback: () => drawings.undo() })
shortcuts.register({ key: 'ctrl+y', description: 'Redo', callback: () => drawings.redo() })
shortcuts.register({ key: 'delete', callback: () => chart.removeOverlay() })
shortcuts.register({ key: 'escape', callback: () => chart.removeOverlay() })

// Disable during modals
shortcuts.setEnabled(false)
shortcuts.setEnabled(true)

shortcuts.destroy()

Chart Templates

import { ChartTemplateManager } from '@simahfud/klinecharts-pro'

const templates = new ChartTemplateManager(chartStore)

// Save current configuration
templates.saveTemplate({
  name: 'My Scalping Setup',
  mainIndicators: ['EMA', 'BOLL'],
  subIndicators: ['RSI', 'MACD'],
  theme: 'dark',
  period: { multiplier: 5, timespan: 'minute', text: '5m' },
  createdAt: Date.now()
})

// List and load
templates.getTemplateNames()                    // ['My Scalping Setup']
const tmpl = templates.loadTemplate('My Scalping Setup')

// Delete
templates.deleteTemplate('My Scalping Setup')

Crosshair Sync

import { CrosshairSyncManager } from '@simahfud/klinecharts-pro'

const sync = new CrosshairSyncManager()

sync.addChart(chart1)
sync.addChart(chart2)
// Moving crosshair on chart1 now moves it on chart2 and vice versa

sync.removeChart(chart1)
sync.destroy()

Custom Indicators & Overlays

import { registerCustomIndicator, registerCustomOverlay } from '@simahfud/klinecharts-pro'

// Register a custom indicator (auto-appears in Indicator menu)
registerCustomIndicator({
  template: { name: 'MyRSI', calc: (dataList) => { /* ... */ }, figures: [{ key: 'value', type: 'line' }] },
  label: 'My Custom RSI',
  paneType: 'sub'
})

// Register a custom overlay (auto-appears in Drawing menu)
registerCustomOverlay({
  template: { name: 'myTool', totalStep: 2, createPointFigures: (params) => { /* ... */ } },
  label: 'My Tool'
})

Price Alerts

chart.setAlert({ id: 'alert1', price: 150.00, condition: 'crosses_above', symbol: 'AAPL' })
chart.getAlerts()
chart.removeAlert('alert1')

Multi-Symbol Comparison

import { ComparisonManager } from '@simahfud/klinecharts-pro'

const comparison = new ComparisonManager(chartWidget, datafeed)
await comparison.addSymbol({ ticker: 'MSFT' }, period, from, to)
comparison.getSymbols()
comparison.toggleVisibility('MSFT')
comparison.removeSymbol('MSFT')
comparison.destroy()

UI Integration: Click the + Compare button in the toolbar to add a comparison symbol via the search modal. Each comparison symbol is drawn as a colored line chart on the main candle pane, normalized to percentage change from the first visible bar. A floating legend in the top-left corner shows active comparisons with a remove button.

Multi-Chart Layout

const chart = new KLineChartPro({
  // ... other options
  onLayoutClick: () => {
    // Handle layout button click β€” create your own split view
    // For example, create a second chart instance side by side
  }
})

// Access the underlying klinecharts widget for advanced integrations
const widget = chart.getWidget()

Example: Dual Chart with Crosshair Sync

import { KLineChartPro, CrosshairSyncManager } from '@simahfud/klinecharts-pro'

// Create two chart instances
const chart1 = new KLineChartPro({ container: 'chart-left', ... })
const chart2 = new KLineChartPro({ container: 'chart-right', ... })

// Sync crosshairs
const sync = new CrosshairSyncManager()
sync.addChart(chart1.getWidget())
sync.addChart(chart2.getWidget())

// Cleanup
sync.destroy()

πŸ’Ύ Settings Save & Database Sync

The library provides robust API callbacks to help you synchronize the user's chart configuration and drawings directly to your backend database (e.g., MySQL, MongoDB) in real-time.

const chart = new KLineChartPro({
  // ...other options
  onSettingsChange: (settings) => {
    // Fired when theme, timezone, period, or indicators change
    console.log('Settings changed:', settings)
    // Example: api.post('/save-settings', { settings })
  },
  onDrawingsChange: (ticker, drawings) => {
    // Fired when a user adds, modifies, or deletes a drawing/overlay
    console.log(`Drawings updated for ${ticker}:`, drawings)
    // Example: api.post(`/save-drawings/${ticker}`, { drawings })
  }
})

Applying Data from your Database

When the user reloads the page or logs in from another device, you can fetch their saved data from your database and inject it into the chart:

// 1. Fetch from your DB
const savedSettings = await api.get('/user/chart-settings')
const savedDrawings = await api.get(`/user/drawings/${ticker}`)

// 2. Wait for chart to be ready
await chart.ready()

// 3. Inject into the chart
if (savedSettings) {
  chart.setSettings(savedSettings)
}
if (savedDrawings) {
  chart.setDrawings(ticker, savedDrawings)
}

// You can also retrieve current state imperatively:
const currentDrawings = chart.getDrawings(ticker)
const currentSettings = chart.getSettings()

πŸ“Š DefaultDatafeed

import { DefaultDatafeed } from '@simahfud/klinecharts-pro'

// Uses Polygon.io API
const datafeed = new DefaultDatafeed('YOUR_API_KEY')

Implements the Datafeed interface:

interface Datafeed {
  searchSymbols(search?: string): Promise<SymbolInfo[]>
  getHistoryKLineData(symbol: SymbolInfo, period: Period, from: number, to: number): Promise<KLineData[]>
  subscribe(symbol: SymbolInfo, period: Period, callback: DatafeedSubscribeCallback): void
  unsubscribe(symbol: SymbolInfo, period: Period): void
}

πŸ— Architecture

src/
β”œβ”€β”€ index.ts                    # Entry point + exports
β”œβ”€β”€ KLineChartPro.tsx           # Main class (lifecycle, API)
β”œβ”€β”€ ChartProComponent.tsx       # SolidJS component (all UI wiring)
β”œβ”€β”€ types.ts                    # TypeScript interfaces
β”œβ”€β”€ config.ts                   # Shared constants
β”œβ”€β”€ registry.ts                 # Custom tool registry (auto-menu)
β”œβ”€β”€ error.ts                    # Error handling system
β”œβ”€β”€ store.ts                    # localStorage persistence
β”œβ”€β”€ drawing-store.ts            # Undo/redo + drawing persistence
β”œβ”€β”€ comparison.ts               # Multi-symbol comparison
β”œβ”€β”€ bar-replay.ts               # Bar replay engine
β”œβ”€β”€ keyboard-shortcuts.ts       # Keyboard shortcut manager
β”œβ”€β”€ chart-template.ts           # Template save/load
β”œβ”€β”€ crosshair-sync.ts           # Multi-chart crosshair sync
β”œβ”€β”€ DefaultDatafeed.ts          # Polygon.io data feed
β”œβ”€β”€ i18n/                       # 5 locale files (168+ keys each)
β”œβ”€β”€ extension/                  # 25 overlay templates
β”‚   β”œβ”€β”€ longPosition.ts         # Long Position tool
β”‚   β”œβ”€β”€ shortPosition.ts        # Short Position tool
β”‚   β”œβ”€β”€ frvp.ts                 # Volume Profile
β”‚   β”œβ”€β”€ measure.ts              # Measure tool
β”‚   β”œβ”€β”€ priceRange.ts           # Price Range zone
β”‚   β”œβ”€β”€ textNote.ts             # Text annotation
β”‚   β”œβ”€β”€ anchoredVwap.ts         # Anchored VWAP
β”‚   β”œβ”€β”€ priceLabel.ts           # Price Label
β”‚   └── ... (17 more)
β”œβ”€β”€ widget/
β”‚   β”œβ”€β”€ period-bar/             # Toolbar (periods, chart type, settings)
β”‚   β”œβ”€β”€ drawing-bar/            # Drawing toolbar (8 groups)
β”‚   β”œβ”€β”€ replay-bar/             # Replay controls (play/pause/step/speed)
β”‚   β”œβ”€β”€ object-tree/            # Object manager modal
β”‚   β”œβ”€β”€ drawing-style-editor/   # Style editor modal
β”‚   β”œβ”€β”€ context-menu/           # Right-click menu
β”‚   β”œβ”€β”€ error-banner/           # Error notification
β”‚   β”œβ”€β”€ performance-panel/      # Debug panel
β”‚   β”œβ”€β”€ alert-modal/            # Price alerts UI
β”‚   └── ...
β”œβ”€β”€ component/                  # Reusable UI (Modal, Select, List, etc.)
└── __tests__/                  # 38 unit tests (100% pass)

πŸ§ͺ Testing

# Run all tests
npx vitest run

# Run with verbose output
npx vitest run --reporter=verbose

# Watch mode
npx vitest

Current status: 38/38 tests passing βœ…


πŸ›  Development

# Install dependencies
npm install

# Start dev server
npm run dev

# Build for production
npm run build-core

# Run tests
npx vitest run

πŸ“„ License

Apache License 2.0

About

Professional TradingView-inspired charting component built on KLineChart. Features bar replay, keyboard shortcuts, 25 drawing tools, 6 chart types, and custom tool API.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages

  • TypeScript 92.2%
  • Less 7.3%
  • Other 0.5%