forked from eatvio/eatvio_app
85 lines
3.0 KiB
Dart
85 lines
3.0 KiB
Dart
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 range = paddedRange(points.map((e) => e.value), minPadding: 2);
|
||
|
||
return Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
SizedBox(
|
||
height: insightsChartHeight,
|
||
child: SfCartesianChart(
|
||
key: const Key('insights_bmi_chart'),
|
||
margin: EdgeInsets.zero,
|
||
plotAreaBorderWidth: 0,
|
||
primaryXAxis: buildInsightsCategoryAxis(),
|
||
primaryYAxis: buildInsightsValueAxis(
|
||
unit: s.insights_unit_bmi,
|
||
min: range.min,
|
||
max: range.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: <CartesianSeries<InsightsPoint, String>>[
|
||
SplineAreaSeries<InsightsPoint, String>(
|
||
name: s.insights_tab_bmi,
|
||
dataSource: points,
|
||
xValueMapper: (point, _) => point.label,
|
||
yValueMapper: (point, _) => point.value,
|
||
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,
|
||
),
|
||
),
|
||
],
|
||
],
|
||
);
|
||
}
|
||
}
|