Axis labels stop being rendered after certain reservedSize threshold, even if there is still enough vertical space
- Dominant language
- Dart
- Stars
- 7.6k
- Forks
- 2k
- Avg merge
- 9d 1h
- Merged PRs (30d)
- 2
Description
Code example will show exactly what I mean. In the below example, change the `reservedSize: 114` to `reservedSize: 115` and observe the effects.
The code that causes this bug I believe lives in `side_titles_widget.dart` in the method `_getPositionsWithinChartRange`. There is a calculation in there:
```
final chartSize = Size(
widget.parentSize.width - thisSidePaddingTotal,
widget.parentSize.height - thisSidePaddingTotal,
).rotateByQuarterTurns(widget.axisChartData.rotationQuarterTurns);
```
This calculation subtracts the same value of `thisSidePaddingTotal` from both the width and the height, when calculating `chartSize`, which is then used to filter out which labels to stop rendering. The issue is, when the chart is rotated, padding from the wrong axis is being used for the value of `thisSidePaddingTotal`, causing one of width/height to then be negative when the chart is small enough, which then in turn causes the `axisPositions.where` call to filter out all the labels (because a negative size causes all points to be treated as outside the rect).
Basically when the chart's height constraint from the parent is smaller than the `reservedSize` for the horizontal (after rotation) axis labels, then the issue occurs. I can try fixing this myself, but I'm not that familiar with the codebase and I'm not sure if I wouldn't break something else, so I'm creating this issue first.
The fix seems simple enough - when calculating the `chartSize` variable, make sure to use correct vertical and horizontal paddings in the subtraction (aka `widget.parentSize.height - verticalPaddingTotal`)
**To Reproduce**
```
import 'package:flutter/material.dart';
import 'package:fl_chart/fl_chart.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(body: Center(child: MyChart())),
);
}
}
class MyChart extends StatelessWidget {
const MyChart({super.key});
@override
Widget build(BuildContext context) {
return Container(
width: 350,
height: 120,
decoration: BoxDecoration(
border: Border.all(color: Colors.black, width: 2),
borderRadius: BorderRadius.circular(16),
),
child: BarChart(
BarChartData(
rotationQuarterTurns: 1,
titlesData: FlTitlesData(
leftTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 25,
),
),
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 114,
),
),
rightTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
topTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
),
barGroups: [
BarChartGroupData(
x: 1,
barRods: [BarChartRodData(toY: 5, color: Colors.blue)],
),
BarChartGroupData(
x: 2,
barRods: [BarChartRodData(toY: 10, color: Colors.red)],
),
BarChartGroupData(
x: 3,
barRods: [BarChartRodData(toY: 7, color: Colors.orange)],
),
BarChartGroupData(
x: 4,
barRods: [BarChartRodData(toY: 12, color: Colors.green)],
),
],
),
),
);
}
}
```
**Screenshots**
**Versions**
- Flutter 3.32.8 (latest stable)
- fl_chart 1.0.0 (latest stable)
Contributor guide
Research direction
In side_titles_widget.dart, inspect _getPositionsWithinChartRange and reproduce the supplied Flutter example by changing reservedSize from 114 to 115 with rotationQuarterTurns: 1. Trace how the chart dimensions affect axisPositions filtering, then verify that the labels remain rendered at the boundary without regressing the unrotated case.
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
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 75/100