DumbbellChart
Compare two measurements per category with connected dots.
← All chart guides · Framework setup · Native counterparts
See it and copy it
Framework example
Explore the live chart, then open its code for Astro, React, or Elements.
Progress by team
Score out of 100 · previous to current quarter
- Design62 88
- Engineering76 91
- Support81 74
View chart data
| Category | Previous | Current |
|---|---|---|
| Design | 62 | 88 |
| Engineering | 76 | 91 |
| Support | 81 | 74 |
View DumbbellChart code
Framework usage
Switch targets to compare the adapter code. This live preview runs the Astro example. React and Elements use their own behavior APIs; complete the matching framework setup before copying an example.---
import { DumbbellChart } from '@santi020k/lumen-astro'
const data = [
{ id: 'design', label: 'Design', reference: 62, value: 88 },
{ id: 'engineering', label: 'Engineering', reference: 76, value: 91 },
{ id: 'support', label: 'Support', reference: 81, value: 74 }
]
---
<DumbbellChart
aria-label="Team scores, previous and current quarter"
heading="Progress by team"
description="Score out of 100 · previous to current quarter"
data={data}
domain={{ min: 0, max: 100 }}
referenceLabel="Previous"
valueLabel="Current"
/>import { DumbbellChart } from '@santi020k/lumen-react'
const data = [
{ id: 'design', label: 'Design', reference: 62, value: 88 },
{ id: 'engineering', label: 'Engineering', reference: 76, value: 91 },
{ id: 'support', label: 'Support', reference: 81, value: 74 }
]
export const Example = () => (
<>
<DumbbellChart
aria-label="Team scores, previous and current quarter"
heading="Progress by team"
description="Score out of 100 · previous to current quarter"
data={data}
domain={{ min: 0, max: 100 }}
referenceLabel="Previous"
valueLabel="Current"
/>
</>
)<lumen-dumbbell-chart
id="example-dumbbell-chart"
aria-label="Team scores, previous and current quarter"
heading="Progress by team"
description="Score out of 100 · previous to current quarter"
domain-min="0" domain-max="100"
reference-label="Previous" value-label="Current"
></lumen-dumbbell-chart>
<!-- In a module processed by your bundler, after the chart markup. -->
<script type="module">
import { defineLumenElements, LumenDumbbellChartElement } from '@santi020k/lumen-elements'
defineLumenElements(['DumbbellChart'])
const chart = document.getElementById('example-dumbbell-chart')
if (chart instanceof LumenDumbbellChartElement) {
chart.data = [
{ id: 'design', label: 'Design', reference: 62, value: 88 },
{ id: 'engineering', label: 'Engineering', reference: 76, value: 91 },
{ id: 'support', label: 'Support', reference: 81, value: 74 }
]
}
</script>Framework differences
Elements: Register DumbbellChart and assign rows with value and reference through the data property or a JSON data attribute. Use reference-label/value-label for the endpoint names and the valueFormatter property for units.
When to use DumbbellChart
Use for before/after comparisons or two consistently defined observations of the same categories.
- Set referenceLabel and valueLabel to name the two observations, such as Previous quarter and Current quarter.
- The connector appears only when both endpoints exist. A lone endpoint remains available without implying a zero comparison.
Prepare the data
import type { LumenComparisonDatum } from '@santi020k/lumen-core'
const data = [
{ id: 'design', label: 'Design', reference: 62, value: 88 },
{ id: 'support', label: 'Support', reference: 81, value: 74 },
{ id: 'sales', label: 'Sales', reference: null, value: 70 }
] satisfies readonly LumenComparisonDatum[]- Use unique nonempty ids and labels. value is the current measurement; reference is the comparison and may be omitted or null.
- Both measurements use the same numeric unit. Input order is preserved and an explicit domain must enclose zero and every available endpoint.
Avoid misleading comparisons
- A movement to the right means a larger value, not necessarily a better outcome. Explain whether higher or lower is desirable.
- Do not compare values calculated from different units or incompatible populations as if they were a paired change.
Choose your target
Add this component
Choose the package for your runtime. All adapters share the Lumen stylesheet. Use the matching registry command when you want a local wrapper for that framework.
pnpm add @santi020k/lumen-astropnpm add @santi020k/lumen-astrolumen add DumbbellChartlumen add DumbbellChartpnpm add @santi020k/lumen-reactpnpm add @santi020k/lumen-reactlumen add DumbbellChart --target reactlumen add DumbbellChart --target reactpnpm add @santi020k/lumen-elementspnpm add @santi020k/lumen-elementslumen add DumbbellChart --target elementslumen add DumbbellChart --target elementsAPI reference
Lumen-specific props and runtime attributes for the Astro primitive. Use the framework differences above and the copyable examples for React composition and Elements attributes; the public adapter types define their supported contracts.
| Attribute | Values | Default | Description |
|---|---|---|---|
| data | readonly LumenComparisonDatum[] | required | Unique non-empty id, label, nullable finite value, optional nullable reference and tone. Input order is preserved. |
| domain | LumenChartDomain | automatic | Must include zero and every displayed measurement. |
| formatValue | (value: number) => string | String | Formats numeric values, ticks, and exact data. Keep the source data numeric. |
| labels | Partial<LumenChartLabels> | English | Localizes unavailable, empty, invalid-data, and data-disclosure text. |
| valueLabel, referenceLabel | string | Value / Before | Names the current and reference observations. Missing endpoints are never converted to zero. |
| heading, description, caption, summary | string | unset | Supplies visible context, a caption, and an optional screen-reader summary. |
| presentation | "default" | "bare" | "default" | Uses bare inside a parent surface that already provides padding and a border. |
| aria-label | string | unset | Names the chart figure; include the measurement and reporting period. |
| showTable | boolean | true | Keeps the keyboard-accessible exact data disclosure available. |
| class, className | string | "" | Merges custom classes with the generated ui-* root classes. |
| ...native attributes | HTML attributes | - | Forwards standard attributes to the root element unless the component consumes them. |