webdevpuneet.com

Bump Chart — Ranking Over Time Line Chart

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

CategoryCharts

Copy & paste

Source Code

<div class="bp-card">
  <h3>Ranking over the season</h3>
  <div class="bp-wrap">
    <svg class="bp-svg" id="bpSvg" viewBox="0 0 340 200" aria-label="Bump chart of rankings"></svg>
  </div>
  <div class="bp-legend" id="bpLegend"></div>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), 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

Rank-based y-axis
#1 at top, evenly spaced ranks regardless of values.
Overtake crossings
Where lines cross, positions were swapped.
Nodes + end labels
A dot per period and the name at the final rank.
Hover highlight
Dim others and thicken the hovered line.
Legend toggle
Click to hide or restore any series.
Smooth strokes
Round caps and joins for clean bends.
Data-driven
Lines, labels, and legend derive from the data.
No library
Pure HTML/CSS/JS/SVG — no D3 or chart dependency.

About this UI Snippet

Bump Chart — Rank-Over-Time Lines with Highlight and Toggle

Screenshot of the Bump Chart snippet rendered live

A bump chart visualises how items move up and down a ranking over time — each line is a competitor, the y-axis is rank (1 at the top), and crossings show overtakes. It's the chart for league tables, chart positions, keyword rankings, and leaderboards over a season. This snippet renders one in pure SVG with end labels, hover highlighting, and a toggling legend, in plain HTML, CSS, and vanilla JavaScript.

Rank, not value, on the y-axis

The key difference from a line chart is the scale: the y-axis is rank, with #1 at the top and the lowest rank at the bottom, evenly spaced regardless of the underlying values. Each item's path connects its rank at each period, so the slope encodes movement up or down the table and where lines cross, positions were swapped. Mapping rank to y is a simple linear scale across the number of ranks.

Lines, nodes, and end labels

Each item gets a coloured polyline through its rank points, a circular node at every period, and its name drawn at its final position — so you can read who's who without hunting in the legend. Round line caps and joins keep the bends smooth, and the period labels sit along the bottom with rank labels (#1…#n) down the side.

Highlight to follow one line

With several crossing lines a bump chart can get busy, so hovering a line (or its legend entry) dims the others and thickens the hovered one, letting you trace a single item's journey through the overtakes. This focus-by-dimming is the standard technique for making dense multi-series charts readable.

Toggle series via the legend

Clicking a legend entry removes or restores that line, so you can declutter to compare just two or three contenders. Because the chart redraws from the data (with an off flag per item), toggling is just a re-render — no fragile show/hide bookkeeping.

Data-driven and dependency-free

Each team is { name, color, ranks } where ranks is the position per period, and the periods are a labels array — so changing the contest is a data edit. With no chart library, it's a clean reference for the bump-chart pattern that's otherwise surprisingly hard to find outside D3.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA bump chart renders five teams ranked across five weeks.
  2. 2
    Use your dataEdit TEAMS ({ name, color, ranks }) and the ROUNDS labels.
  3. 3
    Read the ranks#1 is at the top; crossings show overtakes.
  4. 4
    Hover a lineOthers dim so you can follow one item's path.
  5. 5
    Toggle the legendClick an entry to hide or restore that line.
  6. 6
    RestyleChange colors, node size, or chart dimensions.

Real-world uses

Common Use Cases

League and sports standings
Track how teams climb and drop across a season. Where two lines cross, positions swapped, so overtakes are visible without reading a table.
Keyword and SEO rankings
Show position changes for tracked keywords beside a line chart widget of traffic, so rank moves can be read against what they did to visits.
Chart and popularity rankings
Follow songs, products or pages over several weeks. Evenly spaced ranks keep movement readable regardless of how close the underlying scores are.
Leaderboards over time
Complement a leaderboard table with the story of how the standings got there. Hover dims every other line and thickens the one you are following.
Poll and election tracking
Show candidate standings across polling waves, with end labels naming each line at its final rank so no legend lookup is needed.
Related: D3 Force Bubble Chart
See the D3 Force Bubble Chart for a related charts pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

A line chart plots values on the y-axis; a bump chart plots rank, with #1 at the top and ranks evenly spaced regardless of the actual values. This makes overtakes explicit — when two lines cross, those items swapped positions — and keeps the focus on relative order over time rather than absolute magnitude. It is ideal when ranking, not value, is the story.

Bump charts get visually busy because lines cross frequently. Dimming every line except the hovered one (and thickening that one) lets you trace a single item's path through all the overtakes without losing it among the crossings. It is the standard focus technique for dense multi-series charts and keeps the chart readable as you add competitors.

Yes. Each legend entry toggles an off flag on its team and re-renders, so clicking removes or restores that line. This lets you declutter to just the contenders you care about. Because the chart redraws from the data each time, there is no fragile show/hide state to manage — the visible set is always derived from the flags.

An array of periods (labels) and an array of items, each { name, color, ranks }, where ranks is that item's position at each period in order. Ranks should run 1..n with no gaps for a clean axis. The chart computes positions from the number of periods and ranks, so changing either is just a data edit.

Compute each item's path and node positions from rank using a linear scale, and render them as SVG path and circle elements. Hold a hovered item and a hidden set in state to drive the dimming and toggling. D3 or visx can replace the math for advanced cases, but the rank-to-y mapping stays the same. Tailwind users swap the classes for utilities.