Newer
Older
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:scrobbles/config/app_colors.dart';
import 'package:scrobbles/models/data/heatmap.dart';
import 'package:scrobbles/ui/widgets/abstracts/custom_chart.dart';
const ChartHeatmap({super.key, required this.chartData});
final Color baseColor = AppColors.contentColorPink;
final double scale = 8.0;
final double darkenAmount = 50;
@override
Widget build(BuildContext context) {
if (chartData.data.keys.isEmpty) {
height: chartHeight,
);
}
return AspectRatio(
aspectRatio: 3,
child: ScatterChart(
ScatterChartData(
scatterSpots: getSpots(),
minX: 0,
minY: 0,
maxY: 7,
borderData: FlBorderData(show: false),
gridData: const FlGridData(show: false),
titlesData: getTitlesData(),
scatterTouchData: ScatterTouchData(enabled: false),
),
),
);
}
Color getColorFromNormalizedValue(double value) {
Color colorFrom = Colors.white;
Color colorTo = Colors.pink;
return Color.lerp(colorFrom, colorTo, value) ?? colorFrom;
}
int getMaxCount() {
int maxValue = 0;
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();
chartData.data.forEach((day, hours) {
// hours.removeWhere((h, i) => h == 24);
hours.forEach((hour, count) {
double normalizedValue = count / maxCount;
spots.add(ScatterSpot(
dotPainter: FlDotSquarePainter(
color: getColorFromNormalizedValue(normalizedValue),
size: 12,
strokeWidth: 0,
),
const AxisTitles none = AxisTitles(
sideTitles: SideTitles(showTitles: false),
);
final AxisTitles verticalTitles = AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 40,
getTitlesWidget: getVerticalTitlesWidgetWithValue,
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 getVerticalTitlesWidgetWithValue(double value, TitleMeta meta) {
final String dayShortName = getDayShortName(8 - value.toInt());
space: 10,
child: Text(
tr(dayShortName),
style: TextStyle(
fontSize: titleFontSize,