Scales and axes
The scale
scale on the Chart sets the range of values it shows, as [min, max].
Every block in every Plot of the chart uses it.
<Chart scale={[0, 100]}>…</Chart>
<Chart scale={[-40, 40]}>…</Chart> // negative values run the other way
<Chart scale={[0, Math.max(...values())]}>…</Chart> // a scale that follows the data
When the scale changes, everything on it moves together. A Bar that runs past the scale is cut at its end; dots and labels are drawn where their values are.
The axis
The Chart draws an axis on its own: grid lines with numbers.
tickspicks the lines: a list ([0, 25, 50, 75, 100]), a rough count (5), orfalsefor none.formatturns a value into its text:(v) => v + "%".
import { Chart, Plot, Bar, Label } from "@bezda/rhp";
export default function Battery() {
return (
<Chart
scale={[0, 100]}
ticks={[0, 25, 50, 75, 100]}
format={(v) => v + "%"}
>
<Plot device={["Phone", "Laptop", "Watch"]} charge={[64, 38, 91]}>
{(d) => (
<div>
<Label edge="start">{d.device}</Label>
<Bar to={d.charge} />
<Label at={d.charge}>{d.charge}%</Label>
</div>
)}
</Plot>
</Chart>
);
}Drawing the scale yourself
For a scale that looks different (dashed lines, numbers in a pill, bands between ticks), put a Scale in the Chart.
A Scale is a Plot of ticks: its row is drawn once per tick, and gets d.at, the tick’s value.
import { createSignal } from "solid-js";
import {
Chart,
Scale,
Plot,
Bar,
Tick,
Label,
slat,
every,
} from "@bezda/rhp";
// The scale is drawn by a slat too: one per tick, a dashed line and a
// number
// under the plot.
const Mark = slat(
{
room: { after: 22 },
css: `
.line {
--rhp-tick-width: 1px;
background: none;
border-left: 1px dashed var(--rhp-grid);
}
.number {
top: calc(100% + 6px);
translate: -50% 0;
--rhp-label-gap: 0px;
color: var(--rhp-muted);
font-size: 11px;
}
`,
},
(t) => (
<div>
<Tick at={t.at} thick={1} class="line" />
<Label at={t.at} class="number">
{t.at}
</Label>
</div>
),
);
export default function Rainfall() {
const [max, setMax] = createSignal(60);
return (
<>
<label class="demo-controls">
Scale up to {max()} mm
<input
type="range"
min="40"
max="120"
step="5"
value={max()}
onInput={(e) => setMax(+e.target.value)}
/>
</label>
<Chart scale={[0, max()]}>
<Scale ticks={every(10)}>{Mark}</Scale>
<Plot month={["May", "June", "July"]} rain={[38, 24, 11]}>
{(d) => (
<div>
<Label edge="start">{d.month}</Label>
<Bar to={d.rain} />
</div>
)}
</Plot>
</Chart>
</>
);
}A Scale row also gets:
d.next, the next tick’s value, to fill the space between two ticks,d.firstandd.last, true at the two ends,d.toEnd, how far the tick is from the end of the scale in pixels, to leave out a number that would crowd the end.
every(10) gives a tick at each multiple of 10.
every(10, { ends: true }) adds the scale’s two ends as ticks.
A Chart with a Scale in it draws no axis of its own.