Newer
Older
import 'package:easy_localization/easy_localization.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:scrobbles/config/app_colors.dart';
import 'package:scrobbles/ui/widgets/abstracts/custom_chart.dart';
import 'package:scrobbles/utils/color_extensions.dart';
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
final HeatmapData chartData;
const ChartHeatmap({super.key, required this.chartData});
final double chartHeight = 150.0;
final double titleFontSize = 9;
final Color baseColor = AppColors.contentColorPink;
final double scale = 8.0;
final double darkenAmount = 50;
@override
Widget build(BuildContext context) {
if (this.chartData.data.keys.length == 0) {
return SizedBox(
height: this.chartHeight,
);
}
return AspectRatio(
aspectRatio: 3,
child: ScatterChart(
ScatterChartData(
scatterSpots: getSpots(),
minX: 0,
maxX: 24,
minY: 0,
maxY: 7,
borderData: FlBorderData(show: false),
gridData: FlGridData(show: false),
titlesData: getTitlesData(),
scatterTouchData: ScatterTouchData(enabled: false),
),
),
);
}
Color getColorFromNormalizedValue(double value) {
return baseColor.darken(1 + (darkenAmount * (1 - value)).toInt());
}
int getMaxCount() {
int maxValue = 0;
this.chartData.data.forEach((day, hours) {
hours.forEach((hour, count) {
if (count > maxValue) {
maxValue = count;
}
});
});
return maxValue;
}
List<ScatterSpot> getSpots() {
List<ScatterSpot> spots = [];
final int maxCount = getMaxCount();
this.chartData.data.forEach((day, hours) {
hours.forEach((hour, count) {
double normalizedValue = count / maxCount;
spots.add(ScatterSpot(
hour.toDouble(),
color: getColorFromNormalizedValue(normalizedValue),
radius: scale * normalizedValue,
));
});
});
return spots;
}
FlTitlesData getTitlesData() {
const AxisTitles none = const AxisTitles(
sideTitles: SideTitles(showTitles: false),
);
final AxisTitles verticalTitles = AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 40,
getTitlesWidget: getVerticalTitlesWidget,
interval: 1,
),
);
final AxisTitles horizontalTitles = AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 20,
getTitlesWidget: getHorizontalTitlesWidgetWithHour,
interval: 4,
),
);
return FlTitlesData(
show: true,
bottomTitles: horizontalTitles,
leftTitles: verticalTitles,
topTitles: none,
rightTitles: none,
);
}
Widget getVerticalTitlesWidget(double value, TitleMeta meta) {
final String dayShortName = getDayShortName(8 - value.toInt());