Helix ribbons
Helix ribbons
| Observation | Value |
|---|---|
| API · cycle 0 · phase 0 | 48 |
| API · cycle 0 · phase 0.125 | 59 |
| API · cycle 0 · phase 0.25 | 59 |
| API · cycle 0 · phase 0.375 | 52 |
| API · cycle 0 · phase 0.5 | 42 |
| API · cycle 0 · phase 0.625 | 34 |
| API · cycle 0 · phase 0.75 | 29 |
| API · cycle 0 · phase 0.875 | 25 |
| API · cycle 1 · phase 0 | 22 |
| API · cycle 1 · phase 0.125 | 24 |
| API · cycle 1 · phase 0.25 | 32 |
| API · cycle 1 · phase 0.375 | 46 |
| API · cycle 1 · phase 0.5 | 60 |
| API · cycle 1 · phase 0.625 | 66 |
| API · cycle 1 · phase 0.75 | 59 |
| API · cycle 1 · phase 0.875 | 40 |
| API · cycle 2 · phase 0 | 18 |
| API · cycle 2 · phase 0.125 | 5 |
| API · cycle 2 · phase 0.25 | 8 |
| API · cycle 2 · phase 0.375 | 27 |
| API · cycle 2 · phase 0.5 | 50 |
| API · cycle 2 · phase 0.625 | 66 |
| API · cycle 2 · phase 0.75 | 68 |
| API · cycle 2 · phase 0.875 | 55 |
| API · cycle 3 · phase 0 | 37 |
| API · cycle 3 · phase 0.125 | 22 |
| API · cycle 3 · phase 0.25 | 17 |
| API · cycle 3 · phase 0.375 | 21 |
| API · cycle 3 · phase 0.5 | 29 |
| API · cycle 3 · phase 0.625 | 37 |
| API · cycle 3 · phase 0.75 | 43 |
| API · cycle 3 · phase 0.875 | 49 |
| Workers · cycle 0 · phase 0 | 64 |
| Workers · cycle 0 · phase 0.125 | 72 |
| Workers · cycle 0 · phase 0.25 | 63 |
| Workers · cycle 0 · phase 0.375 | 42 |
| Workers · cycle 0 · phase 0.5 | 20 |
| Workers · cycle 0 · phase 0.625 | 8 |
| Workers · cycle 0 · phase 0.75 | 11 |
| Workers · cycle 0 · phase 0.875 | 26 |
| Workers · cycle 1 · phase 0 | 44 |
| Workers · cycle 1 · phase 0.125 | 56 |
| Workers · cycle 1 · phase 0.25 | 58 |
| Workers · cycle 1 · phase 0.375 | 53 |
| Workers · cycle 1 · phase 0.5 | 45 |
| Workers · cycle 1 · phase 0.625 | 38 |
| Workers · cycle 1 · phase 0.75 | 31 |
| Workers · cycle 1 · phase 0.875 | 26 |
| Workers · cycle 2 · phase 0 | 21 |
| Workers · cycle 2 · phase 0.125 | 21 |
| Workers · cycle 2 · phase 0.25 | 28 |
| Workers · cycle 2 · phase 0.375 | 42 |
| Workers · cycle 2 · phase 0.5 | 58 |
| Workers · cycle 2 · phase 0.625 | 67 |
| Workers · cycle 2 · phase 0.75 | 62 |
| Workers · cycle 2 · phase 0.875 | 44 |
| Workers · cycle 3 · phase 0 | 22 |
| Workers · cycle 3 · phase 0.125 | 6 |
| Workers · cycle 3 · phase 0.25 | 6 |
| Workers · cycle 3 · phase 0.375 | 22 |
| Workers · cycle 3 · phase 0.5 | 46 |
| Workers · cycle 3 · phase 0.625 | 64 |
| Workers · cycle 3 · phase 0.75 | 68 |
| Workers · cycle 3 · phase 0.875 | 58 |
| Search · cycle 0 · phase 0 | 56 |
| Search · cycle 0 · phase 0.125 | 54 |
| Search · cycle 0 · phase 0.25 | 44 |
| Search · cycle 0 · phase 0.375 | 29 |
| Search · cycle 0 · phase 0.5 | 14 |
| Search · cycle 0 · phase 0.625 | 9 |
| Search · cycle 0 · phase 0.75 | 18 |
| Search · cycle 0 · phase 0.875 | 39 |
| Search · cycle 1 · phase 0 | 61 |
| Search · cycle 1 · phase 0.125 | 72 |
| Search · cycle 1 · phase 0.25 | 66 |
| Search · cycle 1 · phase 0.375 | 47 |
| Search · cycle 1 · phase 0.5 | 24 |
| Search · cycle 1 · phase 0.625 | 10 |
| Search · cycle 1 · phase 0.75 | 10 |
| Search · cycle 1 · phase 0.875 | 23 |
| Search · cycle 2 · phase 0 | 40 |
| Search · cycle 2 · phase 0.125 | 53 |
| Search · cycle 2 · phase 0.25 | 57 |
| Search · cycle 2 · phase 0.375 | 54 |
| Search · cycle 2 · phase 0.5 | 47 |
| Search · cycle 2 · phase 0.625 | 41 |
| Search · cycle 2 · phase 0.75 | 34 |
| Search · cycle 2 · phase 0.875 | 28 |
| Search · cycle 3 · phase 0 | 21 |
| Search · cycle 3 · phase 0.125 | 19 |
| Search · cycle 3 · phase 0.25 | 25 |
| Search · cycle 3 · phase 0.375 | 38 |
| Search · cycle 3 · phase 0.5 | 56 |
| Search · cycle 3 · phase 0.625 | 67 |
| Search · cycle 3 · phase 0.75 | 65 |
| Search · cycle 3 · phase 0.875 | 49 |
Usage
Import the component and the stylesheet once. See Getting started to install the package.
import { HelixRibbonsCard } from '@lilt-ui/charts';
import '@lilt-ui/charts/styles.css';<HelixRibbonsCard data={cyclicRibbons} series="series" cycle="cycle" phase="phase" value="value" />Omit title to leave out the visible title. Set header={false} to remove the whole header, and use aria-label to name a chart inside your own card. legend={false} removes the legend independently. surface="ghost" controls only the visual frame. See Card composition.
Data
Supply an integer cycle and a phase from 0 inclusive to 1 exclusive, with nonnegative magnitude. Cycles must span at most 25 consecutive turns. Width interpolates between known samples; null values or gaps larger than maxGap break the ribbon. Concentric lanes separate series without shifting their measured phase. Beads preserve individual samples.
const cyclicRibbons = [
{
"series": "API",
"cycle": 0,
"phase": 0,
"value": 48
},
{
"series": "API",
"cycle": 0,
"phase": 0.125,
"value": 59
},
{
"series": "API",
"cycle": 0,
"phase": 0.25,
"value": 59
},
{
"series": "API",
"cycle": 0,
"phase": 0.375,
"value": 52
},
{
"series": "API",
"cycle": 0,
"phase": 0.5,
"value": 42
},
{
"series": "API",
"cycle": 0,
"phase": 0.625,
"value": 34
},
{
"series": "API",
"cycle": 0,
"phase": 0.75,
"value": 29
},
{
"series": "API",
"cycle": 0,
"phase": 0.875,
"value": 25
},
{
"series": "API",
"cycle": 1,
"phase": 0,
"value": 22
},
{
"series": "API",
"cycle": 1,
"phase": 0.125,
"value": 24
},
{
"series": "API",
"cycle": 1,
"phase": 0.25,
"value": 32
},
{
"series": "API",
"cycle": 1,
"phase": 0.375,
"value": 46
},
{
"series": "API",
"cycle": 1,
"phase": 0.5,
"value": 60
},
{
"series": "API",
"cycle": 1,
"phase": 0.625,
"value": 66
},
{
"series": "API",
"cycle": 1,
"phase": 0.75,
"value": 59
},
{
"series": "API",
"cycle": 1,
"phase": 0.875,
"value": 40
},
{
"series": "API",
"cycle": 2,
"phase": 0,
"value": 18
},
{
"series": "API",
"cycle": 2,
"phase": 0.125,
"value": 5
},
{
"series": "API",
"cycle": 2,
"phase": 0.25,
"value": 8
},
{
"series": "API",
"cycle": 2,
"phase": 0.375,
"value": 27
},
{
"series": "API",
"cycle": 2,
"phase": 0.5,
"value": 50
},
{
"series": "API",
"cycle": 2,
"phase": 0.625,
"value": 66
},
{
"series": "API",
"cycle": 2,
"phase": 0.75,
"value": 68
},
{
"series": "API",
"cycle": 2,
"phase": 0.875,
"value": 55
},
{
"series": "API",
"cycle": 3,
"phase": 0,
"value": 37
},
{
"series": "API",
"cycle": 3,
"phase": 0.125,
"value": 22
},
{
"series": "API",
"cycle": 3,
"phase": 0.25,
"value": 17
},
{
"series": "API",
"cycle": 3,
"phase": 0.375,
"value": 21
},
{
"series": "API",
"cycle": 3,
"phase": 0.5,
"value": 29
},
{
"series": "API",
"cycle": 3,
"phase": 0.625,
"value": 37
},
{
"series": "API",
"cycle": 3,
"phase": 0.75,
"value": 43
},
{
"series": "API",
"cycle": 3,
"phase": 0.875,
"value": 49
},
{
"series": "Workers",
"cycle": 0,
"phase": 0,
"value": 64
},
{
"series": "Workers",
"cycle": 0,
"phase": 0.125,
"value": 72
},
{
"series": "Workers",
"cycle": 0,
"phase": 0.25,
"value": 63
},
{
"series": "Workers",
"cycle": 0,
"phase": 0.375,
"value": 42
},
{
"series": "Workers",
"cycle": 0,
"phase": 0.5,
"value": 20
},
{
"series": "Workers",
"cycle": 0,
"phase": 0.625,
"value": 8
},
{
"series": "Workers",
"cycle": 0,
"phase": 0.75,
"value": 11
},
{
"series": "Workers",
"cycle": 0,
"phase": 0.875,
"value": 26
},
{
"series": "Workers",
"cycle": 1,
"phase": 0,
"value": 44
},
{
"series": "Workers",
"cycle": 1,
"phase": 0.125,
"value": 56
},
{
"series": "Workers",
"cycle": 1,
"phase": 0.25,
"value": 58
},
{
"series": "Workers",
"cycle": 1,
"phase": 0.375,
"value": 53
},
{
"series": "Workers",
"cycle": 1,
"phase": 0.5,
"value": 45
},
{
"series": "Workers",
"cycle": 1,
"phase": 0.625,
"value": 38
},
{
"series": "Workers",
"cycle": 1,
"phase": 0.75,
"value": 31
},
{
"series": "Workers",
"cycle": 1,
"phase": 0.875,
"value": 26
},
{
"series": "Workers",
"cycle": 2,
"phase": 0,
"value": 21
},
{
"series": "Workers",
"cycle": 2,
"phase": 0.125,
"value": 21
},
{
"series": "Workers",
"cycle": 2,
"phase": 0.25,
"value": 28
},
{
"series": "Workers",
"cycle": 2,
"phase": 0.375,
"value": 42
},
{
"series": "Workers",
"cycle": 2,
"phase": 0.5,
"value": 58
},
{
"series": "Workers",
"cycle": 2,
"phase": 0.625,
"value": 67
},
{
"series": "Workers",
"cycle": 2,
"phase": 0.75,
"value": 62
},
{
"series": "Workers",
"cycle": 2,
"phase": 0.875,
"value": 44
},
{
"series": "Workers",
"cycle": 3,
"phase": 0,
"value": 22
},
{
"series": "Workers",
"cycle": 3,
"phase": 0.125,
"value": 6
},
{
"series": "Workers",
"cycle": 3,
"phase": 0.25,
"value": 6
},
{
"series": "Workers",
"cycle": 3,
"phase": 0.375,
"value": 22
},
{
"series": "Workers",
"cycle": 3,
"phase": 0.5,
"value": 46
},
{
"series": "Workers",
"cycle": 3,
"phase": 0.625,
"value": 64
},
{
"series": "Workers",
"cycle": 3,
"phase": 0.75,
"value": 68
},
{
"series": "Workers",
"cycle": 3,
"phase": 0.875,
"value": 58
},
{
"series": "Search",
"cycle": 0,
"phase": 0,
"value": 56
},
{
"series": "Search",
"cycle": 0,
"phase": 0.125,
"value": 54
},
{
"series": "Search",
"cycle": 0,
"phase": 0.25,
"value": 44
},
{
"series": "Search",
"cycle": 0,
"phase": 0.375,
"value": 29
},
{
"series": "Search",
"cycle": 0,
"phase": 0.5,
"value": 14
},
{
"series": "Search",
"cycle": 0,
"phase": 0.625,
"value": 9
},
{
"series": "Search",
"cycle": 0,
"phase": 0.75,
"value": 18
},
{
"series": "Search",
"cycle": 0,
"phase": 0.875,
"value": 39
},
{
"series": "Search",
"cycle": 1,
"phase": 0,
"value": 61
},
{
"series": "Search",
"cycle": 1,
"phase": 0.125,
"value": 72
},
{
"series": "Search",
"cycle": 1,
"phase": 0.25,
"value": 66
},
{
"series": "Search",
"cycle": 1,
"phase": 0.375,
"value": 47
},
{
"series": "Search",
"cycle": 1,
"phase": 0.5,
"value": 24
},
{
"series": "Search",
"cycle": 1,
"phase": 0.625,
"value": 10
},
{
"series": "Search",
"cycle": 1,
"phase": 0.75,
"value": 10
},
{
"series": "Search",
"cycle": 1,
"phase": 0.875,
"value": 23
},
{
"series": "Search",
"cycle": 2,
"phase": 0,
"value": 40
},
{
"series": "Search",
"cycle": 2,
"phase": 0.125,
"value": 53
},
{
"series": "Search",
"cycle": 2,
"phase": 0.25,
"value": 57
},
{
"series": "Search",
"cycle": 2,
"phase": 0.375,
"value": 54
},
{
"series": "Search",
"cycle": 2,
"phase": 0.5,
"value": 47
},
{
"series": "Search",
"cycle": 2,
"phase": 0.625,
"value": 41
},
{
"series": "Search",
"cycle": 2,
"phase": 0.75,
"value": 34
},
{
"series": "Search",
"cycle": 2,
"phase": 0.875,
"value": 28
},
{
"series": "Search",
"cycle": 3,
"phase": 0,
"value": 21
},
{
"series": "Search",
"cycle": 3,
"phase": 0.125,
"value": 19
},
{
"series": "Search",
"cycle": 3,
"phase": 0.25,
"value": 25
},
{
"series": "Search",
"cycle": 3,
"phase": 0.375,
"value": 38
},
{
"series": "Search",
"cycle": 3,
"phase": 0.5,
"value": 56
},
{
"series": "Search",
"cycle": 3,
"phase": 0.625,
"value": 67
},
{
"series": "Search",
"cycle": 3,
"phase": 0.75,
"value": 65
},
{
"series": "Search",
"cycle": 3,
"phase": 0.875,
"value": 49
}
];Props
Every prop HelixRibbonsCard accepts, in the order you are likely to reach for them.
| Prop | Type | Description |
|---|---|---|
title | string | Optional visible title. Omit to render no title. Also supplies the accessible name unless aria-label is set. |
header | boolean | Defaults to true. False removes the whole header: title, headline, delta and period controls, with no reserved space. Pass data directly when your app owns period selection. |
aria-label | string | Accessible chart name, independent of the visible title. Falls back to title, then a generic chart name. |
data | Row[] | One row per observation. Omit when using ranges. |
height | number | Minimum plot height, default 390px. Dense data may expand within the scrollable viewport. |
depth | boolean | Lit tiles, solid bars, or spheres. Data positions remain exact; loading keeps the same depth treatment. |
color | string | Override the palette with one CSS color. |
headline | number | Override the resting headline. |
delta | number | Fractional change shown alongside the headline. |
deltaTone | 'default' | 'inverse' | 'neutral' | Use inverse when a decrease is good. |
range | string | Static period label. |
ranges | { id, label, data, headline?, delta? }[] | Period choices with their own data. |
defaultRange | string | Initial period id. |
locale | string | Locale for numbers and dates; defaults to en-US. |
formatValue | (value: number) => string | Custom value formatter. |
badge | ReactNode | Content for the glass tab above the card. |
className | string | Class on the card frame. |
style | CSSProperties | ChartStyle | Inline styles and scoped chart variables. |
onSelectionChange | (selection | null) => void | Reports id, original row (or null for an absent day), value, and pinned state. |
renderReadout | (selection | null) => ReactNode | Consumer-owned readout, including when the header is hidden. |
valueFormat | Intl.NumberFormatOptions | Formats the headline, tiles, and axis, e.g. currency. |
surface | 'elevated' | 'outline' | 'ghost' | Card treatment. Ghost removes the visual frame only; header and legend are independent controls. |
palette | 'iris' | 'cobalt' | 'emerald' | Series colors. Iris by default; explicit series colors still win. |
numberStyle | 'count' | 'pop' | 'slide' | 'roll' | 'flow' | 'scramble' | How the headline animates when its value changes. Count (default) counts to the new value. |
loading | boolean | Shows a neutral loading skeleton, not data. |
loadingStyle | 'shimmer' | 'draw' | 'breathe' | Shimmer sweeps a highlight over still shapes; draw reveals them in order; breathe lets them settle. Follows the selected look, including depth, and respects reduced motion. |
empty | 'dots' | 'shape' | ReactElement | null | What the card shows when the period has no data. Dots (default) gathers a quiet dot field around the message; shape lays the chart’s own outline behind it. Pass `<ChartEmpty>` with your own words, any element of your own, or null for nothing. Both looks stay still, so empty never reads as loading, and the headline reads a dash, never zero. |
motion | 'auto' | 'none' | None turns off decorative motion; reduced motion does this automatically. |
series | text key of Row | Series label; each series retains one track. |
cycle | numeric key of Row | Safe integer cycle number. A view spans at most 25 consecutive turns. |
phase | numeric key of Row | Fraction of a cycle, from 0 inclusive to 1 exclusive. |
value | numeric key of Row | Nonnegative numeric measurement. Null or undefined is missing. |
yaw | number | Camera rotation around the vertical axis, in degrees from -180 to 180. Default 25. |
elevation | number | Camera elevation, 10 to 70 degrees. Default 20. |
thickness | number | Maximum ribbon width, 3 to 26 pixels. Default 13. |
maxGap | number | Largest gap between samples, measured in cycles, 0.05 to 1. Default 0.3. |
aggregate | 'sum' | 'mean' | 'max' | Fallback resting summary. A family-defined summary (such as located point count, hierarchy total, or mean signed value) takes precedence. Use headline to override that summary. |
onKeyDown | KeyboardEventHandler<HTMLElement> | Keyboard handler on the card frame. Chart inspection also has its own keyboard handling. |
legendSwatch | 'square' | 'dot' | 'line' | Marker beside each group label, where a group legend is present. Defaults to square. |
legend | false | 'tiles' | 'inline' | 'list' | 'pills' | 'bars' | Layout for the group legend where the data produces groups. False hides it; defaults to tiles. |