Skip to content

toolkit: TimeSeriesChart's curve stops staircasing - #456

Merged
tannevaled merged 1 commit into
mainfrom
drawline-antialiased
Sep 6, 2026
Merged

toolkit: TimeSeriesChart's curve stops staircasing#456
tannevaled merged 1 commit into
mainfrom
drawline-antialiased

Conversation

@tannevaled

Copy link
Copy Markdown
Contributor

Summary

  • TimeSeriesChart's curve and dashed Threshold line were visibly jagged — plain Bresenham, no anti-aliasing (live user feedback: "il ne semble pas y avoir d'anti-crénelage sur les courbes des graphes?").
  • Adds drawCurveLine: strokes an anti-aliased path via painter.PathPainter.StrokePath on a GUI back-end, falling back to the shared drawLine unchanged on a CellPainter (TUI).
  • Deliberately scoped to TimeSeriesChart's own diagonal segments, not the shared drawLine. An initial attempt to anti-alias drawLine itself broke TestWidgetsStayWithinBounds (a 1-unit AA stroke centered on an integer coordinate straddles the pixel boundary and bleeds half a pixel past a widget's own Bounds) and TestMetricScaleAudit across LineChart/BarChart/AreaChart/ScatterChart — real regressions on axis-aligned gridlines/rules, not just outdated test expectations. A diagonal curve segment inside a plot area carries no such bounds risk.
  • segmentInk (the OverInk-above-threshold color decision) is pulled out of Draw into its own plain function so it can be tested exactly, since an anti-aliased pixel is a coverage blend and sampling for an exact color match is the wrong tool for that question. Several existing pixel-exact TimeSeriesChart tests are rewritten the same way (compare two renders, or check "differs from the sentinel," rather than assume an opaque Bresenham pixel).

Test plan

  • go build ./..., go vet ./..., gofmt -l . clean
  • go test ./... green across the whole repo — confirmed zero regressions in every OTHER widget after scoping down from the broken toolkit-wide attempt
  • Every function in timeserieschart.go (and its tests) at 100% coverage, including the CellPainter fallback branch

🤖 Generated with Claude Code

toolkit's chart curves are drawn with Bresenham's algorithm — no partial
coverage, visibly staircased on a diagonal. painter.PixelPainter already
supports anti-aliased strokes via StrokePath, so this adds drawCurveLine:
a PathPainter fast path (an AA stroke) for TimeSeriesChart's own
diagonal segments (the main curve and the dashed Threshold line),
falling back to the shared drawLine unchanged everywhere else.

Deliberately scoped to TimeSeriesChart, not the shared drawLine itself:
an early attempt to anti-alias drawLine broke TestWidgetsStayWithinBounds
(a 1-unit AA stroke centred on an integer coordinate straddles the pixel
boundary and bleeds half a pixel past a widget's own Bounds) and
TestMetricScaleAudit across LineChart/BarChart/AreaChart/ScatterChart —
real regressions on axis-aligned gridlines/rules, not just outdated
pixel-exact test expectations. A diagonal segment inside a plot area
carries no such bounds risk, and is exactly the case where staircasing
is visible.

Segment color selection (segmentInk) is pulled out of Draw into its own
plain function so OverInk's decision logic can be tested exactly — an
anti-aliased pixel is a coverage blend, never a pure color match, which
makes sampling drawn pixels the wrong tool for that specific question.
Several existing pixel-exact tests are rewritten the same way: compare
two renders (or count "differs from the untouched sentinel", not "equals
this exact color") rather than assume Bresenham's single opaque pixel.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@tannevaled
tannevaled merged commit ba65ff3 into main Sep 6, 2026
1 check passed
@tannevaled
tannevaled deleted the drawline-antialiased branch September 6, 2026 12:20
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