Added Station Filter without function and refactored

This commit is contained in:
2025-01-27 16:27:25 +01:00
parent 81f5924df5
commit 4765342ad1
5 changed files with 54 additions and 9 deletions

View File

@@ -0,0 +1,53 @@
import 'package:flutter/material.dart';
import '../model/flood_station.dart';
class FloodStationListView extends StatelessWidget {
const FloodStationListView(
{super.key,
required List<FloodStation> stations,
required this.onItemTapped})
: _stations = stations;
final List<FloodStation> _stations;
final void Function(FloodStation) onItemTapped;
@override
Widget build(BuildContext context) {
return ListView.separated(
separatorBuilder: (context, index) => Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: Divider(),
),
itemBuilder: (context, index) {
final item = _stations.elementAt(index);
return ListTile(
isThreeLine: true,
onTap: () => onItemTapped(item),
title: Text(item.label),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.home_outlined),
Padding(padding: EdgeInsets.only(left: 8)),
Text(item.town),
],
),
Row(
children: [
Icon(Icons.water),
Padding(padding: EdgeInsets.only(left: 8)),
Text(item.riverName),
],
)
],
),
);
},
itemCount: _stations.length,
);
}
}

View File

@@ -0,0 +1,115 @@
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart' as intl;
import 'dart:math';
import '../model/reading.dart';
class ReadingGraph extends StatelessWidget {
const ReadingGraph({super.key, required List<Reading> readings})
: _readings = readings;
final List<Reading> _readings;
@override
Widget build(BuildContext context) {
final spots = _readings
.map<FlSpot>(
(e) => FlSpot(
e.dateTime.millisecondsSinceEpoch.toDouble() / 1000 / 60,
e.value),
)
.toList();
return LineChart(
LineChartData(
maxY: _readings.map<double>((e) => e.value).reduce(max) + 0.05,
minY: _readings.map<double>((e) => e.value).reduce(min) - 0.05,
lineBarsData: [
LineChartBarData(
isCurved: true,
color: Colors.cyan,
barWidth: 2,
isStrokeCapRound: true,
dotData: const FlDotData(show: false),
spots: _readings
.map<FlSpot>(
(e) => FlSpot(
e.dateTime.millisecondsSinceEpoch.toDouble() / 1000 / 60,
e.value),
)
.toList(),
)
],
titlesData: FlTitlesData(
bottomTitles: getBottomTitles(spots),
leftTitles: getLeftTitles(spots),
topTitles: const AxisTitles(sideTitles: SideTitles()),
rightTitles: const AxisTitles(sideTitles: SideTitles()),
),
lineTouchData: LineTouchData(
touchTooltipData: LineTouchTooltipData(
getTooltipItems: (touchedSpots) {
return touchedSpots.map((touchedSpot) {
return LineTooltipItem(
'${touchedSpot.y.toString()}\n${getLongDate(touchedSpot.x)}',
TextStyle(
color: Theme.of(context).colorScheme.onPrimary,
fontWeight: FontWeight.bold));
}).toList();
},
),
),
),
);
}
AxisTitles getBottomTitles(List<FlSpot> spots) {
return AxisTitles(
sideTitles: SideTitles(
interval: 90,
reservedSize: 40,
showTitles: true,
maxIncluded: false,
getTitlesWidget: (value, meta) => SideTitleWidget(
meta: meta,
child: Text(getDate(value)),
),
),
);
}
AxisTitles getLeftTitles(List<FlSpot> spots) {
return AxisTitles(
sideTitles: SideTitles(
reservedSize: 50,
showTitles: true,
maxIncluded: false,
minIncluded: false,
getTitlesWidget: (value, meta) => SideTitleWidget(
meta: meta,
child: Text(value.toStringAsFixed(2)),
),
),
);
}
String getDate(double value) {
intl.DateFormat hmFormat = intl.DateFormat('Hm');
return hmFormat.format(
DateTime.fromMillisecondsSinceEpoch((value * 1000 * 60).toInt()));
}
String getLongDate(double value) {
DateTime date =
DateTime.fromMillisecondsSinceEpoch((value * 1000 * 60).toInt());
int daysDifference = (DateTime.now().weekday - date.weekday + 7) % 7;
if (daysDifference == 0) {
return 'Today ${intl.DateFormat('Hm').format(date)}';
} else if (daysDifference == 1) {
return 'Yesterday ${intl.DateFormat('Hm').format(date)}';
}
return intl.DateFormat('yyyy-MM-dd H:m').format(date);
}
}

View File

@@ -0,0 +1,36 @@
import 'package:flutter/material.dart';
class StationFilter extends StatefulWidget {
const StationFilter({super.key, required this.onEditingComplete});
final void Function(String filterText) onEditingComplete;
@override
State<StationFilter> createState() => StationFilterState();
}
class StationFilterState extends State<StationFilter> {
TextEditingController filterController = TextEditingController();
@override
Widget build(BuildContext context) {
return TextField(
controller: filterController,
decoration: InputDecoration(
prefixIcon: Icon(Icons.search),
suffixIcon: Opacity(
opacity: filterController.text.isEmpty ? 0 : 1,
child: IconButton(
onPressed: () {
filterController.clear();
setState(() {});
},
icon: Icon(Icons.delete),
),
),
label: Text('Filter'),
),
onChanged: (_) => setState(() {}),
onEditingComplete: () => widget.onEditingComplete(filterController.text),
);
}
}