flutterdartfl-chart

Flutter list mapping, filtering


so i have this data that I compare with a date range that is requested by the user if the Days list is the same as my transaction date then I put it in that date, and will return a new list

List transactionss = [
    {'date': '2023-02-06', 'amount': 250000, 'type': 0},
    {'date': '2023-02-06', 'amount': 30000, 'type': 1}
  ];

  final daysToGenerates = DateTime.parse('2023-02-07')
      .difference(DateTime.parse('2023-02-01'))
      .inDays;
  List dayss = List.generate(
      daysToGenerates,
      (i) => DateTime(
          DateTime.parse('2023-02-01').year,
          DateTime.parse('2023-02-01').month,
          DateTime.parse('2023-02-01').day + (i)));

  List<Map<String, dynamic>> dats = [];
  for (DateTime date in dayss) {
    for (Map<String, dynamic> transaction in transactionss) {
      DateTime transactionDate = DateTime.parse(transaction['date']);
      if (date == transactionDate) {
        dats.add(transaction);
      } else {
        dats.add({
          'date': date.toString().substring(0, 10),
          'amount': 0,
          'type': 5
        });
      }
    }
  }


     sample result      [
      {date: 2023-02-01, amount: 0, type: 5}, 
      {date: 2023-02-01, amount: 0, type: 5}, 
      {date: 2023-02-02, amount: 0, type: 5}, 
      {date: 2023-02-02, amount: 0, type: 5}, 
      {date: 2023-02-03, amount: 0, type: 5}, 
      {date: 2023-02-03, amount: 0, type: 5}, 
      {date: 2023-02-04, amount: 0, type: 5}, 
      {date: 2023-02-04, amount: 0, type: 5}, 
      {date: 2023-02-05, amount: 0, type: 5}, 
      {date: 2023-02-05, amount: 0, type: 5}, 
      {date: 2023-02-06, amount: 250000, type: 0}, 
      {date: 2023-02-06, amount: 30000, type: 1}, 
      {date: 2023-02-07, amount: 0, type: 5}, 
      {date: 2023-02-07, amount: 0, type: 5}
     ]

            sample FL_chart Spot
                       spot: dataset.where((element) => (element['type'] == 0 ||
                              element['type'] == 5))
                          .mapIndexed((index, e) {
                        return FlSpot(
                            index as double, double.parse(amount));
                      }).toList()

now my problem is why does the dates double? because the 'dataset'(the list that it returns) will be used in fl chart, and because its doubling dates my x axis on chart is getting double dates also becuase that index that just shouldve been 7 for example doubles and becomes 14, what are my options here? filter? hope you understand my question


Solution

  • Your problem is the second for loop, if i get it right, you want that in case you didn't find any transactions to add a zero transaction in the list.

    Now what your code does, is for every transaction that doesn't have the date equals to the date you check, it will add a new "zero" transaction.

    The easiest fix for your issue is to add a simple flag that will be set to true when you find a transaction, if the flag is still false, then add a zero transaction.

     List transactionss = [
        {'date': '2023-02-06', 'amount': 250000, 'type': 0},
        {'date': '2023-02-06', 'amount': 30000, 'type': 1}
      ];
    
      final daysToGenerates = DateTime.parse('2023-02-07')
          .difference(DateTime.parse('2023-02-01'))
          .inDays;
      List dayss = List.generate(
          daysToGenerates,
          (i) => DateTime(
              DateTime.parse('2023-02-01').year,
              DateTime.parse('2023-02-01').month,
              DateTime.parse('2023-02-01').day + (i)));
    
      List<Map<String, dynamic>> dats = [];
      for (DateTime date in dayss) {
        // this for depends on the number of types you have.
        // you need to do adjust the for based on min/max type value
        for (int i = 0; i < 5; i++) {
          bool didFindTransaction = false;
          for (Map<String, dynamic> transaction in transactionss) {
            DateTime transactionDate = DateTime.parse(transaction['date']);
            final type = transaction['type'];      
            if (date == transactionDate && type == i) {
              dats.add(transaction);
              didFindTransaction = true;
            }
          }
          if (!didFindTransaction) {
            dats.addAll([
              {'date': date.toString().substring(0, 10), 'amount': 0, 'type': i}
            ]);
          }
        }
      }
    
    

    UPDATE

    If i get it right, you want values for all types and dates, and if there is no value for that pair date and type it should be set to zero.

    Check out my updated answer.