forked from eatvio/eatvio_app
87 lines
2.9 KiB
Dart
87 lines
2.9 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';
|
|
|
|
/// Три линии: талия, грудь, бёдра. [visibility] — видимость серий в этом порядке.
|
|
class MeasureChart extends StatelessWidget {
|
|
const MeasureChart({
|
|
super.key,
|
|
required this.model,
|
|
required this.visibility,
|
|
required this.emptyText,
|
|
});
|
|
|
|
final MeasureChartModel model;
|
|
final List<bool> visibility;
|
|
final String emptyText;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final waist = buildPoints(model.labels, model.waist);
|
|
final chest = buildPoints(model.labels, model.chest);
|
|
final hips = buildPoints(model.labels, model.hips);
|
|
if (waist.isEmpty && chest.isEmpty && hips.isEmpty) {
|
|
return InsightsChartPlaceholder(text: emptyText);
|
|
}
|
|
final s = S.of(context);
|
|
final series = [
|
|
(
|
|
name: s.insights_series_waist,
|
|
color: InsightsColors.waist,
|
|
points: waist,
|
|
),
|
|
(
|
|
name: s.insights_series_chest,
|
|
color: InsightsColors.chest,
|
|
points: chest,
|
|
),
|
|
(name: s.insights_series_hips, color: InsightsColors.hips, points: hips),
|
|
];
|
|
final visibleValues = <double>[
|
|
for (var i = 0; i < series.length; i++)
|
|
if (_isVisible(i)) ...series[i].points.map((e) => e.value),
|
|
];
|
|
final range = paddedRange(
|
|
visibleValues.isEmpty
|
|
? series.expand((e) => e.points).map((e) => e.value)
|
|
: visibleValues,
|
|
minPadding: 2,
|
|
);
|
|
|
|
return SizedBox(
|
|
height: insightsChartHeight,
|
|
child: SfCartesianChart(
|
|
key: const Key('insights_measure_chart'),
|
|
margin: EdgeInsets.zero,
|
|
plotAreaBorderWidth: 0,
|
|
primaryXAxis: buildInsightsCategoryAxis(),
|
|
primaryYAxis: buildInsightsValueAxis(
|
|
unit: s.insights_unit_cm,
|
|
min: range.min,
|
|
max: range.max,
|
|
),
|
|
trackballBehavior: buildInsightsTrackball(),
|
|
series: <CartesianSeries<InsightsPoint, String>>[
|
|
for (var i = 0; i < series.length; i++)
|
|
if (_isVisible(i))
|
|
SplineSeries<InsightsPoint, String>(
|
|
name: series[i].name,
|
|
dataSource: series[i].points,
|
|
xValueMapper: (point, _) => point.label,
|
|
yValueMapper: (point, _) => point.value,
|
|
color: series[i].color,
|
|
width: 3,
|
|
markerSettings: buildInsightsMarker(series[i].color),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
bool _isVisible(int index) =>
|
|
index < visibility.length ? visibility[index] : true;
|
|
}
|