Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@dschz/solid-lightweight-charts

dsnchz604MIT0.2.5TypeScript support: included

TradingView Lightweight Charts™ as SolidJS components

candlestick, chart, charts, crypto-charts, data-visualization, financial-charts, lightweight-charts, options-chart, price-chart, solid, solid-component, solidjs, stock-charts, technical-analysis, time-chart, time-series, tradingview, typescript, yield-curve

readme

solid-lightweight-charts

@dschz/solid-lightweight-charts

License Lightweight Charts npm Bundle Size JSR CI Discord

A fully typed SolidJS wrapper around TradingView's Lightweight Charts, providing declarative, reactive charting with support for time series, price, and yield curve data.

Solid Lightweight Charts Showcase

✨ Features

  • SolidJS-native reactivity for all chart options and data updates
  • 🔀 Multiple chart types with specialized APIs:
    • TimeChart for time-based financial data (createChart)
    • PriceChart for numeric-based price data (createOptionsChart)
    • YieldCurveChart for rate curves and duration-based data (createYieldCurveChart)
  • 📈 Complete series support: Line, Area, Candlestick, Bar, Histogram, Baseline
  • 🎨 Custom series with full TypeScript integration across all chart types
  • 🖼️ Series primitives for interactive drawings (trend lines, alerts, annotations)
  • 🎯 Pane primitives for chart-wide decorations (watermarks, grids, badges)
  • 📍 Series markers with declarative prop support and reactive updates
  • 📆 Namespaced APIs (e.g. <TimeChart.Series />, <PriceChart.Series />)
  • 📊 Multiple panes for advanced multi-series visualization
  • 🔄 Lifecycle hooks for primitives and markers management
  • 🔖 Core API compatibility - access underlying lightweight-charts APIs when needed
  • 🧹 Automatic cleanup and proper lifecycle management

🛣️ What's New in v0.2.0

Custom Series - Create fully custom visualizations with your own rendering logic
Series Primitives - Interactive drawings attached to specific series
Pane Primitives - Chart-wide decorations and backgrounds
Enhanced Markers - Declarative markers prop with reactive updates
New Lifecycle Hooks - onAttachPrimitives, onDetachPrimitives, onSetMarkers
Comprehensive Examples - Interactive playground showcasing all features

📆 Installation

Install via your favorite package manager:

npm install solid-js lightweight-charts @dschz/solid-lightweight-charts
pnpm install solid-js lightweight-charts @dschz/solid-lightweight-charts
yarn install solid-js lightweight-charts @dschz/solid-lightweight-charts
bun install solid-js lightweight-charts @dschz/solid-lightweight-charts

These are peer dependencies, so they must be installed manually:

  • solid-js
  • lightweight-charts

🚀 Quick Usage

TimeChart (Time-based Data)

import { TimeChart } from "@dschz/solid-lightweight-charts";

<TimeChart>
  <TimeChart.Series
    type="Line"
    data={[
      { time: "2023-01-01", value: 100 },
      { time: "2023-01-02", value: 105 },
    ]}
    lineWidth={2}
    color="#2962FF"
  />
</TimeChart>;

PriceChart (Numeric X-axis)

import { PriceChart } from "@dschz/solid-lightweight-charts";

<PriceChart>
  <PriceChart.Series
    type="Line"
    data={[
      { time: 0, value: 100 },
      { time: 1, value: 105 },
    ]}
    lineWidth={2}
    color="#2962FF"
  />
</PriceChart>;

YieldCurveChart (Duration-based)

import { YieldCurveChart } from "@dschz/solid-lightweight-charts";

<YieldCurveChart>
  <YieldCurveChart.Series
    type="Line"
    data={[
      { time: 0, value: 3.5 }, // 0M
      { time: 12, value: 3.8 }, // 12M
      { time: 60, value: 4.2 }, // 5Y
    ]}
    lineWidth={2}
    color="#2962FF"
  />
</YieldCurveChart>;

Multiple Panes and Markers

import { TimeChart } from "@dschz/solid-lightweight-charts";

<TimeChart>
  {/* Main pane with price data and declarative markers */}
  <TimeChart.Series
    type="Candlestick"
    data={candleData}
    markers={(data) => [
      {
        time: data[10].time,
        position: "aboveBar",
        color: "#f68410",
        shape: "circle",
        text: "Buy",
      },
      {
        time: data[20].time,
        position: "belowBar",
        color: "#e91e63",
        shape: "arrowDown",
        text: "Sell",
      },
    ]}
    onSetMarkers={(markers) => console.log("Markers updated:", markers)}
  />

  {/* Secondary pane with volume */}
  <TimeChart.Pane>
    <TimeChart.Series
      type="Histogram"
      data={volumeData}
      priceScaleId="volume"
      color="rgba(76, 175, 80, 0.8)"
    />
  </TimeChart.Pane>
</TimeChart>;

Custom Series

import { TimeChart } from "@dschz/solid-lightweight-charts";

// Define your custom pane view
const customPaneView = {
  updateAllViews() {
    /* implementation */
  },
  paneViews() {
    /* implementation */
  },
  priceValueBuilder(plotRow) {
    /* implementation */
  },
  isWhitespace(data) {
    /* implementation */
  },
  defaultOptions() {
    /* implementation */
  },
};

<TimeChart>
  <TimeChart.CustomSeries
    paneView={customPaneView}
    data={customData}
    onCreateSeries={(series) => console.log("Custom series created:", series)}
  />
</TimeChart>;

Series Primitives

import { TimeChart, type SeriesPrimitive } from "@dschz/solid-lightweight-charts";
import type {
  ISeriesPrimitiveAxisView,
  IPrimitivePaneView,
  IPrimitivePaneRenderer,
  Time,
  SeriesAttachedParameter,
} from "lightweight-charts";

// Trend line primitive with proper TypeScript implementation
class TrendLinePrimitive implements SeriesPrimitive<"Line", Time> {
  private _paneViews: TrendLinePaneView[];
  private _point1: { time: Time; value: number };
  private _point2: { time: Time; value: number };

  constructor(point1: { time: Time; value: number }, point2: { time: Time; value: number }) {
    this._point1 = point1;
    this._point2 = point2;
    this._paneViews = [new TrendLinePaneView(this)];
  }

  updateAllViews() {
    this._paneViews.forEach((pv) => pv.update());
  }

  paneViews() {
    return this._paneViews;
  }

  attached(param: SeriesAttachedParameter<Time, "Line">) {
    // Implementation for when primitive is attached
  }

  detached() {
    // Cleanup when primitive is detached
  }

  getPoint1() {
    return this._point1;
  }
  getPoint2() {
    return this._point2;
  }
}

class TrendLinePaneView implements IPrimitivePaneView {
  private _source: TrendLinePrimitive;
  private _renderer: TrendLinePaneRenderer;

  constructor(source: TrendLinePrimitive) {
    this._source = source;
    this._renderer = new TrendLinePaneRenderer();
  }

  update() {
    this._renderer.setData({
      point1: this._source.getPoint1(),
      point2: this._source.getPoint2(),
    });
  }

  renderer() {
    return this._renderer;
  }

  zOrder() {
    return "normal" as const;
  }
}

class TrendLinePaneRenderer implements IPrimitivePaneRenderer {
  private _data: { point1: any; point2: any } | null = null;

  setData(data: { point1: any; point2: any } | null) {
    this._data = data;
  }

  draw(target: any) {
    if (!this._data) return;
    // Canvas 2D rendering implementation
    target.useBitmapCoordinateSpace((scope: any) => {
      const ctx = scope.context;
      // Draw trend line using this._data.point1 and this._data.point2
      // ... drawing logic
    });
  }
}

const trendLine = new TrendLinePrimitive(
  { time: "2023-01-01" as Time, value: 100 },
  { time: "2023-01-10" as Time, value: 120 },
);

<TimeChart>
  <TimeChart.Series
    type="Line"
    data={priceData}
    primitives={[trendLine]}
    onAttachPrimitives={(primitives) => console.log("Primitives attached:", primitives)}
  />
</TimeChart>;

Pane Primitives

import { TimeChart, type PanePrimitive } from "@dschz/solid-lightweight-charts";
import type {
  IPanePrimitivePaneView,
  IPrimitivePaneRenderer,
  PaneAttachedParameter,
  Time,
} from "lightweight-charts";

// Watermark primitive with proper TypeScript implementation
class WatermarkPrimitive implements PanePrimitive<Time> {
  private _paneViews: WatermarkPaneView[];
  private _text: string;
  private _color: string;
  private _fontSize: number;

  constructor(text: string, color = "rgba(128, 128, 128, 0.3)", fontSize = 48) {
    this._text = text;
    this._color = color;
    this._fontSize = fontSize;
    this._paneViews = [new WatermarkPaneView(this)];
  }

  updateAllViews() {
    this._paneViews.forEach((pv) => pv.update());
  }

  paneViews() {
    return this._paneViews;
  }

  attached(param: PaneAttachedParameter<Time>) {
    // Pane primitives can use this for initialization
  }

  detached() {
    // Cleanup if needed
  }

  getText() {
    return this._text;
  }
  getColor() {
    return this._color;
  }
  getFontSize() {
    return this._fontSize;
  }
}

class WatermarkPaneView implements IPanePrimitivePaneView {
  private _source: WatermarkPrimitive;
  private _renderer: WatermarkPaneRenderer;

  constructor(source: WatermarkPrimitive) {
    this._source = source;
    this._renderer = new WatermarkPaneRenderer();
  }

  update() {
    this._renderer.setData({
      text: this._source.getText(),
      color: this._source.getColor(),
      fontSize: this._source.getFontSize(),
    });
  }

  renderer() {
    return this._renderer;
  }

  zOrder() {
    return "bottom" as const;
  }
}

class WatermarkPaneRenderer implements IPrimitivePaneRenderer {
  private _data: { text: string; color: string; fontSize: number } | null = null;

  setData(data: { text: string; color: string; fontSize: number } | null) {
    this._data = data;
  }

  draw(target: any) {
    if (!this._data) return;

    target.useBitmapCoordinateSpace((scope: any) => {
      const ctx = scope.context;
      const { width, height } = scope.bitmapSize;

      ctx.save();
      ctx.font = `${this._data!.fontSize}px Arial`;
      ctx.fillStyle = this._data!.color;
      ctx.textAlign = "center";
      ctx.textBaseline = "middle";

      // Draw watermark in center of pane
      ctx.fillText(this._data!.text, width / 2, height / 2);
      ctx.restore();
    });
  }
}

const watermark = new WatermarkPrimitive("DEMO CHART");

<TimeChart>
  <TimeChart.Series type="Line" data={priceData} />

  <TimeChart.Pane
    primitives={[watermark]}
    onAttachPrimitives={(primitives) => console.log("Pane primitives attached")}
  >
    <TimeChart.Series type="Histogram" data={volumeData} />
  </TimeChart.Pane>
</TimeChart>;

💡 Complete Examples: For fully working primitive implementations with comprehensive TypeScript types, see the interactive examples in our playground:

🛠 Playground & Examples

See playground/App.tsx for a complete working showcase with live interactive examples:

Core Chart Types:

  • TimeChart with multiple panes (Candlestick+Line, Volume, Area) and series markers
  • PriceChart with multiple panes (Line+Area, Histogram) and series markers
  • YieldCurveChart with multiple panes (Line, Area) and series markers

Advanced Features (New in v0.2.0):

  • Series Primitives Example - Interactive trend lines, support/resistance levels, price alerts, and text annotations
  • Pane Primitives Example - Watermarks, custom grid overlays, and corner badges with live updates
  • Custom Series Integration - Complete examples with proper TypeScript interfaces
  • Dynamic Management - Real-time updates, lifecycle management, and memory optimization

Run the playground locally:

git clone https://github.com/dsnchz/solid-lightweight-charts
cd solid-lightweight-charts
bun install
bun start

📚 Resources

Full documentation and advanced guides coming soon.

📄 License

MIT © Daniel Sanchez

changelog

@dschz/solid-lightweight-charts

0.2.5

Patch Changes

  • Adds JSR score badge

0.2.4

Patch Changes

  • fixes bundlephobia badge reference

0.2.3

Patch Changes

  • Updates readme badges

0.2.2

Patch Changes

  • Supports adding pane primitives to root chart panes

0.2.1

Patch Changes

  • Updates README markers example

0.2.0

Summary of Changes

Advanced Primitives & Custom Series Support - This release significantly expands the charting capabilities with full support for custom visualizations and primitives.

🎨 Custom Series Support

  • Custom series components for all chart types (TimeChart.CustomSeries, PriceChart.CustomSeries, YieldCurveChart.CustomSeries)
  • Full TypeScript integration with proper pane view interfaces
  • Reactive data updates and lifecycle management for custom series

🖼️ Series Primitives

  • Series primitives support for creating custom visualizations attached to specific series
  • Interactive drawing capabilities (trend lines, support/resistance levels, price alerts, annotations)
  • Proper TypeScript interfaces (SeriesPrimitive, ISeriesPrimitiveAxisView, IPrimitivePaneView, IPrimitivePaneRenderer)
  • Reactive primitive attachment/detachment with automatic cleanup

🎯 Pane Primitives

  • Pane primitives support for chart-wide decorations and backgrounds
  • Full pane coverage for watermarks, custom grids, corner badges, and overlays
  • Proper TypeScript interfaces (PanePrimitive, IPanePrimitivePaneView)
  • Reactive primitive management with lifecycle hooks

📍 Enhanced Markers

  • Series markers prop for declarative marker management
  • Integration with createSeriesMarkers API from lightweight-charts
  • Reactive marker updates based on data changes
  • Support across all chart types and custom series

🔄 New Lifecycle Hooks

  • onAttachPrimitives - Called when primitives are attached (series and pane level)
  • onDetachPrimitives - Called when primitives are detached (series and pane level)
  • onSetMarkers - Called when series markers are updated
  • Enhanced primitive lifecycle management with proper cleanup

🏗️ Developer Experience

  • Comprehensive example pages showcasing primitives usage patterns
  • Interactive primitive demos with multiple primitive types and real-time updates
  • Full test coverage for all primitive functionality across chart types
  • Documentation and usage guides for custom series and primitives implementation

🔧 Technical Improvements

  • Proper TypeScript interface compliance for all primitive classes
  • Reactive primitive updates with SolidJS reactivity system
  • Memory-efficient primitive management with automatic cleanup
  • Cross-chart compatibility for primitives (Time, Price, YieldCurve charts)

0.1.2

Patch Changes

  • adds solid-js as dev dependency for jsr

0.1.1

Patch Changes

  • adds lightweight chart to dev dependencies

0.1.0

Initial Release

The MVP release of @dschz/solid-lightweight-charts - A fully typed SolidJS wrapper around TradingView's Lightweight Charts

  • Multiple chart types with specialized APIs:
    • TimeChart for time-based financial data (using createChart)
    • PriceChart for numeric-based price data (using createOptionsChart)
    • YieldCurveChart for rate curves and duration-based data (using createYieldCurveChart)
  • Complete series type support for all built-in chart types: Line, Area, Candlestick, Bar, Histogram, Baseline
  • Namespaced component APIs with intuitive syntax (<TimeChart.Series />, <PriceChart.Series />, <YieldCurveChart.Series />)
  • Multiple panes support for advanced multi-series visualization (<TimeChart.Pane />, <PriceChart.Pane />, <YieldCurveChart.Pane />)
  • Series markers support with integration for core lightweight-charts APIs (e.g. createSeriesMarkers)
  • SolidJS-native reactivity for all chart options and data updates
  • Proper lifecycle management and automatic state cleanup
  • Full TypeScript support with comprehensive type definitions
  • Flexible data handling with onSetData callbacks for advanced chart manipulation
  • Core API compatibility - can still access underlying lightweight-charts APIs for advanced features