Framework integration
OpenAlgo Charts is a framework-agnostic vanilla library. You call createChart(container)
with a DOM element and get back a Chart instance. Every framework wrapper follows the same
two-step pattern: create in the mount hook, destroy in the teardown hook.
The chart attaches a built-in ResizeObserver to its container on construction, so it
reflows automatically whenever the container changes size.
The built-in ResizeObserver handles responsive resize automatically. You do not need to wire
a window resize listener. Call chart.applySize(width, height) only in environments that
lack ResizeObserver support, or when you need to drive the chart size imperatively.
Install
npm install openalgo-chartsimport { createChart, generateBars } from 'openalgo-charts';generateBars(startTimeSec, count, intervalSec) produces a seeded synthetic OHLCV walk
useful for prototyping. Replace it with real bar data before going to production.
Vanilla JavaScript
<div id="chart" style="width: 100%; height: 400px;"></div>import { createChart, generateBars } from 'openalgo-charts';
const container = document.getElementById('chart');
const chart = createChart(container);
const series = chart.addSeries('candlestick');
series.setData(generateBars(1700000000, 120, 3600));
// When removing the chart from the page:
chart.destroy();destroy() stops the render loop, disconnects the ResizeObserver, removes all input
listeners, and detaches every canvas from the DOM.
React
Keep the chart in a useRef so it persists across re-renders. Create it inside useEffect
(which is client-only) and return the cleanup function so React calls destroy() on unmount.
import { useEffect, useRef } from 'react';
import { createChart, generateBars } from 'openalgo-charts';
import type { Chart } from 'openalgo-charts';
export function CandlestickChart() {
const containerRef = useRef<HTMLDivElement>(null);
const chartRef = useRef<Chart | null>(null);
useEffect(() => {
if (!containerRef.current) return;
const chart = createChart(containerRef.current);
chartRef.current = chart;
const series = chart.addSeries('candlestick');
series.setData(generateBars(1700000000, 120, 3600));
return () => {
chart.destroy();
chartRef.current = null;
};
}, []); // empty deps: create once on mount, destroy on unmount
return <div ref={containerRef} style={{ width: '100%', height: 400 }} />;
}Do not call createChart in the component body or inside a useMemo. Canvas creation
requires a real DOM node, which only exists after the first render.
Next.js / SSR
createChart touches the DOM immediately and must never run on the server. There are two
safe approaches.
Option 1 - useEffect (simplest). useEffect never runs during server-side rendering,
so the React example above works in Next.js without any changes.
Option 2 - dynamic import with ssr: false. Use this when you want to ship the chart
component as its own async chunk or need to suppress the hydration mismatch warning:
// components/Chart.tsx
import { useEffect, useRef } from 'react';
import { createChart, generateBars } from 'openalgo-charts';
export default function Chart() {
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (!containerRef.current) return;
const chart = createChart(containerRef.current);
const series = chart.addSeries('candlestick');
series.setData(generateBars(1700000000, 120, 3600));
return () => chart.destroy();
}, []);
return <div ref={containerRef} style={{ width: '100%', height: 400 }} />;
}// app/page.tsx (or pages/index.tsx)
import dynamic from 'next/dynamic';
const Chart = dynamic(() => import('../components/Chart'), { ssr: false });
export default function Page() {
return <Chart />;
}The ssr: false flag tells Next.js to skip the component entirely during server rendering
and hydrate it on the client only.
Vue 3
Use a template ref with onMounted to create and onUnmounted to destroy.
<template>
<div ref="containerRef" style="width: 100%; height: 400px;" />
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { createChart, generateBars } from 'openalgo-charts';
import type { Chart } from 'openalgo-charts';
const containerRef = ref<HTMLDivElement | null>(null);
let chart: Chart | null = null;
onMounted(() => {
if (!containerRef.value) return;
chart = createChart(containerRef.value);
const series = chart.addSeries('candlestick');
series.setData(generateBars(1700000000, 120, 3600));
});
onUnmounted(() => {
chart?.destroy();
chart = null;
});
</script>Angular
Use @ViewChild to get the container element, ngAfterViewInit to create the chart, and
ngOnDestroy to tear it down.
import {
Component, AfterViewInit, OnDestroy,
ElementRef, ViewChild,
} from '@angular/core';
import { createChart, generateBars } from 'openalgo-charts';
import type { Chart } from 'openalgo-charts';
@Component({
selector: 'app-chart',
template: '<div #chartContainer style="width: 100%; height: 400px;"></div>',
})
export class ChartComponent implements AfterViewInit, OnDestroy {
@ViewChild('chartContainer') containerRef!: ElementRef<HTMLDivElement>;
private chart: Chart | null = null;
ngAfterViewInit(): void {
this.chart = createChart(this.containerRef.nativeElement);
const series = this.chart.addSeries('candlestick');
series.setData(generateBars(1700000000, 120, 3600));
}
ngOnDestroy(): void {
this.chart?.destroy();
this.chart = null;
}
}Svelte
onMount accepts a cleanup function. Return a function that calls chart.destroy() and
Svelte will invoke it when the component is removed from the DOM.
<script lang="ts">
import { onMount } from 'svelte';
import { createChart, generateBars } from 'openalgo-charts';
let containerEl: HTMLDivElement;
onMount(() => {
const chart = createChart(containerEl);
const series = chart.addSeries('candlestick');
series.setData(generateBars(1700000000, 120, 3600));
return () => chart.destroy();
});
</script>
<div bind:this={containerEl} style="width: 100%; height: 400px;" />Related pages
- Getting Started - install, your first chart, and live updates.
- Core Concepts - the data model, gapless time axis, and panes.