NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
pub.dev
The full-featured open-source Flutter charting system. Fourteen native chart families with multi-axis, live streaming, crosshair tracking, annotations, and typed grammar.
Last release 1 months ago
12 Aug 2026
Ships on a steady schedule
a new release about every 8 days
Nearly every release is documented
notes for 29 of 29 stable releases
Nothing withdrawn
no release was ever pulled
2 months old
30 releases · first in 2026
One column per month.
A native Radar and Spider chart family with polygon and circular webs, configurable category axes and labels, per-series fill, gradient, stroke, marke
tension:, dataPointMarkerRadius:, dataPointMarkerStyle:,
dataPointMarkerBackground:, lineGlow:, inlineLabel: and
pathAnimation: on BravenChart.geomLine() and geomArea(), plus
fillGradient:, aboveBaselineFillColor: and belowBaselineFillColor: on
geomArea(), and fillGradient: + pathAnimation: on geomRangeArea().
Each lowers to the matching ChartSeries field and is reversed back into
generated Dart source. Every one is nullable on the mark and null means the
series default, resolved once at lowering, so the mark cannot carry a stale
copy of one; the reversal maps a captured value equal to that default back to
null, so a chart that sets none of them emits exactly the source it emitted
before. A configured Line, Area or Range-Area chart is no longer refused for
any of these fields — the RangeAreaChartsPage went from 0 to 6 of its 7
presets emitting, and the whole-showcase emission census from 59 to 75.Restored the declared Flutter 3.35 floor. flex_color_picker was constrained to ^3.8.0, whose only release requires Flutter >=3.38.0, so version solvin
flex_color_picker was constrained
to ^3.8.0, whose only release requires Flutter >=3.38.0, so version
solving failed outright for every consumer on Flutter 3.35, 3.36, or 3.37 —
the package could not be installed across part of the range it advertised.
The constraint is now ^3.7.2, which still resolves to the latest release on
current Flutter and falls back to 3.7.2 on older toolchains.Per-series showInTrackingTooltip control. Set it to false to omit the complete series row from the crosshair tracking panel while preserving the rende
Per-series showInTrackingTooltip control. Set it to false to omit the
complete series row from the crosshair tracking panel while preserving the
rendered series, tracked snapshot, intersection markers, selection, and
independently configured axis-side tracking labels.
A measure unit on the Cartesian grammar marks: unit: on
BravenChart.geomLine(), geomArea(), geomBar(), geomPoint() and
geomCandlestick(), carried onto the lowered ChartSeries.unit and reversed
back into generated Dart source. A config-authored Cartesian chart whose
series declares a unit is no longer refused for it.
SeriesMark<T>, a sealed intermediate between Mark<T> and the six mark
families that lower to a series — the five Cartesian ones plus RadialMark —
declaring unit once for all of them. TrendMark, ThresholdMark,
BandMark and PointMark stay on Mark<T>: they lower to annotations,
which have no unit, so they structurally cannot carry one. Existing code is
unaffected; unit remains readable on every radial mark exactly as before.
Per-point metadata on the four Cartesian geometry marks: label: and
pointKey: on BravenChart.geomLine(), geomArea(), geomBar() and
geomPoint(). Both are accessors (String? Function(T)) carried onto
ChartDataPoint.label and ChartDataPoint.pointKey, and both are reversed
back into generated Dart source. An empty string means "this point has none",
which is what lets a partially labelled or partially keyed series round-trip.
A duplicatePointKey Grammar diagnostic: a pointKey accessor that yields
the same key for two rows of one mark is refused by name rather than lowering
to a series whose selection identity is ambiguous. The Cartesian counterpart
of duplicateRadialCategory.
isXOrdered: on BravenChart.geomLine(), geomArea(), geomBar() and
geomPoint(), carried onto ChartSeries.isXOrdered and reversed back into
generated Dart source. It is a DECLARATION, never inferred from the data:
a chart that does not declare it stays unordered even when its rows happen to
arrive sorted, so nearest-point behaviour cannot change underneath an
existing chart. geomCandlestick() does not take it —
CandlestickChartSeries is ordered by its own contract.
A named refusal for a per-point segmentStyle, in two sentences because it is
two boundaries. A style setting strokeWidth or dashPattern is reported as
one "no V1 … mark carries"; a COLOUR-ONLY style is reported as a per-point
segment colour that a chain paints from colorBy + colorEncoding, which the
reverser cannot recover from the baked colours. Either way it beats falling
into the generic "does not reproduce exactly" sentence. The style is
deliberately not carried yet: it needs a row-field kind the synthesised rows
do not have, and it shares its slot with LineMark.colorBy, which already
bakes segmentStyle.color per point.
Generated Dart source now reverses the LEGACY SINGLE-AXIS chart: a
BravenChartPlus built the ordinary way — a widget-level yAxis and no
per-series binding — emits a BravenChart chain instead of being refused
with the axis sentence. Only a chart that binds SOME series and not others
still reaches that refusal — an all-unbound chart refused for some OTHER
reason is no longer told to change a binding that was never the problem.
A Range Area grammar geometry: BravenChart.geomRangeArea(low:, high:),
lowering to a real RangeAreaChartSeries and reversed back into generated
Dart source. low/high are nullable accessors — returning null from both
at a row expresses a gap (RangeAreaDataPoint.gap); returning null from
exactly one raises incompleteRangeAreaInterval. The mark carries the
range-area-native fields (interpolation, tension, fill opacity, border mode,
both boundary styles, gap connection, boundary markers, marker radius, label
configuration and hit-test mode); fillGradient and pathAnimation are not
carried and a band using either is refused by name rather than emitted
without it.
Collision-aware Cartesian series callouts through SeriesCalloutConfig and
per-series SeriesCalloutSpec overrides. Line and Area charts can place
stable connector-backed labels in a shared bounded lane, choose
follow-anchor or compact packing, prioritize dense labels, and configure
label, connector, glow, and content-sized lane-panel presentation without
changing legend, selection, or tracking participation. The complete portable
configuration round-trips through artifacts, hydration, JSON, generated
Config Dart, fluent APIs, and AI surface definitions; typed Chart Grammar
reports its current callout limitation explicitly.
BravenPlot mounts a single-axis chain as the legacy single-axis chart.
When a spec declares exactly one Y axis and no mark names it, the axis now
reaches BravenChartPlus as a widget-level yAxis with the series left
unbound, instead of as an inline yAxisConfig on every series. This is what
makes a chain and the config chart it reverses to the SAME chart rather than
merely similar ones.
Rendering asks two different questions here, and they have different answers. Read both before upgrading.
A chain reversed from a config chart renders identically: no change.
Both mounts tint the Y-axis tick and axis labels with the series colour —
an axis takes its colour from the first series bound to it, and a
widget-level axis has the chart's unbound series bound to it at render time
— so the change is not visible. Verified in pixels rather than argued:
eight chart shapes rendered at a fixed 600x400 host and compared as raw
RGBA, each against the config chart it claims to be, all 0 of 240,000
pixels differing (test/widgets/braven_plot_pixel_parity_test.dart). The
shapes are: no widget-level axis; a labelled axis; an axis declaring min
and max; an axis the author named; a two-axis chart (the mount this must
not touch); and the three authored-spec forms of the same. Earlier releases
of this entry claimed the labels turned grey. That was wrong in both
directions and is retracted: the tinting is what the legacy mount
preserves, and the grey it described was a separate defect, now fixed (see
below).
An AUTHORED PlotSpec or BravenChart chain CHANGES appearance for six
shapes. The zeroes above compare two charts that both exist after this
release; they say nothing about what an existing grammar chart drew
before it. Where a spec declares one Y axis that no mark binds to, that
chart is now the legacy chart — and the legacy chart honours axis settings
the previous mount dropped. Measured by reverting
lib/src/grammar/braven_plot.dart and
lib/src/rendering/modules/multi_axis_manager.dart to the previous
release, capturing every shape at the same 600x400 host, and differencing
the frames:
| authored single-axis shape | pixels changed (of 240,000) | in the plot area | filed under |
|---|---|---|---|
axis declares min AND max |
25,885 | 20,770 | Fixed |
min only |
25,126 | 20,284 | Fixed |
max only |
23,196 | 17,854 | Fixed |
scaleType: AxisScaleType.log |
11,948 | 11,745 | Fixed |
position: YAxisPosition.hidden |
9,721 | 8,532 | Changed |
visible: false |
9,721 | 8,532 | Changed |
| no axis declared | 0 | 0 | unchanged |
| a plain labelled axis | 0 | 0 | unchanged |
| an axis the author named | 0 | 0 | unchanged |
"In the plot area" counts the differing pixels outside the 80-column
Y-label gutter. Every row is asserted — both the parity zero and the size
of the before/after change — by the mount divergence table in
test/widgets/braven_plot_pixel_parity_test.dart, which reproduces the
previous mount in process, so this list cannot go stale unnoticed. The four
Fixed rows are described under Fixed below; the two hidden ones are
the next bullet.
A hidden or invisible single Y axis no longer draws horizontal grid
lines. position: YAxisPosition.hidden and visible: false hide the
axis on either mount, and both mounts lay the plot area out identically;
what changed is that the previous mount kept drawing the hidden axis'
horizontal grid and the legacy chart does not. That accounts for the whole
difference, measured by removing the thing at issue: with
GridConfig(horizontal: false) the two mounts draw the byte-identical
frame. Unlike the four rows above this is a behaviour change rather than a
fix — neither mount was ignoring what the author asked for — so it is
called out here rather than under Fixed.
Extracted documents. BravenChartController.extractDocument() on a
single-axis chain no longer sets series[*].axisId or
series[*].inlineAxis; the axis appears once, in axes. Hosts that
persist or diff these documents will see the shape change. It is a fix, not
a new capability: the document now matches the config chart's.
Four shapes are DECLINED and keep the multi-axis mount verbatim: a chart with
several declared axes; a one-axis chart whose mark names its axis (the author
asked for the multi-axis path); a BravenFacetPlot panel, because faceting
delivers the shared range FacetScales.fixed computes through an inline axis
config and a widget-level axis applies min/max where an inline one does
not, so re-mounting a panel would change what every faceted chart draws; and
any chart carrying a series family that cannot express an unbound series
(everything outside the five Cartesian families), which keeps the multi-axis
mount for the whole plot rather than mounting half of it. A radial spec
lowers to no Y axis at all and never reaches this shape.
An axis carrying min/max is NOT declined, although the two mounts do
disagree about it — only a widget-level axis applies the range to the Y
domain. Declining it was measured and rejected: it changes no emitter
refusal anywhere in the suite, and it makes the reversed chart differ from
the chart it was reversed from by 25,885 of 240,000 pixels, 20,770 of them in
the plot area. The reasoning is recorded in _legacySingleAxisSeries. That
is the same 25,885 pixels an upgrading authored chart sees, disclosed as a
fix below — this paragraph is about why an alternative mount was rejected,
and is not where the user-facing change is published.
An authored single Y axis' min/max was silently ignored. A
PlotSpec or BravenChart chain whose one Y axis declares min, max or
both, and whose marks do not bind to it, reached the chart only as an inline
per-series yAxisConfig — and the inline path never applies a range to the
Y domain. It was not a weaker range, it was no range: measured under the
previous mount, an axis with min: 100, max: 300 drew the byte-identical
frame to the same axis carrying none, and so did min-only and max-only.
The axis now reaches the chart as a widget-level yAxis, which applies it,
and the authored chart draws exactly what the equivalent config chart draws.
Charts relying on the old behaviour will see the plot area move: 25,885 of
240,000 pixels for min and max, 25,126 for min only, 23,196 for max
only, at a 600x400 host.
An authored single Y axis' scaleType: AxisScaleType.log drew log tick
labels over a LINEAR plot. BravenChartPlus takes the Y scale type from
its widget-level axis — widget.yAxis?.scaleType ?? AxisScaleType.linear in
braven_chart_plus.dart — and the previous mount never set one, so the data
was mapped linearly while the axis renderer, reading the inline config,
labelled the ticks logarithmically. The chart was not merely linear, it was
mislabelled. Measured: under the previous mount a log axis' plot area is
byte-identical to a plain linear chart's, and the only difference between
them is 3,996 pixels of relabelled gutter. The data is now mapped on the
scale that was asked for — 11,948 of 240,000 pixels against the old chart,
11,745 of them in the plot area. Both halves are asserted in
test/widgets/braven_plot_pixel_parity_test.dart.
A widget-level yAxis carrying an id of its own had nothing bound to it.
A series that declares neither yAxisId nor an inline yAxisConfig is bound
to the chart's primary axis, but that binding named the auto-generated id
'primary_axis' literally — and that id exists only when the widget-level
axis carries none. Give the axis any id and every series pointed at an axis
the chart did not have, leaving the chart's only axis unbound: axis bounds
fell through to the 0..100 no-data fallback for a chart that plainly has
data, and the tick and axis labels dropped from the series colour to the
#333333 default. Reachable three ways — a BravenChartPlus whose
widget-level yAxis was built with YAxisConfig.withId; every hand-written
PlotSpec, because lowering stamps 'axis-0' on an axis that declares no id
(including the axis it invents for a spec with no yAxes at all); and a
generated chain, because extraction stamps 'y'. The grammar shapes were
measured at 4,658 and 5,378 of 240,000 pixels against the config chart they
claim to be, all of it in the Y-label gutter; both are now 0. A chart whose
series carries an inline yAxisConfig is deliberately unchanged: the
widget-level axis is suppressed there, so an unbound series in that chart
stays unbound rather than silently adopting another series' axis and scale.
showInLegend: false now removes the complete series entry from every
built-in legend path, including reusable ChartLegend widgets and explicit
canvas LegendAnnotations, rather than only affecting automatically
generated legends.
A live Range Area band with a label formatter produces generated source at
all. RangeAreaLabelConfig.formatter and the nested
labelConfig.labels.formatter are both refused by the document codec as
runtime-owned, and the source capture adapter had no Range Area arm to strip
them first — so extracting a chart carrying either failed outright with
runtime_binding_required and the Source tab showed NOTHING. Both
are now stripped to a placeholder with a runtime_binding_required capture
warning naming $.series.<id>.labelConfig.formatter or
$.series.<id>.labelConfig.labels.formatter, which is the treatment Line,
Area, Scatter and Bar label formatters already had.
The config emitter also gained a // formatter: placeholder and a
source_runtime_value_omitted warning for RangeAreaLabelConfig.formatter.
That branch is defensive parity with the identical branch on the data-point
label config, and like that one it is unreachable through
ChartDartSourceGenerator / ChartGrammarSourceGenerator: capture strips the
formatter before the emitter ever sees it. It fires only for a caller driving
ChartConfigDartEmitter directly. The user-visible fix is the capture arm
above, not the placeholder.
HeatmapDataPoint keeps X, Y,
and the independently measured colour value in one typed cell, while
HeatmapDataPoint.missing preserves explicit matrix positions without
encoding absence as zero or NaN.HeatmapColorScale with validated sequential, diverging, and threshold
mappings, automatic or explicit domains, semantic midpoint, palette
reversal, clamping, missing-cell colour, formatter descriptors, and a
reusable HeatmapColorLegend.HeatmapColorLegendGroup presents and controls the visible colour axes in a
compact horizontal or vertical surface.HeatmapChartSeries cell geometry, gaps, borders, corners, density-aware
contrast labels, typed hit identity, hover/tap selection, keyboard
row/column traversal, bounded dense-matrix semantics, Cartesian zoom/pan,
X/Y scrollbars, and ordinary chart annotations.HeatmapSelectionExpansion policies for touched cells, complete
source rows, or complete source columns and a dedicated live review preset.HeatmapCellBounds for unequal axis-aligned cells. Explicit
rectangles now drive data extents, indexed viewport culling, painting, hit
testing, semantics, selection, artifacts, generated Dart, AI configuration,
and lossless Workbench Data fields without changing the regular-grid path.HeatmapTileSource,
HeatmapMatrixDomain, and HeatmapViewportController. Hosts can load only
the regular matrix tiles needed by the current viewport, use bounded
overscan and deterministic LRU caching, reject stale asynchronous results,
and publish an ordinary immutable Heatmap snapshot without adding source
fetching to the render loop. Workbench Data, Split, Source, capture, and
artifacts intentionally describe the current resident snapshot.Per-series showInLegend and showTrackingAxisLabel controls. Authors can independently omit a rendered series from automatic legends or suppress its tr
showInLegend and showTrackingAxisLabel controls. Authors can
independently omit a rendered series from automatic legends or suppress its
tracking-axis value labels without removing it from tracking snapshots,
tooltips, selection, or the chart. Both flags default to true and
round-trip through every concrete family, copyWith, JSON, artifacts,
generated Dart source, fluent APIs, and AI surface definitions.PieMark.sliceColor and
DonutMark.sliceColor, with sliceColor: on BravenChart.geomPie() and
geomDonut(), mirroring PolarMark.columnColor. A null return leaves that
category on the series colour, and a concentric composition resolves the
channel per ring bucket.DonutMark: dataLabelsByRing, keyed by the bare ring
key, with dataLabels as the base, and ringIds, giving each ring an
explicit series id so a composition whose ids are decoupled from its ring
names round-trips. Both are exposed on BravenChart.geomDonut().unknownRingKey,
partialRingIds, and perRingOverrideOnRinglessDonut.DonutCenterContent verbatim — labelStyle and valueStyle included — so a
styled centre emits rather than being refused, and a live valueFormatter
emits as a // valueFormatter: placeholder with a runtime-value-omitted
warning. Output is byte-identical for every shape that already emitted a
chain: Cartesian, polar, and pie/donut/concentric charts with no per-slice
colours, uniform ring labels, conforming ring ids and a default centre.import 'package:braven_charts/braven_charts.dart'; and
import 'package:flutter/material.dart';, and TooltipTriggerMode is
declared in both libraries, so triggerMode: TooltipTriggerMode.<mode> was
ambiguous_import — the copied source parsed, read correctly and did not
compile. The material import is now written as
import 'package:flutter/material.dart' hide TooltipTriggerMode; whenever
the emitted body uses that name. Charts that do not emit an ambiguous name
are byte-identical; for those that do, the only change is that one import
line.GrammarDiagnosticCode gained three further enum values (listed under
Added), on top of the six added in 0.15.0. They are declared beside the
radial codes they belong with rather than appended, so the ordinals of the
values after them shifted again. The breakage is confined to compile time: an
exhaustive switch over GrammarDiagnosticCode with no default or wildcard
case will stop compiling until the new codes are handled. Nothing serialises
the enum, and chart artifacts and documents encode every enum by NAME rather
than by ordinal, so persisted documents still load unchanged and the runtime
behavior of existing code is unaffected.PointStyle carrying more than a colour and a size, and a concentric
composition that breaks one of the ring preconditions. A concentric
composition emits only when every ring shares one donutStyle, one
selectionStyle, one unit, one sliceRadiusConfig and one
sliceGroupingConfig, carries no series color of its own, carries no
centre of its own, and has a distinct, non-empty name — DonutMark holds one
of each for the whole composition, and the ring lowering never carries a
per-ring color. Sharing a NON-DEFAULT value is fine; it is divergence that
is refused. Of these, the ring name and the ring centre are refused with a
reason of their own; the five config divergences and the ring colour are
refused by the round-trip proof's catch-all and are not yet named. The pie
and donut showcase pages emit with isComplete == false, for live formatter
callbacks that have no literal form — the pie with ONE runtime-value-omitted
warning covering its two radial label formatters, the donut with TWO, one for
its centre valueFormatter and one for its two radial label formatters. Full
detail is in doc/chart_grammar.md.Three production-shaped Radial Bar Gallery compositions covering target progress, signed values around a shared baseline, and dense collision-aware ca
geomPolar marks sharing one angular and one radial axis, covering layered,
grouped, and stacked compositions, and PolarMark gained the advanced
channels columnColor, target, targetMarkerStyle, intervalLow,
intervalHigh, intervalStyle, and preset (including the area-correct
rose presentation). The chain verb BravenChart.geomPolar() exposes the same
channels, with the preset as the rose flag.PlotSpec.polar and the
BravenChart.polarConfig() verb, forwarding a PolarChartConfig to every
polar mark in the plot. A misplaced .polarConfig(...) is diagnosed rather
than silently discarded. Like grid, title, subtitle and the legend
toggle, the config is a SPEC-level option, so BravenPlot also forwards it
on the empty-data path: a polar chain built over an empty dataset renders
its empty state inside the authored pane rather than a default one. Cartesian
charts are unaffected — a non-polar spec carrying a config is refused by
polarConfigOnNonPolarSpec, which runs above the empty-data guard, so it
still falls through to the const default.DonutMark.concentric and BravenChart.geomDonut(concentric: ...), carrying
ring gap, radial order, ring weights, legend mode, pane radii, and the shared
center into the Grammar, with the ring-series keying rules stated on the API.polarConfigOnNonPolarSpec, invalidPolarComposition,
incompletePolarInterval, conflictingConcentricCenter,
concentricConfigOnRinglessDonut, and invalidConcentricComposition..polarConfig(...), and non-default
ConcentricDonutConfig ring geometry into Grammar chains instead of
refusing them. Output is unchanged for Cartesian, pie, donut, concentric
donut with default ring geometry, and single-series polar with a default
PolarChartConfig and no advanced channels — the shapes that already
emitted a chain.multipleRadialGeoms is now raised only when the several radial geoms are
not all geomPolar, and its message names polar columns as the one
exception to "at most one radial geom". Two pies, or a pie alongside a donut
or a polar column, are still rejected exactly as before.GrammarDiagnosticCode gained six enum values (listed under Added). They are
declared beside the radial codes they belong with rather than appended, so
the ordinals of the values after them shifted. The breakage is confined to
compile time: an exhaustive switch over GrammarDiagnosticCode with no
default or wildcard case will stop compiling until the new codes are
handled. Nothing serialises the enum, and chart artifacts and documents
encode every enum by NAME rather than by ordinal, so persisted documents
still load unchanged and the runtime behavior of existing code is
unaffected.BravenChart,
PlotSpec, marks/channels, and braven_charts_fluent.dart) remain Beta /
experimental and may change before a stable release. Pin a version if you
depend on them.sliceColors) is still refused by the Grammar source emitter, because
PieMark and DonutMark have no per-point colour channel — only PolarMark
does, through columnColor. A concentric composition whose rings carry
different dataLabels is refused for the same class of reason: one
DonutMark holds one dataLabels for every ring it splits into. Both are
named diagnostics, never a silently different chart. Full detail, including
which showcase pages this leaves blocked, is under Known gap in
doc/chart_grammar.md.First-class Gauge and Solid Gauge charts with needle and solid modes, operational zones, targets, reference markers, configurable polar panes, center
/guides/, with stable
deep links, generated navigation, responsive tables of contents, source and
runnable-example links, and release-artifact validation.CrosshairConfig.persistOnPointerExit, retaining the last resolved cursor
across pointer exit, focus loss, and synchronized middle-button viewport
panning for inspection-oriented chart stacks. Ordinary host-page wheel
scrolling no longer claims a false chart-zoom lifecycle or clears the guide.Opt-in, velocity-aware touch-pan inertia with bounded decay and cancellation when a new interaction starts, carried through artifacts, generated sourc
BravenChart, PlotSpec,
marks/channels, and braven_charts_fluent.dart) are Beta / experimental and
may change before a stable release. Pin a version if you depend on them.Checked Chart Grammar authoring for Pie, Donut, Concentric Donut, and Polar Column charts, with radial diagnostics, configuration forwarding, generate
Browse and Explore touch profiles for phone and tablet charts, including touch pan, focal-point pinch zoom, selection arbitration, controller viewport
Unified Range Area selection around the visible low-to-high interval for pointer, lasso, expression, table, statistics, zoom, artifact, keyboard, and
A task-oriented Documentation home in the public showcase, with generated catalog data for evergreen capabilities, chart families, guide groups, and t
/api/ in the same GitHub
Pages artifact as the runnable showcase.A dedicated phone-width showcase selected automatically below 600 logical pixels. It replaces the compressed desktop rail, workbench chrome, and prope
mobile-0.13 package-media capture support in
tool/capture_showcase_media.py, including a deterministic narrow viewport
and a settled post-animation frame for mobile_showcase.png.Renderer-neutral durable selection across all built-in families: point, X/Y interval, rectangle, and lasso acquisition; point, category, composition-s
package:braven_charts/braven_charts_fluent.dart: 98 generated extensions
carrying ~1160 chained verbs over the existing config classes, with a
vocabulary that keeps the two kinds of "unset" apart — withX(v) replaces,
withoutX() suppresses a tri-state ChartStyleValue field, inheritX()
defers it to the theme, clearX() unsets a nullable parameter back to its
default, and updateX(fn) edits a nested config in place. The barrel
re-exports the core barrel, so one import is enough; the core barrel is
untouched, so consumers who never import it never see the verbs. Assert
coupled parameters are only reachable through combined setters
(withOhlc(open:, high:, low:, close:), withRange(min, max)), and
cross-object join keys (id), OR-coupled bar widths and RangeAnnotation
bounds are deliberately construction-only.@chartSurface surface model and the tool/surface_gen build_runner engine
that reads it: an analyzer-based, dev-only generator emitting checked-in
fluent extensions plus an executing smoke suite, with enforcement that fails
when a barrel-reachable, copyWith-carrying config class is unannotated
(missing = 0) and a CI regeneration gate that fails on any diff. Consumers
never run build_runner. The 0.11.0 Range Area family is covered by the
same gate: RangeAreaChartSeries, RangeAreaDataPoint,
RangeAreaBoundaryStyle, RangeAreaLabelConfig and RangeAreaTheme are
modelled, with withInterval(low, high) keeping the high >= low
invariant and id/points construction-only.ChartToolSchema.surfaceDefinitions: structural surface definitions
generated from the same annotated model that drives the fluent layer, so the
AI tool schema and the config builder are derived from one source, guarded
by a bidirectional drift gate in both directions.ChartGrammarSourceGenerator reads a captured chart
document and writes the BravenChart.of(rows).x(...).geomLine(...).build()
chain that rebuilds it, over a SYNTHESISED row class — one field for the
shared x, one per measure, named after each series, with candlesticks
contributing open/high/low/close and scatter channels their own fields.
Fidelity is proven rather than asserted: before emitting anything the
generator lowers the spec it is about to write and compares the resulting
series, annotations, Y-axes AND the X axis, theme and interaction to the
ones the document hydrated to, so a
chain that would render a different chart is refused with a named diagnostic
and no code — one that identifies the specific series, annotation or axis
option a V1 mark cannot carry (a lost series field, or the single-axis
binding a config-authored chart leaves implicit) rather than only reporting
that the chart "does not reproduce exactly". Non-Cartesian families,
misaligned x domains, partially
populated scatter channels, partial candlestick timestamps, mixed bar
orientations, annotations other than
TrendAnnotation and chart-level options BravenPlot does not forward are
each diagnosed by name; runtime bindings and over-budget data are warned
about and emitted, exactly as the config form does. Both forms read the same
captured document, so switching never re-extracts the chart, and the config
form's output, keys and tests are byte-for-byte unchanged.
BravenChartWorkbench gains grammarSourceOptions and initialSourceForm.PlotSpec<T>,
the sealed Mark<T> hierarchy (LineMark, AreaMark, BarMark,
ScatterMark, CandlestickMark, TrendMark), Channel<T> and
CategoryChannel<T> encodings, the PlotSpecLowering.lower() extension, the
BravenPlot<T> widget, and the chained BravenChart.of(rows) facade with
x/y/geomLine/geomArea/geomBar/geomPoint/geomCandlestick/
trend/transposed/theme/interaction/xAxis/yAxis/build. A spec
lowers onto ordinary ChartSeries, ChartAnnotation and axis configs, so
the render pipeline, artifact codecs, generated Source and the Workbench are
untouched — parity is locked by config-equality and artifact-document
equality suites. Failures are fail-fast and carry a machine-readable
GrammarDiagnosticCode, and nothing is dropped silently — a channel without
its encoding AND an encoding with no channel to drive it both raise. Every
data-independent structural check (mark/axis ids, axis binding, channel
pairing, trend source, transposition) runs BEFORE the empty-data check, so
an authoring error surfaces even against a momentarily-empty dataset; empty
data alone is treated as a runtime state and renders the standard empty
state instead of throwing from build..threshold(value:),
.band(start:, end:) and .pointAt(seriesId:, dataPointIndex:) (new
ThresholdMark / BandMark / PointMark) lower to ThresholdAnnotation,
a 1-D RangeAnnotation and PointAnnotation. Chart-level options:
PlotSpec carries a grid, title/subtitle and showLegend, forwarded
by BravenPlot, with .grid(...) / .title(...) / .legend(...) verbs; a
null grid or legend reproduces the chart default. Per-mark data-point
markers and inline labels: showDataPointMarkers and dataPointLabels on
geomLine/geomArea, and labelStyle on geomBar. The grammar-source
emitter emits every one of these — the reference verbs, .grid/.title/
.legend, and the marker/label fields — so charts that previously drew a
"not emitted" diagnostic in the Workbench Grammar form now emit a chain,
proven by the round-trip fidelity guarantee. Marks stay copyWith-free.First-class Range Area charts through RangeAreaDataPoint and RangeAreaChartSeries, including atomic low/high bounds, explicit gaps, linear/Bezier/mono
RangeAreaDataPoint and
RangeAreaChartSeries, including atomic low/high bounds, explicit gaps,
linear/Bezier/monotone/stepped interpolation, solid or gradient fills,
independently styled boundaries, markers, labels, hit policies, typed
low/high/midpoint/span tracking, paired axis values and intersections,
keyboard selection and semantics, invariant-preserving entrance/update
motion, nested bands and ordinary Line composition, viewport culling,
artifacts, hydration, native tables/CSV, generated Dart, Workbench modes,
and strict tool-driven configuration.First-class typed OHLC charts through CandlestickDataPoint, CandlestickChartSeries, and CandlestickChartStyle, including rising/falling/doji presentat
CandlestickDataPoint,
CandlestickChartSeries, and CandlestickChartStyle, including
rising/falling/doji presentation, elapsed and ordinal time spacing,
viewport culling, indexed hit testing, pointer and keyboard selection,
tracking, entrance and compatible data-update animation, live latest-candle
upsert, density grouping, mixed Line/Area/Scatter overlays, native tables,
CSV, artifacts, hydration, generated Dart, and Workbench integration.CartesianNavigator for Line, Area, Bar,
Scatter, and Candlestick charts. It renders a full-domain Line or Area
overview and controls caller-owned synchronized viewports through pointer,
touch, keyboard, and semantic panning/resizing, interval or ordered-value
snapping, accessible controls, external-domain growth, and live retained-
history inspection.ChartContextAction,
ChartContextInvocation, and renderer-neutral ChartContextHit, plus
BravenChartWorkbench.contextActionsBuilder and independently configurable
ChartOverlayAction buttons. Secondary-click, keyboard, and opt-in touch or
stylus long-press entry paths share accessible, theme-aware command styling.release label
tags the package version, publishes to pub.dev with OIDC trusted publishing,
and deploys the release showcase to GitHub Pages.InteractionConfig.valueSummary and CartesianValueSummaryConfig: a
persistent in-plot panel showing the current policy-resolved datum, fed by
the chart's shared immutable tracking snapshot with one resolution per
interaction frame.CartesianValueSummaryPresentation.overlay (fixed, pointer-transparent,
anchored via ChartOverlayPlacement) and
CartesianValueSummaryPresentation.annotation (optionally draggable and
keyboard-movable with plot clamping, continuous drag preview, and exactly
one committed placement per gesture through onPlacementChanged).CartesianValueSummaryValuePolicy precedence chains over
tracking, selection, pinning, and latest/first visible fallbacks, with
automatic invalid-pin clearing.CartesianValueSummaryConfig.valueMode
(interpolated default / dataPoints): tracked summary rows can snap to
the nearest actual data point instead of following the interpolated curve,
independent of the crosshair's own interpolation setting. The summary
keeps reusing the shared per-frame tracking resolution in every compatible
combination; only crosshair interpolation and summary dataPoints
simultaneously active add one extra memoized resolution per frame.
Serialized in artifacts and generated Source when non-default, with a
'Value mode' toggle on the showcase page.CartesianValueSummaryContent.automatic() rows (Line/Area/Bar
values with grouped context, Scatter encodings, Candlestick OHLC/change/
direction, per-series sections for mixed charts, optional trend rows) and
portable CartesianValueSummaryContent.builder() rows over the published
snapshot.CartesianValueSummaryStyle (inherit/value/none per field,
with genuinely transparent clears) resolved against the new
CartesianValueSummaryTheme component, including light, dark,
highContrast, and colorblindFriendly presets.CartesianValueSummaryStyle.labelValueGap (and
the matching nullable CartesianValueSummaryTheme.labelValueGap default):
an explicit gap left-aligns values in a shared column right after the
widest row label and tightens the panel's intrinsic width — clamped by
minWidth/maxWidth, long values still ellipsizing — while inherited or
cleared keeps the spread layout with right-aligned values.CartesianValueSummaryController /
DefaultCartesianValueSummaryController for programmatic pinning by stable
ChartPointRef identity and placement reset.announceChanges
screen-reader announcements debounced by resolved datum identity;
focusability and Move/Reset position custom actions for the draggable
panel; Pin value/Clear pin actions when a controller and pin policy are
active.doc/value_summary.md
feature guide.LiveStreamController.manageViewport can opt out of internal X-viewport
movement so a caller-owned interaction group and navigator remain the sole
viewport authority during ingest; dataRevision and O(1) oldestPoint
support efficient external synchronization.CartesianNavigatorBehavior.allowExternalDomainGrowth preserves an
authoritative live viewport while a bounded overview snapshot catches up,
eliminating stale-domain clamp feedback and left/right oscillation.CrosshairConfig.showCoordinateLabels is now honored by the crosshair
renderer: clearing it removes the axis value labels in both standard and
tracking display modes (previously the flag was serialized but never read
during painting). The labels are their own feedback layer — with
CrosshairMode.none they can now paint without any crosshair lines,
matching the layer-independence contract of the tracking feedback stack.Prerelease validating the new automated release pipeline; content below is release-candidate material for 0.10.0.
Prerelease validating the new automated release pipeline; content below is release-candidate material for 0.10.0.
release label
tags the version, publishes to pub.dev via OIDC trusted publishing, and
deploys the showcase to GitHub Pages (see docs/releasing.md).CartesianNavigator that renders one full-domain
Line or Area overview and controls synchronized Line, Area, Bar, Scatter, and
Candlestick viewports through a caller-owned
ChartInteractionGroupController.CartesianNavigatorStyle states with compact visual handles,
48-pixel default pointer/touch targets, focus treatment, disabled rendering,
and three explicit accessible controls.ChartInteractionGroupController as direct chart gestures.LiveStreamController.dataRevision plus the O(1) oldestPoint endpoint so
external viewport owners can follow live data without copying snapshots.CandlestickDataPoint,
CandlestickChartSeries, CandlestickChartStyle, theme-resolved rising,
falling, and doji presentation, viewport-aware wick/body geometry, indexed
hit testing, pointer and keyboard selection, and sample-based tracking.LiveStreamController.upsertLatestCandlestick revision and
append behavior.CandlestickDensityGrouping using first open, maximum high, minimum
low, and last close while retaining all represented source indices and
keeping raw tables and artifacts unchanged.ChartContextAction, ChartContextInvocation, renderer-neutral
ChartContextHit, and ChartContextMenuConfig.BravenChartWorkbench.contextActionsBuilder, which supplies the same stable
ChartWorkbenchHandle as visible actions so a host command can safely
extract the current artifact from either surface.ChartOverlayAction and ChartOverlayActionButtonConfig, with configurable
placement, sizing, semantics, enabled state, Material styling, a translucent
theme-derived default, and direct-chart or Workbench builders using the same
host callback model.CartesianNavigatorBehavior.allowExternalDomainGrowth keeps a live external
viewport authoritative while a throttled overview snapshot catches up,
preventing stale-domain clamp feedback and left/right viewport oscillation.LiveStreamController.manageViewport can now opt out of built-in X-viewport
movement so a caller-owned ChartInteractionGroupController and
CartesianNavigator remain the single viewport authority during live ingest.RangeAnnotation; the Gallery proves the same control
against a non-financial synchronized Line/Area composition.onAnnotationDragUpdate without replacing controller-owned annotations
during an active gesture; onAnnotationDragged remains the committed
pointer-up callback.grab and
grabbing cursors instead of looking like passive chart content.chart.polar.multiple-series.v1 capability negotiation for portable layered
Polar Column documents and chart.polar.grouped-series.v1 for grouped
geometry, plus production-shaped layered and grouped comparison presets in
the public showcase.PolarColumnCompositionMode.stacked. Signed source values accumulate on
independent positive and negative sides of an explicit zero baseline while
tables, CSV, controllers, artifacts, hydration, and generated Dart retain
the original values and series identity. Stacked documents negotiate
chart.polar.stacked-series.v1.targetValues and
PolarColumnTargetMarkerStyle, plus pane-wide PolarThreshold reference
arcs. Automatic radial domains include both reference types; explicit
domains retain the source data while omitting out-of-range paint. Targets
and thresholds round-trip through tables, CSV, artifacts, hydration, and
generated Dart using explicit capability negotiation.PolarColumnInterval and PolarColumnIntervalStyle. Intervals render as
radial whiskers with tangential caps or compact annular bands, participate
in automatic radial domains, clip against explicit domains while retaining
exact source endpoints, and round-trip through native tables, CSV,
artifacts, hydration, and generated Dart. Stacked contributors reject
intervals because cumulative placement would make their meaning ambiguous.PolarCategoryAxisConfig.maximumVisibleLabels,
PolarCategoryAxisConfig.maximumVisibleGridLines, and
PolarColumnStyle.maximumVisibleDataLabels. Dense panes thin only painted
labels and spokes; every mark remains available to hit testing, semantics,
native tables, CSV, artifacts, hydration, and generated Dart source. A
512-category warm-paint benchmark now guards the renderer's frame budget.PolarColumnCornerRadiusMode for rounding both radial ends, retaining the
original outer-radius-only treatment, or rounding only the exposed positive
and negative boundaries of a complete stack. Non-default modes negotiate
series.polar.column.corner-radius-mode.v1 through artifacts and generated
source.Quantitative Scatter encodings through ScatterSizeEncoding, ScatterColorEncoding, and ScatterOpacityEncoding. Independent ChartDataPoint.magnitude, co
ScatterSizeEncoding,
ScatterColorEncoding, and ScatterOpacityEncoding. Independent
ChartDataPoint.magnitude, colorValue, and opacityValue channels can be
combined without replacing the point's X/Y coordinates or explicit style.ScatterMarkerStyle for independent fill, outline, opacity, width, height,
and rotation; circle, square, triangle, inverted-triangle, diamond, cross,
plus, star, and hidden marker shapes; and per-point style/shape overrides.ScatterInteractionStyle for geometry-and-outline hover, press, durable
selection, keyboard/linked focus, and non-selected dimming states that do not
rely on colour alone.dart pub publish --dry-run remains warning-free.Portable dashPattern outlines for ordinary Line and Area series, including interpolation-aware rendering, continuous Area fills, glow, native outgoing
dashPattern outlines for ordinary Line and Area series, including
interpolation-aware rendering, continuous Area fills, glow, native outgoing-
segment pattern changes, artifacts, built-in hydration, generated Dart
source, legend identity, and a continuous observed-versus-forecast showcase.ChartInteractionGroupController synchronization for
data-space X cursors, local nearest-point tracking, and loop-safe X-only
viewports across independent Cartesian charts, plus a responsive
Speed/Elevation/Heart-rate showcase.DonutChartSeries rings, with automatic or weighted band allocation,
configurable ordering and gaps, one shared center, grouped or flat legends,
coordinated labels, ring-aware tables/tooltips/semantics, exact generated
Source, canonical artifacts, preview capture, and hydration.RadialSelectionStyle presentation across Pie, Donut, and Concentric
Donut charts. Selection can retain the established explode treatment or lift
a scaled, radially offset foreground slice with configurable composition
backdrop blur while preserving durable point identity and ring allocation.transitionKey during an active radial morph now clears the stale
transition before the destination chart enters.ConcentricDonutConfig, including
deterministic ring weights, order, legend mode, and portable center content.Opt-in ChartDisplayMode.source for BravenChartWorkbench, backed by the public deterministic ChartDartSourceGenerator. Generated direct Dart covers Lin
ChartDisplayMode.source for BravenChartWorkbench, backed by the
public deterministic ChartDartSourceGenerator. Generated direct Dart
covers Line, Area, Scatter, Bar, Pie, Donut, mixed and multi-axis charts,
annotations, interactions, resolved themes, legends, and optional durable
view state. ChartDartSourceOptions bounds inline data, while
ChartGeneratedSource reports completeness, placeholders, and diagnostics
for runtime-only behavior instead of silently omitting it.ChartWorkbenchScope and caller-owned
ChartWorkbenchGroupController for system-wide or chart-family-wide display
mode and mode-selector visibility. Grouped Workbenches reconcile their common
supported modes safely while retaining local split sizing, data/source
snapshots, selection, focus, and interaction state.PathAnimationStyle, PathEntranceAnimationMode, and
PathDataUpdateAnimationMode. PathAnimationTiming adds independent
per-series delay and duration for entrance and update phases, while
BravenChartController.replaySeriesEntrance() replays the mounted entrance.CategoryAxisConfig, CategoryLabelDensity, and
CategoryLabelOverflow for stable categorical identity, automatic readable
viewports, label thinning, wrapping or ellipsis, rotation, and transposed
horizontal Bar axes without host label callbacks.BarLayoutMode.divergingStacked, BarDivergingRole, and
BarDivergingStyle for centered normalized Likert-style compositions with a
configurable center line and source-value preservation.BarPatternStyle and BarFillPattern for contrast-aware non-colour fills;
BarLollipopStyle for stem-and-head categorical marks; and
BarBulletStyle/BarBulletRange for qualitative ranges around an actual
measure and target.ParetoCategory/ParetoChartData for stable ranked values and cumulative
mixed-series data, plus HistogramChartData, HistogramBin, configurable
binning methods, and count, percentage, or density output for continuous
samples.BarMotionStyle and BarAnimationOrder for together, forward, reverse,
center-out, or edges-in keyed Bar entrance/update/exit sequencing with
baseline-collapse exits and reduced-motion support.BravenChartPlus.transitionKey for switching one mounted chart between
semantically different configurations without interpolating incompatible
geometry. A changed key clears prior Line, Area, Bar, Pie, and Donut motion
history, replays only the destination entrance, and preserves Workbench and
controller state.BravenChartPlus.donutCenterBuilder, onDonutCenterTap, and
DonutCenterData, with package-owned circular hit testing and semantics,
portable center-content fallback, and explicit rebinding after hydration.RadialValueFormatter and portable formatter descriptors.RadialSliceRadiusAggregation policies when variable-radius Pie or Donut
slices are grouped, without collapsing source rows carried by tables and
artifacts.Chart changed or Refresh source controls. manual and onModeEntry
policies remain explicit opt-ins, independent from Data's snapshot policy.ChartConfigBuilder and the public chart tool schema.Native Bar projection in BravenChartWorkbench Chart, Data, and Split presentations. Tables preserve source values while exposing the resolved target,
BravenChartWorkbench Chart, Data, and Split
presentations. Tables preserve source values while exposing the resolved
target, uncertainty, range, stack-bound, normalized-share, and waterfall
running-total fields used by the renderer; row copy and CSV export include
those fields without creating synthetic chart series.BravenChartPlus.radialLegendItemBuilder, with resolved radial data,
package-owned responsive layout and selection, stable accessibility
semantics, and public Pie/Donut showcase examples.sweep and geometry-preserving fade Pie/Donut entrance modes,
retaining radial grow as the default and honoring reduced motion across
initial mounts, data changes, and explicit controller replays.BravenChartController.replayRadialEntrance() plus public Donut showcase
controls, artifact/theme round trips, AI input, and focused geometry,
rendering, accessibility, and lifecycle coverage for radial motion.BravenChartWorkbench, including a focused divider with a 12-pixel pointer
strip, keyboard resizing, Escape/double-click reset, and stable Pie/Donut
legend footprints when selection changes.First-class DonutChartSeries for single-ring categorical charts, including validated inner and outer radii, full or partial sweeps, clockwise or count
DonutChartSeries for single-ring categorical charts, including
validated inner and outer radii, full or partial sweeps, clockwise or
counter-clockwise layout, slice gaps, gradients, borders, corner policies,
elevation, animation, variable outer radii, and stable category order.DonutCenterContent with total, selected, selected-or-total, and
custom value modes; independent label/value styling; accessible summary
semantics; and selection-aware updates from slices, legends, and tables.BarInteractionStyle, covering hover,
press, keyboard focus, durable selection, selected emphasis, and dimming of
non-selected bars without losing category identity.BarAnimationMode.none.BarChartSeries.targetValues and
BarTargetMarkerStyle, including configurable line length, width, color,
dash pattern, bounds participation, tooltips, semantics, animation, and
canonical artifact round-tripping.errorLowerValues and
errorUpperValues, with BarErrorBarStyle control over stem/cap color,
width, opacity, and cap length. Error ranges participate in automatic axis
bounds, keyed data-update animation, Cartesian and transposed geometry,
tooltips, semantics, and canonical artifact round-tripping.First-class PieChartSeries rendering with deterministic radial geometry, inside or collision-managed outside labels, slice legends, tooltips, keyboard
PieChartSeries rendering with deterministic radial geometry,
inside or collision-managed outside labels, slice legends, tooltips,
keyboard navigation, accessible slice semantics, and selectable explode
state.series.pie), canonical JSON hydration, preview
capture, category/value/share table projection, native copy/CSV actions,
and tool-schema support.Expand data-derived constant per-axis ranges to a stable non-zero span so single-point and constant-valued series render safely with per-series normal
Expand range and threshold annotation label placement from five positions to a complete 3x3 anchor model while retaining all legacy position names.
BravenChartWorkbench with one mounted Chart/Data/Split runtime, responsive compact fallback, document freshness policies, and host-defined artifact ac
BravenChartWorkbench with one mounted Chart/Data/Split runtime, responsive
compact fallback, document freshness policies, and host-defined artifact
actions.ChartPointRef values, including wide-row multi-point linking and
artifact/hydration round-trip.Recompose the pub.dev introduction as two compact analytical stills followed by one full-width animated interaction example.
Pin the README hero to immutable v0.1.2 media so pub.dev invalidates its external-image cache and serves the new dual-chart composition.
v0.1.2 media so pub.dev invalidates its external-image cache and serves the new dual-chart composition.Replace the package hero with a taller, side-by-side analytical showcase: a warm mixed-series threshold view and a dark power-duration baseline model.
Use absolute HTTPS sources for README showcase media so images and animated examples render correctly on pub.dev.
None. All deprecated APIs remain functional with backward compatibility.
RenderBox and Canvas pipeline with cached series layers, spatial hit testing, and no embedded JavaScript chart engine.LiveStreamController.BravenChartPlus.isLoading now supports a responsive, chart-theme-aware animated skeleton, circular, linear, determinate, and custom loading presentations. Empty series render configurable guidance instead of a blank plot.perpendicularIndex on ChordAnnotation draws a line from the chord to a data point, projected perpendicularly onto the chord. Includes independent styling and label support. Used for lactate threshold (LT1) deflection distance visualization.None. All deprecated APIs remain functional with backward compatibility.
This release introduces a unified theming and axis configuration system. Several legacy APIs are now deprecated but remain functional. Please migrate to the new APIs at your convenience.
The following ChartTheme constructor parameters and getters are deprecated in favor of the new component-based theming system:
Deprecated Fields:
gridColor → Use gridStyle.majorColor insteadaxisColor → Use axisStyle.lineColor insteadtextColor → Use typographyTheme or axisStyle.labelStyle.color insteadseriesColors → Use seriesTheme.colors insteadMigration Example:
// OLD (deprecated but still works)
final theme = ChartTheme(
backgroundColor: Colors.white,
gridColor: Colors.grey.shade300,
axisColor: Colors.black,
textColor: Colors.black87,
seriesColors: [Colors.blue, Colors.red, Colors.green],
// ... other required fields
);
// NEW (recommended)
final theme = ChartTheme(
backgroundColor: Colors.white,
gridStyle: GridStyle(
majorColor: Colors.grey.shade300,
majorWidth: 1.0,
),
axisStyle: AxisStyle(
lineColor: Colors.black,
labelStyle: TextStyle(color: Colors.black87),
),
seriesTheme: SeriesTheme(
colors: [Colors.blue, Colors.red, Colors.green],
),
typographyTheme: TypographyTheme.defaultLight,
interactionTheme: InteractionTheme.defaultLight,
animationTheme: AnimationTheme.defaultLight,
annotationTheme: AnnotationTheme.defaultLight,
scrollbarConfig: ScrollbarConfig.defaultLight,
legendStyle: LegendStyle.light,
);
// Or use predefined themes:
final theme = ChartTheme.light; // or .dark, .corporateBlue, .vibrant, etc.
For Y-Axis Configuration:
YAxisConfig when configuring Y-axes in multi-axis chartsChartSeries.yAxisConfig to define Y-axis inline on a seriesAxisConfig remains available for general axis configuration and X-axis useMigration Example:
// Preferred approach for Y-axis configuration
LineChartSeries(
id: 'temperature',
points: tempData,
yAxisConfig: YAxisConfig(
position: YAxisPosition.left,
label: 'Temperature',
unit: '°C',
color: Colors.red,
),
)
// AxisConfig is still valid for X-axis and general configuration
BravenChartPlus(
series: [series1, series2],
xAxisConfig: AxisConfig(
label: 'Time',
showGrid: true,
),
)
SeriesElement Constructor:
strokeWidth parameter → Use seriesTheme insteadthemeColor parameter → Use seriesTheme insteadDataConverter.seriesToElements:
strokeWidth parameter → Use theme.seriesTheme insteadMigration Example:
// OLD (deprecated)
final elements = DataConverter.seriesToElements(
series: chartData,
transform: transform,
strokeWidth: 2.5,
);
// NEW (recommended)
final theme = ChartTheme(
// ... other theme properties
seriesTheme: SeriesTheme(
lineWidth: 2.5,
colors: [Colors.blue, Colors.red],
),
);
final elements = DataConverter.seriesToElements(
series: chartData,
transform: transform,
theme: theme,
);
The widget-level LineStyle enum has been deprecated. Use LineInterpolation directly on individual ChartSeries instead for fine-grained control.
Migration Example:
// OLD (no longer available at widget level)
// BravenChartPlus(lineStyle: LineStyle.smooth)
// NEW (set on each series)
LineChartSeries(
id: 'series1',
points: data,
interpolation: LineInterpolation.bezier, // smooth curves
)
LineChartSeries(
id: 'series2',
points: data,
interpolation: LineInterpolation.linear, // straight lines
)
All deprecated APIs remain functional with full backward compatibility. Existing code will continue to work with deprecation warnings. You can migrate incrementally at your own pace.
Your coding agent can read these notes before it upgrades. Set up the MCP server →