webdevpuneet.com

Slope Chart — HTML CSS JS Slopegraph (No Library)

Slope Chart · Charts · Plain HTML, CSS & JS · Live preview

CategoryCharts

Copy & paste

Source Code

<div class="sl-card">
  <div class="sl-head"><h3>Market share: 2024 → 2025</h3></div>
  <div class="sl-cols"><span>2024</span><span>2025</span></div>
  <svg class="sl-svg" id="slSvg" viewBox="0 0 380 280" role="img" aria-label="Slope chart"></svg>
  <div class="sl-tip" id="slTip" hidden></div>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Slope encodes change
Each category is a line between its before and after value — direction and steepness show the change.
Shared scale
Both axes use one scale from the combined range, so slopes are honest and comparable.
Endpoints labelled both sides
Name and value at each end let you follow any line without a legend.
Rank-shift crossings
Lines that cross reveal categories swapping positions.
Hover focus-and-dim
Hovering a line dims the rest and thickens it, taming crossings.
Change tooltip
Shows the exact +/- change in points for the focused line.
Grouped SVG rows
Each line, its dots, and labels are one group that highlights together.
Data-driven & no library
Renders from a DATA array in plain HTML/CSS/SVG/JS — zero dependencies.

About this UI Snippet

Slope Chart — Before-and-After Lines That Show Change at a Glance

Screenshot of the Slope Chart snippet rendered live

A slope chart (or slopegraph, popularised by Edward Tufte) compares two points in time by drawing a line for each category between its before and after value on two parallel axes. The slope of each line — up, down, steep, flat — instantly communicates the direction and size of change, and crossings show rank shifts. This snippet builds it in plain HTML, CSS, SVG, and vanilla JavaScript, with labelled endpoints and hover focus — no charting library.

Two axes, one line per category

The chart has two vertical axes — left for the "before" period, right for "after" — and each category is a single line connecting its two values, with a dot at each end. A line that climbs rose; one that falls dropped; a steep line changed a lot. This direct encoding of change as slope is what a slopegraph does better than a grouped bar chart or two pies: the eye reads the trend without comparing bar heights across a gap.

A shared scale for honest slopes

Both axes share one scale computed from the combined min and max of all values, so a slope's steepness genuinely reflects the magnitude of change and lines are comparable across categories. The y() function maps each value to a pixel position on that shared range (inverted for SVG). Using one scale for both columns is essential — separate scales would make the slopes meaningless.

Endpoints labelled on both sides

Each line is labelled at both ends: the category name and its before value on the left, its after value and name on the right. Labelling both endpoints (rather than relying on a legend) lets the reader follow any line across without losing track of which is which — the convention that makes a slopegraph readable even with crossing lines.

Hover to focus

Hovering a line dims all the others and thickens the focused one, with a tooltip showing the exact change in points. This focus-and-dim interaction is what tames a busy slope chart: when several lines cross, hovering isolates the one you care about so you can trace it cleanly. The whole row (line, dots, labels) is one SVG group, so it highlights together.

Data-driven and drop-in

It renders from a DATA array of { name, before, after, color }. Swap in any two-period comparison — market share, rankings, prices, survey results across two years — and the slopes, scale, and labels follow. It is a clear, dependency-free reference for slopegraph construction: shared-scale endpoints, connecting lines, and focus interaction. A slope chart only scales gracefully to a dozen or so categories before the left and right labels start overlapping vertically — past that point, either label only the lines a viewer is most likely to care about (the biggest movers) and let the rest go unlabeled until hovered, or switch to small multiples grouping related categories into separate, less crowded slope charts.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA slope chart renders connecting each company's 2024 and 2025 market share.
  2. 2
    Read the slopesUpward lines rose, downward fell; steeper means a bigger change, crossings mean rank shifts.
  3. 3
    Hover a lineThe others dim and a tooltip shows the change in points for the focused line.
  4. 4
    Swap in your dataReplace the DATA array with your own { name, before, after, color } items.
  5. 5
    Use for any two periodsYears, before/after, baseline/result — any two comparable points work.
  6. 6
    Wire to an APIMap your two-period data into the DATA shape and call render().

Real-world uses

Common Use Cases

Before-and-after comparisons
Show change between two periods with one line per category, where steepness reads as the size of the change and direction as an increase or decrease.
Market share and ranking shifts
Visualise share or rank movement between two years, where lines that cross reveal the categories that swapped positions.
Survey and poll waves
Compare responses across two waves with the name and value labelled at both ends, so every line can be followed without a legend.
Price and KPI movement
Show how prices or KPIs moved between two dates on one shared scale, so slopes stay honest and comparable across categories.
Experiment results
Compare a baseline with the result across segments, and reach for a bar chart or multi-line chart when you need more than two time points.

Got questions?

Frequently Asked Questions

Comparing exactly two points — usually two time periods — across several categories. Each category becomes a line whose slope shows the direction and size of change, and crossings reveal rank swaps. It communicates change more directly than grouped bars (no comparing heights across a gap) or two pies (no tracking slices between them), which is why Tufte popularised it for before/after comparisons.

The whole point of a slope chart is that the steepness of a line reflects how much a value changed. If each axis had its own scale, identical changes would render as different slopes and the chart would mislead. The snippet computes one min/max from all values across both periods and maps both endpoints through the same y() function, so every slope is comparable and honest.

When several lines are close together or cross, a legend forces the reader to match colours back and forth. Labelling each line's name and value at both endpoints lets the eye follow any line straight across the chart without losing it. This dual labelling is the standard slopegraph convention and is what keeps it readable as the number of categories grows.

With many categories the lines can overlap and cross, making one hard to trace. Hovering a line adds a dim class to all the other rows and thickens the focused line and its dots, visually isolating it, while a tooltip shows its exact change. Because each line, its dots, and labels are grouped in one SVG <g>, they highlight and dim together.

In React, hold the data in useState and render the line groups from .map() (or run render() in a useEffect with a ref), tracking the hovered index in state for the dim effect; in Vue, use v-for with a hovered ref; in Angular, *ngFor with a property. The shared-scale y() math is framework-agnostic and ports unchanged.