Carlos Costa
Carlos Costa

Reputation: 197

Using fl_chart. Combining 3 charts in 1

In my app i am reading some values from a local Json and displaying them in 3 different charts. I would like instead having only one chart and displaying on it everything. How i structure my code at this moment i do not see how i could accomplish this. I declared a reusable widget as follows:

// Function to generate the LineChart widget
Widget generateLineChart({
  required List<FlSpot> spots,
  required String axisName,
  required Color color,
}) {
  return LineChart(
    LineChartData(
      lineTouchData: LineTouchData(
        getTouchedSpotIndicator: (LineChartBarData barData, List<int> indicators) {
          return indicators.map(
            (int index) {
              final line = FlLine(
                color: Colors.white,
                strokeWidth: 1,
                dashArray: [2, 2],
              );
              return TouchedSpotIndicatorData(
                line,
                FlDotData(show: true),
              );
            },
          ).toList();
        },
        getTouchLineEnd: (_, __) => double.infinity,
      ),
      lineBarsData: [
        LineChartBarData(
          isStrokeCapRound: false,
          spots: spots,
          isCurved: true,
          barWidth: 2,
          color: color,
          dotData: FlDotData(
            show: true,
            getDotPainter: (spot, percent, barData, index) {
              return FlDotCirclePainter(
                radius: 2,
                color: const Color.fromARGB(255, 151, 124, 124),
                strokeColor: AppColors.chartColor1,
              );
            },
          ),
        ),
      ],
      minY: 0,
      titlesData: FlTitlesData(
        bottomTitles: AxisTitles(
          sideTitles: SideTitles(
            showTitles: true,
            reservedSize: 25,
          ),
        ),
        rightTitles: AxisTitles(
          sideTitles: SideTitles(showTitles: false),
        ),
        topTitles: AxisTitles(
          axisNameWidget: Text(
            axisName,
            textAlign: TextAlign.start,
            style: TextStyle(
              //color: AppColors.textColor5,
              color: color,
              fontSize: 25.0,
            ),
          ),
          axisNameSize: 34,
          sideTitles: SideTitles(
            showTitles: true,
            reservedSize: 0,
          ),
        ),
      ),
    ),
  );
}

For the 3 charts i am reading the Json as follows:

//***********************************************************************************************
//**            Functions Future<void> loadDataOpenForceMaxFLChart()
//***********************************************************************************************
  Future<void> loadDataOpenForceMaxFLChart() async {
    try {
      final jsonString = await getJsonDataPathforChart();
      final data = jsonDecode(jsonString);

      final List<dynamic> measures = data['measure'];

      // process data to create FlSpots
      List<FlSpot> spots = [];

      for (int i = 0; i < measures.length; i++) {
        final measure = measures[i];
        final rangeArray = measure['open_force_array'];
        final count = measure['count'];

        double highestForce = double.negativeInfinity; // Reset highestForce for each iteration

        for (int j = 0; j < rangeArray.length; j++) {
          final forceValue = rangeArray[j].toDouble();
          if (forceValue > highestForce) {
            highestForce = forceValue;
          }
        }

        spots.add(FlSpot(count.toDouble(), highestForce));
      }

      flSpots3 = spots;
    } catch (e) {
      print(e);
    }
  }

//***********************************************************************************************
//**            Functions Future<void> loadDataOpenForceMinFLChart()
//***********************************************************************************************
  Future<void> loadDataOpenForceMinFLChart() async {
    try {
      final jsonString = await getJsonDataPathforChart();
      final data = jsonDecode(jsonString);

      final List<dynamic> measures = data['measure'];

      // process data to create FlSpots
      List<FlSpot> spots = [];

      for (int i = 0; i < measures.length; i++) {
        final measure = measures[i];
        final rangeArray = measure['open_force_array'];
        final count = measure['count'];

        double lowestForce = double.infinity;

        for (int j = 0; j < rangeArray.length; j++) {
          final forceValue = rangeArray[j].toDouble();
          if (forceValue < lowestForce) {
            lowestForce = forceValue;
          }
        }

        spots.add(FlSpot(count.toDouble(), lowestForce));
      }

      flSpots4 = spots;
    } catch (e) {
      print(e);
    }
  }

//***********************************************************************************************
//**            Functions Future<void> loadDataOpenForceAverageFLChart()
//***********************************************************************************************
  Future<void> loadDataOpenForceAverageFLChart() async {
    try {
      final jsonString = await getJsonDataPathforChart();
      final data = jsonDecode(jsonString);

      final List<dynamic> measures = data['measure'];

      // process data to create FlSpots
      List<FlSpot> spots = [];

      for (int i = 0; i < measures.length; i++) {
        final measure = measures[i];
        final rangeArray = measure['open_force_array'];
        final count = measure['count'];

        double sumForce = 0;
        for (int j = 0; j < rangeArray.length; j++) {
          final forceValue = rangeArray[j].toDouble();
          sumForce += forceValue;
        }

        double averageForce = sumForce / rangeArray.length;
        // Format the averageForce value with two decimal places
        averageForce = double.parse(averageForce.toStringAsFixed(2));

        spots.add(FlSpot(count.toDouble(), averageForce));
      }

      flSpots5 = spots;
    } catch (e) {
      print(e);
    }
  }

Then on the screen i am displaying it as follows:

                                     FutureBuilder(
                                       future: gtxs1.getJsonDataPathforChart(),
                                       builder: (BuildContext context, AsyncSnapshot snapshot) {
                                         if (snapshot.hasData) {
                                           return Column(
                                             mainAxisAlignment: MainAxisAlignment.start,
                                             crossAxisAlignment: CrossAxisAlignment.start,
                                             children: <Widget>[
                                               //**************************************** 3 Chart ********************************************************************
                                               //************************************ Open Force Max *****************************************************************
                                               Column(
                                                 children: [
                                                   const SizedBox(
                                                     height: 30,
                                                   ),
                                                   SizedBox(
                                                     width: 580,
                                                     height: 280,
                                                     child: generateLineChart(
                                                       spots: gtxs1.flSpots3, // Replace with your desired spots list
                                                       axisName: 'Open Force Max', // Replace with your desired axis name
                                                       color: AppColors.textColor8,
                                                     ),
                                                   ),
                                                 ],
                                               ),

                                               //**************************************** 4 Chart ********************************************************************
                                               //************************************ Open Force Min *****************************************************************
                                               Column(
                                                 children: [
                                                   SizedBox(
                                                     width: 580,
                                                     height: 280,
                                                     child: generateLineChart(
                                                       spots: gtxs1.flSpots4, // Replace with your desired spots list
                                                       axisName: 'Open Force Min', // Replace with your desired axis name
                                                       color: AppColors.textColor2,
                                                     ),
                                                   ),
                                                 ],
                                               ),

                                               //**************************************** 5 Chart ********************************************************************
                                               //************************************ Open Force Average *************************************************************
                                               Column(
                                                 children: [
                                                   SizedBox(
                                                     width: 580,
                                                     height: 280,
                                                     child: generateLineChart(
                                                       spots: gtxs1.flSpots5, // Replace with your desired spots list
                                                       axisName: 'Open Force Average', // Replace with your desired axis name
                                                       color: AppColors.textColor5,
                                                     ),
                                                   ),
                                                 ],
                                               ),
                                             ],
                                           );
                                         } else {
                                           return const CircularProgressIndicator();
                                         }
                                       },
                                     ),

Using this approach is it possible to display the 3 different charts in only one chart, or do i have to rethink my approach?

Thanks in advance for some help

Upvotes: 1

Views: 534

Answers (0)

Related Questions