Skip to content
Snippets Groups Projects
bar_data.dart 5.73 KiB
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>>{};
  double totalHeight = 0;
  int touchedIndex = -1;

  @override
  void initState() {
    super.initState();

    // Allocate bar data dynamically based from the selected subdivision
    for (int i = 0; i < 7; i++) {
      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,
              const Color(0xFF3766E0),
            ),
            BarChartRodStackItem(
              value1 + value2,
              value1 + value2 + value3,
              Colors.white60,
  // _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,
                      reservedSize: 20,
                      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),
                      margin: 5,
                      reservedSize: 30,
                      interval: totalHeight/5,
                    ),
                    rightTitles: SideTitles(
                      showTitles: true,
                      getTextStyles: (value) => const TextStyle(color: Colors.white60),
                      margin: 5,
                      reservedSize: 30,
                      interval: totalHeight/5,
                    ),
                  ),
                  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: 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"),