Newer
Older
import 'package:flutter/material.dart';
import 'package:fl_chart/fl_chart.dart';
import '../../consts.dart';
import '../../utils/format_month.dart';
class BarData extends StatefulWidget {
const BarData({super.key});
@override
State<StatefulWidget> createState() => _BarDataState();
}
class _BarDataState extends State<BarData> {
static const double barWidth = 30;
// Allocate bar data dynamically from selected subdivision
var barData = <int, List<double>>{};
int touchedIndex = -1;
@override
void initState() {
super.initState();
// Allocate bar data dynamically based from the selected subdivision
var entry = selectedSubDiv?.iceStats[i];
if (entry != null) {
barData[i] = [
entry.slushIce,
entry.blackIce,
entry.snowDepth,
];
// Find tallest layer
if (entry.totalIce > totalHeight) {
totalHeight = entry.totalIce;
}
} else {
barData[i] = [0.0, 0.0, 0.0];
}
}
}
BarChartGroupData generateGroup(
int x,
double value1,
double value2,
double value3,
) {
final sum = value1 + value2 + value3;
final isTouched = touchedIndex == x;
return BarChartGroupData(
x: x,
showingTooltipIndicators: isTouched ? [0] : [],
barRods: [
BarChartRodData(
y: sum,
width: barWidth,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(6),
topRight: Radius.circular(6),
),
rodStackItems: [
BarChartRodStackItem(
0,
value1,
const Color(0xFF13dbff),
),
BarChartRodStackItem(
value1,
value1 + value2,
),
BarChartRodStackItem(
value1 + value2,
value1 + value2 + value3,
],
),
],
);
}
// _buildLegendItem renders a colored circle and text to form a legend
Widget _buildLegendItem(Color color, String text) {
return Row(
children: [
Container(
width: 20,
height: 20,
decoration: BoxDecoration(
color: color,
shape: BoxShape.circle,
),
),
const SizedBox(width: 8),
Text(
text,
style: const TextStyle(
fontSize: 14,
color: Colors.white,
),
),
],
);
}
@override
Widget build(BuildContext context) {
SizedBox(
width: MediaQuery.of(context).size.width, // Set the desired width
child: BarChart(
BarChartData(
alignment: BarChartAlignment.center,
maxY: totalHeight + totalHeight/4, // NB Set
minY: 0,
titlesData: FlTitlesData(
show: true,
bottomTitles: SideTitles(
showTitles: true,
getTextStyles: (value) => const TextStyle(color: Colors.white60),
getTitles: (value) {
// Convert bar indexes to dates
if (barData.isNotEmpty && value >= 0 && value < barData.length) {
int index = value.toInt();
DateTime today = DateTime.now();
// Subtract index from the day of the month of the current date
int day = today.day - (6-index);
String date = day.toString();
String month = formatMonth(today.month);
return '$month $date';
}
return '';
},
),
leftTitles: SideTitles(
showTitles: true,
getTextStyles: (value) => const TextStyle(color: Colors.white60),
),
rightTitles: SideTitles(
showTitles: true,
getTextStyles: (value) => const TextStyle(color: Colors.white60),
),
),
groupsSpace: 14,
gridData: FlGridData(
show: true,
borderData: FlBorderData(
show: false,
),
barGroups: barData.entries
.map(
(e) => generateGroup(
e.key,
e.value[0],
e.value[1],
e.value[2],
),
).toList(),
),
),
),
Padding( // Legend items
padding: const EdgeInsets.only(top: 20),
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildLegendItem(const Color(0xFF13dbff), "Black ice"),
_buildLegendItem(const Color(0xFF3766E0), "Slush ice"),
_buildLegendItem(Colors.white60, "Snow"),
],
),
),
),
],
);
}
}