Fl Chart Flutter with date data

Viewed 463

I want to show fl line chart using this plugin https://pub.dev/packages/fl_chart. data is double value and date in format of yyyy-MM-dd. Now I tried to show this data in chart. Y axis showing data correctly but date calculations are not may be correct it showing lots of dates. and If I add minX and maxX app got stuck due to lots of dates calculation between min and max X date values.

this is my code: in this data x is Date value and Y is double value. I got the idea from this link https://github.com/imaNNeoFighT/fl_chart/issues/471

class AnalyticsChart extends StatefulWidget {
  const AnalyticsChart({Key? key}) : super(key: key);

  @override
  _AnalyticsChartState createState() => _AnalyticsChartState();
}

class _AnalyticsChartState extends State<AnalyticsChart> {
  List<Color> gradientColors = [
    const Color(0xff099f53),
    const Color(0xfffefffe),
  ];

  bool showAvg = false;
  final dateList = [];

  @override
  Widget build(BuildContext context) {
    double windowHeight = MediaQuery.of(context).size.height - 370;

    return Container(
      height: windowHeight,
      decoration: const BoxDecoration(
          borderRadius: BorderRadius.all(
            Radius.circular(0),
          ),
          color: whiteColor),
      child: Padding(
        padding:
            const EdgeInsets.only(right: 18.0, left: 12.0, top: 15, bottom: 12),
        child: BlocBuilder<AnalyticsChartBloc, AnalyticsChartState>(
            builder: (BuildContext context, AnalyticsChartState state) {
          if (state is LoadAnalyticsStatesState) {

              if (state.totalSales != null &&
                  (state.totalSales?.isNotEmpty ?? false)) {
                List<FlSpot>? flSpots = [];
                dateList.clear();
                flSpots = state.totalSales?.map((e) {
                  dateList.add(e.x);
                  return FlSpot(
                      DateTime.parse(e.x ?? '') // e.date = "2020-10-24"
                          .millisecondsSinceEpoch
                          .toDouble(),
                      double.parse(e.y ?? '0'));
                }).toList();
                return LineChart(
                  mainData(flSpots),
                );
              }

          }
          return _buildNoChart();
        }),
      ),
    );
  }

  Widget bottomTitleWidgets(double value, TitleMeta meta) {
    const style = TextStyle(
      height: 1,
      color: placeholderColor,
      fontWeight: weight500,
      fontSize: fontsize12,
    );

    final DateTime date = DateTime.fromMillisecondsSinceEpoch(value.toInt());
    final parts = date.toIso8601String().split("T");

    return SideTitleWidget(
      space: 12,
      child: Text(parts.first, style: style),
      axisSide: meta.axisSide,
    );
  }

  Widget leftTitleWidgets(double value, TitleMeta meta) {
    const style = TextStyle(
      color: placeholderColor,
      fontWeight: weight100,
      fontSize: fontsize9,
    );

    return Container(
        padding: const EdgeInsets.only(right: 10),
        height: 50.0,
        child: Text(
          value.toStringAsFixed(0),
          style: style,
        ));
  }

  LineChartData mainData(List<FlSpot>? flSpots) {
    final List<double> xList = [];
    final List<double> yList = [];
    flSpots?.map((e) {
      xList.add(e.x);
      yList.add(e.y);
    }).toList();

    final minX = xList.reduce(min); //
    final maxX = xList.reduce(max); //

    final minY = yList.reduce(min); //
    final maxY = ((yList.reduce(max)) + 1000).toInt().toDouble(); //

    debugPrint('minX/maxX $minX $maxX ');
    debugPrint('minY/maxY $minY $maxY ');
    debugPrint('maxX-minX ${maxX - minX} ');
    return LineChartData(
      lineTouchData: LineTouchData(
        enabled: true,
        touchTooltipData: LineTouchTooltipData(
          tooltipBgColor: primaryColorGreen,
          tooltipRoundedRadius: 4.0,
          showOnTopOfTheChartBoxArea: false,
          fitInsideHorizontally: true,
          getTooltipItems: (touchedSpots) {
            return touchedSpots.map(
              (LineBarSpot touchedSpot) {
                const textStyle = TextStyle(
                  fontSize: fontsize13,
                  fontWeight: weight500,
                  color: whiteColor,
                  height: 1.4,
                );
                return LineTooltipItem(
                  'Total Sales \n 17,500',
                  textStyle,
                );
              },
            ).toList();
          },
        ),
      ),
      gridData: FlGridData(
        show: true,
        drawVerticalLine: true,
        horizontalInterval: 1,
        verticalInterval: 1,
        getDrawingHorizontalLine: (value) {
          return FlLine(
            color: borderColor,
            strokeWidth: 1,
          );
        },
        getDrawingVerticalLine: (value) {
          return FlLine(
            color: Colors.transparent,
            strokeWidth: 1,
          );
        },
      ),
      titlesData: FlTitlesData(
          show: true,
          rightTitles: AxisTitles(
            sideTitles: SideTitles(showTitles: false),
          ),
          topTitles: AxisTitles(
            sideTitles: SideTitles(showTitles: false),
          ),
          bottomTitles: AxisTitles(
              sideTitles: SideTitles(
            showTitles: true,
            interval: (flSpots![flSpots.length - 1].x - flSpots[0].x),
            getTitlesWidget: bottomTitleWidgets,
          ))),
      maxX: maxX,
      minX: minX,
      maxY: maxY,
      minY: minY,
      borderData: FlBorderData(
          show: true, border: Border.all(color: Colors.transparent, width: 0)),
      lineBarsData: [
        LineChartBarData(
          spots: flSpots.asMap().entries.map((e) {
            return FlSpot(e.key.toDouble(), e.value.y);
          }).toList(),
          isCurved: false,
          color: primaryColorGreen,
          barWidth: 2,
          isStrokeCapRound: true,
          dotData: FlDotData(
            show: true,
          ),
          belowBarData: BarAreaData(
            show: true,
            gradient: LinearGradient(
              colors: gradientColors
                  .map((color) => color.withOpacity(0.3))
                  .toList(),
              begin: Alignment.topCenter,
              end: Alignment.bottomCenter,
            ),
          ),
        ),
      ],
    );
  }

  Widget _buildNoChart() => const SizedBox(
        child: Center(
          child: Text('No chart data found'),
        ),
      );
}
///////////////////////
0 Answers
Related