Chart your data
The Blotch Library has ready-made charts for showing numbers at a glance. They're drawn in black and white, and tell series apart with dashes and fill patterns instead of colors, so they stay readable on e-ink. They switch to light-on-dark by themselves when the Frame uses its dark theme.
import { LineChart } from "~lib/charts/line-chart";
export const Widget = () => <LineChart data={[12, 18, 15, 22, 30]} />;
Every chart is imported from ~lib/charts/<name>.
Choose a chart
| Chart | Good for |
|---|---|
LineChart | Trends over time, as a line. |
AreaChart | A line with the area below it filled. |
BarChart | Comparing values side by side, upright or on its side. |
Sparkline | A tiny trend line with no axes, to sit beside a number. |
BarIndicator | How far one number is towards another, such as storage used. |
DonutGauge | One number as a share of another, as a ring, such as battery level. |
PieChart | Parts of a whole. |
TreeMap | Parts of a whole, as nested rectangles sized by value. |
CandlestickChart | Open, high, low and close prices. |
ScatterPlot | Individual points, without a line joining them. |
Heatmap | Intensity across a grid, such as activity per day. |
ContributionGrid | A year of activity, a square per day. |
FunnelChart | Stages that narrow, such as sign-ups becoming customers. |
RadarChart | Comparing several measures at once. |
SankeyChart | Amounts flowing from one place to another. |
SurfaceChart | A 3D surface of values over a grid. |
Each one's page in the reference lists its props, with examples.
Charting fetched data
Charts take plain arrays, so turn the API's response into one with map. Because useFetch waits for the data before your Widget renders, there is nothing to check first:
import { LineChart } from "~lib/charts/line-chart";
import { useFetch } from "~lib/use-fetch";
type Reading = {
readonly time: string;
readonly temperature: number;
};
export const Widget = () => {
const { data } = useFetch<Reading[]>("https://api.example.com/readings");
return (
<LineChart
data={data.map((reading): [Date, number] => [
new Date(reading.time),
reading.temperature,
])}
axis={{ x: { visible: true }, y: { visible: true, name: "°C" } }}
width="100%"
height="100%"
/>
);
};
Sizing
width and height take a number of pixels (200) or any CSS size ("100%", "12rem"). To have a chart fill the space it is given, set both to "100%", which keeps it looking right as the Widget is resized.
A chart set to "100%" also fills its box in every preview of your Widget. Lines, areas and bars stretch to the box, while text, dots and patterns stay the same size. Round charts, such as PieChart and DonutGauge, keep their shape and grow or shrink to fit instead.