PlLineChart
A value against time, or against anything else with an order to it. The line is the mark for change: it reads the space between two points as one movement rather than two separate facts.
import { PlLineChart } from 'plass-ui';
<PlLineChart
series={[{ name: 'Europe', data: [42, 45, 51, 49] }]}
categories={['Jan', 'Feb', 'Mar', 'Apr']}
/>;import 'package:plass_ui/plass_ui.dart';
PlLineChart(
series: const <PlassChartSeries>[
PlassChartSeries(
name: 'Europe',
data: <PlassChartDatum>[
PlassChartDatum(42), PlassChartDatum(45), PlassChartDatum(51),
],
),
],
categories: const <PlassChartCategory>[
PlassChartCategory.text('Jan'),
PlassChartCategory.text('Feb'),
PlassChartCategory.text('Mar'),
],
);Reach for a bar chart when the categories could be shuffled without losing anything: a line between two products draws a relationship the data does not have.
Everything around the line (the axes, the grid, the crosshair, the legend, the tooltip and what a screen reader gets instead of the picture) comes from a shared frame, which is what makes two different charts on one dashboard read as one drawing rather than two.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| series * | readonly PlassChartSeries[] | — | The data |
| categories | readonly PlassChartCategory[] | — | What the category axis says, when the points do not carry it themselves |
| curve | 'linear' | 'smooth' | 'step' | 'linear' | How the line gets from one point to the next. smooth is a monotone cubic and will not dip below a value both neighbours are above |
| markers | 'none' | 'auto' | 'all' | 'auto' | Dots on the points. auto stops at fourteen; whatever this says, the point under the pointer always gets one |
| connectNulls | boolean | false | Draws the line straight through a gap. A bridged gap is a number the chart made up |
| valueLabels | 'none' | 'last' | 'extremes' | 'all' | 'none' | Which values are written on the line. last is the one to reach for — where each series ended up |
| stacked | boolean | false | Stacks the series. Rare on a line chart and worth thinking twice about |
| gradient | boolean | false | Fades the line from a paler step of its own hue at the start to the full colour at the end |
| xAxis | PlassChartAxis | — | The category axis |
| yAxis | PlassChartAxis | — | The value axis |
| legend | PlassChartLegend | — | The legend |
| tooltip | PlassChartTooltip | — | The tooltip |
| height | number | string | — | How tall the plot is. Falls back to the size ladder |
| format | Intl.NumberFormatOptions | — | How a value is written. Passed straight to Intl |
| locale | string | — | BCP 47 tag deciding how numbers and dates are formatted |
| label | string | 'Chart' | What the whole drawing is called |
| empty | ReactNode | — | What is drawn when there is nothing to draw |
| sizeshared | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' | Type scale, plot height, line weight and marker radius |
| variantshared | 'solid' | 'glass' | 'ghost' | 'ghost' | The sheet the chart sits on. None by default: a chart is a drawing, not a sheet |
| Prop | Type | Default | Description |
|---|---|---|---|
| series * | List<PlassChartSeries> | — | The data |
| categories | List<PlassChartCategory>? | — | What the category axis says, when the points do not carry it themselves |
| curve | PlChartCurve | PlChartCurve.linear | How the line gets from one point to the next. smooth is a monotone cubic and will not dip below a value both neighbours are above |
| markers | PlChartMarkers | PlChartMarkers.auto | Dots on the points. auto stops at fourteen; whatever this says, the point under the pointer always gets one |
| connectNulls | bool | false | Draws the line straight through a gap. A bridged gap is a number the chart made up |
| valueLabels | PlassChartValueLabels | PlassChartValueLabels.none | Which values are written on the line. last is the one to reach for — where each series ended up |
| xAxis | PlChartAxis | PlChartAxis() | The category axis |
| yAxis | PlChartAxis | PlChartAxis() | The value axis |
| legend | PlChartLegend | PlChartLegend() | The legend. React's `legend={false}` is `PlChartLegend(hidden: true)` here, because Dart has no union type |
| tooltip | PlChartTooltip | PlChartTooltip() | The tooltip. Turning it off is `PlChartTooltip(hidden: true)` |
| height | double? | — | How tall the plot is. Falls back to the size ladder |
| format | String Function(double)? | — | How a value is written. A callback rather than Intl options, because the framework ships no Intl |
| semanticLabel | String? | 'Chart' | What the whole drawing is called |
| empty | Widget? | — | What is drawn when there is nothing to draw |
| sizeshared | PlassSize | PlassSize.md | Type scale, plot height, line weight and marker radius |
PlassChartSeries
| Prop | Type | Default | Description |
|---|---|---|---|
| data * | readonly PlassChartDatum[] | — | The values, in category order |
| name | string | — | Its name in the legend, the tooltip and the data table |
| color | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info' | (string & {}) | — | Overrides the palette slot. The one place in the library where a colour is not a semantic role |
| hidden | boolean | false | Starts the series hidden. An interactive legend is what turns it back on |
| Prop | Type | Default | Description |
|---|---|---|---|
| data * | List<PlassChartDatum> | — | The values, in category order |
| name | String? | — | Its name in the legend, the tooltip and the data table |
| color | Color? | — | Overrides the palette slot. The one place in the library where a colour is not a semantic role |
| hidden | bool | false | Starts the series hidden. An interactive legend is what turns it back on |
| id | String? | — | What identifies it. Defaults to its place in the list |
| dashed | bool | false | Draws the line dashed — a forecast, a target, a last year |
A datum is a bare number, a null, or a point that says more about itself. A null is a gap and never a zero, a sensor that was offline, a month that has not closed yet. A chart that renders missing data as zero reports an outage as a collapse.
data: [42, null, 51, { y: 49, label: 'Revised' }];data: const <PlassChartDatum>[
PlassChartDatum(42),
PlassChartDatum.gap(),
PlassChartDatum(51),
PlassChartDatum.point(PlassChartPoint(y: 49, label: 'Revised')),
],A closed union rather than React's number | null | object, which is what Dart gives instead of a union type.
What the shared axes mean across the library is in prop conventions.
Examples
curve
linear is the default and the only one that adds nothing to the data. smooth is a monotone cubic, not a plain spline: it is curved, but it will not dip below a value that both of its neighbours are above. A chart is allowed to be curved and it is not allowed to show a value that is not in the data. step is what a rate, a tier or a setting actually did between two readings, rather than a diagonal pretending it drifted.
Gaps
A null breaks the line. connectNulls bridges it instead, and it should stay off unless the gap is an artefact of how the data was collected rather than a period where nothing happened.
A point with a gap either side of it is drawn as a dot rather than dropped: it is a reading, and a reading with nothing to join to is still a reading.
valueLabels
last names where each series ended up, which is the question a line chart is usually being asked, and it is the setting that lets a chart drop its value axis entirely.
extremes writes the high and the low; all writes every one of them, and a chart with a number on every point is a table drawn badly.
The value axis leaves zero out
A line encodes a position, so cropping the scale moves every point by the same amount and the shape survives. A bar encodes a length, which stops meaning anything the moment it starts from 98, which is why a bar chart's axis includes zero and this one does not.
A series that lives between 98 and 99 is a flat line on a scale that begins at zero. Ask for one with the axis' own min.
<PlLineChart series={series} yAxis={{ min: 0 }} />Colour
The palette is eight hues in a fixed order, and it is the one place in the library where a colour is not a semantic role. A series is an entity (a region, a plan, a competitor), and nothing about it says success or danger.
Slots are handed out by a series' index in the array it was passed, never by its position among the ones currently visible: a reader who learned that Europe is blue has learned something a filter is not allowed to take back. A ninth series is not a ninth colour; it is an "Other" row, or a second chart.
The tokens are --plass-chart-1 through --plass-chart-8, and a project that must match a brand overrides them once rather than per chart.
Accessibility
- The whole drawing carries a name and, as its value, each visible series and where it ended up. The reading a sighted reader takes from the shape, rather than a cell-by-cell recital of the table.
- The legend is a row of real controls: each entry says whether its series is on, and pressing one switches it.
- A hovered legend entry dims the others rather than lighting its own, a chart whose hovered series changes colour is a chart whose legend lies for as long as the pointer is on it.
- The chart also renders a real
<table>of the data, visually hidden, which is what a screen reader reads instead of the picture.
- A tap leaves the tooltip up and a second tap on the same column takes it down. Clearing it on the release would be a tooltip a reader with no pointer never gets to read: on a touch screen the press and the release are a tenth of a second apart. A drag scrubs along the axis.