skantravels/Mobile/lib/weather.dart
2024-08-05 09:00:16 +02:00

151 lines
5.3 KiB
Dart

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:fl_chart/fl_chart.dart';
class WeatherForecastPage extends StatefulWidget {
@override
_WeatherForecastPageState createState() => _WeatherForecastPageState();
}
class _WeatherForecastPageState extends State<WeatherForecastPage> {
List<dynamic> forecasts = [];
List<double> temperaturesC = [];
List<String> dates = [];
Future<void> fetchForecasts() async {
final response =
await http.get(Uri.parse('https://h4api.onrender.com/WeatherForecast'));
if (response.statusCode == 200) {
setState(() {
temperaturesC.clear();
dates.clear();
forecasts = json.decode(response.body).map((f) {
temperaturesC.add(f['temperatureC'].toDouble());
dates.add(f['date']);
return f;
}).toList();
});
} else {
throw Exception('Failed to load forecasts');
}
}
@override
void initState() {
super.initState();
fetchForecasts();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Weather Forecast Graph'),
actions: [
IconButton(
icon: Icon(Icons.refresh),
onPressed: fetchForecasts,
),
],
),
body: forecasts.isEmpty
? Center(child: CircularProgressIndicator())
: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Expanded(
child: LineChart(
LineChartData(
minY:
(temperaturesC.reduce((a, b) => a < b ? a : b) - 10)
.toDouble(),
maxY:
(temperaturesC.reduce((a, b) => a > b ? a : b) + 20)
.toDouble(),
gridData: FlGridData(show: true), // Grid
titlesData: FlTitlesData(
leftTitles: SideTitles(
showTitles: true,
reservedSize: 40,
getTextStyles: (context, value) => const TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 12,
),
interval: 10,
getTitles: (value) {
return '${value.toInt()}°C';
},
),
bottomTitles: SideTitles(
showTitles: true,
reservedSize: 40,
getTextStyles: (context, value) => const TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 12,
),
getTitles: (value) {
int index = value.toInt();
if (index >= 0 && index < dates.length) {
return dates[index].substring(5); // MM-DD
}
return '';
},
),
),
borderData: FlBorderData(
show: true,
border: Border.all(color: Colors.black, width: 1),
),
lineBarsData: [
LineChartBarData(
spots: temperaturesC.asMap().entries.map((e) {
return FlSpot(e.key.toDouble(), e.value);
}).toList(),
isCurved: true,
colors: [Colors.blue],
barWidth: 4,
dotData: FlDotData(show: true),
belowBarData: BarAreaData(show: false),
),
],
),
),
),
SizedBox(height: 20),
Text(
'Weather Summaries',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
Expanded(
child: ListView.builder(
itemCount: forecasts.length,
itemBuilder: (context, index) {
final forecast = forecasts[index];
return ListTile(
title: Text(
'${forecast['date']}: ${forecast['summary']}',
),
);
},
),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: fetchForecasts,
child: Text('Refresh Data'),
),
],
),
),
);
}
}