Merge branch 'branch_percobaan'

This commit is contained in:
kleponijo 2026-04-27 20:40:06 +07:00
commit c5f5b7d900
5 changed files with 42 additions and 27 deletions

View File

@ -30,10 +30,14 @@ Future<void> exportWindSpeedPdf({
title: 'Data Terkini',
subtitle: 'Periode: $period',
items: [
SummaryItem('Kecepatan', '${currentSpeed.toStringAsFixed(1)} m/s', '💨'),
SummaryItem('Rata-rata', '${stats['avg']!.toStringAsFixed(1)} m/s', '📊'),
SummaryItem('Maksimum', '${stats['max']!.toStringAsFixed(1)} m/s', '⬆️'),
SummaryItem('Minimum', '${stats['min']!.toStringAsFixed(1)} m/s', '⬇️'),
SummaryItem(
'Kecepatan', '${currentSpeed.toStringAsFixed(1)} m/s', '💨'),
SummaryItem(
'Rata-rata', '${stats['avg']!.toStringAsFixed(1)} m/s', '📊'),
SummaryItem(
'Maksimum', '${stats['max']!.toStringAsFixed(1)} m/s', '⬆️'),
SummaryItem(
'Minimum', '${stats['min']!.toStringAsFixed(1)} m/s', '⬇️'),
],
),
pw.SizedBox(height: 24),
@ -63,11 +67,15 @@ pw.Widget _buildPeriodTable(List<double> speeds, String period) {
final labels = _periodLabels(speeds.length, period);
return buildDataTable(
headers: ['No', 'Label', 'Kecepatan (m/s)'],
rows: speeds.asMap().entries.map((e) => [
'${e.key + 1}',
labels[e.key],
e.value.toStringAsFixed(2),
]).toList(),
rows: speeds
.asMap()
.entries
.map((e) => [
'${e.key + 1}',
labels[e.key],
e.value.toStringAsFixed(2),
])
.toList(),
colWidths: {
0: const pw.FixedColumnWidth(30),
1: const pw.FlexColumnWidth(2),
@ -78,7 +86,7 @@ pw.Widget _buildPeriodTable(List<double> speeds, String period) {
pw.Widget _buildHistoryTable(List<Map<String, dynamic>> data) {
return buildDataTable(
headers: ['No', 'Waktu', 'Kecepatan (m/s)', 'Pulse'],
headers: ['No', 'Waktu', 'Kecepatan (m/s)'],
rows: data.asMap().entries.map((e) {
final d = e.value;
final ts = d['timestamp'] as DateTime?;
@ -86,21 +94,20 @@ pw.Widget _buildHistoryTable(List<Map<String, dynamic>> data) {
'${e.key + 1}',
ts != null ? pdfFullFormat.format(ts) : '-',
(d['speed'] as double? ?? 0).toStringAsFixed(2),
'${d['pulse'] ?? 0}',
];
}).toList(),
colWidths: {
0: const pw.FixedColumnWidth(25),
1: const pw.FlexColumnWidth(2.5),
2: const pw.FlexColumnWidth(1.5),
3: const pw.FlexColumnWidth(1),
},
);
}
List<String> _periodLabels(int count, String period) {
if (period == 'Hari Ini') {
return List.generate(count, (i) => 'Jam ${i.toString().padLeft(2, '0')}:00');
return List.generate(
count, (i) => 'Jam ${i.toString().padLeft(2, '0')}:00');
} else if (period == 'Minggu Ini') {
const days = ['Sen', 'Sel', 'Rab', 'Kam', 'Jum', 'Sab', 'Min'];
return List.generate(count, (i) => days[i % 7]);

View File

@ -163,7 +163,12 @@ class WindSpeedBloc extends Bloc<WindSpeedEvent, WindSpeedState> {
final updatedGraph = TimeSeriesMapper.smooth(raw);
emit(state.copyWith(
dailySpeeds: updatedGraph,
dailySpeeds:
event.period == "Hari Ini" ? updatedGraph : state.dailySpeeds,
weeklySpeeds:
event.period == "Minggu Ini" ? updatedGraph : state.weeklySpeeds,
monthlySpeeds:
event.period == "Bulan Ini" ? updatedGraph : state.monthlySpeeds,
isLoading: false,
));
}

View File

@ -55,7 +55,6 @@ class WindSpeedScreen extends StatelessWidget {
.map((e) => {
'timestamp': e.timestamp,
'speed': e.speed,
'pulse': e.pulse,
})
.toList();

View File

@ -51,11 +51,19 @@ class FirebaseMonitoringRepo implements MonitoringRepository {
if (snapshot.exists && snapshot.value is Map) {
final Map<dynamic, dynamic> data = snapshot.value as Map;
// Karena RTDB push() menghasilkan Map dengan ID unik,
// kita ambil values-nya saja dan ubah jadi List objek
return data.values.map((item) {
final list = data.values.map((item) {
return mapper(item as Map<dynamic, dynamic>);
}).toList();
// Sort by timestamp Firebase push tidak jamin urutan
list.sort((a, b) {
if (a is MyWindSpeed && b is MyWindSpeed) {
return a.timestamp.compareTo(b.timestamp);
}
return 0;
});
return list;
}
return [];
} catch (e) {

View File

@ -1,26 +1,22 @@
class MyWindSpeed {
double speed;
int pulse;
DateTime timestamp;
MyWindSpeed({
required this.speed,
required this.pulse,
required this.timestamp,
});
MyWindSpeed({required this.speed, required this.timestamp});
static final empty = MyWindSpeed(
speed: 0.0,
pulse: 0,
timestamp: DateTime.fromMillisecondsSinceEpoch(0),
);
factory MyWindSpeed.fromJson(Map<dynamic, dynamic> json) {
return MyWindSpeed(
speed: (json['speed'] ?? 0).toDouble(),
pulse: (json['pulse'] ?? 0) as int,
timestamp: DateTime.fromMillisecondsSinceEpoch(
(json['timesTamp'] ?? 0) * 1000, // kalau dari Unix detik
(json['timestamp'] ?? 0) * 1000, // kalau dari Unix detik
).toLocal(),
);
}