imaNNeo / imaNNeo/fl_chart

Bug: BarChart touchedStackItemIndex always -1 for downward (negative) rod stack items

Open
#2,104 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Dart
Stars
7.6k
Forks
2k
Avg merge
9d 1h
Merged PRs (30d)
2

Description

## Bug

When a `BarChartRodData` is downward (`fromY > toY`, e.g. `fromY: 0, toY: -10` — common for plotting losses or values below a baseline) and has `rodStackItems`, the painter detects the outer rod but the inner stack item is silently missed: `BarTouchResponse.touchedStackItemIndex` is always `-1` and `touchedStackItem` is always `null`, no matter where the touch lands inside the rod.

This breaks tooltips, `getTooltipItem`, and any callback that keys off `touchedStackItemIndex` for negative bars (e.g. financial loss bars).

## Cause

`BarChartPainter.handleTouch` checks:

```dart
if (touchedPoint.dy <= fromPixel && touchedPoint.dy >= toPixel) { ... }
```

at [`bar_chart_painter.dart:946`](https://github.com/imaNNeo/fl_chart/blob/main/lib/src/chart/bar_chart/bar_chart_painter.dart#L946). For an upward stack item (`toY > fromY`), `toPixel < fromPixel` in screen space (Flutter Y grows downward) and the inequality describes the rod's pixel range correctly. For a downward stack item (`fromY > toY`), `fromPixel < toPixel` and the predicate `dy <= small && dy >= big` is mathematically empty — no `dy` can ever satisfy it.

## Reproduction (no real device needed)

```dart
final data = BarChartData(
minY: -10,
maxY: 0,
barGroups: [
BarChartGroupData(x: 0, barRods: [
BarChartRodData(
fromY: 0,
toY: -10,
width: 20,
rodStackItems: [BarChartRodStackItem(0, -10, Colors.red)],
),
]),
],
);
final painter = BarChartPainter();
final holder = PaintHolder(data, data, TextScaler.noScaling);
final r = painter.handleTouch(const Offset(100, 50), const Size(200, 100), holder);
// r.touchedStackItemIndex is -1 (expected 0)
// r.touchedStackItem is null (expected not null)
```

## Fix

Make the check orientation-agnostic with `min`/`max`. PR #2103 has the one-line fix + a regression test inside the existing `handleTouch()` group.

Contributor guide

Open the contributing guide

Research direction

Start in lib/src/chart/bar_chart/bar_chart_painter.dart at handleTouch(), around line 946, and inspect the existing handleTouch() tests. Reproduce the downward rod case from the issue, then verify that the regression test reports stack item index 0 and a non-null touchedStackItem; PR #2103 is also referenced as containing the fix and test.

Written by the indexing model from the issue text.

Assessment

Tech stack
dart, flutter
Domain
frontend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.