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 row, written as a function of d, the row’s data.
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 row per number.
In each row, d.sold is that row’s number, and the Bar runs from 0 to it.
A row is always one element that holds everything drawn in it: here, a <div> around the Bar.
rhp stacks that element with the others and moves it when the rows are sorted, and the blocks inside it are placed by their values.
2. Names and numbers
Give the Plot a second list, fruit, and each row 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 rows 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 row its own look.
Its css is plain CSS for the classes in the row, and it only reaches this chart’s rows.
thickness sets each row’s height, and series() gives each row a color from the theme.
import { createSignal } from "solid-js";
import {
Chart,
Plot,
Bar,
Label,
slat,
sortBy,
series,
} from "@bezda/rhp";
const Row = slat(
{
thickness: 40,
css: `
.row: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="row">
<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")}
>
{Row}
</Plot>
</Chart>
</>
);
}A few things to notice in the CSS:
.row:hoverlights up the row 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.