Skip to content

fix(flet-charts): ScatterChart failing to render spots with error ranges - #6885

Merged
FeodorFitsner merged 6 commits into
mainfrom
fix/charts-scatter-spot-error-range
Sep 26, 2026
Merged

FeodorFitsner merged 6 commits into
mainfrom
fix/charts-scatter-spot-error-range

Conversation

@ndonkoHenri

@ndonkoHenri ndonkoHenri commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Problem

ScatterChartSpot.x_error and y_error were typed Optional[Any] and passed unparsed to fl_chart's ScatterSpot, whose xError/yError are FlErrorRange?. Control.get<T> infers T from the parameter and returns the wire value as is, so any value other than None failed the cast in build():

type '_Map<dynamic, dynamic>' is not a subtype of type 'FlErrorRange?'

Flutter then replaced the whole chart with its error widget, a grey box in release builds, and the message only reached Python as page.on_error. No value could work, so both fields could only ever be None. It's the same defect class as #6684 and #6744.

Changes

  • New ChartErrorRange value type with the lower_by and upper_by bounds of FlErrorRange (fl_chart 1.2.0), plus symmetric() and copy(). Negative bounds raise ValueError, since FlErrorRange asserts they are non-negative. x_error/y_error are now typed with it; every non-None value crashed before, so no working code changes.
  • Dart: parseFlErrorRange() parses both fields.
  • Error bars are drawn in the color of their spot, which replaces the commented-out errorIndicatorData line. fl_chart already draws bars for spots with error ranges (FlErrorIndicatorData.show defaults to true), but its default painter is white, which is invisible on light backgrounds. Spot color is also the default in matplotlib and Plotly.
  • The field docstrings note that automatic axis bounds cover spot positions only (fl_chart's ScatterChartHelper ignores error ranges), so bars need explicit min_*/max_* to stay inside the chart.
  • New example scatter_chart_with_error_bars (pendulum timings: a symmetric range on x, an asymmetric fastest-to-slowest range on y), shown on the ScatterChart docs page.
  • ChartErrorRange docs page and sidebar entry, and changelog entries in CHANGELOG.md and the flet-charts changelog.
  • sdk/python/Taskfile.yml: Yarn telemetry is disabled in the docs tasks.

Not in this PR: an API to style the bars (color, width, cap length) through fl_chart's errorIndicatorData, and error ranges for LineChart/BarChart, which fl_chart also supports.

Testing

  • A widget test that builds the chart from a MessagePack-shaped Control tree reproduced the cast error before the fix and passed after it. It also checked the bar color and the parser's fallbacks.
  • Rendering the chart to PNG in light and dark themes: with fl_chart's default painter the bars were invisible on the light background; spot-colored bars show in both.
  • Python: a spot sends {"lower_by": 0, "upper_by": 1.5} (both bounds are always sent, zero included), and negative bounds raise.
  • The new example in the macOS test client renders as expected, and the existing scatter_chart integration goldens (image_for_docs, example_1) still match.
  • dart analyze, ruff, the Python unit tests (914 passed), and crocodocs generate.

Summary by Sourcery

Fix scatter-chart error-range support and add a public API and documentation for visible error bars.

New Features:

  • Add the ChartErrorRange value type for configuring symmetric or asymmetric scatter-plot uncertainty ranges.
  • Provide a scatter-chart example demonstrating horizontal and vertical error bars.

Bug Fixes:

  • Fix ScatterChart rendering failures when spots include x- or y-axis error ranges.
  • Render scatter-chart error bars using each spot’s color so they remain visible across themes.

Enhancements:

  • Document error-range axis-bound behavior and expose the new type through the charts package API.

Build:

  • Disable Yarn telemetry during documentation tasks.

Documentation:

  • Document ChartErrorRange and add the error-bar example to the ScatterChart documentation.

Tests:

  • Add coverage for error-range parsing, validation, serialization, rendering, and backward compatibility of existing scatter-chart examples.

`ScatterChartSpot.x_error` and `y_error` were typed `Any` and handed to
fl_chart's `ScatterSpot` unparsed. `Control.get` infers `FlErrorRange?`
from the parameter and returns the wire value as is, so any value other
than `None` failed the cast in `build()` with `type '_Map<dynamic,
dynamic>' is not a subtype of type 'FlErrorRange?'`. Flutter then
replaced the whole chart with its error widget, a grey box in release
builds, and the message only reached Python as `page.on_error`.

Add a `ChartErrorRange` value type with the `lower_by` and `upper_by`
bounds of `FlErrorRange`, parse it with `parseFlErrorRange()`, and reject
negative bounds in Python since `FlErrorRange` asserts they are
non-negative.

fl_chart draws error bars for any spot with an error range, but its
default painter draws them in white, which is invisible on light
backgrounds. Draw each spot's bars in the color of that spot, which is
also the default in matplotlib and Plotly.
The example plots the mean period of a pendulum for each string length.
Horizontal bars use `ChartErrorRange.symmetric()` for the length
uncertainty, and vertical bars use an asymmetric `ChartErrorRange` that
spans the fastest and slowest timing. Explicit axis bounds keep the bars
inside the chart. The ScatterChart docs page shows its code.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Deploying flet-website-v2 with  Cloudflare Pages  Cloudflare Pages

Latest commit: 478d6dd
Status: ✅  Deploy successful!
Preview URL: https://9aef15c5.flet-website-v2.pages.dev
Branch Preview URL: https://fix-charts-scatter-spot-erro.flet-website-v2.pages.dev

View logs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Range validation remains bypassable, and the regression tests claimed in the PR are absent.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 1 Medium severity · 1 Low severity

Open (2)
What changed in this PR

Fixes ScatterChart error-range rendering and adds a typed Python API with supporting documentation and examples.

Changes:

  • Adds ChartErrorRange and parses it into Flutter FlErrorRange.
  • Renders spot-colored error bars and adds an example.
  • Updates documentation, changelogs, and docs task telemetry settings.
File Description
CHANGELOG.md Records the user-facing fix.
sdk/​python/​Taskfile.yml Disables Yarn telemetry for docs tasks.
.../​scatter_chart_with_error_bars/​main.py Demonstrates error bars.
.../​scatter_chart_with_error_bars/​pyproject.toml Defines example metadata.
sdk/​python/​packages/​flet-charts/​CHANGELOG.md Records the package fix.
flet_charts/​__init__.py Exports ChartErrorRange.
flet_charts/​scatter_chart_spot.py Types and documents error ranges.
flet_charts/​types.py Implements ChartErrorRange.
flutter/​.../​scatter_chart.dart Parses and renders error ranges.
flutter/​.../​utils/​charts.dart Adds the range parser.
flutter/​.../​utils/​scatter_chart.dart Adds the error-bar painter.
website/​docs/​.../​scatterchart.md Adds the example to documentation.
website/​docs/​.../​charterrorrange.md Adds API reference documentation.
website/​sidebars.yml Adds the new type to navigation.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread sdk/python/packages/flet-charts/src/flet_charts/types.py
ndonkoHenri and others added 2 commits September 24, 2026 20:49
`nan < 0` is false, so a NaN bound passed the non-negative check.
`FlErrorRange` asserts both bounds are `>= 0`, so debug builds lost the
chart again. Check the documented predicate itself, so NaN raises
`ValueError` like a negative bound does.
@FeodorFitsner
FeodorFitsner merged commit b23c4cf into main Sep 26, 2026
2 of 83 checks passed
@FeodorFitsner
FeodorFitsner deleted the fix/charts-scatter-spot-error-range branch September 26, 2026 02:21
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.

3 participants