Chart
Bars, a line, an area or a donut drawn to scale, with a tooltip, a legend, keys through the points and its data as a table.
Bars #
January to June
| Category | Desktop | Mobile |
|---|---|---|
| January | 186 | 80 |
| February | 305 | 200 |
| March | 237 | 120 |
| April | 73 | 190 |
| May | 209 | 130 |
| June | 214 | 140 |
export const ChartStyle = forSlots(ChartSlots)(Recipes.Chart({}))
/** A chart fills its container's width: the page gives it one. */
const chartFrame = <Message>(h: HtmlBuilder<Message>, chart: Html): Html =>
h.div([h.Style({ inlineSize: 'min(36rem, 100%)' })], [chart])
export const visitors = {
categories: ['January', 'February', 'March', 'April', 'May', 'June'],
series: [
{ name: 'Desktop', values: [186, 305, 237, 73, 209, 214] },
{ name: 'Mobile', values: [80, 200, 120, 190, 130, 140] },
],
}
// The lit point is the chart's Model, folded with `Chart.update`.
export const chartBar = <Message>(
style: NamedStyle<typeof ChartSlots>,
model: Chart.Model,
onMessage: (message: Chart.Message) => Message,
h: HtmlBuilder<Message>,
): Html =>
chartFrame(
h,
Chart.view(
{
id: 'preview-visitors',
label: 'Visitors',
description: 'January to June',
kind: 'bar',
...visitors,
model,
onMessage,
style,
},
h,
),
)A line #
| Category | Desktop | Mobile |
|---|---|---|
| January | 186 k | 80 k |
| February | 305 k | 200 k |
| March | 237 k | 120 k |
| April | 73 k | 190 k |
| May | 209 k | 130 k |
| June | 214 k | 140 k |
export const chartLine = <Message>(
style: NamedStyle<typeof ChartSlots>,
model: Chart.Model,
onMessage: (message: Chart.Message) => Message,
h: HtmlBuilder<Message>,
): Html =>
chartFrame(
h,
Chart.view(
{
id: 'line-visitors',
label: 'Visitors',
kind: 'line',
...visitors,
model,
onMessage,
format: value => `${value} k`,
style,
},
h,
),
)An area #
| Category | Sign-ups |
|---|---|
| Mon | 42 |
| Tue | 58 |
| Wed | 51 |
| Thu | 77 |
| Fri | 69 |
| Sat | 31 |
| Sun | 24 |
export const SmallChartStyle = forSlots(ChartSlots)(Recipes.Chart({ height: 'sm', grid: 'zero' }))
// One series: no legend, the title names it.
export const chartArea = <Message>(
style: NamedStyle<typeof ChartSlots>,
model: Chart.Model,
onMessage: (message: Chart.Message) => Message,
h: HtmlBuilder<Message>,
): Html =>
chartFrame(
h,
Chart.view(
{
id: 'area-signups',
label: 'Sign-ups',
kind: 'area',
categories: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
series: [{ name: 'Sign-ups', values: [42, 58, 51, 77, 69, 31, 24] }],
model,
onMessage,
style,
},
h,
),
)A donut #
| Value | |
|---|---|
| Chrome | 275 |
| Safari | 200 |
| Firefox | 187 |
| Edge | 173 |
| Other | 90 |
export const chartDonut = <Message>(
style: NamedStyle<typeof ChartSlots>,
model: Chart.Model,
onMessage: (message: Chart.Message) => Message,
h: HtmlBuilder<Message>,
): Html =>
chartFrame(
h,
Chart.view(
{
id: 'donut-browsers',
label: 'Visitors by browser',
kind: 'donut',
slices: [
{ name: 'Chrome', value: 275 },
{ name: 'Safari', value: 200 },
{ name: 'Firefox', value: 187 },
{ name: 'Edge', value: 173 },
{ name: 'Other', value: 90 },
],
totalLabel: 'Visitors',
model,
onMessage,
style,
},
h,
),
)Its data, shown #
| Month | Desktop | Mobile |
|---|---|---|
| January | 186 | 80 |
| February | 305 | 200 |
| March | 237 | 120 |
| April | 73 | 190 |
| May | 209 | 130 |
| June | 214 | 140 |
// The table assistive technology reads, shown for every reader.
export const chartTable = <Message>(
style: NamedStyle<typeof ChartSlots>,
model: Chart.Model,
onMessage: (message: Chart.Message) => Message,
h: HtmlBuilder<Message>,
): Html =>
chartFrame(
h,
Chart.view(
{
id: 'table-visitors',
label: 'Visitors',
kind: 'bar',
...visitors,
categoryLabel: 'Month',
table: 'shown',
model,
onMessage,
style,
},
h,
),
)A series keeps its color #
| Category | Mobile |
|---|---|
| January | 80 |
| February | 200 |
| March | 120 |
| April | 190 |
| May | 130 |
| June | 140 |
// Mobile names its color, so hiding Desktop does not repaint it.
export const chartColors = <Message>(
style: NamedStyle<typeof ChartSlots>,
model: Chart.Model,
onMessage: (message: Chart.Message) => Message,
h: HtmlBuilder<Message>,
): Html =>
chartFrame(
h,
Chart.view(
{
id: 'colors-visitors',
label: 'Mobile visitors',
kind: 'bar',
categories: visitors.categories,
series: [{ name: 'Mobile', values: [80, 200, 120, 190, 130, 140], color: 2 }],
legend: true,
model,
onMessage,
style,
},
h,
),
)Usage
Each example above names the function that drew it, over the theme module Create a theme writes. The preview passes it the style picked above instead of its default.