What it does, and how fast it does it.
Everything on this page ships in @tradecanvas/chart 1.31.0. Frame times were measured in Chrome on a laptop with integrated graphics (Intel UHD); node scripts/bench-render.mjs in the repository runs the same scenes on yours.
In numbers
- chart types
- 18
- built-in indicators
- 111
- drawing tools
- 69
- widget languages
- 30
- style keys
- 101
- widget feature switches
- 112
- third-party runtime dependencies
- 0
- unit tests
- 3,000+
Frame time
Time to draw one frame while panning. 16.7 ms is 60 frames a second.
| Chart | Pixel ratio | Canvas 2D | WebGL | Canvas 2D / WebGL |
|---|---|---|---|---|
| 1600×900, 500 candles + 4 indicators · 2× | 2 | 27.4 ms | 19.6 ms | |
| 1600×900, zoomed out on 200,000 bars + 4 indicators · 2× | 2 | 34.5 ms | 20.2 ms | |
| 1600×900, zoomed out on 1,000,000 bars + 4 indicators · 2× | 2 | 34.5 ms | 16.7 ms | |
| 1600×900, depth heatmap, 240 snapshots × 80 levels · 2× | 2 | 25.5 ms | 16.8 ms | |
| Six charts, 500 candles and 2 indicators each · 2× | 2 | 23.5 ms | 17.2 ms | |
| 2560×1400, 2,000 candles + 4 indicators · 1× | 1 | 41.6 ms | 17.7 ms | |
| 2560×1400, 2,000 candles + 4 indicators · 1.5× | 1.5 | 70.8 ms | 17.6 ms | |
| 2560×1400, 2,000 candles + 4 indicators · 2× | 2 | 114.5 ms | 29.1 ms |
Canvas 2D is the default. renderer: 'webgl' (or 'auto') draws the plot with WebGL 2 and falls back to Canvas 2D where WebGL 2 is missing or its context is lost.
Data path
- A live tick with Bollinger Bands, EMA, RSI and MACD on 100,000 bars
- ~0.001 ms
- The same four indicators recalculated in full on 100,000 bars
- ~27 ms
- A line of 1,000,000 visible points, downsampled for one frame
- ~2.6 ms
- A hover redraw (crosshair, legend)
- ~0.2 ms
- A symbol or timeframe switch shows a loading veil only after
- 200 ms
Download size
Minified and gzipped, with everything it imports.
- Chart, the headless API
- 176 KB
- ChartWidget, the full interface
- 315 KB
- The WebGL renderer, loaded on first use
- 18 KB
How it is checked
- More than 3,000 unit tests across the seven packages run in CI on every pull request.
- The WebGL renderer draws candles on the same device pixels as Canvas 2D; lines and fills differ only on a few antialiased edge pixels.
- The WebGL renderer has been checked in Chromium, Firefox and WebKit. Without WebGL 2, or when its context is lost, the chart carries on with Canvas 2D.
- The code examples in the docs and in the agent skill are type-checked against the real API.
- Charts read out to screen readers and work from the keyboard; the widget reads right to left in Arabic, Hebrew and Persian.
Capabilities
Filter by area, or search by name or API.
| Capability | Area | Details and API |
|---|---|---|
| Candles, OHLC bars, line, area, baseline, Heikin-Ashi, hollow candles | Chart types | candlestick, bar, line, area, baseline, heikinAshi, hollowCandle |
| Renko, line break, Kagi, point & figure, range bars | Chart types | Box size or ATR, lines to break, reversal in percent or price, range per bar |
| Volume candles, Equivolume, HLC area, step line, line with markers, high-low | Chart types | 18 chart types in all |
| The main series hidden | Chart types | Only the indicators and drawings stay |
| Charts for dashboards | Chart types | Bars (grouped, stacked, sideways), donut and pie, scatter and bubbles, histograms, calendars, correlation matrices, sector maps, counter-clock charts, sparklines, gauges, heatmaps and treemaps, waterfalls, depth, equity curves |
| Canvas 2D or WebGL 2 | Rendering | renderer: 'canvas' | 'webgl' | 'auto', setRenderer, the rendererChange event |
| One span per pixel column when zoomed out | Rendering | Indicator lines, bands and histograms below a pixel per bar |
| A million bars panned smoothly | Rendering | With four indicators, at a pixel ratio of 2 |
| Depth heatmap, volume profile and market profile on the GPU | Rendering | pushDepthSnapshot(book, time) |
| Several WebGL charts on a page | Rendering | Up to 8 (setMaxWebGLCharts); the rest draw with Canvas 2D; back to WebGL when the context returns |
| Sharp at any screen scale | Rendering | Candles, volume and drawings on device pixels at 100%, 125% and 200% |
| No third-party runtime dependencies | Rendering | Nothing else to install or audit |
| 134 built-in indicators | Indicators | Pivot points in six kinds, MA Cross, correlation with another symbol |
| Price source | Indicators | open, high, low, hl2, hlc3, ohlc4, hlcc4 |
| An indicator on an indicator | Indicators | Such as a moving average of RSI, updated on every tick |
| Several indicators in one pane, moved between panes | Indicators | moveIndicatorToPane |
| Several of the same indicator | Indicators | EMA 20 and EMA 50 side by side |
| Levels and thresholds | Indicators | RSI 30/70, CCI ±100, saved with the layout |
| Last value on the axis | Indicators | On the price axis and each pane’s axis, in the line’s colour |
| Panes collapsed, maximised and reordered | Indicators | Saved with the layout |
| Indicator templates | Indicators | Inputs, style, levels and pane, saved and applied together |
| Each line’s style and visibility | Indicators | A hidden line doesn’t stretch the scale; setIndicatorDefaults |
| Volume delta and CVD | Indicators | Estimated from the bars |
| Indicator values exported | Indicators | CSV or JSON, one column per line |
| Incremental updates on live ticks | Indicators | update() recomputes only the forming bar |
| 69 drawing tools | Drawing tools | Lines, channels, Fibonacci, Gann, pitchforks, Elliott waves, patterns, cycles, projections |
| Each tool’s own settings | Drawing tools | Style, properties and coordinates on the market’s price grid |
| Long and short positions | Drawing tools | Risk:reward, quantity from risk in percent or money |
| Alerts on a drawing | Drawing tools | When price crosses a trend line or channel as drawn, log scale included |
| Order, groups and templates | Drawing tools | Bring forward, send back, group, lock, hide |
| Notes, callouts, arrows, flags, brush, path, curve | Drawing tools | Freehand and multi-point drawing |
| Anchored VWAP and fixed-range volume profile | Drawing tools | Read the chart’s bars |
| Eraser, zoom box, strong magnet, keyboard shortcuts | Drawing tools | Alt+T, Alt+H, Alt+J, Alt+V, Alt+C, Alt+F |
| Go to a date; 1D to All ranges | Scales and time | No zoom-out limit |
| IANA time zones with daylight saving | Scales and time | Or the exchange’s own zone |
| Any timeframe, and tick bars | Scales and time | 7m, 90m, 2d built from what the feed serves; 100T from its trades |
| Left and right scales; log, inverted and percent per pane | Scales and time | The left scale for an overlay or a copy of the price scale |
| Compare symbols, spread and ratio | Scales and time | On their own scale or pane, matched by time |
| Extended hours | Scales and time | From the symbol’s session hours |
| Price and time formats | Scales and time | priceFormat as a function or fractions such as 1/32; timeFormatter |
| The scale in the symbol’s decimals and price step | Scales and time | pricePrecision, minTick: a stock that moves in 10 never shows 21,705 |
| High and low lines, bid and ask | Scales and time | Bid and ask from the feed’s ticks |
| Event marks on the chart | Scales and time | signalMarkerHover, signalMarkerClick |
| Ready-made feeds and your own | Data and realtime | Binance, Bybit, Coinbase, Kraken, mock; WebSocketAdapter, PollingAdapter |
| Older history loaded while scrolling left | Data and realtime | fetchHistoryBefore |
| Symbol search with details | Data and realtime | searchSymbols, resolveSymbol: decimals, price step, sessions, time zone |
| Symbol details learned after connecting | Data and realtime | The adapter’s symbolInfo event |
| Depth-of-market ladder | Data and realtime | Bid and ask size by price; click to trade |
| Live quotes for watchlists | Data and realtime | subscribeQuotes, setQuotes, getQuote |
| News and market status | Data and realtime | fetchNews; a countdown to the open or close |
| Exchange rules | Data and realtime | setMarket: steps by price band, daily ceiling and floor, lots, sessions; HOSE, HNX, UPCoM and VN30 futures |
| Orders and positions on the chart | Trading | Drag to modify; cancel, close and reverse from the line |
| Fill marks | Trading | Reason and profit or loss in executionFill |
| Order ticket | Trading | Quantity, type, stop-loss and take-profit, time in force, checked as you type; the exchange’s price step, ceiling, floor and lots |
| Account panel | Trading | Positions with live profit and loss, working orders, fills |
| Signals and trade zones | Trading | markers.*, tradeZones.* style keys |
| Backtesting and risk metrics | Trading | @tradecanvas/analytics: commission, slippage, Sharpe, Sortino, Calmar, drawdown |
| Alerts beyond a price level | Alerts and replay | Line crossing line, a move of N% in N bars, on bar close, with expiry |
| Bar replay in finer steps | Alerts and replay | A larger timeframe replayed from smaller bars |
| Paper trading on a replay | Alerts and replay | Orders filled at the replayed prices |
| Replay across a grid of charts | Alerts and replay | Kept in step |
| Replay for applications | Alerts and replay | startTime, hideHistory, duration, marks revealed as it plays, replayComplete |
| A grid of synchronised widgets | Workspace | Up to 6, sharing symbol, timeframe, crosshair, time and drawings |
| Named layouts on your own storage | Workspace | Save, open, rename, autosave; LayoutStorage for a server |
| Undo and redo for everything | Workspace | Drawings, indicators, settings and chart type; recordUndo |
| Context menus by area | Workspace | Drawings, plot, panes, price axis, time axis |
| Watchlists | Workspace | Several lists, reordered by dragging |
| Events for the host | Workspace | symbolChange, timeframeChange, ordersChange, executionFill, styleChange and more |
| Three looks for the widget | Customization | Studio, Terminal, Capsule; ui and setUI; --tcw-* CSS variables |
| The chart’s look by key | Customization | applyOverrides over 101 typed keys, on a host layer and a user layer |
| Settings that reach every key | Customization | A style tab for the chart type on view, a trading tab |
| 112 feature switches | Customization | features, setFeatures, isFeatureOn; changed while running |
| Your own parts in the widget | Customization | Toolbar buttons and dropdowns, sidebar buttons, status items, slots, menu items |
| Your own shortcuts | Customization | addHotkey by the keyboard layout |
| The widget in 30 languages | Languages and access | Arabic, Hebrew and Persian right to left |
| Screen readers and the keyboard | Languages and access | A chart summary, bars read one by one, dialogs by keyboard |
| Docs in six languages, this site in fourteen | Languages and access | English, Tiếng Việt, 简体中文, 日本語, 한국어, Español |
| React, Vue and Svelte components | Developers | Reactive props: overrides, indicators, features |
| Plugins | Developers | Indicators, drawing tools, chart types and overlays; overlayScale and getPriceStep to draw on the price grid |
| Docs for coding agents | Developers | llms.txt, llms-full.txt and an agent skill |
Known limits
- Canvas 2D stays the default renderer until WebGL has been tried on more devices; its frame rate on Safari and on 5K screens has not been measured yet.
- At a pixel ratio of 2 on a 2560×1400 chart, the browser’s compositing alone takes about 23 ms on integrated graphics, so WebGL frames there average 29 ms.
- Tick timeframes are built from the recent trades a feed returns; older tick history cannot be loaded.
- Volume delta and CVD are estimated from the bars, not from each trade’s side.
- At most 8 charts on a page draw with WebGL at once; the others draw with Canvas 2D.