Data
A slat is a function of one row of your data.
That row arrives as d, so the slat reads d.name, d.value, and so on.
You can give a Plot its data in three ways, and mix them.
Lists, shared values and functions
Every prop you give a Plot is data for its slats, apart from the settings it already knows (order, key, reorder and the rest):
- Lists line up by position: the third name, the third number and the third picture belong together, and go to the third slat. The longest list sets how many slats there are.
- A single value is shared by every slat.
- A function of
druns once for each slat, and runs again when a value it reads changes, or when the Plot is given a new function.
import { Chart, Plot, Bar, Label } from "@bezda/rhp";
export default function Weather() {
return (
<Chart scale={[0, 30]}>
<Plot
// a list: each slat gets its own entry
city={["Oslo", "Rome", "Cairo"]}
temp={[6, 16, 27]}
// one value: shared by every slat
unit="°C"
// a function of `d`: worked out per slat
warm={(d) => d.temp > 15}
>
{(d) => (
<div>
<Label edge="start">{d.city}</Label>
<Bar to={d.temp} color={d.warm ? "negative" : "series-1"} />
<Label at={d.temp}>
{d.temp} {d.unit}
</Label>
</div>
)}
</Plot>
</Chart>
);
}Inside the slat, d.city, d.temp, d.unit and d.warm all read the same way.
d also has d.index (the row’s place in the data, from 0) and d.position (the slat’s place on screen once sorted).
Row objects
If your data is already a list of objects, one object per row, pass it as rows.
Each object becomes one row, and its fields are what the slat reads: d.city, d.temp and so on.
import { Chart, Plot, Bar, Label } from "@bezda/rhp";
const cities = [
{ city: "Oslo", temp: 6 },
{ city: "Rome", temp: 16 },
{ city: "Cairo", temp: 27 },
];
export default function Weather() {
return (
<Chart scale={[0, 30]}>
<Plot rows={cities}>
{(d) => (
<div>
<Label edge="start">{d.city}</Label>
<Bar to={d.temp} />
<Label at={d.temp}>{d.temp} °C</Label>
</div>
)}
</Plot>
</Chart>
);
}You can use rows together with lists and functions.
If a prop and a field have the same name, the slat reads the prop.
Adding and removing rows: keys
By default a slat is tied to a place in the list, not to a row: the first slat shows the first row, the second slat the second row. So if you remove the first city, every slat after it takes the data of the row below, and the whole chart shuffles.
Give the Plot a key, the field that identifies a row, and each slat follows its own city instead.
Removing a city now removes that city’s slat, and the others stay where they are.
import { createSignal } from "solid-js";
import { Chart, Plot, Bar, Label } from "@bezda/rhp";
const all = [
{ city: "Oslo", temp: 6 },
{ city: "Rome", temp: 16 },
{ city: "Cairo", temp: 27 },
{ city: "Lima", temp: 19 },
];
export default function Weather() {
const [cities, setCities] = createSignal(all);
const remove = (name) =>
setCities(cities().filter((c) => c.city !== name));
return (
<>
<div class="demo-controls">
<span>Click a bar to remove its city.</span>
<button onClick={() => setCities(all)}>Bring them back</button>
</div>
<Chart scale={[0, 30]}>
<Plot rows={cities()} key="city">
{(d) => (
<div>
<Label edge="start">{d.city}</Label>
<Bar
to={d.temp}
onClick={() => remove(d.city)}
style={{ cursor: "pointer" }}
/>
<Label at={d.temp}>{d.temp} °C</Label>
</div>
)}
</Plot>
</Chart>
</>
);
}key is a field name (key="city") or a function (key={(d) => d.id}).
Data that changes
Pass data that changes as a signal or a store, the way you would in any Solid app. The Plot reads it, and when it changes, only the slats and blocks that use the changed values update.
const [sold, setSold] = createSignal([12, 18, 7]);
<Plot fruit={fruits} sold={sold()}>{Fruit}</Plot>
setSold([12, 25, 7]); // one bar grows; nothing else is touched
For big lists that change one item at a time, a store is even lighter: setting one item re-runs just that slat.
Data that never changes
If a chart’s data is fixed (a report, a printed page, a chart in an article), add static to the Chart:
<Chart static scale={[0, 100]}>…</Chart>
Each slat is then drawn once and keeps nothing to watch for changes, so a big chart uses a fraction of the memory: about a sixth for 1,000 bars.
Hover styles, themes, resizing and the scale all still work.
If the data does change anyway, the chart draws all its slats again, without animation, so it’s never out of date.
Only the data you give the Plot is watched.
A function of d that reads some other signal, a hovered item for example, runs once and never again, so a chart that reacts to choices like that should not be static.
Helpers that turn raw numbers into what a chart needs
Some charts need their numbers prepared first, and rhp comes with small functions that do it.
For example, stackUp turns [8, 8, 8] into where each piece of a stacked bar starts and ends.
They’re all in the helpers reference.