Skip to content

Commit

Permalink
fix: Fixes overlapping power axis titles if max value is close to las…
Browse files Browse the repository at this point in the history
…t horizontal line.

This partially reverts commit f1fc08b.
  • Loading branch information
just-seba committed Sep 11, 2024
1 parent 07aa1ae commit 1d0b3ba
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 2 deletions.
15 changes: 13 additions & 2 deletions app/lib/ui/analytics/charts/analytics_day_chart.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:emma/application/analytics/power_data_point_dto.dart';
import 'package:emma/ui/analytics/analytics_view_model.dart';
import 'package:emma/ui/analytics/charts/analytics_chart_color_scheme.dart';
import 'package:emma/ui/analytics/charts/analytics_chart_colors.dart';
import 'package:emma/ui/analytics/charts/nice_scale.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
Expand Down Expand Up @@ -44,7 +45,7 @@ class AnalyticsDayChart extends StatelessWidget {

LineChartData mainData(
TextTheme textTheme, AnalyticsChartColorScheme colorScheme) {
final maxPower = [
final maxValue = [
if (viewModel.chartControl.showHome.value) ...viewModel.day.value.home,
if (viewModel.chartControl.showProduction.value)
...viewModel.day.value.production,
Expand All @@ -54,12 +55,21 @@ class AnalyticsDayChart extends StatelessWidget {
...viewModel.day.value.gridFeedIn,
].map((x) => x.power).fold(100.0, math.max);

final niceScale = NiceScale.calculate(
maxTicks: 10,
min: 0,
max: maxValue,
);

const timeAxisInterval = 120.0;
return LineChartData(
maxY: maxPower,
minY: niceScale.min,
maxY: niceScale.max,
gridData: FlGridData(
show: true,
drawVerticalLine: false,
horizontalInterval: niceScale.tickInterval,
verticalInterval: timeAxisInterval,
getDrawingHorizontalLine: (value) {
return FlLine(
color: colorScheme.mainGridLine,
Expand Down Expand Up @@ -87,6 +97,7 @@ class AnalyticsDayChart extends StatelessWidget {
leftTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
interval: niceScale.tickInterval,
getTitlesWidget: (value, meta) =>
_buildPowerAxisTitleWidget(textTheme, value, meta),
reservedSize: 48,
Expand Down
70 changes: 70 additions & 0 deletions app/lib/ui/analytics/charts/nice_scale.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import 'dart:math' as math;

// https://stackoverflow.com/a/16363437
class NiceScale {
NiceScale._(
{required this.min, required this.max, required this.tickInterval});

final double min;
final double max;
final double tickInterval;

factory NiceScale.calculate({
required int maxTicks,
required double min,
required double max,
}) {
final range = _niceNum(max - min, _NiceNumMethod.ceil);
final tickInterval = _niceNum(range / (maxTicks - 1), _NiceNumMethod.round);
final niceMin = (min / tickInterval).floor() * tickInterval;
final niceMax = (max / tickInterval).ceil() * tickInterval;

return NiceScale._(
min: niceMin,
max: niceMax,
tickInterval: tickInterval,
);
}

static double _niceNum(double range, _NiceNumMethod method) {
final exponent = _log10(range).floor();
final fraction = range / math.pow(10, exponent);

late final double niceFraction;
switch (method) {
case _NiceNumMethod.round:
switch (fraction) {
case < 1.5:
niceFraction = 1;
case < 3:
niceFraction = 2;
case < 7:
niceFraction = 5;
default:
niceFraction = 10;
}
break;
case _NiceNumMethod.ceil:
switch (fraction) {
case <= 1:
niceFraction = 1;
case <= 2:
niceFraction = 2;
case <= 5:
niceFraction = 5;
default:
niceFraction = 10;
}
break;
}

return niceFraction * math.pow(10, exponent);
}

static double _log10(double x) => math.log(x) / math.ln10;
}

enum _NiceNumMethod {
round,
ceil,
}

0 comments on commit 1d0b3ba

Please sign in to comment.