Charts
Open-to-close Chart
An ordered series that highlights the movement from each opening value to its closing value.
When to use it: Use it for compact open-versus-close comparisons when high and low values are not part of the story.
Example
import {
ChartDescription,
ChartTable,
ChartTitle,
ChartTooltip,
OpenToCloseChart,
OpenToCloseChartPlot,
OpenToCloseChartRange,
} from "@comp0/react";
const prices = [
{ x: 1, open: 98, close: 104 },
{ x: 2, open: 104, close: 101 },
{ x: 3, open: 101, close: 110 },
{ x: 4, open: 110, close: 108 },
] as const;
const formatPrice = (value: number) => `$${value}`;
export function Example() {
return (
<OpenToCloseChart
values={prices}
xLabel="Trading day"
yLabel="Share price"
formatX={(value) => `Day ${value}`}
formatY={formatPrice}
className="w-full max-w-2xl rounded-lg has-[:focus-visible]:outline-2 has-[:focus-visible]:outline-offset-4 has-[:focus-visible]:outline-teal-600 dark:has-[:focus-visible]:outline-teal-400"
>
<ChartTitle className="text-base font-semibold text-zinc-950 dark:text-zinc-50">
Opening to closing price
</ChartTitle>
<OpenToCloseChartPlot
aria-label="Open-to-close chart showing four trading days"
className="mx-auto mt-5 aspect-square w-full max-w-md overflow-visible"
>
{(range) => (
<OpenToCloseChartRange range={range} className="group outline-none">
<line
x1={range.x}
x2={range.x}
y1={range.openY}
y2={range.closeY}
className="stroke-teal-600 group-data-[direction=down]:stroke-rose-600 dark:stroke-teal-400 dark:group-data-[direction=down]:stroke-rose-400"
strokeWidth="3"
vectorEffect="non-scaling-stroke"
/>
<line
x1={range.x - range.width / 2}
x2={range.x + range.width / 2}
y1={range.openY}
y2={range.openY}
className="stroke-zinc-700 dark:stroke-zinc-300"
strokeWidth="2"
vectorEffect="non-scaling-stroke"
/>
<circle
cx={range.x}
cy={range.closeY}
r="2.4"
className="fill-zinc-950 dark:fill-white"
/>
</OpenToCloseChartRange>
)}
</OpenToCloseChartPlot>
<ChartDescription className="mt-5 text-sm text-zinc-600 dark:text-zinc-400">
Day three produced the strongest upward move; day two closed below its open.
</ChartDescription>
<ChartTable className="mt-4 w-full border-collapse text-left text-sm [&_td]:border-t [&_td]:border-zinc-200 [&_td]:py-2 [&_th]:border-zinc-200 [&_th]:py-2 dark:[&_td]:border-zinc-800 dark:[&_th]:border-zinc-800">
<caption className="sr-only">Opening and closing prices</caption>
<thead>
<tr>
<th scope="col">Day</th>
<th scope="col">Open</th>
<th scope="col">Close</th>
</tr>
</thead>
<tbody>
{prices.map((price) => (
<tr key={price.x}>
<th scope="row">Day {price.x}</th>
<td>{formatPrice(price.open)}</td>
<td>{formatPrice(price.close)}</td>
</tr>
))}
</tbody>
</ChartTable>
<ChartTooltip className="pointer-events-none z-50 rounded-md bg-zinc-950 px-2 py-1 text-sm text-white shadow-lg dark:bg-zinc-50 dark:text-zinc-950" />
</OpenToCloseChart>
);
}Anatomy
Dashed frames are invisible state providers; shaded shapes own real DOM. Numbered pins match the list below.
A wireframe sketch of the assembled component. Each numbered marker matches a part in the list that follows.
OpenToCloseChart
Native figure sharing ordered opening and closing values with every part. Owns a DOM element.
ChartTitle
Native figcaption that visibly names the figure. Owns a DOM element.
OpenToCloseChartPlot / OpenToCloseChartRange
Ordered SVG ranges with explicit open and close endpoints. Owns a DOM element.
ChartDescription
Visible prose summarizing the movement. Owns a DOM element.
ChartTable
Native table with exact open and close values. Owns a DOM element.
ChartTooltipOptional
Optional floating open/close pair label shown on hover or focus. Owns a DOM element.
Step by step
- 1
Add the main part
Start OpenToCloseChart with strictly increasing x values and explicit open and close labels.
- 2
Add the supporting parts
Render each range with OpenToCloseChartRange so the direction and both endpoints are keyboard reachable.
- 3
Make the behavior clear
Describe upward and downward movement with shape or position as well as color, and list both values in a native table.
Exampletsx <OpenToCloseChart values={prices} xLabel="Trading day" yLabel="Share price"> <ChartTitle>Opening to closing price</ChartTitle> <OpenToCloseChartPlot aria-label="Open-to-close chart showing trading days"> {(range) => ( <OpenToCloseChartRange range={range}> <line x1={range.x} x2={range.x} y1={range.openY} y2={range.closeY} /> </OpenToCloseChartRange> )} </OpenToCloseChartPlot> <ChartTable> <caption>Opening and closing prices</caption> </ChartTable> <ChartTooltip /> </OpenToCloseChart>;
Keyboard
- ⇥
- Enters the chart at its current range and leaves with one more Tab.
- →
- Moves to the next range without wrapping.
- ←
- Moves to the previous range without wrapping.
- Home
- Moves to the first range.
- End
- Moves to the last range.
- Esc
- Dismisses an open ChartTooltip.
Forms and accessibility
Charts are descriptive content and do not create form values.
Accessibility checklist
- Keep both axis labels visible and use the same formatters for x values, open values, close values, and the table.
- Wrap each range in OpenToCloseChartRange so its open and close values are one roving tab stop.
- Announce the explicit open and close labels and use shape or position as well as color for direction.
- Include both endpoints in a native table; ChartTooltip must not be the only source of exact values.
API reference
import { ChartDescription, ChartTable, ChartTitle, ChartTooltip, OpenToCloseChart, OpenToCloseChartPlot, OpenToCloseChartRange } from "@comp0/react";OpenToCloseChart
DOM elementNative figure sharing ordered opening and closing values with every part.
| Prop | Type | Description |
|---|---|---|
values | readonly OpenToCloseChartValue[] | Strictly increasing x values with finite open and close values. |
xLabel | string | Visible headings for time and value axes. |
yLabel | string | Visible headings for time and value axes. |
openLabel | string | Accessible and table labels for each endpoint. |
closeLabel | string | Accessible and table labels for each endpoint. |
formatX | (value) => string | Formatters shared by ticks and table cells. |
formatY | (value) => string | Formatters shared by ticks and table cells. |
ChartTitle
DOM elementNative figcaption that visibly names the figure.
OpenToCloseChartPlot / OpenToCloseChartRange
DOM elementOrdered SVG ranges with explicit open and close endpoints.
| Prop | Type | Description |
|---|---|---|
aria-label | string | Concise text alternative naming the series and period. |
yMin | number | Optional vertical bounds and tick count. |
yMax | number | Optional vertical bounds and tick count. |
yTickCount | number | Optional vertical bounds and tick count. |
children | (range: OpenToCloseChartRangeState) => ReactNode | Custom range renderer. |
range | OpenToCloseChartRangeState | Range state passed to the mark. |
ChartDescription
DOM elementVisible prose summarizing the movement.
ChartTable
DOM elementNative table with exact open and close values.
ChartTooltip
OptionalDOM elementOptional floating open/close pair label shown on hover or focus.
Style hooks
Attributes that appear while a state is true. Target them with Tailwind data variants such as data-open:bg-zinc-100, or with any CSS selector.
OpenToCloseChartPlot / OpenToCloseChartRange
| Style hook | Meaning |
|---|---|
[data-direction] | Whether close is up, down, or unchanged from open. |
[data-active] | The range currently reached by pointer or keyboard. |
ChartTooltip
| Style hook | Meaning |
|---|---|
[data-open] | A value tooltip is visible. |