ModsCode / Gallery / Designs / Bump chart
Bump chart
Repos ranked by tokens week by week; each line shows a repo overtaking and falling back, names at both ends, one climber in Claude orange.


hooks/designs/bump.mjs
// bump: eight repos ranked by tokens each week for eight weeks (W34 to W41), in candle's look. Each repo
// is a 1px line at 35% ink (candle's reference-line weight) through its rank in every week, so the
// crossings read as overtakes; the one repo to notice, cli, climbs from 7th to 1st and is the only Claude orange.
// Names sit at both ends, at the rank the repo opens and closes on, and rank numbers run down the left.
// Every week is a permutation of 1..8 written out below, so no two lines share a point. The lines use
// d3-shape's line() with curveBumpX (ISC, Mike Bostock). Sample data only.
import { line, curveBumpX } from '../vendor/d3.mjs'
const W = 380
const H = 240
const STAGE = '#FAF9F5'
const INK = '#141413'
const MUTED = '#73726C'
const CLAUDE = '#D77757'
const FONT = "'Inter Tight','Segoe UI',system-ui,sans-serif"
const MONO = "ui-monospace,'Cascadia Mono',Consolas,monospace"
const PLOT = { left: 92, right: 292 } // the left names end 8px before it, the right names start 8px after it
const ROW0 = 40 // the y of rank 1
const ROW = 24
const WEEKS = ['W34', 'W35', 'W36', 'W37', 'W38', 'W39', 'W40', 'W41']
const HIGHLIGHT = 'cli'
const f = n => n.toFixed(1)
// Rank in each week, 1 = most tokens. Each column is a permutation of 1..8.
const REPOS = [
['api-server', [1, 1, 1, 2, 2, 2, 3, 2]],
['web-app', [2, 2, 3, 3, 4, 3, 2, 3]],
['infra', [3, 4, 2, 1, 1, 4, 5, 5]],
['billing', [4, 3, 4, 5, 5, 5, 4, 4]],
['docs', [5, 5, 7, 8, 7, 6, 6, 7]],
['auth', [6, 8, 6, 6, 6, 7, 8, 8]],
['cli', [7, 6, 5, 4, 3, 1, 1, 1]],
['mobile', [8, 7, 8, 7, 8, 8, 7, 6]],
]
const text = (x, y, s, { size = 9, fill = MUTED, anchor = 'start', font = FONT } = {}) =>
`<text x="${f(x)}" y="${f(y)}"${anchor === 'start' ? '' : ` text-anchor="${anchor}"`} font-size="${size}" font-family="${font}" fill="${fill}">${s}</text>`
function draw() {
const n = WEEKS.length
const x = i => PLOT.left + ((PLOT.right - PLOT.left) * i) / (n - 1)
const y = r => ROW0 + (r - 1) * ROW
const path = line().x((r, i) => x(i)).y(r => y(r)).curve(curveBumpX).digits(1)
const parts = [`<rect width="${W}" height="${H}" rx="4" fill="${STAGE}"/>`]
WEEKS.forEach((w, i) => parts.push(text(x(i), 20, w, { anchor: 'middle' })))
for (let r = 1; r <= REPOS.length; r++) parts.push(text(18, y(r) + 3, String(r), { anchor: 'end', font: MONO }))
// The quiet lines first, so the Claude orange one runs over every crossing
const ordered = [...REPOS.filter(([name]) => name !== HIGHLIGHT), ...REPOS.filter(([name]) => name === HIGHLIGHT)]
for (const [name, ranks] of ordered) {
const top = name === HIGHLIGHT
parts.push(`<path d="${path(ranks)}" fill="none" stroke="${top ? CLAUDE : INK}"${top ? '' : ' stroke-opacity="0.35"'} stroke-width="1"/>`)
if (top) ranks.forEach((r, i) => parts.push(`<circle cx="${f(x(i))}" cy="${f(y(r))}" r="2" fill="${CLAUDE}"/>`))
const fill = top ? CLAUDE : INK
parts.push(text(PLOT.left - 8, y(ranks[0]) + 3.5, name, { size: 10, fill, anchor: 'end' }))
parts.push(text(PLOT.right + 8, y(ranks[n - 1]) + 3.5, name, { size: 10, fill }))
}
parts.push(text(12, H - 8, `SAMPLE REPOS RANKED BY TOKENS, ${n} WEEKS`))
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${W} ${H}" width="${W}" height="${H}">${parts.join('')}</svg>`
}
let source // drawn on first use and kept: the pane loads every design, so none pays at load time
export default {
id: 'bump',
title: 'Bump chart',
category: 'time',
description: 'Repos ranked by tokens week by week; each line shows a repo overtaking and falling back, names at both ends, one climber in Claude orange.',
element: ui => ui.Svg({ source: (source ??= draw()), alt: 'Bump chart of eight repos ranked by tokens over eight weeks, one repo climbing to first in Claude orange, sample data', width: W, height: H }),
}
Imports d3-shape 3.2.0 (ISC), bundled with its licence in look's hooks/vendor/.
To use it in a mod: copy the file to your mod's hooks/designs/ and return its element(ui) from a pane's ui.render. How a pane is built.
Code: PolyForm Noncommercial License 1.0.0: noncommercial use only. Required Notice: Copyright 2026 Haruki Nakada (https://modscode.com).