QFChart

QFChart is a lightweight, high-performance financial charting library built on top of Apache ECharts. It is designed to easily render candlestick charts with multiple technical indicators, flexible layouts, and interactive features.

Key Features

  • Candlestick Charts: High-performance rendering of OHLCV data.
  • Real-time Updates: Incremental data updates for live trading without full re-renders.
  • Multi-Pane Indicators: Support for stacking indicators in separate panes (e.g., RSI, MACD) with customizable heights.
  • Overlay Indicators: Add indicators directly on top of the main chart (e.g., SMA, Bollinger Bands).
  • Flexible Layouts: Configurable sidebars for data display (Left/Right/Floating) to avoid obstructing the chart.
  • Dynamic Resizing: Automatically handles window resizing and layout adjustments.
  • Plugin System: Extensible architecture for adding interactive tools (e.g., Measure Tool, Line Drawing, Fibonacci Retracements).
  • TypeScript Support: Written in TypeScript with full type definitions.

QFChart in Action

This is demo uses QFChart for visualization and PineTS library for market data loading and indicators processing.



Installation

Browser (UMD)

Include the ECharts library and QFChart in your HTML file:

<!-- 1. Include ECharts (Required) -->
<script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>

<!-- 2. Include QFChart -->
<script src="https://cdn.jsdelivr.net/npm/@qfo/qfchart/dist/qfchart.min.browser.js"></script>

NPM

npm install @qfo/qfchart echarts

Quick Start

Here is a minimal example to get a chart up and running.

1. HTML Container

Create a container element with a defined width and height.

<div id="chart-container" style="width: 100%; height: 600px;"></div>

2. Initialize Chart

// Initialize the chart
const container = document.getElementById('chart-container');
const chart = new QFChart.QFChart(container, {
    title: 'BTC/USDT',
    height: '600px',
    layout: {
        mainPaneHeight: '60%',
        gap: 20,
    },
});

3. Set Market Data

Prepare your OHLCV data (Time, Open, High, Low, Close, Volume) and pass it to the chart.

const marketData = [
    {
        time: 1620000000000,
        open: 50000,
        high: 51000,
        low: 49000,
        close: 50500,
        volume: 100,
    },
    // ... more data
];

chart.setMarketData(marketData);

4. Add an Indicator

Add a simple Line indicator (e.g., SMA).

const smaData = [
    { time: 1620000000000, value: 50200 },
    // ...
];

const plots = {
    SMA: {
        data: smaData,
        options: {
            style: 'line',
            color: '#ff9900',
            linewidth: 2,
        },
    },
};

// Add as overlay on main chart
chart.addIndicator('SMA_14', plots, { overlay: true });

Plotting System

QFChart supports multiple plot styles for rendering technical indicators: line, step, histogram, columns, circles, cross, background, char, bar, candle, barcolor, and shape. Each style offers different visualization options and per-point styling capabilities. The char style displays values only in tooltips without visual representation, perfect for auxiliary data (equivalent to Pine Script’s plotchar()). The bar and candle styles render OHLC data for indicators like Heikin Ashi (equivalent to plotbar() and plotcandle()). The barcolor style colors the main chart candlesticks based on indicator conditions (equivalent to barcolor()). The shape style is particularly powerful, with support for various shapes (arrows, triangles, labels), custom sizes, text labels, and flexible positioning modes.

For detailed information about plot styles, options, and examples, see the Plotting System Documentation.

5. Real-time Updates (Optional)

For real-time data feeds (e.g., WebSocket), use updateData() for optimal performance:

// Keep reference to indicator for updates
const macdIndicator = chart.addIndicator('MACD', macdPlots, {
    overlay: false,
    height: 15,
});

// Later: update with new/modified data
function onNewTick(bar, indicators) {
    // Step 1: Update indicator data first
    macdIndicator.updateData(indicators);

    // Step 2: Update chart data (triggers re-render)
    chart.updateData([bar]);
}

Key Points:

  • updateData() merges data by timestamp (update existing or append new)
  • Always update indicators before calling chart.updateData()
  • Much faster than calling setMarketData() (no full re-render)
  • Perfect for WebSocket tick updates or periodic data refreshes

See API Reference for detailed documentation.