Realtime Line Chart — Live SVG Chart HTML CSS JS

Realtime Line Chart · Charts · Plain HTML, CSS & JS · Live preview

Share & Support

What's included

Features

Sliding data window
A fixed-length array push/shifts each tick, so the chart streams forward in time like a real live monitor.
Auto-scaling Y axis
render rescales to the visible window's min/max (with a flat-line guard) so the line always uses the full height.
Single SVG path
The line is one M…L… <path> rebuilt per tick — cheap to draw and trivial to feed from any data source.
SVG gradient area
The area fills with an in-markup linearGradient, so it renders identically across HTML, React, Vue, and Tailwind exports.
Pulsing latest point
A transform-box: fill-box pulse circle rings the newest value, with a solid dot marking it precisely.
Live value + delta
The header shows the current reading and a coloured ▲/▼ change versus the previous tick for instant trend reading.
Running peak
A peak counter tracks the highest value seen, a common companion stat on live dashboards.
Fluid sizing
preserveAspectRatio="none" stretches the viewBox to the card width, so the chart is responsive with no JS resize handling.

About this UI Snippet

Realtime Line Chart — Streaming SVG Path, Auto-Scaling Axis & Pulsing Latest Point

Screenshot of the Realtime Line Chart snippet rendered live

Live dashboards need charts that move — active users, requests per second, temperature, price. A realtime line chart streams in new data points, drops the oldest, and rescales so the trend is always readable. This snippet implements one in plain HTML, CSS, and vanilla JavaScript with an SVG path: a sliding window of points, an auto-scaling Y axis, a gradient area fill, a pulsing dot on the latest value, and a live readout with an up/down delta.

A sliding data window

The chart keeps a fixed-length array of COUNT values. On each tick, it pushes a new value (a clamped random walk standing in for live data) and shifts off the oldest, so the window slides forward in time. render then maps that array to SVG coordinates and rewrites the path — the classic streaming-chart loop. Driving updates from JavaScript (a setInterval here, your websocket or polling fetch in production) means there is no fragile CSS animation of path data; the chart simply redraws each tick.

Auto-scaling Y axis

Real metrics drift, so a fixed scale wastes space or clips. render computes the current min and max of the visible window and maps each value into the plot area between them, with a guard so a flat line (max ≈ min) doesn't divide by zero. The line always uses the full vertical space, keeping small fluctuations visible — the behaviour you want from a live monitor.

SVG path and gradient area

The line is a single <path> built as M x y L x y … from the points; the area is the same path closed down to the baseline and filled with an SVG linearGradient (defined in <defs>). Using an SVG gradient — rather than a CSS background — means the fill is part of the markup and survives every framework export untouched, sidestepping the CSS-gradient conversion quirks of utility frameworks. preserveAspectRatio="none" lets the 320×140 viewBox stretch fluidly to the card width.

Pulsing latest point and live readout

Two circles sit on the most recent point: a solid dot and a .rt-pulse that scales and fades on a CSS loop (using transform-box: fill-box so the SVG transform-origin is the circle's own centre). The header shows the current value and a coloured ▲/▼ delta versus the previous tick, plus a running peak — the at-a-glance numbers that accompany any live chart, with a "live" indicator dot pulsing beside the label.

Swap the random walk in step for your real feed and you have a production monitor. Pair this with a sparkline chart for compact trends, a bar chart for categories, or a metric card grid for KPIs.

Build with AI

Build, Understand, Optimize, and Extend It With AI

You do not have to work through the sliding-window math alone. Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly how the fixed-length data array combined with push and shift produces the streaming effect, and why render() recomputes min and max from only the visible window on every tick rather than from the whole history. The same assistant can help you optimize it — ask whether rebuilding the entire path string from scratch every 1100ms is wasteful at a much faster update rate, and what a more efficient incremental update would look like for a high-frequency feed. It's also useful for extending the chart: ask it to smooth the line between points with Bezier curves instead of straight segments, add a second overlaid series for comparison, or replace the setInterval demo feed with a real WebSocket subscription while keeping the same render function. Treat the code less like a finished artifact and more like a starting point for a conversation.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a realtime streaming line chart in plain HTML, CSS, and JavaScript using inline SVG — no charting library, no canvas.

Requirements:
- Maintain a fixed-length array of numeric values as the visible window. On every tick, push exactly one new value onto the end and shift exactly one value off the front, so the window slides forward without growing.
- On every render, recompute the minimum and maximum from only the values currently in that window (not any historical values outside it), with a guard so a perfectly flat series does not divide by zero when scaling.
- Map the array into a single SVG path string built from straight line segments (M x y L x y ...), and build a second closed path reusing the same points but extended down to a baseline and filled with an SVG linearGradient defined in a defs block, not a CSS background.
- Place a small circle exactly on the most recent data point, plus a second circle animated with a CSS keyframe that scales up and fades out on a continuous loop to create a pulsing highlight on the latest value, using transform-box set to fill-box so the animation's transform origin is the circle's own center rather than the SVG viewport's origin.
- Display the current value as large text, plus a colored up or down arrow indicator comparing the newest value to the previous one, and track a running peak value across all ticks seen so far (not just the current window).
- Make the SVG viewBox stretch fluidly to its container width using preserveAspectRatio set to none, so no JavaScript resize handling is needed.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA dark dashboard card appears with a live line chart that updates every ~1.1 seconds, sliding new points in from the right.
  2. 2
    Watch it streamEach tick adds a value and drops the oldest; the gradient area and line redraw, and the pulsing dot rides the latest point.
  3. 3
    Read the live numbersThe big value shows the current reading with a green ▲ or red ▼ delta versus the previous tick, plus a running peak.
  4. 4
    See the auto-scalingAs values drift, the chart rescales so the line always fills the vertical space — small changes stay visible.
  5. 5
    Connect real dataReplace the random walk in step with values from a websocket or polling fetch and push them in tick.
  6. 6
    Tune the windowChange COUNT for a longer/shorter history and the setInterval delay for a faster/slower stream.

Real-world uses

Common Use Cases

Live analytics dashboards
Active users, sessions, or events per second. Sit it beside a metric card grid and bar chart.
System and server monitoring
CPU, memory, request rate, or latency streams where auto-scaling keeps spikes readable.
Trading and price tickers
Live price or volume feeds; pair the delta readout with a sparkline chart for a compact watchlist.
IoT and sensor readouts
Temperature, humidity, or power draw from a device, updated over a websocket into tick.
Realtime gaming / app stats
Concurrent players or live engagement counts, with the pulsing dot reinforcing that the data is live.
Status and uptime pages
Live throughput on a status dashboard, giving visitors confidence the system is healthy.

Got questions?

Frequently Asked Questions

Remove the random step call in tick and instead push values from your source: subscribe to a websocket and call a push(value) that does data.push(value); data.shift(); render(), or poll an endpoint on an interval. Keep the array length fixed so the window keeps sliding. render handles scaling and drawing regardless of where the numbers come from.

Build the path with cubic Béziers instead of straight L segments: for each point, use control points derived from its neighbours (Catmull-Rom to Bézier) so the curve flows smoothly. Alternatively, animate the whole path group's translateX by one step per tick with a CSS transform transition, then reset — giving a continuous scrolling motion rather than discrete jumps.

The area fill is part of the SVG (fill: url(#rtGrad) with a <linearGradient> in <defs>), so it renders identically everywhere and is not subject to CSS-to-utility conversion quirks. It also clips perfectly to the area path shape, which a CSS background on a rectangular element cannot do.

An animated SVG line is not screen-reader friendly on its own, so expose the data textually: the live value and delta are already real text, and you can add an aria-live="polite" region announcing the current reading on a throttled cadence (not every tick). Provide an accessible summary or data table for the full series, and give the SVG a role="img" with an aria-label.

In React, keep the data array in a ref and the displayed value in state, run the interval in a useEffect with a cleanup that calls clearInterval, and compute the path with useMemo from the data. In Vue, use onMounted/onUnmounted for the interval and a computed path. In Angular, start/stop the interval in ngOnInit/ngOnDestroy. The path-building and scaling math port unchanged.