Snap.svg Animated Line Chart — Self-Drawing Chart Reveal Snippet

Snap.svg Animated Line Chart · Charts · Plain HTML, CSS & JS · Live preview

What's included

Features

Dash-offset draw reveal
stroke-dasharray/dashoffset set to path length create the classic line-draw effect.
Native path length measurement
getTotalLength() measures the exact path length regardless of point count.
Sequenced dot reveal
Data points only start appearing once the line animation completes.
Staggered fade-in
setTimeout delays scaled by index create a left-to-right point cascade.
Auto-scaling data
toPoints() maps arbitrary data ranges to the chart\u2019s pixel bounds.
Replayable animation
A single draw() function both builds and rebuilds the whole chart.
Subtle gridlines
Faint horizontal guides render underneath the line and points.
Snap.svg easing
mina.easeinout and mina.easeout shape the line and dot timing curves.

About this UI Snippet

Snap.svg Animated Line Chart — The Dash-Offset Draw Reveal, Explained

Screenshot of the Snap.svg Animated Line Chart snippet rendered live

The "line draws itself in" effect looks like it must involve some kind of clipping mask or path-length trickery unique to animation libraries, but it's actually a clever repurposing of two ordinary SVG stroke properties: stroke-dasharray and stroke-dashoffset.

Dash arrays are just a repeating on/off pattern

stroke-dasharray normally creates dashed lines by telling the renderer to alternate a fixed length of visible stroke with a fixed length of gap, repeating along the path. The reveal trick sets the dash length to the exact total length of the path:

var len = linePath.node.getTotalLength(); linePath.attr({ strokeDasharray: len, strokeDashoffset: len });

With a dash-and-gap length equal to the whole path, there is effectively only one dash and one gap, each as long as the entire line. getTotalLength() is a native SVG DOM method (called on linePath.node, the raw DOM element Snap wraps) that measures the path's actual on-screen length regardless of how many points or curves it contains.

Offsetting the dash out of view

stroke-dashoffset shifts *where along the path* the dash pattern begins. Setting it equal to the path's own length shifts the single visible dash entirely past the end of the path — so what's actually rendered is 100% gap, and the line appears completely invisible, even though it's technically already drawn.

Animating the reveal

linePath.animate({ strokeDashoffset: 0 }, 1100, mina.easeinout, callback);

As stroke-dashoffset eases from len down to 0, the single dash's starting position slides backward along the path, which has the visual effect of the visible portion growing from the path's start point toward its end — exactly like a pen drawing the line. Snap.svg's .animate() handles interpolating the numeric attribute over the given duration and calls the fourth argument as a completion callback once the tween finishes.

Staggering the data points after the line

The completion callback, revealDots(points), only runs once strokeDashoffset finishes animating to 0 — so the circles never appear before the line has visually "reached" them. Each dot's own .animate({ opacity: 1 }, ...) call is additionally delayed with a plain setTimeout scaled by its index (i * 90ms), producing a left-to-right cascade rather than all eight dots popping in simultaneously.

Why s.clear() at the top of draw()

Because draw() doubles as the replay handler, it needs to remove the previous line, gridlines, and dots before rebuilding them — s.clear() empties the whole <svg> root so each replay starts from a truly blank canvas rather than stacking a second line and a second set of dots on top of the first.

Build with AI

Build, Understand, Optimize, and Extend It With AI

The dash-offset reveal is a classic SVG trick worth fully internalizing, so start there. Paste the code into an AI assistant like Claude and ask it to walk through, step by step, why setting stroke-dasharray and stroke-dashoffset to the SAME value (the path's total length) produces an invisible line, and why animating dashoffset down to zero specifically reveals the line from its start point rather than its end or its middle. Then ask what would need to change to reveal the line from right to left instead, or to reveal it from the center outward in both directions. To extend it: add a second data series with its own color and dash-reveal timing, add a value tooltip that appears on hover over each dot, animate the y-axis gridlines in with a similar staggered fade, or make the chart responsive to a live-updating data source with a smooth path transition between old and new data.

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 self-drawing animated line chart using Snap.svg (v0.5.1, from a CDN) in plain HTML, CSS, and JavaScript.

Requirements:
- An inline SVG chart area with a data array of numeric values, and a toPoints() function that maps those values into {x, y} pixel coordinates scaled to fit the SVG's viewBox, accounting for a padding margin.
- Draw a few faint horizontal gridlines first, underneath everything else.
- Build the line as a single Snap.svg path (s.path(...)) from an "M x,y L x,y L x,y ..." string generated from the mapped points, styled with a colored stroke, no fill, and rounded line caps/joins.
- Implement the classic SVG draw-in reveal: measure the path's real length with linePath.node.getTotalLength(), set both stroke-dasharray and stroke-dashoffset to that length (making the line start fully invisible), then animate stroke-dashoffset down to 0 over roughly 1 second using Snap's .animate() with a mina easing function.
- Pass a completion callback to that animate() call that reveals circular data-point markers at each mapped coordinate ONLY after the line has finished drawing \u2014 fade each circle's opacity in via its own short animate() call, staggered with an increasing setTimeout delay per point (e.g. index * 90ms) so they cascade in left to right rather than appearing all at once.
- Wrap the whole build sequence in a single function (e.g. draw()) that starts with s.clear() to empty the SVG, and wire a "Replay" button to call that same function again so the entire animation can be re-triggered.
- Style it as a dark card containing the chart with a small replay button in the corner.

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.

Source Code

Requires
<div class="salc-stage">
  <div class="salc-head">
    <span class="salc-tag">Snap.svg · dash-offset reveal</span>
    <h2>Animated Line Chart</h2>
    <p>The line draws itself in on load, then each data point fades in in sequence.</p>
  </div>
  <div class="salc-card">
    <svg id="salcSvg" viewBox="0 0 480 220" width="100%" height="220"></svg>
    <button class="salc-replay" id="salcReplay">Replay</button>
  </div>
</div>

Step by step

How to Use

  1. 1
    Add the Snap.svg CDNInclude snap.svg-min.js from the CDN panel — it attaches a global Snap function.
  2. 2
    Paste HTML, CSS, and JSThe chart draws itself in automatically as soon as the script runs.
  3. 3
    Watch the line revealstroke-dashoffset eases from the path\u2019s length to 0 over 1.1 seconds.
  4. 4
    Watch the points cascade inCircles fade in left to right only after the line finishes drawing.
  5. 5
    Click Replaydraw() clears the SVG and re-runs the whole reveal sequence from scratch.
  6. 6
    Swap in your own dataChange the data array — toPoints() rescales it to fit the chart automatically.

Real-world uses

Common Use Cases

Dashboard KPI charts
A line chart that draws itself in when a dashboard section loads.
Landing page stat reveals
An animated growth chart as a marketing page scroll trigger.
Teaching SVG dash tricks
A concrete reference for the dasharray/dashoffset reveal technique.
Report / summary animations
Data visualizations that animate in on a report\u2019s first render.
Presentation-style reveals
A chart timed to reveal alongside a spoken or scrolled narrative.

Got questions?

Frequently Asked Questions

It sets stroke-dasharray to the path\u2019s exact total length (from getTotalLength()), which makes the dash pattern effectively one dash and one gap the length of the whole line. Setting stroke-dashoffset to that same length shifts the visible dash entirely off the path, so it starts invisible. Animating dashoffset down to 0 slides the visible portion in from the start, reading as a line being drawn.

getTotalLength() is a native SVG DOM method that returns the path\u2019s actual rendered length, accounting for however many points or curve segments it has. Using a fixed guess would either leave a visible dash gap if too short, or not fully reveal the line if too long.

revealDots() is passed as the completion callback to the line\u2019s Snap.animate() call, so it only runs once stroke-dashoffset has finished easing to 0 \u2014 keeping the visual sequence as "line draws in, then points land" rather than everything appearing at once.

Each dot\u2019s animate() call is wrapped in a setTimeout whose delay is the dot\u2019s index multiplied by a fixed interval (90ms), so dot 0 starts immediately, dot 1 after 90ms, dot 2 after 180ms, and so on \u2014 producing a left-to-right cascade.

draw() is reused as the replay handler. Without clearing the SVG root first, each replay would add a second line, second gridlines, and second set of dots on top of the previous ones instead of starting from a blank chart.

Build the path string with C (cubic Bezier) commands instead of L, but the dash-offset reveal technique works identically \u2014 getTotalLength() and stroke-dashoffset operate on the rendered path length regardless of whether it is made of lines or curves.