Vertical lines in Lightweight Charts, how to implement them from plugins?

179 Views Asked by At

Stack Overflow community,

I've come across the Lightweight library on GitHub and am interested in using it for my project. However, I'm facing some challenges due to the lack of clear documentation on the repository. The GitHub page provides an example, but it doesn't thoroughly explain how to implement or use the library.

Has anyone here used the Lightweight library before? If so, I would greatly appreciate it if you could share your experience or provide some guidance on the following:

  1. How did you integrate the Lightweight library into your project?

  2. Are there any specific configurations or dependencies needed?

  3. Could you provide a basic example of using a key feature of the library?

Any insights, code snippets, or links to resources you found helpful would be immensely beneficial.

enter image description here

2

There are 2 best solutions below

0
SlicedSilver On

There is a documentation site for the Lightweight Charts library here: https://tradingview.github.io/lightweight-charts/

There is a Getting Started guide to explain the basics of the library. I would also recommend having a look through the Customization Tutorial to learn more of the basics for the library.

The development of Plugins is a more advanced use-case for the library which is described here: Plugins Intro

Are there any specific configurations or dependencies needed?

The library doesn't require any additional dependencies.

Could you provide a basic example of using a key feature of the library?

Finally, there is a product page for the library here (which includes some demos): https://www.tradingview.com/lightweight-charts/

0
klugjo On

Here is the "official" vertical line plugin code:

https://github.com/tradingview/lightweight-charts/blob/master/plugin-examples/src/plugins/vertical-line/vertical-line.ts

Demo: https://tradingview.github.io/lightweight-charts/plugin-examples/plugins/vertical-line/example/

Code:

import { CanvasRenderingTarget2D } from 'fancy-canvas';
import {
    Coordinate,
    IChartApi,
    ISeriesApi,
    ISeriesPrimitive,
    ISeriesPrimitiveAxisView,
    ISeriesPrimitivePaneRenderer,
    ISeriesPrimitivePaneView,
    SeriesOptionsMap,
    SeriesType,
    Time,
} from 'lightweight-charts';
import { positionsLine } from '../../helpers/dimensions/positions';

class VertLinePaneRenderer implements ISeriesPrimitivePaneRenderer {
    _x: Coordinate | null = null;
    _options: VertLineOptions;
    constructor(x: Coordinate | null, options: VertLineOptions) {
        this._x = x;
        this._options = options;
    }
    draw(target: CanvasRenderingTarget2D) {
        target.useBitmapCoordinateSpace(scope => {
            if (this._x === null) return;
            const ctx = scope.context;
            const position = positionsLine(
                this._x,
                scope.horizontalPixelRatio,
                this._options.width
            );
            ctx.fillStyle = this._options.color;
            ctx.fillRect(
                position.position,
                0,
                position.length,
                scope.bitmapSize.height
            );
        });
    }
}

class VertLinePaneView implements ISeriesPrimitivePaneView {
    _source: VertLine;
    _x: Coordinate | null = null;
    _options: VertLineOptions;

    constructor(source: VertLine, options: VertLineOptions) {
        this._source = source;
        this._options = options;
    }
    update() {
        const timeScale = this._source._chart.timeScale();
        this._x = timeScale.timeToCoordinate(this._source._time);
    }
    renderer() {
        return new VertLinePaneRenderer(this._x, this._options);
    }
}

class VertLineTimeAxisView implements ISeriesPrimitiveAxisView {
    _source: VertLine;
    _x: Coordinate | null = null;
    _options: VertLineOptions;

    constructor(source: VertLine, options: VertLineOptions) {
        this._source = source;
        this._options = options;
    }
    update() {
        const timeScale = this._source._chart.timeScale();
        this._x = timeScale.timeToCoordinate(this._source._time);
    }
    visible() {
        return this._options.showLabel;
    }
    tickVisible() {
        return this._options.showLabel;
    }
    coordinate() {
        return this._x ?? 0;
    }
    text() {
        return this._options.labelText;
    }
    textColor() {
        return this._options.labelTextColor;
    }
    backColor() {
        return this._options.labelBackgroundColor;
    }
}

export interface VertLineOptions {
    color: string;
    labelText: string;
    width: number;
    labelBackgroundColor: string;
    labelTextColor: string;
    showLabel: boolean;
}

const defaultOptions: VertLineOptions = {
    color: 'green',
    labelText: '',
    width: 3,
    labelBackgroundColor: 'green',
    labelTextColor: 'white',
    showLabel: false,
};

export class VertLine implements ISeriesPrimitive<Time> {
    _chart: IChartApi;
    _series: ISeriesApi<keyof SeriesOptionsMap>;
    _time: Time;
    _paneViews: VertLinePaneView[];
    _timeAxisViews: VertLineTimeAxisView[];

    constructor(
        chart: IChartApi,
        series: ISeriesApi<SeriesType>,
        time: Time,
        options?: Partial<VertLineOptions>
    ) {
        const vertLineOptions: VertLineOptions = {
            ...defaultOptions,
            ...options,
        };
        this._chart = chart;
        this._series = series;
        this._time = time;
        this._paneViews = [new VertLinePaneView(this, vertLineOptions)];
        this._timeAxisViews = [new VertLineTimeAxisView(this, vertLineOptions)];
    }
    updateAllViews() {
        this._paneViews.forEach(pw => pw.update());
        this._timeAxisViews.forEach(tw => tw.update());
    }
    timeAxisViews() {
        return this._timeAxisViews;
    }
    paneViews() {
        return this._paneViews;
    }
}