flutterchartsstockfl-chart

How to remove sideTitles from FlChart?


I am currently trying to use the FlChart library for flutter to display stock data. However i am having trouble with the titles on the side of the chart as i dont know why they are there. I have commented out the titlesData property from the LineChartData but there are still titles on every side. My question is how can i remove these titles. (Btw. ignore the weird looking graph)

Code:

import 'dart:convert';
//import 'package:intl/intl.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:futura_api/api.dart';

class LineChartSample2 extends StatefulWidget {
  final String symbol;

  const LineChartSample2({Key? key, required this.symbol}) : super(key: key);

  @override
  State<LineChartSample2> createState() => _LineChartSample2State();
}

class _LineChartSample2State extends State<LineChartSample2> {
  late Future<StockData?> stockDataFuture;
  late LineChartData stockChartData;

  bool showAvg = false;

  final StocksApi _stocksApi =
      StocksApi(ApiClient(basePath: 'http://192.168.178.33'));

  List<Color> gradientColors = [
    Colors.deepPurple[200] as Color,
    Colors.deepPurple[800] as Color,
  ];

  final int _divider = 25;
  final int _leftLabelsCount = 6;

  final List<FlSpot> _values = [];
  double _minX = 0;
  double _maxX = 0;
  double _minY = 0;
  double _maxY = 0;
  double _leftTitlesInterval = 0;

  @override
  void initState() {
    // todo add websocket connection
    stockDataFuture = fetchData(widget.symbol);
    super.initState();
  }

  Future<StockData?> fetchData(String symbol) async {
    try {
      if (kDebugMode) {
        return Future<StockData?>.delayed(const Duration(seconds: 0), () async {
          Map<String, dynamic> jsonData = jsonDecode(
              await DefaultAssetBundle.of(context)
                  .loadString("lib/assets/fonts/stock_data.json"));
          return StockData.fromJson(jsonData);
        });
      }
      return await _stocksApi.apiStocksGet(symbol: symbol, interval: "1d");
    } catch (e) {
      return null; // Return an empty string or handle the error as needed
    }
  }

  void parseStockData(Map<String, StockDto>? data) {
    double minY = double.maxFinite;
    double maxY = double.minPositive;

    data?.forEach(
      (key, value) {
        if (minY > (value.close ?? 0)) minY = value.close ?? 0;
        if (maxY < (value.close ?? 0)) maxY = value.close ?? 0;
        _values.add(FlSpot(getXValueFromDateString(key), value.close ?? 0));
      },
    );

    _minX = _values.first.x;
    _maxX = _values.last.x;
    _minY = (minY / _divider).floorToDouble() * _divider;
    _maxY = (maxY / _divider).ceilToDouble() * _divider;
    _leftTitlesInterval =
        ((_maxY - _minY) / (_leftLabelsCount - 1)).floorToDouble();
  }

  LineChartData _mainData() {
    return LineChartData(
      // titlesData: FlTitlesData(
      //     bottomTitles: _bottomTitles(), leftTitles: _leftTitles()),
      gridData: _gridData(),
      minX: _minX,
      maxX: _maxX,
      minY: _minY,
      maxY: _maxY,
      lineBarsData: [
        _lineBarData(),
      ],
    );
  }

  LineChartBarData _lineBarData() {
    return LineChartBarData(
      spots: _values,
      gradient: LinearGradient(
        colors: gradientColors,
      ),
      isCurved: true,
      barWidth: 2,
      isStrokeCapRound: true,
      dotData: const FlDotData(
        show: false,
      ),
      belowBarData: BarAreaData(
        show: true,
        gradient: LinearGradient(
          colors:
              gradientColors.map((color) => color.withOpacity(0.3)).toList(),
        ),
      ),
      // Other properties...
    );
  }

  Widget buildChart(LineChartData data) {
    stockChartData = data;
    return AspectRatio(
      aspectRatio: 1.70,
      child: Padding(
        padding:
            const EdgeInsets.only(right: 18, left: 12, top: 24, bottom: 12),
        child: _values.isEmpty ? const Placeholder() : LineChart(_mainData()),
      ),
    );
  }

  double getXValueFromDateString(String dateString) {
    DateTime dateTime = DateTime.parse(dateString);
    return dateTime.millisecondsSinceEpoch.toDouble();
  }

  LineChartData avgData() {
    // Implement this method based on your requirement for average data display
    return stockChartData; // Return the same data for simplicity in this example
  }

  // AxisTitles _bottomTitles() {
  //   return AxisTitles(
  //       sideTitles: SideTitles(
  //     showTitles: true,
  //     getTitlesWidget: (value, meta) {
  //       final DateTime date =
  //           DateTime.fromMillisecondsSinceEpoch(value.toInt());
  //       return SideTitleWidget(
  //           axisSide: AxisSide.bottom,
  //           child: Text(
  //             DateFormat.MMM().format(date),
  //             style: const TextStyle(color: Colors.white, fontSize: 12),
  //           ));
  //     },
  //     interval: (_maxX - _minX) / 6,
  //   ));
  // }

  // AxisTitles _leftTitles() {
  //   return AxisTitles(
  //       sideTitles: SideTitles(
  //           showTitles: true,
  //           interval: _leftTitlesInterval,
  //           getTitlesWidget: (value, meta) {
  //             return SideTitleWidget(
  //               axisSide: AxisSide.left,
  //               space: 4,
  //               child: Text(
  //                 NumberFormat.compactCurrency(symbol: '€').format(value),
  //                 style: const TextStyle(color: Colors.white, fontSize: 12),
  //               ),
  //             );
  //           }));
  // }

  FlGridData _gridData() {
    return FlGridData(
      show: true,
      drawVerticalLine: false,
      getDrawingHorizontalLine: (value) {
        return const FlLine(color: Colors.white, strokeWidth: 1);
      },
      checkToShowHorizontalLine: (value) {
        return (value - _minY) % _leftTitlesInterval == 0;
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<StockData?>(
      future: stockDataFuture,
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Center(child: CircularProgressIndicator());
        } else if (snapshot.hasError) {
          return Center(child: Text('Error: ${snapshot.error}'));
        } else if (snapshot.hasData) {
          parseStockData(snapshot.data!.timeSeries);
          return buildChart(_mainData());
        } else {
          return const Center(child: Text('No data available'));
        }
      },
    );
  }
}

Photo of the graph: enter image description here

I have already tried commenting out the TitlesData property but that has not worked.


Solution

  • The following snippet should work:

    titlesData: FlTitlesData(
                  show: false,
                ),