{chart}

Draws a chart as inline SVG on the server - 46 kinds, from bars and lines to sankeys, maps of a hierarchy and org charts.

Charts and codes Either form

Syntax

{chart 'bar', data='name', label='field', value='field, field', stacked, title='text', width=600, height=300}
{chart 'line', sequence='fibonacci', rows=12}
{chart 'pie', data='name', label='field', value='field'}
{chart 'scatter', data='name', x='field', y='field', size='field', color='field', trend}
{chart 'gauge', value=72, from=0, to=100, bands='60, 85', target=80, unit='%'}
{chart 'bar', label='field', value='field', type='csv'} ... {/chart}

Parameters

kind
The kind of chart: bar (or column), hbar, line, sparkline, pie, donut, scatter, bubble, heatmap, sankey, network, treemap, sunburst, gauge, radar, waterfall, histogram, boxplot, calendar, gantt, area, stream, multiples, candlestick, dual, spiral, rose, radialbar, funnel, pyramid, waffle, marimekko, parliament, venn, density, violin, bullet, rings, parallel, proportional, chord, arc, pack or orgchart.

Options

data
The rows: a {data} store, a sequence store, the page's array or a _data file of that name, or a literal (data='[3,1,4]'). Left out on a pair, the content is the data.
type
For a pair: the format of the content - json, yaml, xml or csv - when it is not to be recognised on sight.
sequence
Plot the first rows terms (default 10) of a sequence type instead of rows.
value
The field with the number - else the first numeric field. A comma list draws a series each (eight at most) for bar, hbar, line, area, stream, radar, rose, marimekko, pyramid and parallel. For a gauge it can be the number itself.
label
The field for the category axis or the names - else the first other field, else the row number.
title
The accessible name in the SVG's <title>; by default made from value and label.
width
The width in pixels, default 600 (round kinds 480, gauge 320, calendar 720).
height
The height in pixels, default 300 (round kinds 280, the tall kinds 400, gauge 200, calendar 150).
stacked
Bare option, bar, hbar and area: the series one on the other instead of side by side.
percent
Bare option, area: every column stacked to 100%.
x
Scatter, bubble, heatmap: the field of the horizontal axis (heatmap: the columns).
y
Scatter, bubble, heatmap: the field of the vertical axis (heatmap: the rows).
size
Bubble: the field that gives each dot its area.
color
Scatter, bubble, gantt, parallel: a field whose values colour the marks, with a legend.
trend
Bare option, scatter and bubble: adds the least-squares line.
source
Sankey, network, chord, arc: the field of where a link starts.
target
Sankey, network, chord, arc: the field of where a link goes. Gauge and bullet: the value (or field) marked as the goal.
layout
Network: force (default) or radial.
arrows
Bare option, network: draws the direction of the links.
levels
Treemap, sunburst, pack: the fields above the parts, outermost first.
from
Gauge: the start of the scale (0). Gantt: the field with the start of a task.
to
Gauge: the end of the scale (100). Gantt: the field with the end of a task. Radar, radialbar, rings, bullet: the end of the scale, a number (or for rings and bullet a field).
bands
Gauge and bullet: thresholds that split the track into coloured or grey steps ('60, 85').
unit
Gauge: written after the number.
total
Waterfall: the name of the closing bar (Total); total='' leaves it out.
bins
Histogram: about how many bins (10).
date
Calendar: the field with the day.
year
Calendar: draw the whole year instead of the span of the data.
progress
Gantt: the field with the part done, 0 to 100.
mark
Gantt: a date marked with a dashed line.
by
Multiples: the field that splits the rows into small charts.
columns
Multiples: the number of small charts side by side.
open
Candlestick: the field of the opening price (also high, low and close, each defaulting to its own name).
volume
Candlestick: a field of volumes drawn as light bars below.
line
Dual: the field drawn as a line on the right axis, beside the bars of value.
period
Spiral: rows to one turn (12).
turn
Spiral: the field that names each turn.
cells
Waffle: the number of squares (100).
sets
Venn: the field naming a set (A) or an overlap (A&B).
bandwidth
Density, violin: the width of the kernel, else Silverman's rule.
square
Bare option, proportional: squares instead of circles.
id
Orgchart: the field with a row's id.
parent
Orgchart: the field with the id of the row above.
sub
Orgchart: a field for the second line of a box.

Description

{chart} draws a chart as inline SVG on the server - no JavaScript, no image library and no remote service, so a chart works in print and in an e-mail and is cached like any other output. The first parameter is the kind, the options name the data and the fields to plot. An unknown kind is an error under the strict check (and is drawn as a bar chart without it).

Where the data comes from

data='name' names the rows: a {data} store, a sequence store, an array of the page's PHP or a file in _data/ - or a literal, data='[3,1,4]'. sequence='fibonacci' plots the first rows terms (10) of a sequence type. Written as a pair, without data or sequence, the content between the tags is the data - JSON, YAML, XML or CSV, recognised on sight as {data} recognises it, or named by type=. The content is taken as it stands before the level walks it, so the braces of JSON need no {ignore}, and the indent its lines share is taken off. A chart with no data at all is an error under the strict check.

The data option is not iterated: the chart is drawn once, from all rows. A field option left out takes the first field of the first row that fits - a numeric field for value, another for label. A row without a finite number is left out, and a chart without points writes nothing, so its @else@ shows.

The kinds and their options

  • Bars and lines - bar (column), hbar, line, area, stream, multiples, dual: label, value (a comma list draws a series each), stacked (bar, hbar, area), percent (area), by and columns (multiples), line (dual).
  • Parts of a whole - pie, donut, waffle (cells), funnel, pyramid, marimekko, parliament, treemap, sunburst, pack (levels), venn (sets), proportional (square).
  • Distributions - histogram (bins), boxplot, density and violin (bandwidth), scatter and bubble (x, y, size, color, trend), heatmap (x, y, value), parallel (color).
  • Measures - gauge (from, to, bands, target, unit - value=72 is the number itself, no data needed), bullet, rings, radialbar, radar, rose, waterfall (total).
  • Time - calendar (date, year), gantt (from, to, progress, color, mark), candlestick (open, high, low, close, volume), spiral (period, turn), sparkline.
  • Relations - sankey, chord, arc and network (source, target, value; network also layout and arrows), orgchart (id, parent, label, sub).

A kind reads only the options it draws with, so an option of another kind - stacked on a line chart - is an option nothing reads, which the strict check reports. The chart's options are named apart from the handling options every tag takes (rows, group, sort ...).

Size, colours and accessibility

The default size is 600 x 300; the round kinds are 480 x 280, the tall ones (sankey, network, treemap, radar, chord, pack, orgchart, parallel, multiples) 600 x 400. .pad-chart { max-width: 100%; height: auto } in the page's CSS lets a chart shrink with its column. The colours are CSS custom properties on .pad-chart - --pad-chart-series, --pad-chart-text, --pad-chart-grid, --pad-chart-surface, the slots --pad-chart-1 to -8 - with light and dark defaults that follow the page's color-scheme. The SVG has role="img", a <title> and a <desc> listing the values, and every bar, point or slice its own <title>, the tooltip on hover. {sparkline} is the word-sized line by its own name.

Examples

Bars from a page array

label= names the axis, value= the number; data= is an array of the page's PHP.

Templateexamples/chart/1-bar.pad
{chart 'bar', data='sales', label='month', value='amount', title='Sales per month', width=480, height=240}
PHPexamples/chart/1-bar.php
<?php

  $sales = [
    [ 'month' => 'Jan', 'amount' => 12400 ],
    [ 'month' => 'Feb', 'amount' =>  9500 ],
    [ 'month' => 'Mar', 'amount' => 14300 ],
    [ 'month' => 'Apr', 'amount' => 16100 ],
    [ 'month' => 'May', 'amount' => 15200 ],
    [ 'month' => 'Jun', 'amount' => 18750 ] ];

?>
Resultopen alone
Sales per month Jan: 12,400; Feb: 9,500; Mar: 14,300; Apr: 16,100; May: 15,200; Jun: 18,750 0 5,000 10,000 15,000 20,000 Jan Feb Mar Apr May Jun Jan: 12,400 Feb: 9,500 Mar: 14,300 Apr: 16,100 May: 15,200 Jun: 18,750

Two lines from a data block

A comma list in value= draws a line per field, each named at its end.

Templateexamples/chart/2-line.pad
{data 'visits'}
  [ { "day": "Mon", "desktop": 420, "mobile": 610 },
    { "day": "Tue", "desktop": 380, "mobile": 650 },
    { "day": "Wed", "desktop": 455, "mobile": 590 },
    { "day": "Thu", "desktop": 510, "mobile": 700 },
    { "day": "Fri", "desktop": 470, "mobile": 820 } ]
{/data}
{chart 'line', data='visits', label='day', value='desktop, mobile', title='Visits this week', width=480, height=240}
Resultopen alone
Visits this week Mon: Desktop 420, Mobile 610; Tue: Desktop 380, Mobile 650; Wed: Desktop 455, Mobile 590; Thu: Desktop 510, Mobile 700; Fri: Desktop 470, Mobile 820 Desktop Mobile 0 200 400 600 800 1,000 Mon Tue Wed Thu Fri Mobile Desktop Mon · Desktop: 420 Tue · Desktop: 380 Wed · Desktop: 455 Thu · Desktop: 510 Fri · Desktop: 470 Mon · Mobile: 610 Tue · Mobile: 650 Wed · Mobile: 590 Thu · Mobile: 700 Fri · Mobile: 820

A donut from a CSV data block

Parts of a whole: a legend with value and share, the total in the middle of a donut.

Templateexamples/chart/3-pie.pad
{data 'budget'}
  post,amount
  Rent,1200
  Food,450
  Transport,180
  Savings,300
{/data}
{chart 'donut', data='budget', label='post', value='amount', title='Monthly budget'}
Resultopen alone
Monthly budget Rent: 1,200 (56.3%); Food: 450 (21.1%); Transport: 180 (8.5%); Savings: 300 (14.1%) Rent: 1,200 (56.3%) Food: 450 (21.1%) Transport: 180 (8.5%) Savings: 300 (14.1%) 2,130 Rent 1,200 (56.3%) Food 450 (21.1%) Transport 180 (8.5%) Savings 300 (14.1%)

The data inside the pair

Without data=, the content between the tags is the data - here CSV, two series stacked.

Templateexamples/chart/4-pair.pad
{chart 'bar', label='quarter', value='online, shop', stacked, title='Orders per quarter', width=480, height=240}
  quarter,online,shop
  Q1,320,410
  Q2,380,390
  Q3,450,360
  Q4,610,420
{/chart}
Resultopen alone
Orders per quarter Q1: Online 320, Shop 410; Q2: Online 380, Shop 390; Q3: Online 450, Shop 360; Q4: Online 610, Shop 420 Online Shop 0 250 500 750 1,000 1,250 Q1 Q2 Q3 Q4 Q1 · Online: 320 Q1 · Shop: 410 Q2 · Online: 380 Q2 · Shop: 390 Q3 · Online: 450 Q3 · Shop: 360 Q4 · Online: 610 Q4 · Shop: 420

See also

  • {sparkline} Draws a word-sized line chart as inline SVG - no axes, the last point marked - to stand in a sentence or a table cell.
  • {map} Draws a choropleth map as inline SVG - every country coloured by a value of its row - of the world or one of its regions.
  • {timeline} Draws events on a time axis as inline SVG - cards above and below the axis, spans as bars, or one under the other.
  • {diagram} Draws a flowchart or a sequence diagram from Mermaid-style lines of text, laid out on the server as inline SVG.
  • {data} Turns its content - JSON, XML, YAML, CSV, a list or a range - into a named data set for a later tag to iterate.
  • {sequence} Generates a range, a list or one of 80 mathematical sequences, and iterates its values.