Your first chart
We’ll draw how much fruit a shop sold today, in four steps.
1. Bars
A Chart sets the scale: here, from 0 to 30.
A Plot inside it gets the data.
Its child is the slat, written as a function of d, one row of the data.
Chart and Plot are two different components.
In everyday language, “plot” and “chart” are often used interchangeably, and that’s done here too: a bar chart, a box plot, a pie chart.
As components they have separate jobs.
A Chart is the frame, and it sets the scale, the direction, the axis and the theme.
A Plot is one stack of slats inside that frame, and every prop of it that is not a setting is a column of your data.
A Chart can hold more than one Plot, drawn over each other on the same scale.
import { Chart, Plot, Bar } from "@bezda/rhp";
export default function FirstChart() {
return (
<Chart scale={[0, 30]}>
<Plot sold={[12, 18, 7, 22]}>
{(d) => (
<div>
<Bar to={d.sold} />
</div>
)}
</Plot>
</Chart>
);
}sold is a list, so the Plot makes one slat per number.
In each slat, d.sold is its row’s number, and the Bar runs from 0 to it.
Every slat returns one DOM root.
Here, the stacking Plot needs a <div> around the Bar: rhp stacks and sorts the root as a full band, while the Bar inside it is placed and sized by its value.
A Plot with overlap, or a Scale, can use a single block as its root without a wrapper: see a slat’s element.
2. Names and numbers
Give the Plot a second list, fruit, and each slat gets its item as d.fruit.
A Label with edge="start" sits at the start of the chart, and one with at sits just past a value.
import { Chart, Plot, Bar, Label } from "@bezda/rhp";
export default function FirstChart() {
return (
<Chart scale={[0, 30]}>
<Plot
fruit={["Apples", "Bananas", "Cherries", "Kiwis"]}
sold={[12, 18, 7, 22]}
>
{(d) => (
<div>
<Label edge="start">{d.fruit}</Label>
<Bar to={d.sold} />
<Label at={d.sold}>{d.sold}</Label>
</div>
)}
</Plot>
</Chart>
);
}3. Data that changes
Keep the numbers in a signal, Solid’s box for a value that changes. When you set it, the chart updates: the bars grow or shrink.
order sorts the rows.
sortBy("sold", "desc") puts the largest first, and the slats slide to their new places.
import { createSignal } from "solid-js";
import { Chart, Plot, Bar, Label, sortBy } from "@bezda/rhp";
export default function FirstChart() {
const [sold, setSold] = createSignal([12, 18, 7, 22]);
const newNumbers = () =>
setSold(sold().map(() => Math.round(Math.random() * 30)));
return (
<>
<div class="demo-controls">
<button onClick={newNumbers}>New numbers</button>
</div>
<Chart scale={[0, 30]}>
<Plot
fruit={["Apples", "Bananas", "Cherries", "Kiwis"]}
sold={sold()}
order={sortBy("sold", "desc")}
>
{(d) => (
<div>
<Label edge="start">{d.fruit}</Label>
<Bar to={d.sold} />
<Label at={d.sold}>{d.sold}</Label>
</div>
)}
</Plot>
</Chart>
</>
);
}Nothing else is needed: no update calls, no redraws. The chart reads the signal, so it knows when the numbers change.
4. Style
slat() gives the slat its own look.
Its css is plain CSS for the classes in the slat, and it only reaches this chart’s slats.
thickness sets each slat’s height, and series() gives each slat a color from the theme.
import { createSignal } from "solid-js";
import {
Chart,
Plot,
Bar,
Label,
slat,
sortBy,
series,
} from "@bezda/rhp";
const Fruit = slat(
{
thickness: 40,
css: `
.slat:hover {
background: color-mix(in srgb, var(--rhp-ink) 8%, transparent);
border-radius: 8px;
}
.bar { --rhp-end-radius: 8px; }
.value { font-weight: 700; color: var(--rhp-color); }
`,
},
(d) => (
<div class="slat">
<Label edge="start">{d.fruit}</Label>
<Bar to={d.sold} color={d.color} class="bar" />
<Label at={d.sold} class="value">
{d.sold}
</Label>
</div>
),
);
export default function FirstChart() {
const [sold, setSold] = createSignal([12, 18, 7, 22]);
const newNumbers = () =>
setSold(sold().map(() => Math.round(Math.random() * 30)));
return (
<>
<div class="demo-controls">
<button onClick={newNumbers}>New numbers</button>
</div>
<Chart scale={[0, 30]}>
<Plot
fruit={["Apples", "Bananas", "Cherries", "Kiwis"]}
sold={sold()}
color={series()}
order={sortBy("sold", "desc")}
>
{Fruit}
</Plot>
</Chart>
</>
);
}A few things to notice in the CSS:
.slat:hoverlights up the slat under the pointer.--rhp-end-radiusrounds the bar’s end only. rhp reads a few variables like this one; they’re listed in Styling.var(--rhp-color)is the bar’s color, so the number matches its bar.