BulletChart
Compares a measured value with a target and optional labeled performance ranges.
← 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.
On-time delivery
Completed deliveries within the service window
Actual: 86%. Goal: 95%.
Goal95%
- Developing0%–70%
- Consistent70%–90%
- Excellent90%–100%
View chart data
| Category | Value |
|---|---|
| Actual | 86% |
| Goal | 95% |
| Developing | 0%–70% |
| Consistent | 70%–90% |
| Excellent | 90%–100% |
View BulletChart 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 { BulletChart } from '@santi020k/lumen-astro'
const ranges = [
{ end: 70, label: 'Developing' },
{ end: 90, label: 'Consistent' },
{ end: 100, label: 'Excellent' }
]
---
<BulletChart
aria-label="Delivery performance, current quarter"
heading="On-time delivery"
description="Completed deliveries within the service window"
value={86}
target={95}
ranges={ranges}
domain={{ min: 0, max: 100 }}
valueLabel="Actual"
targetLabel="Goal"
formatValue={value => `${value}%`}
/>import { BulletChart } from '@santi020k/lumen-react'
const ranges = [
{ end: 70, label: 'Developing' },
{ end: 90, label: 'Consistent' },
{ end: 100, label: 'Excellent' }
]
export const Example = () => (
<>
<BulletChart
aria-label="Delivery performance, current quarter"
heading="On-time delivery"
description="Completed deliveries within the service window"
value={86}
target={95}
ranges={ranges}
domain={{ min: 0, max: 100 }}
valueLabel="Actual"
targetLabel="Goal"
formatValue={value => `${value}%`}
/>
</>
)<lumen-bullet-chart
id="example-bullet-chart"
aria-label="Delivery performance, current quarter"
heading="On-time delivery"
description="Completed deliveries within the service window"
domain-min="0" domain-max="100"
value="86" target="95" value-label="Actual" target-label="Goal"
></lumen-bullet-chart>
<!-- In a module processed by your bundler, after the chart markup. -->
<script type="module">
import { defineLumenElements, LumenBulletChartElement } from '@santi020k/lumen-elements'
defineLumenElements(['BulletChart'])
const chart = document.getElementById('example-bullet-chart')
if (chart instanceof LumenBulletChartElement) {
chart.ranges = [
{ end: 70, label: 'Developing' },
{ end: 90, label: 'Consistent' },
{ end: 100, label: 'Excellent' }
]
chart.valueFormatter = value => String(value) + '%'
}
</script>Framework differences
Elements: Register BulletChart. Use numeric value/target attributes and a ranges property or JSON attribute; assign valueFormatter as a function. Remove the value attribute, or set the value property to null, for an unavailable observation.
When to use BulletChart
Use for a compact goal comparison, such as service performance, delivery rate, or capacity against a planned limit.
- The bar shows actual magnitude from zero. The separate marker shows the target; background bands explain the configured ranges.
- Set valueLabel and targetLabel to make the comparison explicit. The exact-data disclosure reports actual, target, and range boundaries.
Prepare the data
import type { LumenBulletRange } from '@santi020k/lumen-core'
const value: number | null = 86
const target = 95
const ranges = [
{ end: 70, label: 'Developing' },
{ end: 90, label: 'Consistent' },
{ end: 100, label: 'Excellent' }
] satisfies readonly LumenBulletRange[]- value accepts a finite number or null; target must be finite. Keep values numeric and use formatValue for units.
- Each optional range needs a nonempty label and a unique finite end. Ranges are sorted by end without mutating your input.
- A supplied domain must increase, contain zero, and enclose the actual, target, and all range ends.
Avoid misleading comparisons
- A target is not automatically a maximum. Choose a domain that leaves room for exceeding it when that is possible.
- Lumen does not decide whether higher values are good. Choose range labels and tones that match the measure.
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 BulletChartlumen add BulletChartpnpm add @santi020k/lumen-reactpnpm add @santi020k/lumen-reactlumen add BulletChart --target reactlumen add BulletChart --target reactpnpm add @santi020k/lumen-elementspnpm add @santi020k/lumen-elementslumen add BulletChart --target elementslumen add BulletChart --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 |
|---|---|---|---|
| value, target | number | null, number | required | Compares a measured value with a target. Null is unavailable, zero remains a real value. |
| ranges | LumenBulletRange[] | [] | Uses labeled, finite, unique range ends. Ranges are sorted without mutating input. |
| domain | LumenChartDomain | automatic | Must include zero, the actual value, target, and all range ends. Invalid input fails closed. |
| formatValue, valueLabel, targetLabel, labels | formatters and labels | String, Value, Target | Localizes the visible values and exact data inspection. |
| 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 | Exposes the actual, target, and exact range boundaries. |
| 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. |