Star 历史趋势
数据来源: GitHub API · 生成自 Stargazers.cn
README.md

Liveline

Real-time animated charts for React. Line, multi-series, and candlestick modes, canvas-rendered, 60fps, zero CSS imports.

Install

pnpm add liveline

Peer dependency: react >=18.

Quick Start

import { Liveline } from 'liveline'
import type { LivelinePoint } from 'liveline'

function Chart() {
  const [data, setData] = useState<LivelinePoint[]>([])
  const [value, setValue] = useState(0)

  // Feed data from WebSocket, polling, etc.
  // Each point: { time: unixSeconds, value: number }

  return (
    <div style={{ height: 300 }}>
      <Liveline data={data} value={value} color="#3b82f6" theme="dark" />
    </div>
  )
}

The component fills its parent container. Set a height on the parent. Pass data as a growing array of points and value as the latest number — Liveline handles smooth interpolation between updates.

Props

Data

PropTypeDefaultDescription
dataLivelinePoint[]requiredArray of { time, value } points
valuenumberrequiredLatest value (smoothly interpolated)

Appearance

PropTypeDefaultDescription
theme'light' | 'dark''dark'Color scheme
colorstring'#3b82f6'Accent color — all palette colors derived from this
gridbooleantrueY-axis grid lines + labels
badgebooleantrueValue pill tracking chart tip
badgeVariant'default' | 'minimal''default'Badge style: accent-colored or white with grey text
badgeTailbooleantruePointed tail on badge pill
fillbooleantrueGradient under the curve
pulsebooleantruePulsing ring on live dot
lineWidthnumber2Stroke width of the main line in pixels

Features

PropTypeDefaultDescription
momentumboolean | MomentumtrueDot glow + arrows. true = auto-detect, or 'up' | 'down' | 'flat'
scrubbooleantrueCrosshair scrubbing on hover
exaggeratebooleanfalseTight Y-axis — small moves fill chart height
showValuebooleanfalseLarge live value overlay (60fps DOM update, no re-renders)
valueMomentumColorbooleanfalseColor the value text green/red by momentum
degenboolean | DegenOptionsfalseBurst particles + chart shake on momentum swings

Candlestick

PropTypeDefaultDescription
mode'line' | 'candle''line'Chart type
candlesCandlePoint[]OHLC candle data { time, open, high, low, close }
candleWidthnumberSeconds per candle
liveCandleCandlePointCurrent in-progress candle with real-time OHLC
lineModebooleanfalseMorph candles into a line display
lineDataLivelinePoint[]Tick-level data for line mode density
lineValuenumberCurrent tick value for line mode
onModeChange(mode) => voidCallback for built-in line/candle toggle

When mode="candle", pass candles (committed OHLC bars) and liveCandle (the current bar, updated every tick). candleWidth sets the time bucket in seconds. The lineMode prop smoothly morphs between candle and line views — candle bodies collapse to close price, then the line extends outward. Provide lineData and lineValue (tick-level resolution) for a smooth density transition during the morph.

The onModeChange prop renders a built-in line/candle toggle next to the time window buttons.

Multi-series

PropTypeDefaultDescription
seriesLivelineSeries[]Multiple overlapping lines { id, data, value, color, label? }
onSeriesToggle(id, visible) => voidCallback when a series is toggled via built-in chips
seriesToggleCompactbooleanfalseShow only colored dots in toggle (no text labels)

Pass series instead of data/value to draw multiple lines sharing the same axes. Each series gets its own color, label, and endpoint dot. Toggle chips appear automatically when there are 2+ series — clicking one hides/shows that line with a smooth fade. The Y-axis range adjusts when series are hidden. Badge, momentum arrows, and fill are disabled in multi-series mode.

State

PropTypeDefaultDescription
loadingbooleanfalseBreathing line animation — use while waiting for data
pausedbooleanfalseSmoothly freeze chart scrolling; resume catches up to real time
emptyTextstring'No data to display'Text shown in the empty state

When loading flips to false with data present, the loading line morphs into the actual chart shape. In line mode, the fill, grid, and badge animate in. In candle mode, flat lines expand into full OHLC bodies while the morph line fades out. When data is empty and loading is false, a minimal "No data" empty state is shown.

Time

PropTypeDefaultDescription
windownumber30Visible time window in seconds
windowsWindowOption[]Time horizon buttons [{ label, secs }]
onWindowChange(secs) => voidCalled when a window button is clicked
windowStyle'default' | 'rounded' | 'text''default'Window button visual style

Crosshair

PropTypeDefaultDescription
tooltipYnumber14Vertical offset for crosshair tooltip text
tooltipOutlinebooleantrueStroke outline on tooltip text for readability

Orderbook

PropTypeDefaultDescription
orderbookOrderbookDataBid/ask depth stream { bids, asks }

Advanced

PropTypeDefaultDescription
referenceLineReferenceLineHorizontal reference line { value, label? }
formatValue(v: number) => stringv.toFixed(2)Value label formatter
formatTime(t: number) => stringHH:MM:SSTime axis formatter
lerpSpeednumber0.08Interpolation speed (0–1)
paddingPadding{ top: 12, right: auto, bottom: 28, left: 12 }Chart padding override (right is 80/54/12 based on badge/grid)
onHover(point | null) => voidHover callback with { time, value, x, y }
cursorstring'crosshair'CSS cursor on canvas hover
classNamestringContainer class
styleCSSPropertiesContainer styles

Examples

Basic (line + badge)

<Liveline data={data} value={value} color="#3b82f6" theme="dark" />

Candlestick (minimal)

<Liveline
  mode="candle"
  data={ticks}
  value={latestTick}
  candles={candles}
  candleWidth={60}
  liveCandle={liveCandle}
  color="#f7931a"
  formatValue={(v) => `$${v.toLocaleString('en-US', { minimumFractionDigits: 2 })}`}
/>

Candlestick (line mode toggle + time windows)

<Liveline
  mode="candle"
  data={ticks}
  value={latestTick}
  candles={candles}
  candleWidth={60}
  liveCandle={liveCandle}
  lineMode={showLine}
  lineData={ticks}
  lineValue={latestTick}
  onModeChange={(mode) => setShowLine(mode === 'line')}
  color="#f7931a"
  formatValue={(v) => `$${v.toLocaleString('en-US', { minimumFractionDigits: 2 })}`}
  windows={[
    { label: '5m', secs: 300 },
    { label: '15m', secs: 900 },
    { label: '1h', secs: 3600 },
  ]}
/>

Crypto-style (momentum + degen + exaggerate)

<Liveline
  data={data}
  value={value}
  color="#f7931a"
  exaggerate
  degen
  showValue
  valueMomentumColor
  formatValue={(v) => `$${v.toLocaleString('en-US', { minimumFractionDigits: 2 })}`}
/>

Dashboard (showValue + windows + no badge)

<Liveline
  data={data}
  value={value}
  badge={false}
  showValue
  windows={[
    { label: '15s', secs: 15 },
    { label: '30s', secs: 30 },
    { label: '2m', secs: 120 },
    { label: '5m', secs: 300 },
  ]}
  onWindowChange={(secs) => console.log('window:', secs)}
/>

Multi-series (prediction market)

<Liveline
  data={[]}
  value={0}
  series={[
    { id: 'yes', data: yesData, value: yesValue, color: '#3b82f6', label: 'Yes' },
    { id: 'no', data: noData, value: noValue, color: '#ef4444', label: 'No' },
  ]}
  grid
  scrub
  pulse
  windowStyle="rounded"
  formatValue={(v) => v.toFixed(1) + '%'}
  onSeriesToggle={(id, visible) => console.log(id, visible)}
  windows={[
    { label: '10s', secs: 10 },
    { label: '30s', secs: 30 },
    { label: '1m', secs: 60 },
  ]}
/>

Loading + pause

<Liveline
  data={data}
  value={value}
  loading={isConnecting}
  paused={!isTabVisible}
/>

Orderbook (orderbook data + particles)

<Liveline
  data={data}
  value={value}
  color="#f7931a"
  orderbook={{ bids: [[100, 2], [99, 5]], asks: [[101, 3], [102, 4]] }}
  degen
  showValue
/>

How It Works

  • Canvas rendering — single <canvas> element, no DOM nodes per data point
  • requestAnimationFrame loop pauses when the tab is hidden
  • Fritsch-Carlson monotone splines for smooth curves — no overshoots beyond local min/max
  • Frame-rate-independent lerp on value, Y-axis range, badge color, and scrub opacity
  • Candlestick rendering — OHLC bodies + wicks with bull/bear coloring, smooth live candle updates
  • Line/candle morph — candle bodies collapse to close price, morph line extends center-out, coordinated alpha crossfade
  • Multi-series — overlapping lines with per-series toggle, smooth alpha fade, and dynamic Y-axis range
  • ResizeObserver tracks container size — no per-frame layout reads
  • Theme derivation — full palette from one accent color + light/dark mode
  • Binary search interpolation for hover value lookup

No CSS imports. No external dependencies beyond React.

License

© 2026 Benji Taylor

Licensed under MIT

关于 About

Real-time animated line chart for React.
animatedchartcrypto

语言 Languages

TypeScript99.6%
HTML0.4%

提交活跃度 Commit Activity

代码提交热力图
过去 52 周的开发活跃度
22
Total Commits
峰值: 9次/周
Less
More

核心贡献者 Contributors