Atmosphere✨ Premium

Line Graph

Real-time scrolling SVG: the line and its gradient fill update frame-by-frame via rAF, combining a sine wave and random noise over a 60-point rolling buffer.

SVGContinuous

You'll get access to the interactive demo with a free account.

This effect is part of Effect.Labs — 811 vanilla effects, some free, some premium. Atmosphere has 57 effects, including 10 free. Explore the category →

3 usage examples

Hero / Landing — Real-time analytics platform — Line Graph example 1

① Hero / Landing — Real-time analytics platform

WhenThe product is an analytics or SaaS monitoring platform; the hero must demonstrate business value before any copy.
WhyThe moving curve draws the eye to the key metric (traffic, sessions, conversions) and lends the product credibility without extra text — the animation makes the dashboard feel live.
Settingsstroke: #6366f1, stroke-width: 2, container height 180 px, sine amplitude ×30, noise ±10 (code defaults).
Product component — Dashboard metric widget — Line Graph example 2

② Product component — Dashboard metric widget

WhenIn a SaaS dashboard, each metric card (revenue, active users, CPU) displays its rolling 60-frame history behind the numeric value.
WhyThe pure-SVG component has zero dependencies, letting you instantiate several charts on the same page without bundle overhead — ideal for dashboards with 5–10 metric cards.
Settingsstroke: #22c55e (green for a positive trend), stroke-width: 1.5, container height 64 px, noise ±5 (smoother curve, less anxiety-inducing).
Conversion micro-interaction — Live social proof indicator — Line Graph example 3

③ Conversion micro-interaction — Live social proof indicator

WhenOn a pricing page or conversion popup, a live widget shows recent user activity (purchases, sign-ups, subscriptions) to create a sense of urgency.
WhyAn amber animated curve paired with a 'live purchases' label reinforces urgency without being intrusive — more credible than a static counter, less aggressive than a pop-up.
Settingsstroke: #f59e0b (amber), stroke-width: 2.5, container height 56 px, amplitude ×20, frequency time ×0.008 (faster rhythm to emphasize activity).

How it works

The component uses a <svg viewBox="0 0 300 100" preserveAspectRatio="none"> with two overlapping paths: <path class="area"> for the filled region below the curve and <path class="line"> for the visible stroke. preserveAspectRatio="none" forces the SVG to stretch to fill its CSS container exactly — no aspect ratio is preserved, making the chart fully responsive to any width without JavaScript.

The animation relies on a rolling buffer of 60 values, all initialized at 50 (the viewBox midpoint). Each requestAnimationFrame call invokes animateLineGraph, which runs lineData.shift() to drop the oldest point, then pushes a new point computed as 50 + Math.sin(time × 0.005) × 30 + Math.random() × 20 − 10: a sine wave of ±30 amplitude sets the overall curve shape, while random noise of ±10 simulates real-world data volatility. There is no smoothing or bézier interpolation — each point generates a raw SVG L segment.

Both path d attributes are fully rebuilt each frame via setAttribute. The line path starts at M0,y[0] then chains L xi,yi segments for the remaining 59 points. The area path follows the same trace but closes the shape with L300,100 Z — the viewBox bottom — to form the filled polygon.

The CSS rule fill: url(#areaGradient) expects a <linearGradient id="areaGradient"> declared in an SVG <defs> block. This gradient is absent from the base HTML: without it, the area renders black or transparent depending on the browser. The animation runs inside a shared requestAnimationFrame loop alongside other effects from the same IIFE — only animateLineGraph is active when the id="linePath" and id="lineArea" elements are present in the DOM.

Accessibility

  • prefers-reduced-motion not checked: the animation runs unconditionally regardless of the OS preference. For WCAG 2.3.3 compliance, add a guard if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return; before the first requestAnimationFrame call.
  • The <svg> carries no aria-hidden, role, or aria-label — it is treated as generic content by screen readers. Add aria-hidden="true" for purely decorative use, or role="img" aria-label="…" if the chart conveys information.
  • No <title> element inside the SVG: assistive technologies receive no description of the curve.
  • The stroke color #6366f1 on background #0a0a0f yields a contrast ratio of approximately 4.6:1 — meeting WCAG AA for normal text, and well above the threshold for a decorative graphical element.
  • No keyboard or pointer interaction is implemented — the effect is purely decorative, which limits interactive accessibility requirements.

Browser compatibility

Requires inline SVG and requestAnimationFrame — supported in all modern browsers since 2013.

Chrome 110+✓ Full
Firefox 110+✓ Full
Safari 16+✓ Full
Edge 110+✓ Full
Mobile iOS✓ Full
Android Chrome✓ Full

If SVG is not rendered (very old browsers or screen readers in text mode), the <code>&lt;path&gt;</code> elements do not appear — no JS errors, the page remains functional with any text overlay elements.

The code

HTML structure to paste into your page (CSS + JS available with a premium account):

index.html — structure
<div class="demo-preview">
  <div class="line-graph" id="lineGraph">
    <svg viewBox="0 0 300 100" preserveAspectRatio="none">
      <!-- Declare the gradient for the fill (missing from the base HTML) -->
      <defs>
        <linearGradient id="areaGradient" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stop-color="#6366f1" stop-opacity="0.35"/>
          <stop offset="100%" stop-color="#6366f1" stop-opacity="0.03"/>
        </linearGradient>
      </defs>
      <path class="area" id="lineArea"></path>
      <path class="line" id="linePath"></path>
    </svg>
  </div>
</div>
🔒 Unlock the full code — from €2.99 the first month

Full HTML + CSS + JS, copy-paste ready — with hundreds of premium effects.

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
.line { stroke } #6366f1 Line color — swap for your brand color. Any CSS color value is accepted.
.line { stroke-width } 2 Line thickness in px. 1 = thin and subtle, 3–4 = bold and prominent.
url(#areaGradient) in undefined in base HTML Gradient below the curve: declare a <linearGradient id="areaGradient"> manually inside the SVG <defs> (see structure_html) with stop-color and stop-opacity matching your palette.
.line-graph { height } 120px Container height. The curve stretches proportionally (preserveAspectRatio="none") — adjust freely without touching the viewBox.
Array(60) — buffer size 60 Number of data points in the rolling history. More points mean slower scroll (60 ≈ 1 second at 60 fps). Drop to 30 for a more reactive chart.
time * 0.005 — sine frequency 0.005 Sine wave frequency. 0.002 = slow and sweeping, 0.012 = fast and nervous.
Math.random() * 20 - 10 — noise ±10 amplitude Random noise added to each new point. Reduce to ±3 for a smooth curve (financial dashboard), increase to ±20 for high volatility (network monitoring).

FAQ

The CSS rule .area { fill: url(#areaGradient) } references an identifier that is not defined in the base HTML. Add a <defs> block to your <svg> (see structure_html) containing a <linearGradient id="areaGradient"> with two color stops — the fill appears immediately.
Replace the const newValue = 50 + Math.sin(…) line inside animateLineGraph with your actual value, normalized to [0, 100] to stay within the SVG viewBox. Push values from a WebSocket callback or fetch-polling loop: lineData.push(normalizedValue); lineData.shift(); is all that's needed — the current frame will read the new value on the next requestAnimationFrame tick.
Not without changes: the JS targets getElementById('linePath') and getElementById('lineArea'), which must be unique per page. For multiple instances, extract the animateLineGraph logic into a function that accepts the target elements as parameters, then launch a separate requestAnimationFrame loop per instance — as shown in scenes 2 and 3 of this effect's example file.