|
...
|
...
|
@@ -3,10 +3,12 @@ import 'dart:math' as math; |
|
|
|
|
|
|
|
import 'package:fl_chart/fl_chart.dart';
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:doublefeel_flutter/data/models/interaction/interaction_models.dart';
|
|
|
|
import 'package:doublefeel_flutter/app/utils/platform_compact.dart';
|
|
|
|
import 'package:doublefeel_flutter/l10n/l10n_extensions.dart';
|
|
|
|
|
|
|
|
import '../../../../r.dart';
|
|
|
|
import '../../../widget/friend_interact_click_view.dart';
|
|
|
|
import '../../report_common/widgets/chart_selection_line_overlay.dart';
|
|
|
|
import '../../report_common/widgets/health_report_subject_scope.dart';
|
|
|
|
import '../../report_common/utils/report_localization.dart';
|
|
...
|
...
|
@@ -16,14 +18,14 @@ import 'activity_burn_ring.dart'; |
|
|
|
import 'activity_burn_trend_lines.dart';
|
|
|
|
|
|
|
|
String _weekdayLabel(BuildContext context, int weekday) => switch (weekday) {
|
|
|
|
DateTime.monday => context.l10n.activityWeeklyWeekdayMonday,
|
|
|
|
DateTime.tuesday => context.l10n.activityWeeklyWeekdayTuesday,
|
|
|
|
DateTime.wednesday => context.l10n.activityWeeklyWeekdayWednesday,
|
|
|
|
DateTime.thursday => context.l10n.activityWeeklyWeekdayThursday,
|
|
|
|
DateTime.friday => context.l10n.activityWeeklyWeekdayFriday,
|
|
|
|
DateTime.saturday => context.l10n.activityWeeklyWeekdaySaturday,
|
|
|
|
_ => context.l10n.activityWeeklyWeekdaySunday,
|
|
|
|
};
|
|
|
|
DateTime.monday => context.l10n.activityWeeklyWeekdayMonday,
|
|
|
|
DateTime.tuesday => context.l10n.activityWeeklyWeekdayTuesday,
|
|
|
|
DateTime.wednesday => context.l10n.activityWeeklyWeekdayWednesday,
|
|
|
|
DateTime.thursday => context.l10n.activityWeeklyWeekdayThursday,
|
|
|
|
DateTime.friday => context.l10n.activityWeeklyWeekdayFriday,
|
|
|
|
DateTime.saturday => context.l10n.activityWeeklyWeekdaySaturday,
|
|
|
|
_ => context.l10n.activityWeeklyWeekdaySunday,
|
|
|
|
};
|
|
|
|
|
|
|
|
class ActivityBurnWeekReportView extends StatelessWidget {
|
|
|
|
const ActivityBurnWeekReportView({
|
|
...
|
...
|
@@ -135,7 +137,9 @@ class _WeeklySummary extends StatelessWidget { |
|
|
|
children: [
|
|
|
|
_SummaryMetric(
|
|
|
|
title: HealthReportSubjectScope.titleOf(
|
|
|
|
context, context.l10n.activityWeeklyExerciseTitle),
|
|
|
|
context,
|
|
|
|
context.l10n.activityWeeklyExerciseTitle,
|
|
|
|
),
|
|
|
|
value: exercise.value,
|
|
|
|
unit: exercise.unit,
|
|
|
|
color: isOhos()
|
|
...
|
...
|
@@ -145,7 +149,9 @@ class _WeeklySummary extends StatelessWidget { |
|
|
|
const SizedBox(width: 34),
|
|
|
|
_SummaryMetric(
|
|
|
|
title: HealthReportSubjectScope.titleOf(
|
|
|
|
context, context.l10n.activityWeeklyStandTitle),
|
|
|
|
context,
|
|
|
|
context.l10n.activityWeeklyStandTitle,
|
|
|
|
),
|
|
|
|
value: stand.value,
|
|
|
|
unit: stand.unit,
|
|
|
|
color: ActivityBurnWeekReportView._stand,
|
|
...
|
...
|
@@ -158,8 +164,8 @@ class _WeeklySummary extends StatelessWidget { |
|
|
|
}
|
|
|
|
|
|
|
|
String _totalBurnTitle(BuildContext context) {
|
|
|
|
final scope =
|
|
|
|
context.dependOnInheritedWidgetOfExactType<HealthReportSubjectScope>();
|
|
|
|
final scope = context
|
|
|
|
.dependOnInheritedWidgetOfExactType<HealthReportSubjectScope>();
|
|
|
|
return scope == null || scope.isSelf
|
|
|
|
? context.l10n.activityWeeklySelfTitle
|
|
|
|
: context.l10n.activityWeeklyOtherTitle;
|
|
...
|
...
|
@@ -294,9 +300,7 @@ class _RingOverviewCard extends StatelessWidget { |
|
|
|
const SizedBox(height: 20),
|
|
|
|
Row(
|
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
|
children: [
|
|
|
|
for (final day in report.days) _DayRing(report: day),
|
|
|
|
],
|
|
|
|
children: [for (final day in report.days) _DayRing(report: day)],
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
...
|
...
|
@@ -327,10 +331,7 @@ class _RingStat extends StatelessWidget { |
|
|
|
children: [
|
|
|
|
Row(
|
|
|
|
children: [
|
|
|
|
ActivityBurnRing(
|
|
|
|
report: report,
|
|
|
|
size: 12,
|
|
|
|
),
|
|
|
|
ActivityBurnRing(report: report, size: 12),
|
|
|
|
const SizedBox(width: 5),
|
|
|
|
Text(
|
|
|
|
label,
|
|
...
|
...
|
@@ -506,169 +507,175 @@ class _ActivityBurnEnergyTrendCardState |
|
|
|
final hasChartData = _hasChartData;
|
|
|
|
final maxY = _maxY;
|
|
|
|
final comparisonPercent = widget.report.activeEnergyComparisonPercent;
|
|
|
|
return Container(
|
|
|
|
height: 344,
|
|
|
|
padding: const EdgeInsets.fromLTRB(20, 20, 14, 32),
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
color: Colors.white,
|
|
|
|
borderRadius: BorderRadius.circular(16),
|
|
|
|
),
|
|
|
|
child: Column(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
children: [
|
|
|
|
Text(
|
|
|
|
HealthReportSubjectScope.titleOf(
|
|
|
|
context, context.l10n.activityCalorieTrend),
|
|
|
|
style: const TextStyle(
|
|
|
|
color: ActivityBurnWeekReportView._h1,
|
|
|
|
fontSize: 16,
|
|
|
|
fontWeight: FontWeight.w600,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
const SizedBox(height: 10),
|
|
|
|
Row(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.baseline,
|
|
|
|
textBaseline: TextBaseline.alphabetic,
|
|
|
|
children: [
|
|
|
|
Text(
|
|
|
|
hasData
|
|
|
|
? widget.report.averageDailyActiveEnergy.toString()
|
|
|
|
: '-',
|
|
|
|
style: const TextStyle(
|
|
|
|
color: ActivityBurnWeekReportView._h1,
|
|
|
|
fontSize: 18,
|
|
|
|
fontWeight: FontWeight.w700,
|
|
|
|
),
|
|
|
|
return FriendInteractCardOverlay(
|
|
|
|
showInteraction: !HealthReportSubjectScope.isViewingSelf(context),
|
|
|
|
interactionType: FriendInteractionType.weeklyActivityBurn,
|
|
|
|
child: Container(
|
|
|
|
height: 344,
|
|
|
|
padding: const EdgeInsets.fromLTRB(20, 20, 14, 32),
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
color: Colors.white,
|
|
|
|
borderRadius: BorderRadius.circular(16),
|
|
|
|
),
|
|
|
|
child: Column(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
children: [
|
|
|
|
Text(
|
|
|
|
HealthReportSubjectScope.titleOf(
|
|
|
|
context,
|
|
|
|
context.l10n.activityCalorieTrend,
|
|
|
|
),
|
|
|
|
Padding(
|
|
|
|
padding: const EdgeInsets.only(left: 4),
|
|
|
|
child: Text(
|
|
|
|
context.l10n.activityKcalDailyAverage,
|
|
|
|
style: const TextStyle(
|
|
|
|
color: ActivityBurnWeekReportView._h1,
|
|
|
|
fontSize: 16,
|
|
|
|
fontWeight: FontWeight.w600,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
const SizedBox(height: 10),
|
|
|
|
Row(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.baseline,
|
|
|
|
textBaseline: TextBaseline.alphabetic,
|
|
|
|
children: [
|
|
|
|
Text(
|
|
|
|
hasData
|
|
|
|
? widget.report.averageDailyActiveEnergy.toString()
|
|
|
|
: '-',
|
|
|
|
style: const TextStyle(
|
|
|
|
color: ActivityBurnWeekReportView._h1,
|
|
|
|
fontSize: 12,
|
|
|
|
fontSize: 18,
|
|
|
|
fontWeight: FontWeight.w700,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
const SizedBox(height: 2),
|
|
|
|
Row(
|
|
|
|
children: [
|
|
|
|
if (comparisonPercent != null) ...[
|
|
|
|
Image.asset(
|
|
|
|
comparisonPercent >= 0
|
|
|
|
? R.assetsImagesHealthTrendUp
|
|
|
|
: R.assetsImagesHealthTrendDown,
|
|
|
|
width: 12,
|
|
|
|
height: 12,
|
|
|
|
Padding(
|
|
|
|
padding: const EdgeInsets.only(left: 4),
|
|
|
|
child: Text(
|
|
|
|
context.l10n.activityKcalDailyAverage,
|
|
|
|
style: const TextStyle(
|
|
|
|
color: ActivityBurnWeekReportView._h1,
|
|
|
|
fontSize: 12,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
const SizedBox(width: 2),
|
|
|
|
],
|
|
|
|
Text(
|
|
|
|
_comparisonText(context, comparisonPercent),
|
|
|
|
style: const TextStyle(
|
|
|
|
color: ActivityBurnWeekReportView._h2,
|
|
|
|
fontSize: 12,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
const Spacer(),
|
|
|
|
_TrendLegend(
|
|
|
|
color: const Color(0xFFFFC0CE),
|
|
|
|
label: context.l10n.activityTrendAverage,
|
|
|
|
),
|
|
|
|
const SizedBox(width: 12),
|
|
|
|
_TrendLegend(
|
|
|
|
color: const Color(0xFF96E9CB),
|
|
|
|
label: context.l10n.activityTrendGoal,
|
|
|
|
dashed: true,
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
const SizedBox(height: 8),
|
|
|
|
Expanded(
|
|
|
|
child: Stack(
|
|
|
|
alignment: Alignment.center,
|
|
|
|
clipBehavior: Clip.none,
|
|
|
|
),
|
|
|
|
const SizedBox(height: 2),
|
|
|
|
Row(
|
|
|
|
children: [
|
|
|
|
Positioned(
|
|
|
|
left: 0,
|
|
|
|
right: 0,
|
|
|
|
top: _chartTopInset,
|
|
|
|
bottom: 0,
|
|
|
|
child: ActivityBurnTrendPlotFrame(
|
|
|
|
maxY: maxY,
|
|
|
|
average: widget.report.averageDailyActiveEnergy.toDouble(),
|
|
|
|
target: widget.report.activeEnergyGoal.toDouble(),
|
|
|
|
child: LayoutBuilder(
|
|
|
|
builder: (context, constraints) => Listener(
|
|
|
|
behavior: HitTestBehavior.opaque,
|
|
|
|
onPointerDown: (event) => _selectTooltipAt(
|
|
|
|
event.localPosition.dx,
|
|
|
|
constraints.maxWidth,
|
|
|
|
),
|
|
|
|
onPointerMove: (event) => _selectTooltipAt(
|
|
|
|
event.localPosition.dx,
|
|
|
|
constraints.maxWidth,
|
|
|
|
),
|
|
|
|
onPointerUp: (_) => _scheduleTooltipDismissal(),
|
|
|
|
onPointerCancel: (_) => _scheduleTooltipDismissal(),
|
|
|
|
child: Transform.translate(
|
|
|
|
offset: const Offset(
|
|
|
|
(_xAxisLeftInset - _xAxisRightInset) / 2,
|
|
|
|
0,
|
|
|
|
),
|
|
|
|
child: BarChart(
|
|
|
|
_chartData(maxY, constraints.maxWidth),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
if (comparisonPercent != null) ...[
|
|
|
|
Image.asset(
|
|
|
|
comparisonPercent >= 0
|
|
|
|
? R.assetsImagesHealthTrendUp
|
|
|
|
: R.assetsImagesHealthTrendDown,
|
|
|
|
width: 12,
|
|
|
|
height: 12,
|
|
|
|
),
|
|
|
|
const SizedBox(width: 2),
|
|
|
|
],
|
|
|
|
Text(
|
|
|
|
_comparisonText(context, comparisonPercent),
|
|
|
|
style: const TextStyle(
|
|
|
|
color: ActivityBurnWeekReportView._h2,
|
|
|
|
fontSize: 12,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
if (_touchedIndex != null)
|
|
|
|
Positioned.fill(
|
|
|
|
const Spacer(),
|
|
|
|
_TrendLegend(
|
|
|
|
color: const Color(0xFFFFC0CE),
|
|
|
|
label: context.l10n.activityTrendAverage,
|
|
|
|
),
|
|
|
|
const SizedBox(width: 12),
|
|
|
|
_TrendLegend(
|
|
|
|
color: const Color(0xFF96E9CB),
|
|
|
|
label: context.l10n.activityTrendGoal,
|
|
|
|
dashed: true,
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
const SizedBox(height: 8),
|
|
|
|
Expanded(
|
|
|
|
child: Stack(
|
|
|
|
alignment: Alignment.center,
|
|
|
|
clipBehavior: Clip.none,
|
|
|
|
children: [
|
|
|
|
Positioned(
|
|
|
|
left: 0,
|
|
|
|
right: 0,
|
|
|
|
top: _chartTopInset,
|
|
|
|
child: LayoutBuilder(
|
|
|
|
builder: (context, constraints) {
|
|
|
|
return ChartSelectionLineOverlay(
|
|
|
|
offset: Offset.zero,
|
|
|
|
color: ActivityBurnWeekReportView._h3,
|
|
|
|
bottomTitleHeight:
|
|
|
|
ActivityBurnTrendPlotFrame.bottomTitleHeight,
|
|
|
|
tooltipMargin: _tooltipMargin,
|
|
|
|
plotLeft: _xAxisLeftInset,
|
|
|
|
plotRight: _xAxisRightInset,
|
|
|
|
lineX: _lineXForIndex(
|
|
|
|
bottom: 0,
|
|
|
|
child: ActivityBurnTrendPlotFrame(
|
|
|
|
maxY: maxY,
|
|
|
|
average: widget.report.averageDailyActiveEnergy
|
|
|
|
.toDouble(),
|
|
|
|
target: widget.report.activeEnergyGoal.toDouble(),
|
|
|
|
child: LayoutBuilder(
|
|
|
|
builder: (context, constraints) => Listener(
|
|
|
|
behavior: HitTestBehavior.opaque,
|
|
|
|
onPointerDown: (event) => _selectTooltipAt(
|
|
|
|
event.localPosition.dx,
|
|
|
|
constraints.maxWidth,
|
|
|
|
),
|
|
|
|
lineTop:
|
|
|
|
_tooltipBottomForHeight(constraints.maxHeight),
|
|
|
|
);
|
|
|
|
},
|
|
|
|
onPointerMove: (event) => _selectTooltipAt(
|
|
|
|
event.localPosition.dx,
|
|
|
|
constraints.maxWidth,
|
|
|
|
),
|
|
|
|
onPointerUp: (_) => _scheduleTooltipDismissal(),
|
|
|
|
onPointerCancel: (_) => _scheduleTooltipDismissal(),
|
|
|
|
child: Transform.translate(
|
|
|
|
offset: const Offset(
|
|
|
|
(_xAxisLeftInset - _xAxisRightInset) / 2,
|
|
|
|
0,
|
|
|
|
),
|
|
|
|
child: BarChart(
|
|
|
|
_chartData(maxY, constraints.maxWidth),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
if (!hasChartData)
|
|
|
|
Positioned(
|
|
|
|
left: _xAxisLeftInset,
|
|
|
|
right: _xAxisRightInset,
|
|
|
|
top: _chartTopInset,
|
|
|
|
bottom: ActivityBurnTrendPlotFrame.bottomTitleHeight,
|
|
|
|
child: Center(
|
|
|
|
child: Text(
|
|
|
|
context.l10n.activityTrendAwaitingData,
|
|
|
|
style: const TextStyle(
|
|
|
|
color: Color(0xFFA1A0A5),
|
|
|
|
fontSize: 12,
|
|
|
|
fontWeight: FontWeight.w400,
|
|
|
|
if (_touchedIndex != null)
|
|
|
|
Positioned.fill(
|
|
|
|
top: _chartTopInset,
|
|
|
|
child: LayoutBuilder(
|
|
|
|
builder: (context, constraints) {
|
|
|
|
return ChartSelectionLineOverlay(
|
|
|
|
offset: Offset.zero,
|
|
|
|
color: ActivityBurnWeekReportView._h3,
|
|
|
|
bottomTitleHeight:
|
|
|
|
ActivityBurnTrendPlotFrame.bottomTitleHeight,
|
|
|
|
tooltipMargin: _tooltipMargin,
|
|
|
|
plotLeft: _xAxisLeftInset,
|
|
|
|
plotRight: _xAxisRightInset,
|
|
|
|
lineX: _lineXForIndex(constraints.maxWidth),
|
|
|
|
lineTop: _tooltipBottomForHeight(
|
|
|
|
constraints.maxHeight,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
},
|
|
|
|
),
|
|
|
|
),
|
|
|
|
if (!hasChartData)
|
|
|
|
Positioned(
|
|
|
|
left: _xAxisLeftInset,
|
|
|
|
right: _xAxisRightInset,
|
|
|
|
top: _chartTopInset,
|
|
|
|
bottom: ActivityBurnTrendPlotFrame.bottomTitleHeight,
|
|
|
|
child: Center(
|
|
|
|
child: Text(
|
|
|
|
context.l10n.activityTrendAwaitingData,
|
|
|
|
style: const TextStyle(
|
|
|
|
color: Color(0xFFA1A0A5),
|
|
|
|
fontSize: 12,
|
|
|
|
fontWeight: FontWeight.w400,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
...
|
...
|
@@ -678,9 +685,9 @@ class _ActivityBurnEnergyTrendCardState |
|
|
|
.map((day) => day.activeEnergy?.value ?? 0)
|
|
|
|
.fold<int>(0, (max, value) => value > max ? value : max);
|
|
|
|
final maxReference = math.max(maxValue, widget.report.activeEnergyGoal);
|
|
|
|
return _roundUpToFiveOrZero(maxReference)
|
|
|
|
.clamp(100, double.infinity)
|
|
|
|
.toDouble();
|
|
|
|
return _roundUpToFiveOrZero(
|
|
|
|
maxReference,
|
|
|
|
).clamp(100, double.infinity).toDouble();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool get _hasChartData =>
|
|
...
|
...
|
@@ -753,16 +760,18 @@ class _ActivityBurnEnergyTrendCardState |
|
|
|
if (chartWidth <= 0) return null;
|
|
|
|
final groupsSpace = _groupsSpace(chartWidth, count);
|
|
|
|
const chartLeft = _xAxisLeftInset;
|
|
|
|
final index = ((dx - chartLeft - widget.report.barWidth / 2) /
|
|
|
|
(widget.report.barWidth + groupsSpace))
|
|
|
|
.round();
|
|
|
|
final index =
|
|
|
|
((dx - chartLeft - widget.report.barWidth / 2) /
|
|
|
|
(widget.report.barWidth + groupsSpace))
|
|
|
|
.round();
|
|
|
|
return index.clamp(0, count - 1).toInt();
|
|
|
|
}
|
|
|
|
|
|
|
|
void _selectTooltipAt(double? dx, double plotWidth) {
|
|
|
|
_tooltipDismissTimer?.cancel();
|
|
|
|
final touchedIndex = _indexForTouch(dx, plotWidth);
|
|
|
|
final hasTouchedData = touchedIndex != null &&
|
|
|
|
final hasTouchedData =
|
|
|
|
touchedIndex != null &&
|
|
|
|
(widget.report.days[touchedIndex].activeEnergy?.value ?? 0) > 0;
|
|
|
|
final nextIndex = hasTouchedData ? touchedIndex : null;
|
|
|
|
if (_touchedIndex == nextIndex) return;
|
|
...
|
...
|
@@ -779,16 +788,16 @@ class _ActivityBurnEnergyTrendCardState |
|
|
|
|
|
|
|
BarChartData _chartData(double maxY, double plotWidth) {
|
|
|
|
final hasData = widget.report.hasData;
|
|
|
|
final chartWidth =
|
|
|
|
math.max(0.0, plotWidth - _xAxisLeftInset - _xAxisRightInset);
|
|
|
|
final chartWidth = math.max(
|
|
|
|
0.0,
|
|
|
|
plotWidth - _xAxisLeftInset - _xAxisRightInset,
|
|
|
|
);
|
|
|
|
return BarChartData(
|
|
|
|
minY: 0,
|
|
|
|
maxY: maxY,
|
|
|
|
alignment: BarChartAlignment.center,
|
|
|
|
groupsSpace: _groupsSpace(chartWidth, widget.report.days.length),
|
|
|
|
gridData: FlGridData(
|
|
|
|
show: false,
|
|
|
|
),
|
|
|
|
gridData: FlGridData(show: false),
|
|
|
|
borderData: FlBorderData(show: false),
|
|
|
|
barTouchData: BarTouchData(
|
|
|
|
enabled: hasData,
|
|
...
|
...
|
@@ -802,10 +811,7 @@ class _ActivityBurnEnergyTrendCardState |
|
|
|
_scheduleTooltipDismissal();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
_selectTooltipAt(
|
|
|
|
event.localPosition?.dx,
|
|
|
|
plotWidth,
|
|
|
|
);
|
|
|
|
_selectTooltipAt(event.localPosition?.dx, plotWidth);
|
|
|
|
},
|
|
|
|
touchTooltipData: BarTouchTooltipData(
|
|
|
|
tooltipRoundedRadius: 4,
|
|
...
|
...
|
@@ -850,7 +856,8 @@ class _ActivityBurnEnergyTrendCardState |
|
|
|
reservedSize: 36,
|
|
|
|
interval: activityBurnTrendYInterval(maxY),
|
|
|
|
getTitlesWidget: (value, meta) {
|
|
|
|
final isRegularTick = value % activityBurnTrendYInterval(maxY) == 0;
|
|
|
|
final isRegularTick =
|
|
|
|
value % activityBurnTrendYInterval(maxY) == 0;
|
|
|
|
final isMax = (value - maxY).abs() < 0.001;
|
|
|
|
if (!isRegularTick && !isMax) return const SizedBox.shrink();
|
|
|
|
return Transform.translate(
|
|
...
|
...
|
@@ -939,8 +946,10 @@ class _ActivityBurnEnergyTrendCardState |
|
|
|
final count = widget.report.days.length;
|
|
|
|
if (count <= 7) return true;
|
|
|
|
final lastIndex = count - 1;
|
|
|
|
return List.generate(7, (tick) => (tick * lastIndex / 6).round())
|
|
|
|
.contains(index);
|
|
|
|
return List.generate(
|
|
|
|
7,
|
|
|
|
(tick) => (tick * lastIndex / 6).round(),
|
|
|
|
).contains(index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
...
|
...
|
|