Rapport PDF : empêcher les cartes de se couper entre deux pages

pw.Container délègue canSpan à son enfant, si bien qu'une carte pouvait se
scinder entre deux pages — titre seul en bas de l'une, contenu en haut de
l'autre. Enveloppe le graphique et les groupes de barres dans un widget
non sécable, que MultiPage reporte alors en entier.

Les tableaux restent sécables : un tableau long doit pouvoir se répartir
sur plusieurs pages.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Thomas Fransolet 2026-08-14 15:35:13 +02:00
parent a6463acce6
commit 7407335371

View File

@ -303,7 +303,7 @@ pw.Widget _chart(StatisticsReportData data) {
data.series.map((point) => point.visits).reduce((a, b) => a > b ? a : b); data.series.map((point) => point.visits).reduce((a, b) => a > b ? a : b);
final axisMax = _roundedAxisMax(peak); final axisMax = _roundedAxisMax(peak);
return _card( return _Unbreakable(_card(
data, data,
title: data.chartTitle, title: data.chartTitle,
subtitle: data.chartSubtitle, subtitle: data.chartSubtitle,
@ -352,11 +352,11 @@ pw.Widget _chart(StatisticsReportData data) {
], ],
], ],
), ),
); ));
} }
pw.Widget _barGroup(StatisticsReportData data, ReportBarGroup group) { pw.Widget _barGroup(StatisticsReportData data, ReportBarGroup group) {
return _card( return _Unbreakable(_card(
data, data,
title: group.title, title: group.title,
subtitle: group.subtitle, subtitle: group.subtitle,
@ -388,7 +388,7 @@ pw.Widget _barGroup(StatisticsReportData data, ReportBarGroup group) {
), ),
], ],
), ),
); ));
} }
pw.Widget _table(StatisticsReportData data, ReportTable table) { pw.Widget _table(StatisticsReportData data, ReportTable table) {
@ -460,6 +460,22 @@ pw.Widget _barTrack(double fraction, PdfColor color) {
); );
} }
/// `Container` délègue `canSpan` à son enfant : une carte se coupait donc entre
/// deux pages, titre seul en bas de l'une et contenu en haut de l'autre.
/// `MultiPage` reporte en entier tout enfant non sécable.
class _Unbreakable extends pw.SingleChildWidget {
_Unbreakable(pw.Widget child) : super(child: child);
@override
bool get canSpan => false;
@override
void paint(pw.Context context) {
super.paint(context);
paintChild(context);
}
}
double _roundedAxisMax(int peak) { double _roundedAxisMax(int peak) {
if (peak <= 4) return 4; if (peak <= 4) return 4;
var magnitude = 1.0; var magnitude = 1.0;