Extract amount and date fields from firebase and display the last three month amount data in a chart in flutter using fl_chart

67 views Asked by At

I have been trying to display two line graphs from two firebase collections containing date and amount in each documents and also another line graph of total amount for the last three months data. I have the below code, however, for some reason this is not working. I believe the data is not getting extracted, however, I am unable to find the reason for this. Request if anyone can help

One reason I think is maybe because my date data is in timestamp format i.e 31 August 2023 11:53:43 UTC+5:30

However, I have been unable to find a solution. The output shows only the graph and no line bar

import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:fl_chart/fl_chart.dart';

class ProcessDPage extends StatefulWidget {
  @override
  _ProcessDPageState createState() => _ProcessDPageState();
}

class _ProcessDPageState extends State<ProcessDPage> {

  final FirebaseFirestore _firestore = FirebaseFirestore.instance;
  final String user = FirebaseAuth.instance.currentUser!.uid;

  List<LineChartBarData> lineBars = []; // Line chart data for collections
  int currentMonth = DateTime.now().month;
  int currentYear = DateTime.now().year;

  @override
  void initState() {
    super.initState();
    fetchData(); // Fetch data when the widget initializes
  }

  Future<void> fetchData() async {
    try {
      // Fetch data for Collection 1 (e.g., "collection1")
      final QuerySnapshot collection1Data = await _firestore
          .collection('users').doc(user)
          .collection('sms_upi_exp')
          .where('date', isGreaterThan: getLastThreeMonthsDate())
          .get();

      // Fetch data for Collection 2 (e.g., "collection2")
      final QuerySnapshot collection2Data = await _firestore
          .collection('users').doc(user)
          .collection('sms_creditCard_Exp')
          .where('date', isGreaterThan: getLastThreeMonthsDate())
          .get();

      setState(() {
        lineBars = createLineBars(
          collection1Data,
          collection2Data,
        );
      });
      print(collection1Data);
    } catch (e) {
      print('Error fetching data: $e');
    }
  }

  DateTime getLastThreeMonthsDate() {
    return DateTime(currentYear, currentMonth - 2, 1);
  }

  List<LineChartBarData> createLineBars(
      QuerySnapshot collection1Data,
      QuerySnapshot collection2Data,
      ) {

    // Create a list of data points for Collection 1
    final List<DataPoint> collection1Points = processData(collection1Data);
    // Create a list of data points for Collection 2
    final List<DataPoint> collection2Points = processData(collection2Data);

    final List<FlSpot> totalDataPoints = [];
    for (int month = currentMonth - 2; month <= currentMonth; month++) {
      final monthYear = '$month-$currentYear';
      final totalAmount = calculateTotalAmount(
        collection1Points,
        collection2Points,
        monthYear,
      );

      totalDataPoints.add(FlSpot(month.toDouble(), totalAmount));
    }

    final List<FlSpot> collection1Spots = collection1Points
        .map((point) => FlSpot(point.x.toDouble(), point.y))
        .toList();

    final List<FlSpot> collection2Spots = collection2Points
        .map((point) => FlSpot(point.x.toDouble(), point.y))
        .toList();

    return [
      LineChartBarData(
        spots: collection1Spots,
        isCurved: true,
        color: Colors.blue,
        dotData: FlDotData(show: false),
        belowBarData: BarAreaData(show: false),
      ),
      LineChartBarData(
        spots: collection2Spots,
        isCurved: true,
        color: Colors.green,
        dotData: FlDotData(show: false),
        belowBarData: BarAreaData(show: false),
      ),
      LineChartBarData(
        spots: totalDataPoints,
        isCurved: true,
        color: Colors.red,
        dotData: FlDotData(show: false),
        belowBarData: BarAreaData(show: false),
      ),
    ];
  }

  List<DataPoint> processData(QuerySnapshot data) {

    final Map<String, double> monthlyAmounts = {};

    for (QueryDocumentSnapshot doc in data.docs) {
      final date = (doc['date'] as Timestamp).toDate();
      final monthYear = '${date.month}-${date.year}';
      final amount = doc['amount'] as double;

      monthlyAmounts[monthYear] =
          (monthlyAmounts[monthYear] ?? 0) + amount;
    }

    final List<DataPoint> dataPoints = [];
    monthlyAmounts.forEach((monthYear, amount) {
      final parts = monthYear.split('-');
      final month = int.parse(parts[0]);
      final year = int.parse(parts[1]);
      dataPoints.add(DataPoint(
        x: month.toDouble(),
        y: amount, monthYear: '',
      ));
    });

    return dataPoints;
  }

  double calculateTotalAmount(
      List<DataPoint> collection1Points,
      List<DataPoint> collection2Points,
      String monthYear,
      ) {
    // Calculate total amount for a given month and year
    double totalAmount = 0;

    for (DataPoint point in collection1Points) {
      if (point.monthYear == monthYear) {
        totalAmount += point.y;
      }
    }

    for (DataPoint point in collection2Points) {
      if (point.monthYear == monthYear) {
        totalAmount += point.y;
      }
    }

    return totalAmount;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Monthly Line Chart'),
      ),
      body: SingleChildScrollView(
        child: Column(
          children: [
            // Add your line chart(s) here using the fl_chart package
            Container(
              height: 300,
              child: LineChart(
                LineChartData(
                  // Customize your line chart data here
                  // Use the lineBars list to populate the chart
                  gridData: FlGridData(show: false),
                  titlesData: FlTitlesData(
                    // Customize the titles and labels here
                  ),
                  borderData: FlBorderData(
                    // Customize the border data here
                  ),
                  minX: currentMonth - 2,
                  maxX: currentMonth.toDouble(),
                  minY: 0,
                  maxY: 1000, // Set the appropriate maximum Y value
                  lineBarsData: lineBars,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class DataPoint {
  final double x; // X-axis value (month)
  final double y; // Y-axis value (amount)
  final String monthYear; // Month-Year string (e.g., "7-2023")

  DataPoint({required this.x, required this.y, required this.monthYear});
}

0

There are 0 answers