import 'package:eatvio_app/features/insights/models/insights_payload_model.dart'; import 'package:eatvio_app/features/insights/presentation/charts/insights_chart_common.dart'; import 'package:eatvio_app/features/insights/presentation/widgets/insights_colors.dart'; import 'package:eatvio_app/generated/l10n.dart'; import 'package:flutter/material.dart'; import 'package:syncfusion_flutter_charts/charts.dart'; /// График ИМТ с цветными зонами: норма 18.5–25, избыточная масса 25–30, ожирение 30–40. class BmiChart extends StatelessWidget { const BmiChart({super.key, required this.model}); final BmiChartModel model; @override Widget build(BuildContext context) { final points = buildPoints(model.labels, model.values); if (points.isEmpty) { return InsightsChartPlaceholder(text: model.deltaText); } final s = S.of(context); final dataRange = paddedRange(points.map((e) => e.value), minPadding: 2); // Ось всегда покрывает зоны нормы/избытка/ожирения, иначе при ИМТ ≈30 // зелёная полоса 18.5–25 уезжает за нижний край графика. const zoneMin = 18.5; const zoneMax = 40.0; final min = dataRange.min < zoneMin ? dataRange.min : zoneMin; final max = dataRange.max > zoneMax ? dataRange.max : zoneMax; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( height: insightsChartHeight, child: SfCartesianChart( key: const Key('insights_bmi_chart'), margin: insightsChartMargin, plotAreaBorderWidth: 0, primaryXAxis: buildInsightsIndexAxis(model.labels), primaryYAxis: buildInsightsValueAxis( unit: s.insights_unit_bmi, min: min, max: max, plotBands: const [ PlotBand( start: 18.5, end: 25, color: InsightsColors.bmiNormalZone, ), PlotBand( start: 25, end: 30, color: InsightsColors.bmiOverweightZone, ), PlotBand( start: 30, end: 40, color: InsightsColors.bmiObesityZone, ), ], ), trackballBehavior: buildInsightsTrackball(), series: >[ SplineAreaSeries( name: s.insights_tab_bmi, dataSource: points, xValueMapper: (point, _) => point.index, yValueMapper: (point, _) => point.value, splineType: insightsSplineType, borderColor: InsightsColors.blue, borderWidth: 3, gradient: buildInsightsAreaGradient(InsightsColors.blue), markerSettings: buildInsightsMarker(InsightsColors.blue), ), ], ), ), if (model.hint.isNotEmpty) ...[ const SizedBox(height: 8), Text( model.hint, key: const Key('insights_bmi_hint'), style: const TextStyle( fontSize: 13, color: InsightsColors.subtitle, ), ), ], ], ); } }