-
Notifications
You must be signed in to change notification settings - Fork 95
Expand file tree
/
Copy pathheatmap_page.dart
More file actions
182 lines (156 loc) · 5.33 KB
/
heatmap_page.dart
File metadata and controls
182 lines (156 loc) · 5.33 KB
1
2
3
4
5
6
7
8
9
10
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
import 'dart:math';
import 'package:flutter/material.dart';
import './heatmap_month_text.dart';
import './heatmap_column.dart';
import '../data/heatmap_color_mode.dart';
import '../util/datasets_util.dart';
import '../util/date_util.dart';
import './heatmap_week_text.dart';
class HeatMapPage extends StatelessWidget {
/// List value of every sunday's month information.
///
/// From 1: January to 12: December.
final List<int> _firstDayInfos = [];
/// The number of days between [startDate] and [endDate].
final int _dateDifferent;
/// The Date value of start day of heatmap.
///
/// HeatMap shows the start day of [startDate]'s week.
///
/// Default value is 1 year before the [endDate].
/// And if [endDate] is null, then set 1 year before the [DateTime.now]
final DateTime startDate;
/// The Date value of end day of heatmap.
///
/// Default value is [DateTime.now]
final DateTime endDate;
/// The double value of every block's width and height.
final double? size;
/// The double value of every block's fontSize.
final double? fontSize;
/// The datasets which fill blocks based on its value.
final Map<DateTime, int>? datasets;
/// The margin value for every block.
final EdgeInsets? margin;
/// The default background color value of every blocks.
final Color? defaultColor;
/// The text color value of every blocks.
final Color? textColor;
/// ColorMode changes the color mode of blocks.
///
/// [ColorMode.opacity] requires just one colorsets value and changes color
/// dynamically based on hightest value of [datasets].
/// [ColorMode.color] changes colors based on [colorsets] thresholds key value.
final ColorMode colorMode;
/// The colorsets which give the color value for its thresholds key value.
///
/// Be aware that first Color is the maximum value if [ColorMode] is [ColorMode.opacity].
final Map<int, Color>? colorsets;
/// The double value of every block's borderRadius.
final double? borderRadius;
/// The integer value of the maximum value for the [datasets].
///
/// Get highest key value of filtered datasets using [DatasetsUtil.getMaxValue].
final int? maxValue;
/// Function that will be called when a block is clicked.
///
/// Paratmeter gives clicked [DateTime] value.
final Function(DateTime)? onClick;
final bool? showText;
final bool? showWeekText;
HeatMapPage({
Key? key,
required this.colorMode,
required this.startDate,
required this.endDate,
this.size,
this.fontSize,
this.datasets,
this.defaultColor,
this.textColor,
this.colorsets,
this.borderRadius,
this.onClick,
this.margin,
this.showText,
this.showWeekText,
}) : _dateDifferent = endDate.difference(startDate).inDays,
maxValue = DatasetsUtil.getMaxValue(datasets),
super(key: key);
/// Get [HeatMapColumn] from [startDate] to [endDate].
List<Widget> _heatmapColumnList() {
// Create empty list.
List<Widget> columns = [];
// Set cursor(position) to first day of weeks
// until cursor reaches the final week.
for (int datePos = 0 - (startDate.weekday % 7);
datePos <= _dateDifferent;
datePos += 7) {
// Get first day of week by adding cursor's value to startDate.
DateTime _firstDay = DateUtil.changeDay(startDate, datePos);
columns.add(HeatMapColumn(
// If last day is not saturday, week also includes future Date.
// So we have to make future day on last column blanck.
//
// To make empty space to future day, we have to pass this HeatMapPage's
// endDate to HeatMapColumn's endDate.
startDate: _firstDay,
endDate: datePos <= _dateDifferent - 7
? DateUtil.changeDay(startDate, datePos + 6)
: endDate,
colorMode: colorMode,
numDays: min(endDate.difference(_firstDay).inDays + 1, 7),
size: size,
fontSize: fontSize,
defaultColor: defaultColor,
colorsets: colorsets,
textColor: textColor,
borderRadius: borderRadius,
margin: margin,
maxValue: maxValue,
onClick: onClick,
datasets: datasets,
showText: showText,
));
// also add first day's month information to _firstDayInfos list.
_firstDayInfos.add(_firstDay.month);
}
return columns;
}
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Row(
mainAxisSize: MainAxisSize.min,
children: [
// Show week labels to left side of heatmap.
if (showWeekText ?? true) HeatMapWeekText(
margin: margin,
fontSize: fontSize,
size: size,
fontColor: textColor,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Show month labels to top of heatmap.
HeatMapMonthText(
firstDayInfos: _firstDayInfos,
margin: margin,
fontSize: fontSize,
fontColor: textColor,
size: size,
),
// Heatmap itself.
Row(
children: <Widget>[..._heatmapColumnList()],
),
],
),
],
),
],
);
}
}