Market Chart

A trading-desk chart in pure SVG: OHLC candles, a volume pane, a snapping crosshair with axis-pinned price and time, a range selector, and a live tape.

Candles, volume, and a range selector

@spectrumui/market-chart
SOLSolana
$245.85−2.27%

variant='area' — baseline shading

SOLSolana
$245.85+161.04%

live — streaming ticks

SOLSolanaLive
$245.85+3.44%

Equities

AAPLApple Inc.
$327.58+26.52%

hollowUp — Bitcoin

BTCBitcoin
$126.44K+15.51%

Compact — no volume, no range selector

SOLSolana
$245.85−2.27%

Manual installation

Prefer to copy by hand? Open the Code tab on any example above and switch to the file you need — every source file is there, not just the demo. Drop them in your project like this:

  • chart-engine.tsxcomponents/spectrumui/charts/chart-engine.tsx
  • market-chart.tsxcomponents/spectrumui/charts/market-chart.tsx

There is nothing to install — this chart draws its own SVG and imports only @/lib/utils.

Usage

import { MarketChart } from '@/components/spectrumui/charts/market-chart';

<MarketChart data={candles} symbol="SOL" name="Solana" />
  • Candles need { t, open, high, low, close, volume } with t in epoch milliseconds.
  • live appends simulated ticks — drive it from your own socket by feeding data instead.
  • Arrow keys scrub the crosshair once the plot has focus.

Props

PropTypeDefaultDescription
dataCandle[]SOL_MARKETOHLC series as { t, open, high, low, close, volume }, with t in epoch ms.
symbolstring'SOL'Ticker shown in the header.
namestring'Solana'Long name beside the ticker.
variant'candles' | 'area''candles'Candles, or a baseline area shaded against the first close in view.
showVolumebooleantrueVolume pane under the price plot.
hollowUpbooleanfalseHollow bodies on up candles — the stock-desk look.
rangesMarketRange[]MARKET_RANGESRange selector options. Each is a label plus a bar count, or null for the whole series.
defaultRangestring'3M'Which range is selected on mount.
showRangeSelectorbooleantrueHide it for a compact card.
livebooleanfalseAppend simulated ticks and flash the header on each one.
compactPricebooleanfalseAbbreviate the headline price, for assets in the thousands.
heightnumber-Plot height in pixels. The header sits above it, so the card is taller than this.
status'ready' | 'loading' | 'empty' | 'error''ready'Which state to render. All four reserve the same frame height, so nothing shifts when data lands.
onRetry() => void-Called by the retry button in the error state. Omit it and no button is shown.
classNamestring-Merged onto the root element.