Lightweight Charts™ Documentation

website·Indexed 29 days ago

https://tradingview.github.io/lightweight-charts/

A client-side library for drawing financial data on a canvas. Documentation covers version 5.2, including installation, series and chart types, price and time scales, and pane management. Includes comprehensive guides on plugin development for custom series and primitives, pixel-perfect canvas rendering, framework integrations like React, and migration paths from v2 through v5.

Tokens
56.7K
Snippets
257
Records
359
Agent score
74%

What's inside Lightweight Charts

  1. Overview of Pane Primitives

    Pane primitives are elements attached to a chart pane instead of a specific series. They are used for chart-wide elements that are not tied to series data, such as watermarks. Unlike series primitives, they cannot draw on price or time scales, cannot define axis labels, and do not have access to autoscaleInfo because they are not tied to a price scale.
  2. Understand the Series Primitive architecture

    A series primitive follows a three-tier architecture to optimize rendering performance by separating state, coordinate calculation, and pixel drawing:

    1. Primitive: Owns the state (defines what to draw).
    2. View: Converts state into coordinates (defines where to draw).
    3. Renderer: Uses the CanvasRenderingContext2D API to put pixels on the canvas (the actual drawing).

    During a redraw, the library first lets views recompute coordinates and then calls the renderers, avoiding unnecessary recomputations.

  3. Use Panes to segregate data in Lightweight Charts

    Panes allow you to display different types of data in separate visual areas within a single chart. This is commonly used to show a stock's price in one pane and trading volume in another to prevent chart clutter. By default, a chart contains a single pane, but additional panes can be added to host different series.
  4. Use CanvasRenderingTarget2D for plugin rendering

    In Lightweight Charts plugins (custom series or primitives), renderer functions receive a CanvasRenderingTarget2D object. This object allows you to execute drawing logic using the browser's 2D Canvas API. It provides two primary scopes for rendering: useMediaCoordinateSpace and useBitmapCoordinateSpace.
  5. Implement a component-based architecture for Lightweight Charts in React

    To integrate Lightweight Charts™ into a React application with a scalable architecture, use a combination of createContext, forwardRef, and useImperativeHandle. This approach allows a parent <Chart /> component to manage the chart instance and provide it to child <Series /> components via context, while still exposing the chart API to the application via refs for manual updates (e.g., calling .update() on a series).
    import { createChart, LineSeries, AreaSeries } from 'lightweight-charts';
    import React, {
    	createContext,
    	forwardRef,
    	useCallback,
    	useContext,
    	useEffect,
    	useImperativeHandle,
    	useLayoutEffect,
    	useRef,
    	useState,
    } from 'react';
    
    const Context = createContext();
    
    export function Chart(props) {
    	const [container, setContainer] = useState(false);
    	const handleRef = useCallback(ref => setContainer(ref), []);
    	return (
    		<div ref={handleRef}>
    			{container && <ChartContainer {...props} container={container} />}
    		</div>
    	);
    }
    
    export const ChartContainer = forwardRef((props, ref) => {
    	const { children, container, layout, ...rest } = props;
    
    	const chartApiRef = useRef({
    		isRemoved: false,
    		api() {
    			if (!this._api) {
    				this._api = createChart(container, {
    					...rest,
    					layout,
    					width: container.clientWidth,
    					height: 300,
    				});
    				this._api.timeScale().fitContent();
    			}
    			return this._api;
    		},
    		free(series) {
    			if (this._api && series) {
    				this._api.removeSeries(series);
    			}
    		},
    	});
    
    	useLayoutEffect(() => {
    		const currentRef = chartApiRef.current;
    		const chart = currentRef.api();
    
    		const handleResize = () => {
    			chart.applyOptions({
    				...rest,
    				width: container.clientWidth,
    			});
    		};
    
    		window.addEventListener('resize', handleResize);
    		return () => {
    			window.removeEventListener('resize', handleResize);
    			chartApiRef.current.isRemoved = true;
    			chart.remove();
    		};
    	}, []);
    
    	useImperativeHandle(ref, () => chartApiRef.current.api(), []);
    
    	useEffect(() => {
    		const currentRef = chartApiRef.current;
    		currentRef.api().applyOptions({ layout });
    	}, [layout]);
    
    	return (
    		<Context.Provider value={chartApiRef.current}>
    			{props.children}
    		</Context.Provider>
    	);
    });
    
    export const Series = forwardRef((props, ref) => {
    	const parent = useContext(Context);
    	const context = useRef({
    		api() {
    			if (!this._api) {
    				const { data, type, ...rest } = props;
    				this._api = 
    					type === 'line' 
    					? parent.api().addSeries(LineSeries, rest) 
    					: parent.api().addSeries(AreaSeries, rest);
    				this._api.setData(data);
    			}
    			return this._api;
    		},
    		free() {
    			if (this._api && !parent.isRemoved) {
    				parent.free(this._api);
    			}
    		},
    	});
    
    	useLayoutEffect(() => {
    		const currentRef = context.current;
    		currentRef.api();
    		return () => currentRef.free();
    	}, []);
    
    	useLayoutEffect(() => {
    		const currentRef = context.current;
    		const { data, ...rest } = props;
    		currentRef.api().applyOptions(rest);
    	});
    
    	useImperativeHandle(ref, () => context.current.api(), []);
    
    	return (
    		<Context.Provider value={context.current}>
    			{props.children}
    		</Context.Provider>
    	);
    });
  6. Implement a component-based architecture for Lightweight Charts in React

    To integrate Lightweight Charts™ into a complex React application, use a hierarchical component structure where a parent Chart component manages the chart instance and child Series components manage individual data series.

    Because React hooks (like useEffect) execute in a bottom-up order during instantiation, a child Series component might attempt to initialize before the parent Chart has created the chart instance. To prevent this, use useRef, useImperativeHandle, and React.createContext to share internal references and lifecycle methods from the parent chart to its children.

    <ChartComponent>
        <ChartContainer>
            <SeriesComponent 1>
                <ChildComponent />
            </SeriesComponent 1>
            <SeriesComponent N>
                <ChildComponent />
            </SeriesComponent N>
        </ChartContainer>
    </ChartComponent>
  7. Implement accessibility in Lightweight Charts

    Lightweight Charts™ does not include built-in accessibility attributes or behaviors by default. Developers are responsible for implementing their own accessibility layer to integrate charts into their site's accessibility policy. Key areas for implementation include enabling keyboard navigation, integrating ARIA (Accessible Rich Internet Applications) attributes, and generating descriptive textual content for screen readers.
  8. Integrate Lightweight Charts with React

    Lightweight Charts can be integrated into React using a component-based architecture. Basic implementations involve creating a charting component, while advanced implementations focus on a more robust component-based architecture for better state management and reusability.
  9. Choose the right TradingView charting product

    TradingView offers several products depending on the level of integration and functionality required. Note that none of these products provide market data (except for Widgets); you must provide your own data source for Lightweight Charts™, Advanced Charts, and Trading Platform.

    • Lightweight Charts™: Best when you have your own data and interface and need a small, open-source npm library to draw financial data on a canvas.
    • Advanced Charts: Best for a ready-made charting application including toolbars, symbol search, 100+ indicators, drawing tools, and chart layout saving. Data is connected via the Datafeed API. (Requires private GitHub access).
    • Trading Platform: Best for building a trading front end that requires order tickets, positions, and an Account Manager integrated with the chart. (Requires private GitHub access).
    • Widgets: Best for embedding a TradingView-hosted chart via a code snippet without writing custom code or providing your own data.