### Basic setup with one tool plugin Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/index-and-core-plugin.md Basic setup example showing how to create a chart, add a candlestick series, initialize the Line Tools plugin, register a rectangle tool, and enter interactive draw mode. ```ts import { createChart, CandlestickSeries } from 'lightweight-charts'; import { createLineToolsPlugin } from 'lightweight-charts-line-tools-core'; import { LineToolRectangle } from 'lightweight-charts-line-tools-rectangle'; const chart = createChart(document.getElementById('chart-container')); const series = chart.addSeries(CandlestickSeries, {}, 0); // pane 0 const lineTools = createLineToolsPlugin(chart, series); lineTools.registerLineTool('Rectangle', LineToolRectangle); // Interactive draw mode lineTools.addLineTool('Rectangle'); ``` -------------------------------- ### Install required packages Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/README.md Install the core plugin, the rectangle tool plugin, and the lightweight-charts library from GitHub repositories. ```bash npm install github:difurious/lightweight-charts-line-tools-core github:difurious/lightweight-charts-line-tools-rectangle lightweight-charts ``` -------------------------------- ### Build the Core with npm install and npm run build Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/README.md Install dependencies and build the core orchestrator from source. Requires Node.js to be installed. ```bash # Install dependencies npm install # Build the project npm run build ``` -------------------------------- ### Basic integration with Rectangle tool Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/README.md Basic integration example: create a chart, add a CandlestickSeries, initialize the line tools plugin, register the Rectangle tool, and start drawing mode. ```typescript import { createChart, CandlestickSeries } from 'lightweight-charts'; import { createLineToolsPlugin } from 'lightweight-charts-line-tools-core'; import { LineToolRectangle } from 'lightweight-charts-line-tools-rectangle'; const chart = createChart(document.getElementById('chart-container')); // Lightweight Charts v5 way to add a series const series = chart.addSeries(CandlestickSeries, { // optional series options }, 0); //0 at the end is what pane you want the series to belong to // Initialize the Core Orchestrator const lineTools = createLineToolsPlugin(chart, series); // Register the specific tool classes you have installed lineTools.registerLineTool('Rectangle', LineToolRectangle); // Start interactive drawing mode (user clicks to place points) lineTools.addLineTool('Rectangle'); ``` -------------------------------- ### LineToolPaneView (Usage Example) Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/pane-views.md Example of extending LineToolPaneView to create a custom tool view. Shows how to implement _updateImpl to render segments and anchors. ```APIDOC ## LineToolPaneView ### Description Base class for creating custom tool pane views. Extend this class and implement _updateImpl to render your tool's graphics. ### Usage Example ```ts import { LineToolPaneView, LineToolPaneViewBase, CompositeRenderer, SegmentRenderer, AnchorPoint } from './src/views/line-tool-pane-view'; export class MyToolPaneView extends LineToolPaneView { protected _updateImpl(height: number, width: number): void { const composite = this._renderer as CompositeRenderer; composite.clear(); if (!this._tool.options().visible) return; if (!this._updatePoints()) return; const [p0, p1] = this._points; // screen-space anchors const segment = new SegmentRenderer(); segment.setData({ points: [p0, p1], line: { /* LineOptions */ }, }); composite.append(segment); if (this.areAnchorsVisible()) { this._addAnchors(composite); } } protected _addAnchors(renderer: CompositeRenderer): void { renderer.append(this.createLineAnchor({ points: this._points }, 0)); } } ``` ### Methods - **_updateImpl(height: number, width: number): void** - Protected method to implement rendering logic. - **_addAnchors(renderer: CompositeRenderer): void** - Protected method to add anchor renderers. - **areAnchorsVisible(): boolean** - Returns whether anchors are visible. - **createLineAnchor(data: any, index: number): AnchorRenderer** - Creates a line anchor renderer. - **_updatePoints(): boolean** - Updates internal points; returns false if points are not available. ### Properties - **_renderer** (CompositeRenderer) - The composite renderer used for drawing. - **_points** (Array) - Screen-space anchor points. - **_tool** - The associated tool instance. ``` -------------------------------- ### Delegate usage example Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/utils-helpers.md Example usage of `Delegate` from the package. It creates a `Delegate`, subscribes a callback, fires an event, unsubscribes, and destroys the delegate. The `fire` call logs 'hello' to the console. ```ts import { Delegate } from 'lightweight-charts-line-tools-core'; const d = new Delegate(); const fn = (msg: string) => console.log(msg); d.subscribe(fn); d.fire('hello'); // logs 'hello' d.unsubscribe(fn); d.destroy(); ``` -------------------------------- ### Example: textWrap with cache canvas Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/text-helpers.md Example usage of textWrap with a cache canvas. The comment shows the expected wrapped lines for the given input. ```ts import { textWrap, getBoxWidth, getBoxHeight, createCacheCanvas } from 'lightweight-charts-line-tools-core'; createCacheCanvas(); const lines = textWrap('Long label that must wrap', '12px sans-serif', 90); // ['Long label that', 'must wrap'] ``` -------------------------------- ### SegmentRenderer example Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/generic-renderers.md Creates a SegmentRenderer, sets its data with two anchor points and line styling, and draws it. The example shows how to configure line color, width, style, join, cap, and end decorations. ```typescript import { SegmentRenderer, AnchorPoint, LineEnd } from 'lightweight-charts-line-tools-core'; const renderer = new SegmentRenderer(); renderer.setData({ points: [ new AnchorPoint(100, 200, 0), new AnchorPoint(300, 150, 1), ], line: { color: '#4a90d9', width: 2, style: LineStyle.Dashed, join: LineJoin.Round, cap: LineCap.Round, end: { left: LineEnd.Normal, right: LineEnd.Arrow }, // arrow head at point[1] extend: { left: false, right: false }, }, }); // draw(renderer, target); ``` -------------------------------- ### TextRenderer usage example Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/generic-renderers.md Creates a TextRenderer, sets data with a multi-line label, centered alignment, a semi-transparent background, and a blue border, then draws it. The example uses BoxVerticalAlignment.Top and BoxHorizontalAlignment.Center for the box alignment and includes a commented draw call. ```ts import { TextRenderer, BoxHorizontalAlignment, BoxVerticalAlignment } from 'lightweight-charts-line-tools-core'; const text = new TextRenderer(); text.setData({ text: { value: 'Support\nLevel @ 150.50', alignment: 'center', padding: 4, wordWrapWidth: 120, forceTextAlign: false, forceCalculateMaxLineWidth: true, font: { color: '#ffffff', size: 12, bold: true, italic: false, family: 'sans-serif' }, box: { alignment: { vertical: BoxVerticalAlignment.Top, horizontal: BoxHorizontalAlignment.Center }, angle: 0, scale: 1, padding: { x: 6, y: 4 }, maxHeight: undefined, background: { color: 'rgba(0,0,0,0.6)', inflation: { x: 2, y: 2 } }, border: { color: '#2962FF', width: 1, radius: 4, highlight: false, style: LineStyle.Solid }, }, }, points: [new Point(250, 180)], hitTestBackground: true, }); // text.draw(target); ``` -------------------------------- ### ToolRegistry usage example Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/interaction-manager.md Shows how to import ToolRegistry and BaseLineTool, create a registry, register a tool, check registration, and instantiate a tool. ```typescript import { ToolRegistry, BaseLineTool } from 'lightweight-charts-line-tools-core'; const registry = new ToolRegistry(); registry.registerTool('TrendLine', LineToolTrendLine); if (registry.isRegistered('TrendLine')) { const Ctor = registry.getToolClass('TrendLine'); const tool = new Ctor(/* coreApi, chart, series, horzScaleBehavior, options, points, stackingManager */); } ``` -------------------------------- ### Applying options to a line tool Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/line-tools-api.md Example of applying options to an existing tool. Points are optional; if omitted, geometry remains unchanged. ```ts const ok = plugin.applyLineToolOptions({ id: 'a1b2c3', toolType: 'TrendLine', options: { line: { color: 'blue' } }, points: [] // omitted points → geometry unchanged }); ``` -------------------------------- ### Custom line tool plugin example Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/base-line-tool.md Example of the contract a tool plugin must fulfil: extend BaseLineTool, set toolType and pointsCount, call super with the required arguments, and implement _internalHitTest. The toolType must exist in LineToolType at runtime. Registration is done via plugin.registerLineTool. ```ts import { BaseLineTool, LineToolPoint, LineToolOptions, LineToolsCorePlugin } from 'lightweight-charts-line-tools-core'; import { IChartApiBase, ISeriesApi, SeriesType, IHorzScaleBehavior } from 'lightweight-charts'; import { PriceAxisLabelStackingManager } from 'lightweight-charts-line-tools-core'; export class LineToolCustom extends BaseLineTool { public readonly toolType = 'CustomTool' as const; // must exist in LineToolType at runtime public readonly pointsCount = 2; constructor( coreApi: LineToolsCorePlugin, chart: IChartApiBase, series: ISeriesApi, horzScaleBehavior: IHorzScaleBehavior, options: LineToolOptions, points: LineToolPoint[], priceAxisLabelStackingManager: PriceAxisLabelStackingManager, ) { super(coreApi, chart, series, horzScaleBehavior, options, points, 'CustomTool', 2, priceAxisLabelStackingManager); } public _internalHitTest(x: any, y: any): any { return null; } } // registration plugin.registerLineTool('CustomTool', LineToolCustom); ``` -------------------------------- ### Using merge, deepCopy, and randomHash utilities Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/utils-helpers.md Shows how to import and use the merge, deepCopy, and randomHash utilities from the package. The merge example demonstrates deep merging with nested objects, and randomHash generates a random alphanumeric id. ```typescript import { merge, deepCopy, randomHash } from 'lightweight-charts-line-tools-core'; const opts = merge({ line: { width: 1 } }, { line: { color: 'red' } }); // opts.line => { width: 1, color: 'red' } const id = randomHash(); // e.g. 'k3fQmZ9xAv1p' ``` -------------------------------- ### coreApi(): LineToolsCorePlugin Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/base-line-tool.md Geometry utility to get the core plugin instance. ```APIDOC ## coreApi(): LineToolsCorePlugin ### Description Returns the owning plugin instance, providing access to formatters, magnet threshold, and layout. ### Method Function ### Signature `coreApi(): LineToolsCorePlugin` ### Returns - **LineToolsCorePlugin** - The core plugin instance. ``` -------------------------------- ### Example usage of TextWidthCache Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/text-helpers.md Creates a cache with size 100 and measures text '12 345.67', which is normalized to '10 000.00' key due to digit substitution. ```TypeScript import { TextWidthCache } from './src/utils/text-width-cache'; const cache = new TextWidthCache(100); const w = cache.measureText(ctx, '12 345.67'); // normalized to '10 000.00' key ``` -------------------------------- ### roundPriceToStep Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/utils-helpers.md Documentation for the `roundPriceToStep` utility function, including its signature, parameters, behavior, and usage example. ```APIDOC ## `roundPriceToStep` ### Description Rounds a price to the nearest step defined by `minMove`, using a two-stage sanitizer that validates input, aligns to a grid, and strips binary floating-point jitter. ### Signature ```ts export function roundPriceToStep(price: number, minMove: number): number ``` ### Parameters - **price** (number) - Required - The price value to round. - **minMove** (number) - Required - The minimum price movement step (must be greater than 0). ### Returns - **number** - The rounded price. ### Behavior 1. Validates input: if `price` is not finite or `minMove <= 0`, returns `price` unchanged. 2. Grid alignment: `Math.round(price * (1/minMove)) / (1/minMove)`. 3. Dynamic precision discovery from the `minMove` string (scientific notation exponents, decimal length, or 0 for integers), then `Number(alignedPrice.toFixed(precision))` strips binary floating-point jitter. ### Example ```ts import { roundPriceToStep } from 'lightweight-charts-line-tools-core'; roundPriceToStep(12.31, 0.25); // 12.25 roundPriceToStep(12.250000000000004, 0.25); // 12.25 ``` ``` -------------------------------- ### Example - building 2 anchors for a trend line Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/composite-and-anchor-renderers.md Creates two AnchorPoint instances at (100,120) and (320,90) with data indices 0 and 1, square set to false, and no specific cursor. Demonstrates the constructor usage for a trend line's endpoints. ```typescript import { AnchorPoint } from 'lightweight-charts-line-tools-core'; const p0 = new AnchorPoint(100, 120, 0, false, undefined); const p1 = new AnchorPoint(320, 90, 1, false, undefined); ``` -------------------------------- ### Multi-pane isolation with one plugin per series Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/index-and-core-plugin.md Multi-pane isolation example: create one plugin per series so line tools are trapped in their respective panes. Demonstrates registering and adding a rectangle tool on both a main candlestick series (pane 0) and an RSI line series (pane 1). ```ts import { createChart, CandlestickSeries, LineSeries } from 'lightweight-charts'; import { createLineToolsPlugin } from 'lightweight-charts-line-tools-core'; import { LineToolRectangle } from 'lightweight-charts-line-tools-rectangle'; const chart = createChart(document.getElementById('chart-container')); const mainSeries = chart.addSeries(CandlestickSeries, {}, 0); // Pane 0 const rsiSeries = chart.addSeries(LineSeries, { title: 'RSI' }, 1); // Pane 1 const lineToolsMain = createLineToolsPlugin(chart, mainSeries); const lineToolsRSI = createLineToolsPlugin(chart, rsiSeries); lineToolsMain.registerLineTool('Rectangle', LineToolRectangle); lineToolsRSI.registerLineTool('Rectangle', LineToolRectangle); lineToolsMain.addLineTool('Rectangle'); // trapped in Pane 0 lineToolsRSI.addLineTool('Rectangle'); // trapped in Pane 1 ``` -------------------------------- ### Example with sub-segment culling info Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/culling-engine.md Demonstrates passing cullingInfo with subSegments to getToolCullingState for a polyline, ensuring visibility when any specified segment crosses the screen. ```typescript const info = { subSegments: [ [0, 1], [2, 3], [4, 5], // index pairs of interesting segments ], }; const state = getToolCullingState(points, tool, { left: false, right: false }, undefined, info); ``` -------------------------------- ### LineAnchorRenderer Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/composite-and-anchor-renderers.md Documentation for the LineAnchorRenderer class, including its constructor, methods, and an example usage. ```APIDOC ## LineAnchorRenderer ### Description Renders line tool anchor points (square/circle bodies, hover halos) and performs hit-testing for mouse interaction. It is re-exported at the package root and implements `IPaneRenderer`. ### Constructor `constructor(chart: IChartApiBase, data?: LineAnchorRendererData)` Stores the chart reference and optional initial data. ### Methods #### setData(data: LineAnchorRendererData): void Replaces the entire payload. #### updateData(data: Partial): void Deep-merges a partial update into the current payload. #### draw(target: CanvasRenderingTarget2D): void Splits anchors into square vs. circle groups, then draws bodies via `drawRectBody`/`drawCircleBody` (stroke width +1 when selected) and hover halos (`drawRectShadow`/`drawCircleShadow`, `globalAlpha 0.2`) when within `radius + 8` of the mouse. The currently edited anchor is skipped while being dragged. #### hitTest(x: Coordinate, y: Coordinate): HitTestResult | null For each anchor within `radius + interactionTolerance.anchor` distance: cursor priority (1) `point.specificCursor` → (2) `data.defaultAnchorHoverCursor` → (3) `DiagonalNwSeResize` when `hitTestType === ChangePoint` → (4) `Pointer`; returns `new HitTestResult(hitTestType, { pointIndex: point.data, suggestedCursor })`. Works even when `visible` is `false` (hidden anchors can still be grabbed, e.g. unselected tools). ### Example — building an 8-handle rectangle grid (virtual anchors) ```ts import { LineAnchorRenderer, AnchorPoint, HitTestType } from 'lightweight-charts-line-tools-core'; const anchors = [ new AnchorPoint(100, 100, 0, false, undefined), // NW new AnchorPoint(300, 100, 1, false, undefined), // N new AnchorPoint(300, 200, 2, false, undefined), // NE // ... 8 corners/edges total ]; const anchorRenderer = new LineAnchorRenderer(chart, { points: anchors, backgroundColors: anchors.map(() => 'rgba(0,0,0,0)'), editedPointIndex: null, currentPoint: new Point(0, 0), color: '#1E53E5', radius: 6, strokeWidth: 1, hoveredStrokeWidth: 4, selected: true, visible: true, hitTestType: HitTestType.ChangePoint, defaultAnchorHoverCursor: PaneCursorType.Pointer, defaultAnchorDragCursor: PaneCursorType.Move, }); // anchorRenderer.draw(target); ``` ``` -------------------------------- ### draw Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/generic-renderers.md Builds the path (moveTo + lineTo), fills if a background color exists, closes only when enclosePerimeterWithLine, strokes the perimeter, then draws end decorations at the start and end points. ```APIDOC ## draw ### Description Builds the path (moveTo + lineTo), fills if a background color exists, closes only when enclosePerimeterWithLine, strokes the perimeter, then draws end decorations at the start and end points. ``` -------------------------------- ### Subscribe and unsubscribe to after-edit event Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/line-tools-api.md Example of subscribing and unsubscribing to the after-edit event. The same function reference must be used for both subscribe and unsubscribe. ```typescript function onAfterEdit(params) { fetch('/api/save-tool', { method: 'POST', body: JSON.stringify(params.selectedLineTool) }); } plugin.subscribeLineToolsAfterEdit(onAfterEdit); // ... plugin.unsubscribeLineToolsAfterEdit(onAfterEdit); ``` -------------------------------- ### SegmentRenderer Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/generic-renderers.md Documentation for the SegmentRenderer class, including its constructor, methods, data interface, and usage example. ```APIDOC ## SegmentRenderer ### Description Renders a straight line segment between two anchor points. Used by tools such as TrendLine, Ray, Arrow, ExtendedLine, Horizontal/Vertical/Cross lines, Parallel Channel borders, and Fib lines. ### Constructor `new SegmentRenderer(hitTest?: HitTestResult)` - `hitTest` (optional) - Pre-configured hit-test result template; defaults to `new HitTestResult(HitTestType.MovePoint)`. ### Methods #### `setData(data: SegmentRendererData): void` Replaces the renderer's data payload. #### `draw(target: CanvasRenderingTarget2D): void` Draws the segment inside `target.useMediaCoordinateSpace(...)` (CSS pixels). #### `hitTest(x: Coordinate, y: Coordinate): HitTestResult | null` Performs a geometric hit test. Returns hit-type plus `{ pointIndex, suggestedCursor }` when the distance to the segment is within the interaction tolerance (4 pixels). ### SegmentRendererData | Field | Type | Required | Description | |-------|------|----------|-------------| | points | `[AnchorPoint, AnchorPoint]` | yes | Screen-space start/end points. | | line | `LineOptions` | yes | Full styling. `extend.left/right` enable Ray/ExtendedLine behavior; `end.left/right` may be `LineEnd.Arrow`/`LineEnd.Circle` (decorations drawn first for correct Z-order). | | toolDefaultHoverCursor | `PaneCursorType?` | no | Cursor suggested on line hover (default `Pointer`). | | toolDefaultDragCursor | `PaneCursorType?` | no | Cursor when dragging the line. | ### Example ```ts import { SegmentRenderer, AnchorPoint, LineEnd } from 'lightweight-charts-line-tools-core'; const renderer = new SegmentRenderer(); renderer.setData({ points: [ new AnchorPoint(100, 200, 0), new AnchorPoint(300, 150, 1), ], line: { color: '#4a90d9', width: 2, style: LineStyle.Dashed, join: LineJoin.Round, cap: LineCap.Round, end: { left: LineEnd.Normal, right: LineEnd.Arrow }, // arrow head at point[1] extend: { left: false, right: false }, }, }); // draw(renderer, target); ``` ``` -------------------------------- ### Building an 8-handle rectangle grid with LineAnchorRenderer Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/composite-and-anchor-renderers.md Example of creating a LineAnchorRenderer with an array of AnchorPoint objects to form an 8-handle rectangle grid. The renderer is configured with colors, radius, stroke widths, and hit-test settings. ```typescript import { LineAnchorRenderer, AnchorPoint, HitTestType } from 'lightweight-charts-line-tools-core'; const anchors = [ new AnchorPoint(100, 100, 0, false, undefined), // NW new AnchorPoint(300, 100, 1, false, undefined), // N new AnchorPoint(300, 200, 2, false, undefined), // NE // ... 8 corners/edges total ]; const anchorRenderer = new LineAnchorRenderer(chart, { points: anchors, backgroundColors: anchors.map(() => 'rgba(0,0,0,0)'), editedPointIndex: null, currentPoint: new Point(0, 0), color: '#1E53E5', radius: 6, strokeWidth: 1, hoveredStrokeWidth: 4, selected: true, visible: true, hitTestType: HitTestType.ChangePoint, defaultAnchorHoverCursor: PaneCursorType.Pointer, defaultAnchorDragCursor: PaneCursorType.Move, }); // anchorRenderer.draw(target); ``` -------------------------------- ### Time Axis Views and Renderers - Shared Types and Interfaces Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/time-axis-views-and-renderers.md Documentation for the shared data types and interfaces used by time axis views and renderers, including options, data, and renderer interfaces, plus an example usage of CrosshairTimeAxisLabelView. ```APIDOC ## TimeAxisViewRendererOptions ### Description Interface defining the options required by the time axis view renderer. ### Fields - **baselineOffset** (`number`) - Required - Text baseline correction. - **borderSize** (`number`) - Required - Top border thickness. - **font** (`string`) - Required - Typography. - **fontSize** (`number`) - Required - Typography. - **paddingBottom** (`number`) - Required - Vertical box padding. - **paddingTop** (`number`) - Required - Vertical box padding. - **tickLength** (`number`) - Required - Tick length below the box. - **paddingHorizontal** (`number`) - Required - Horizontal box padding (used in `draw` to compute label width). - **widthCache** (`TextWidthCache?`) - Optional - Optional text measurement cache (renderer falls back to its own `TextWidthCache`). ## TimeAxisViewRendererData ### Description Interface defining the data required by the time axis view renderer. ### Fields - **width** (`number`) - Required - Time-scale width (used as drawable area width). - **text** (`string`) - Required - Label text. - **coordinate** (`number`) - Required - Center X coordinate. - **color** (`string`) - Required - Foreground color. - **background** (`string`) - Required - Box background. - **visible** (`boolean`) - Required - Draw gate. - **tickVisible** (`boolean?`) - Optional - Default `true` for tool anchors; set to `false` by `CrosshairTimeAxisLabelView` (drawer checks `!== false`). ## ITimeAxisViewRenderer ### Description Interface for a time axis view renderer. ### Methods - **draw(target: CanvasRenderingTarget2D, rendererOptions: TimeAxisViewRendererOptions): void** - Draws the renderer. - **setData(data: TimeAxisViewRendererData): void** - Sets the data for the renderer. - **height(rendererOptions: TimeAxisViewRendererOptions): number** - Returns the height of the renderer. ## ITimeAxisView ### Description Interface for a time axis view. ### Methods - **update(): void** - Updates the view. - **getRenderer(): ITimeAxisViewRenderer** - Returns the renderer. - **text(): string** - Returns the text. - **coordinate(): Coordinate** - Returns the coordinate. - **textColor(): string** - Returns the text color. - **backColor(): string** - Returns the background color. - **visible(): boolean** - Returns visibility. ## CrosshairTimeAxisLabelView Example ### Description Example usage of `CrosshairTimeAxisLabelView` to show a supplemental label. ### Code ```ts import { CrosshairTimeAxisLabelView } from './src/views/crosshair-time-axis-label-view'; const crosshairLabel = new CrosshairTimeAxisLabelView(chart); crosshairLabel.updateState('2024-01-01 10:00', 480, true); // show in blank space // chart repaint happens via requestUpdate() ``` ``` -------------------------------- ### Resolving a point in the future blank space Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/geometry.md Example resolving a point in the future 'blank space'. Uses interpolateTimeFromLogicalIndex to project a timestamp past the last bar (gliding over weekends), then interpolateLogicalIndexFromTime to get the fractional index, and logicalIndexToCoordinate to convert to pixel coordinates. ```ts import { interpolateTimeFromLogicalIndex, interpolateLogicalIndexFromTime, logicalIndexToCoordinate, } from 'lightweight-charts-line-tools-core'; // Mouse is at pixel x=900 which maps to logical index 2450.3 (past the last bar): const futureTime = interpolateTimeFromLogicalIndex(chart, series, 2450.3); // => projected timestamp that glides over the weekend (Zone 3) // Conversely, get the fractional index for exact render position: const index = interpolateLogicalIndexFromTime(chart, series, futureTime ?? 1672531200); const xPx = index !== null ? logicalIndexToCoordinate(chart.timeScale(), index) : null; ``` -------------------------------- ### Set up multi-pane line tools with separate plugin instances Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/README.md Create a separate Core Plugin instance for each series to support multiple panes. Each instance independently manages drawings for its own pane, ensuring correct coordinate math, height clamping, and drawing silos. Register and add tools per instance to trap drawings in the desired pane. ```typescript import { createChart, CandlestickSeries, LineSeries } from 'lightweight-charts'; import { createLineToolsPlugin } from 'lightweight-charts-line-tools-core'; import { LineToolRectangle } from 'lightweight-charts-line-tools-rectangle'; const chart = createChart(document.getElementById('chart-container'), { // ... chart options }); // 1. Create the Main Price Series (Pane 0 by default) const mainSeries = chart.addSeries( CandlestickSeries, { //options }, 0); // 0 is Pane index // 2. Create an Indicator Series in a New Pane (Pane 1) const rsiSeries = chart.addSeries( LineSeries, { title: 'RSI' //more options }, 1); // 1 is Pane index // 3. Initialize a Core Orchestrator for each Series // Each instance will independently manage the drawings for its own pane. const lineToolsMain = createLineToolsPlugin(chart, mainSeries); const lineToolsRSI = createLineToolsPlugin(chart, rsiSeries); // 4. Register tools for both instances lineToolsMain.registerLineTool('Rectangle', LineToolRectangle); lineToolsRSI.registerLineTool('Rectangle', LineToolRectangle); // 5. Usage // This rectangle is mathematically trapped in the Main Pane (Pane 0) lineToolsMain.addLineTool('Rectangle'); // This rectangle is mathematically trapped in the RSI Pane (Pane 1) lineToolsRSI.addLineTool('Rectangle'); ``` -------------------------------- ### roundPriceToStep usage example Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/utils-helpers.md Usage example of roundPriceToStep. It rounds a price to the nearest step defined by minMove and removes floating-point jitter, as shown by the two calls returning 12.25. ```ts import { roundPriceToStep } from 'lightweight-charts-line-tools-core'; roundPriceToStep(12.31, 0.25); // 12.25 roundPriceToStep(12.250000000000004, 0.25); // 12.25 ``` -------------------------------- ### drawArrowEnd usage example Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/canvas-helpers.md Example usage of `drawArrowEnd` with a solid line style. Imports `drawArrowEnd` and `LineStyle` from the package and draws an arrow from (100, 100) to (200, 100) with width 2. ```ts import { drawArrowEnd, LineStyle } from 'lightweight-charts-line-tools-core'; drawArrowEnd(new Point(100, 100), new Point(200, 100), ctx, 2, LineStyle.Solid); ``` -------------------------------- ### Handle createLineToolsPlugin dummy fallback Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/errors.md The factory never throws, so consumer code must check the return value of addLineTool. An empty string indicates either the dummy fallback (initialization failure) or an unregistered tool type; inspect the console for the corresponding error message. ```ts const plugin = createLineToolsPlugin(chart, series); const result = plugin.addLineTool('Rectangle'); if (result === '') { // Plugin is the dummy fallback OR the tool type is unregistered. // Inspect the console for "Failed to initialize..." / "not registered". } ``` -------------------------------- ### getChart(): IChartApiBase Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/base-line-tool.md Geometry utility to get the chart API. ```APIDOC ## getChart(): IChartApiBase ### Description Returns the chart API instance. Throws an error if the chart API is not available. ### Method Function ### Signature `getChart(): IChartApiBase` ### Throws - **Error** - `Chart API not available. Tool might not be attached.` when missing. ### Returns - **IChartApiBase** - The chart API. ``` -------------------------------- ### getChartDrawingHeight(): number Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/base-line-tool.md Geometry utility to get chart drawing height. ```APIDOC ## getChartDrawingHeight(): number ### Description Returns the height of the pane containing this tool's series from the layout snapshot. Returns 0 if the pane is not found. ### Method Function ### Signature `getChartDrawingHeight(): number` ### Returns - **number** - The drawing height, or 0 if not found. ``` -------------------------------- ### getChartDrawingWidth(): number Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/base-line-tool.md Geometry utility to get chart drawing width. ```APIDOC ## getChartDrawingWidth(): number ### Description Returns the width of the chart drawing area, excluding the price axis, from the Core's cached layout snapshot. ### Method Function ### Signature `getChartDrawingWidth(): number` ### Returns - **number** - The drawing width. ``` -------------------------------- ### Creating line tools with addLineTool Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/line-tools-api.md Shows two ways to create line tools: interactive mode (no points) and programmatic creation with points and options. ```ts // Interactive drawing plugin.addLineTool('Rectangle'); // Programmatic creation const id = plugin.addLineTool('TrendLine', [ { timestamp: 1672531200, price: 100 }, { timestamp: 1672617600, price: 120 } ], { line: { color: '#ff0000', width: 2 } }); ``` -------------------------------- ### getSeries(): ISeriesApi Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/base-line-tool.md Geometry utility to get the series API. ```APIDOC ## getSeries(): ISeriesApi ### Description Returns the series API associated with this tool. Throws an error if the series is not attached. ### Method Function ### Signature `getSeries(): ISeriesApi` ### Throws - **Error** - `Series not attached to tool .` when missing. ### Returns - **ISeriesApi** - The series API. ``` -------------------------------- ### LineToolOptionsMap interface Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/types.md Maps every valid tool string to its complete options structure. Includes all line tools such as FibRetracement, ParallelChannel, and TrendLine. ```ts export interface LineToolOptionsMap { FibRetracement: FibRetracementToolOptions; ParallelChannel: ParallelChannelToolOptions; HorizontalLine: HorizontalLineToolOptions; VerticalLine: VerticalLineToolOptions; Highlighter: HighlighterToolOptions; CrossLine: CrossLineToolOptions; TrendLine: TrendLineToolOptions; Callout: CalloutToolOptions; Rectangle: RectangleToolOptions; LongShortPosition: LongShortPositionToolOptions; Circle: CircleToolOptions; PriceRange: PriceRangeToolOptions; Triangle: TriangleToolOptions; Brush: BrushToolOptions; Path: PathToolOptions; Text: TextToolOptions; Ray: TrendLineToolOptions; Arrow: TrendLineToolOptions; ExtendedLine: TrendLineToolOptions; HorizontalRay: HorizontalLineToolOptions; MarketDepth: MarketDepthToolOptions; } ``` -------------------------------- ### LineToolPaneView Class Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/pane-views.md Documentation for the abstract LineToolPaneView class, including its constructor and methods. ```APIDOC ## Class: LineToolPaneView ### Description Abstract base view that renders a line tool's body (lines, shapes, text) onto its chart pane and manages interactive resize anchors. Concrete tool implementations extend this class and override `_updateImpl` to define their specific rendering logic. ### Constructor | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | tool | `BaseLineTool` | yes | The tool model (options, points, state). | | chart | `IChartApiBase` | yes | Chart API for time-scale conversions. | | series | `ISeriesApi` | yes | Series API for price conversions. | Initializes a `CompositeRenderer`, a reusable `RectangleRenderer`, and a reusable `TextRenderer`. ### Methods #### updateSeries(series: ISeriesApi): void Updates the series used for price conversions. #### update(updateType?: 'data' | 'other' | 'options'): void Updates the view. The optional `updateType` indicates the kind of update. #### renderer(): IPaneRenderer | null Returns the pane renderer for this view, or `null` if none. #### _updatePoints(): boolean Protected method to update the tool's points. Returns a boolean indicating success. #### _updateImpl(height: number, width: number): void Protected method that concrete implementations override to define specific rendering logic. #### areAnchorsVisible(): boolean Protected method that returns whether resize anchors are visible. #### _addAnchors(renderer: CompositeRenderer): void Protected method that adds resize anchors to the given composite renderer. #### createLineAnchor(data: LineAnchorCreationData, index: number): LineAnchorRenderer Protected method that creates a line anchor renderer for the given data and index. #### _lineAnchorColors(points: AnchorPoint[]): string[] Protected method that returns the colors for the line anchors based on the given points. ``` -------------------------------- ### getExtendedVisiblePriceRange Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/geometry.md Utility function to get the extended visible price range for a tool. ```APIDOC ## getExtendedVisiblePriceRange ### Description Maps the pane's physical top (`y=0`) and bottom (`y=paneHeight`) to logical prices using the unified layout snapshot's pane height (`tool.getChartDrawingHeight()`). Returns `{ from: bottomPrice, to: topPrice }` or `null` when the series is not attached. ### Signature ```ts export function getExtendedVisiblePriceRange( tool: BaseLineTool ): { from: BarPrice | null; to: BarPrice | null; } | null ``` ### Parameters - **tool** (BaseLineTool) - Required - The base line tool instance. ### Returns - **{ from: BarPrice | null; to: BarPrice | null; } | null** - The extended visible price range, or `null` if the series is not attached. ``` -------------------------------- ### get horzScaleBehavior(): IHorzScaleBehavior Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/base-line-tool.md Geometry utility getter for horizontal scale behavior. ```APIDOC ## get horzScaleBehavior(): IHorzScaleBehavior ### Description Getter for the horizontal scale behavior. Throws an error if not attached. ### Method Getter ### Signature `get horzScaleBehavior(): IHorzScaleBehavior` ### Throws - **Error** - `Horizontal Scale Behavior not attached to tool .` when missing. ### Returns - **IHorzScaleBehavior** - The horizontal scale behavior. ``` -------------------------------- ### Line Tool Options, Export, and Views Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/base-line-tool.md Documentation for the line tool's options, export, and views methods. ```APIDOC ## options() ### Description Returns the full current options object for the line tool. The object is mutable by convention; views cache-invalidate on `'options'` updates. ### Method options ### Signature `(): LineToolOptionsInternal` ### Returns - **LineToolOptionsInternal** - The full current options object. ## applyOptions(options) ### Description Deep-merges partial options into the current options, then updates all views with `'options'` update type and triggers a redraw. ### Method applyOptions ### Signature `(options: DeepPartial>): void` ### Parameters - **options** (DeepPartial>) - Required - Partial options to merge. ### Request Example ```ts // Update only the line color of an existing tool tool.applyOptions({ line: { color: '#00ff00' } }); ``` ### Returns - **void** - No return value. ## getExportData() ### Description Builds an export object containing the tool's id, type, points, and options. ### Method getExportData ### Signature `(): LineToolExport` ### Returns - **LineToolExport** - An object with `{ id, toolType, points: this.points(), options: this.options() }`. ## _setupOptions(finalOptions) ### Description Protected method that assigns the finalized options object. ### Method _setupOptions ### Signature `(finalOptions: LineToolOptionsInternal): void` ### Parameters - **finalOptions** (LineToolOptionsInternal) - Required - The finalized options object. ### Returns - **void** - No return value. ## paneViews() ### Description Returns the pane views array. Returns an empty array while destroying. ### Method paneViews ### Signature `(): readonly IPaneView[]` ### Returns - **readonly IPaneView[]** - The pane views array. ## priceAxisViews() ### Description Returns the price axis label views array. Returns an empty array while destroying. ### Method priceAxisViews ### Signature `(): readonly IPriceAxisView[]` ### Returns - **readonly IPriceAxisView[]** - The price axis label views array. ## timeAxisViews() ### Description Returns the time axis label views array. Returns an empty array while destroying. ### Method timeAxisViews ### Signature `(): readonly ITimeAxisView[]` ### Returns - **readonly ITimeAxisView[]** - The time axis label views array. ## updateAllViews(updateType?) ### Description Runs culling state update, updates pane views, price/time axis views, and synchronously updates the price axis label stacking manager so shifted Y-coordinates are ready for the paint cycle. ### Method updateAllViews ### Signature `(updateType?: 'data' | 'other' | 'options'): void` ### Parameters - **updateType** ('data' | 'other' | 'options') - Optional - The type of update to perform. ### Returns - **void** - No return value. ## _setPaneViews(views) ### Description Protected setter for the pane view array. ### Method _setPaneViews ### Signature `(views: IUpdatablePaneView[]): void` ### Parameters - **views** (IUpdatablePaneView[]) - Required - The pane view array to set. ### Returns - **void** - No return value. ## priceAxisLabelColor() ### Description Returns the color for the price axis label. Default is `'#2962FF'`; override for state-dependent colors. ### Method priceAxisLabelColor ### Signature `(): string | null` ### Returns - **string | null** - The price axis label color. ## timeAxisLabelColor() ### Description Returns the color for the time axis label. Default is `'#2962FF'`; override for state-dependent colors. ### Method timeAxisLabelColor ### Signature `(): string | null` ### Returns - **string | null** - The time axis label color. ## _isDestroying ### Description Private guard that disables views during teardown. ### Type boolean (private) ``` -------------------------------- ### Exporting and importing line tools Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/line-tools-api.md Shows exporting all tools to JSON, storing in localStorage, and later importing them back. Import is non-destructive and updates by id. ```ts const state = plugin.exportLineTools(); localStorage.setItem('chartTools', state); // later… plugin.importLineTools(localStorage.getItem('chartTools')); ``` -------------------------------- ### Getting tools by ID regex Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/line-tools-api.md Retrieves tools whose IDs match the regex and parses the returned JSON string into an array. ```ts const tools = JSON.parse(plugin.getLineToolsByIdRegex(/^fib-/)); ``` -------------------------------- ### PriceAxisLabelStackingManager class signature Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/price-axis-stacking.md Public class signature for the price axis label stacking manager. Constructor initializes default renderer options from chart layout and logs initialization. Methods register/unregister labels, set renderer options, and run the stacking algorithm. ```typescript export class PriceAxisLabelStackingManager { public constructor( chart: IChartApiBase, series: ISeriesApi, ) public registerLabel(labelData: LabelDataForStacking): void public unregisterLabel(id: string): void public setPriceAxisRendererOptions(options: PriceAxisViewRendererOptions): void public updateStacking(): void } ``` -------------------------------- ### LineToolsCorePlugin class constructor Source: https://github.com/difurious/lightweight-charts-line-tools-core/blob/main/_autodocs/api-reference/index-and-core-plugin.md Shows the constructor signature for the concrete plugin implementation. It requires chart, series, and horzScaleBehavior parameters. The constructor attaches the plugin as a primitive to the series and initializes internal managers. ```TypeScript export class LineToolsCorePlugin implements ILineToolsApi, ISeriesPrimitive { public constructor( chart: IChartApiBase, series: ISeriesApi, horzScaleBehavior: IHorzScaleBehavior, ) ```