Skip to content

2.5.0 — series, pie, radar and heatmap charts, and a candlestick chart that asks for less - #5

Closed
CtrlAltDevelop wants to merge 10 commits into
mainfrom
feat/series-charts-2.5.0
Closed

CtrlAltDevelop wants to merge 10 commits into
mainfrom
feat/series-charts-2.5.0

Conversation

@CtrlAltDevelop

Copy link
Copy Markdown
Owner

One package for every chart an app draws. A balance over time, sign-ups per
month or a holdings breakdown had nowhere to go in a candlestick package, so an
app carried fl_chart beside this one — and the candlestick chart itself asked
for arguments most charts have no use for.

What this adds

SeriesChart — values against numbers rather than candles against time.
Lines with four curves (including a monotone one that never swings past a
peak), areas that fade to a baseline and never paint across it, bars that
group, stack or float between two values, and scatter with four dot shapes.
Plus error bars, a band between two lines, axes you write, name or hide, a
tooltip of your own, one crosshair shared across charts, a range strip for long
data, and animation between data sets. orientation: horizontal turns the
whole chart — curves, fills, gradients, crosshair and tooltip included — on its
side.

PieChart — a pie, a doughnut with a widget in its hole, or a ring gauge.
Sections are worth a share rather than an angle; each takes a colour or a
gradient, a label placed anywhere across it, a radius of its own, an offset
that explodes it, and a badge widget pinned to it.

RadarChart — a web of features with one outline per series, drawn as a
polygon or as rings, with ring values and a readout of the nearest corner.

HeatmapChart — a grid of squares coloured by value, from a matrix or from
sparse cells: a fading or a stepped colour scale, labels in the squares and
down both sides, a legend, and a readout for the square under the pointer.

The candlestick chartKChartWidget(candles, ChartColors()) is now a
whole chart: isTrendLine and timeFrame are optional, and with no
timeFrame the current-price tag drops its countdown and the one-second timer
that kept it ticking.

Requirements — runs on Flutter 3.27 and Dart 3.6 again instead of 3.47 and
3.13, and decimal and intl float rather than pinning the newest, so the
package resolves beside an app's own flutter_localizations.

Breaking changes

  • watermarkAssetPath is replaced by watermark, which takes any widget — an
    Image.asset, an icon, a line of text, or an SvgPicture in an app that
    still wants one. This removes flutter_svg as a dependency, so a chart
    passing watermarkAssetPath has to change: drop it, or pass the image as
    watermark.
  • timeFrame is now a Duration?, so code reading it back off the widget as
    non-null needs a fallback.

Testing

flutter analyze is clean and the suite is green at 977 tests, 46 test files
changed or added — including goldens for the series charts and unit tests for
the pure geometry behind the new widgets (layOutPie, pieSectionAt,
radarCorner, RadarLayout, HeatmapLayout, stackedBase).

Docs

Four new pages — series charts, pie,
radar, heatmap — plus
migrating from fl_chart and candlesticks,
which maps both packages' APIs onto this one with worked examples. Every new
screenshot is rendered by example/tool/screenshots.dart, so the pictures are
reproducible, and the README now presents the whole package as a three-column
gallery with each picture linking to the page that covers it.

CtrlAltDevelop and others added 10 commits September 14, 2026 10:52
…k as a widget

`KChartWidget(candles, ChartColors())` is now a whole chart. It used to need
three arguments most charts had no use for, and one of them tied every app to
`flutter_svg`.

### `isTrendLine` and `timeFrame` are optional

`isTrendLine` defaults to false, so the drawing tools stay off unless asked
for. `timeFrame` is a `Duration?`: given one, the current-price tag counts
down to the close as before; without one it reads just the price, and the
one-second timer that kept the countdown ticking is never started.

### The watermark is any widget — `watermark` replaces `watermarkAssetPath`

`watermarkAssetPath` took only an SVG asset, loaded through `flutter_svg`. The
new `watermark` takes any widget — an `Image.asset`, an icon, a line of text,
or an `SvgPicture` in an app that still depends on `flutter_svg` itself. It is
sized by `ChartStyle.watermarkScale` and placed by `watermarkAlignment` inside
the candle area, measured by the painter's own layout so the two cannot drift,
and painted in `ChartColors.watermarkColor`. A widget cannot be drawn inside
the painter, so it now sits faintly over the candles, ignoring touches, rather
than under them. `flutter_svg` is no longer a dependency.

BREAKING CHANGE: `watermarkAssetPath` is removed — pass the image as
`watermark` — and `timeFrame` is nullable, so code reading it back off the
widget needs a fallback.

The tests, the docs and the example lose the placeholder
`watermarkAssetPath: 'assets/none.svg'` lines, and the example's watermark is
a line of text instead of a bundled SVG.
The package asked for Dart 3.13 and Flutter 3.47, which shut out every app a
few releases behind, though nothing it draws needed them. The lowest Flutter
left is 3.27, the release that brought `Color.withValues` and `Color.a`, which
the chart uses throughout.

`decimal` is accepted from 3.0.0 and `intl` from 0.19.0 up to 0.21, instead
of only the newest of each, so the package resolves beside the `intl` an
app's `flutter_localizations` pins. The suite passes against both ends:
`flutter pub downgrade` (decimal 3.0.0, intl 0.19.0, rational 2.0.0) and
`flutter pub upgrade`. The example's own ranges are widened to match.

Reading under Dart 3.6 also means writing the two newer forms the older way.
Nine collection elements written `?value`, which needs Dart 3.8, are now
`if (value case final v?) v` — evaluated once and left out when null, so each
list is the same as before — and test callbacks that named two parameters
`_`, which needs 3.7, use `_, __`. Nothing changes in behaviour. Both halves
share one commit because each is wrong without the other: the older forms are
flagged under 3.13, and the newer ones do not parse under 3.6.
A balance over time, sign-ups per month or profit per trade had nowhere to go
in a candlestick package, so an app carried `fl_chart` beside this one.
`SeriesChart` reads any numbers against any numbers.

- `LineSeries` and `BarSeries`, from `SeriesPoint(x, y)` or plain values, with
  `null` for a gap; several at once, mixed.
- Lines joined `linear`, `smooth`, `monotone` (never swinging past a peak) or
  `step`; dashed, gradient-stroked, dotted per point, and split into
  `negativeColor` exactly where they cross their baseline.
- `SeriesFill`, which fades to the baseline and never paints across it, the
  lower half mirroring the upper gradient.
- Bars grown from a baseline, rounded on the far end, width fixed or a share
  of the slot held between a minimum and a maximum, grouped side by side, one
  draw call per colour.
- `SeriesXAxis` / `SeriesYAxis` that write, space or hide their labels,
  `SeriesGrid`, a plot border, reference lines and bands.
- A value range fitted to the x window in view, padded without crossing zero
  and widened to round ticks.
- Touch on press, long press, tap or hover, with a default tooltip or one
  built by the host and kept inside the chart; `onTouch` with every series'
  value; `SeriesChartController` to share one crosshair between charts.
- `SeriesRangeSelector`, a draggable window over long data.
- Animated data changes, including a grow-in on the first build.

Unit, widget and golden tests cover the fitting, the paths, the gestures, the
controller, the animation and the selector.
A third tab, Series, draws the four shapes a business app asks for: a
sparkline with a press tooltip, two series over a window of long data with a
range selector, a balance panel and a profit panel sharing one crosshair, and
a return line split at zero. A smoke test builds it at both layouts and in
both palettes.
…them

The control panel has grown past the 3000-pixel box the test lays it out in,
so "Add indicator" sat at y = 3132, off the screen, and the tap landed on
nothing — the sheet never opened and the test failed looking for its ATR chip.
Each control is now scrolled into view before it is tapped.
…icks

`doc/series-chart.md` covers `SeriesChart` part by part. The migration page
maps `fl_chart`'s line and bar APIs and `candlesticks`' widget, candle and
style onto this package's, with worked examples of a sparkline, a windowed
multi-series chart, two panels on one crosshair and a line split at zero. Both
are linked from the doc index, and the README gains a feature line.
`theming.md` called the drawing kinds seventeen; there are thirty, so it no
longer gives a number. `indicators.md` said sixteen indicators recompute in
full and fourteen resume, which is thirty of the thirty-one — seventeen
recompute in full.
…eries charts

An app that reached for this package still reached for another one to draw a
pie of its holdings or a radar of its scores, and `SeriesChart` could draw a
line and a bar but not a dot, a stack or a bar lying on its side.

`PieChart` draws a pie, a doughnut or a ring gauge: each section is worth a
share rather than an angle, takes a colour or a gradient, a label placed
anywhere across it, a radius of its own, an offset that explodes it and a
badge widget pinned to it, with a hole that holds a widget of its own.
`RadarChart` draws a web of features with an outline per series, as a polygon
or as rings. Both animate, both report what a touch landed on, and the
geometry both are laid out by — `layOutPie`, `pieSectionAt`, `radarCorner` and
`RadarLayout` — is public, so it can be tested or reused to place a widget.

`SeriesChart` gains what the other packages' bar and line charts have:
`ScatterSeries` with four dot shapes and a touch that snaps to the nearest
point rather than to an x; bar series that stack on each other, float between
two values, carry a border and label their far end; error bars on any series;
a fill between two lines; a step's position; a line shadow; axis titles and an
x axis that can sit above the plot.

The painter is rewritten to work in an x and a value rather than in screen
pixels, which is what lets `orientation: SeriesOrientation.horizontal` turn
the whole chart — curves, fills, gradients, crosshair and tooltip included —
on its side.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A table of numbers hides what a heatmap says at a glance: which hour of
which weekday is busy, which pair of instruments moves together, which
weeks of the year went quiet. The package could draw the line, the bar,
the pie and the radar, but not that.

It takes a matrix — rows of columns — or sparse `HeatmapCell`s where the
data has holes in it, and colours each square through a
`HeatmapGradientScale` that fades between colours or a `HeatmapStepScale`
that paints whole bands. The range is fitted from the cells, or pinned
with `minValue` and `maxValue`, which is what keeps two heatmaps beside
each other comparable.

Three decisions worth knowing about. A square with no cell is drawn
empty and still answers a touch, reporting a null value, because
"nothing happened here" is an answer rather than a missed tap. A label
inside a square is written in black or white by how dark that square is,
and is dropped when it will not fit rather than spilling over its
neighbour. `squareCells` holds the squares square, which is the whole
difference between a contribution graph and a row of coloured columns.

`HeatmapAxis` names the columns and the rows on either side, every nth
one when there is no room for all of them; `HeatmapLegend` draws the
scale as a bar; and `HeatmapLayout` is public, like the pie and radar
geometry before it, so where a square lands can be tested or reused to
put a widget on it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
One package for every chart an app draws. `SeriesChart` arrives for
values rather than candles — lines, areas, bars that group, stack or
float, scatter, error bars, a chart that can be turned on its side — and
with it `PieChart`, `RadarChart` and `HeatmapChart`, the three shapes an
axis cannot draw. The candlestick chart stops asking for two arguments
most charts have no use for, and drops the `flutter_svg` dependency with
the watermark that needed it. It runs on Flutter 3.27 and Dart 3.6 again,
so an app a few releases behind is not shut out.

The README now presents the whole package rather than a list: every
screenshot in a three-column gallery, grouped by what it draws, each one
linking to the page that covers it. CHANGELOG.md has the rest.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@CtrlAltDevelop
CtrlAltDevelop deleted the feat/series-charts-2.5.0 branch September 14, 2026 11:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant