BumpChart
Ranking-over-stages chart that shows who led and who overtook whom.
A token-driven bump chart for tracking finishing rank across an ordered sequence of stages (e.g. the four games of one Friday). Each series is a competitor; its 1-based `ranks` are plotted with rank 1 drawn at the top, connected by lines so crossings reveal overtakes. The x-axis uses a `scalePoint` over `stages`, the y-axis runs integer rank ticks top-down, and `showLabels` puts each series name at its last node (direct labelling). Every node is keyboard-focusable with an accessible tooltip, series absent from a stage (non-finite rank) are skipped while the line still connects present nodes, and empty input shows an em-dash placeholder.
Demo
Usage
<script>
import { BumpChart } from 'dssoca';
const stages = ['G1', 'G2', 'G3', 'G4'];
const series = [
{ label: 'Ana', ranks: [1, 2, 1, 1] },
{ label: 'Bruno', ranks: [2, 1, 3, 2] },
{ label: 'Caio', ranks: [3, 4, 2, 3] },
];
</script>
<BumpChart {series} {stages} />HTML
CSS only — static markup The exact markup the component renders, generated at build time. Use it with dssoca/vanilla.css — see Plain HTML & CSS.
<div class="ss-bump" role="group" aria-label="Bump chart with 2 series over 3 stages (q1, q2, q3).">
<div class="plot">
<svg class="canvas" viewBox="0 0 480 280" width="480" height="280" preserveAspectRatio="xMidYMid meet" role="presentation">
<g transform="translate(32,12)">
<line class="grid" x1="0" x2="392" y1="0" y2="0">
</line>
<text class="tick y" x="-6" y="0" dy="0.32em" text-anchor="end">1</text>
<line class="grid" x1="0" x2="392" y1="240" y2="240">
</line>
<text class="tick y" x="-6" y="240" dy="0.32em" text-anchor="end">2</text>
<line class="axis" x1="0" x2="0" y1="0" y2="240">
</line>
<line class="axis" x1="0" x2="392" y1="240" y2="240">
</line>
<text class="tick x" x="65.33333333333334" y="256" text-anchor="middle">q1</text>
<text class="tick x" x="196" y="256" text-anchor="middle">q2</text>
<text class="tick x" x="326.66666666666663" y="256" text-anchor="middle">q3</text>
<path class="line" d="M65.333,0L196,240L326.667,0" style="stroke:var(--ss-accent)">
</path>
<path class="line" d="M65.333,240L196,0L326.667,240" style="stroke:var(--ss-blue)">
</path>
<circle class="node" cx="65.33333333333334" cy="0" r="5" style="fill:var(--ss-accent)" tabindex="0" role="button" aria-label="api: q1, rank 1">
</circle>
<circle class="node" cx="196" cy="240" r="5" style="fill:var(--ss-accent)" tabindex="0" role="button" aria-label="api: q2, rank 2">
</circle>
<circle class="node" cx="326.66666666666663" cy="0" r="5" style="fill:var(--ss-accent)" tabindex="0" role="button" aria-label="api: q3, rank 1">
</circle>
<circle class="node" cx="65.33333333333334" cy="240" r="5" style="fill:var(--ss-blue)" tabindex="0" role="button" aria-label="db: q1, rank 2">
</circle>
<circle class="node" cx="196" cy="0" r="5" style="fill:var(--ss-blue)" tabindex="0" role="button" aria-label="db: q2, rank 1">
</circle>
<circle class="node" cx="326.66666666666663" cy="240" r="5" style="fill:var(--ss-blue)" tabindex="0" role="button" aria-label="db: q3, rank 2">
</circle>
<text class="series-label" x="334.66666666666663" y="0" dy="0.32em" style="fill:var(--ss-accent)">api</text>
<text class="series-label" x="334.66666666666663" y="240" dy="0.32em" style="fill:var(--ss-blue)">db</text>
</g>
</svg>
</div>
</div>Charts are rendered geometry: copy the SVG as-is. Hover tooltips are not wired by vanilla.js.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
series | BumpSeries[] | — | Required. Each series has a `label`, 1-based `ranks` (length must match `stages`) and optional `color`. |
stages | string[] | — | Required. Ordered x-axis category labels (e.g. ["G1","G2","G3","G4"]). |
showLabels | boolean | true | Draw each series label at its last node (direct labelling). |
height | number | 280 | Intrinsic drawing height in px. |
width | number | 480 | Intrinsic drawing width in px. |
fluid | boolean | false | Stretch to the container width via the viewBox. |
tooltip | boolean | true | Reveal a tooltip on hover/focus of a node. Each node is keyboard-focusable. |
summary | string | — | Screen-reader summary + accessible name; auto-generated when absent. |
size | 'sm' | 'md' | 'lg' | — | Per-instance size override; inherits the ancestor `data-size-variant` when unset. |