Search code examples
flutterchartsfl-chart

How to rotate text in flutter charts?


I am trying to design a chart in a flutter app that displays data graphed against time or day (depending on a button press), however, I am running into an issue where the graph label text runs into each other.

I was wondering if there is a way to rotate text in the fl_chart object LineChartData to show the date or time at an angle or vertically rotated?

My code looks like this so far and the output of the graph looks like this:

enter image description here

import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:sembast/timestamp.dart';

import '../models/outcome.dart';

dynamic grapher() {
  return Stack(
    children: <Widget>[
      AspectRatio(
        aspectRatio: 1.70,
        child: Container(
          decoration: const BoxDecoration(
              borderRadius: BorderRadius.all(
                Radius.circular(18),
              ),
              color: Colors.black),
          child: Padding(
            padding: const EdgeInsets.only(
                right: 18.0, left: 12.0, top: 24, bottom: 12),
            child: LineChart(
              mainData(),
            ),
          ),
        ),
      ),
    ],
  );
}

LineChartData mainData() {
  return LineChartData(

    ...

    titlesData: FlTitlesData(
      show: true,
      bottomTitles: SideTitles(
        showTitles: true,
        reservedSize: 22,
        textStyle: const TextStyle(
            color: Colors.white, fontWeight: FontWeight.bold, fontSize: 16),
        getTitles: (value) {
          //return value.round().toString();
          for (int i = 0; i <= outcomeList.length; i++) {
            return outcomeList[i].recordedTime.toString();
          }
        },
        margin: 8,
      ),

      ...

    ),

    ...

}



List<FlSpot> datapoints = [
  FlSpot(0, outcomeList[0].value),
  FlSpot(2.6, outcomeList[1].value),
  FlSpot(4.9, outcomeList[2].value),
  FlSpot(6.8, outcomeList[3].value),
  FlSpot(8, outcomeList[4].value),
  FlSpot(10, outcomeList[5].value),
];

List<Outcome> outcomeList = [
  Outcome(name: 'mood', recordedTime: Timestamp.now(), value: 5.6),
  Outcome(
      name: 'mood',
      recordedTime:
          Timestamp.fromDateTime(DateTime.now().add(new Duration(hours: 1))),
      value: 6.7),
  Outcome(
      name: 'mood',
      recordedTime:
          Timestamp.fromDateTime(DateTime.now().add(new Duration(hours: 2))),
      value: 5.5),
  Outcome(
      name: 'mood',
      recordedTime:
          Timestamp.fromDateTime(DateTime.now().add(new Duration(hours: 3))),
      value: 6.2),
  Outcome(
      name: 'mood',
      recordedTime:
          Timestamp.fromDateTime(DateTime.now().add(new Duration(hours: 4))),
      value: 7.7),
  Outcome(
      name: 'mood',
      recordedTime: Timestamp.fromDateTime(
          DateTime.now().add(new Duration(hours: 5, minutes: 26))),
      value: 6.4),
];



Solution

  • You can use SideTitles's attribute rotateAngle
    full code is official demo LineChartSample7 use rotateAngle
    You can see red rectangle of working demo below

    code snippet

    SideTitles(
                rotateAngle: 90,
                showTitles: true,
    

    working demo

    enter image description here

    full code

    import 'package:fl_chart/fl_chart.dart';
    import 'package:flutter/material.dart';
    
    class LineChartSample7 extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return SizedBox(
          width: 300,
          height: 140,
          child: LineChart(
            LineChartData(
              lineTouchData: LineTouchData(enabled: false),
              lineBarsData: [
                LineChartBarData(
                  spots: [
                    FlSpot(0, 4),
                    FlSpot(1, 3.5),
                    FlSpot(2, 4.5),
                    FlSpot(3, 1),
                    FlSpot(4, 4),
                    FlSpot(5, 6),
                    FlSpot(6, 6.5),
                    FlSpot(7, 6),
                    FlSpot(8, 4),
                    FlSpot(9, 6),
                    FlSpot(10, 6),
                    FlSpot(11, 7),
                  ],
                  isCurved: true,
                  barWidth: 2,
                  colors: [
                    Colors.green,
                  ],
                  dotData: FlDotData(
                    show: false,
                  ),
                ),
                LineChartBarData(
                  spots: [
                    FlSpot(0, 0),
                    FlSpot(1, 3),
                    FlSpot(2, 4),
                    FlSpot(3, 5),
                    FlSpot(4, 8),
                    FlSpot(5, 3),
                    FlSpot(6, 5),
                    FlSpot(7, 8),
                    FlSpot(8, 4),
                    FlSpot(9, 7),
                    FlSpot(10, 7),
                    FlSpot(11, 8),
                  ],
                  isCurved: true,
                  barWidth: 2,
                  colors: [
                    Colors.black,
                  ],
                  dotData: FlDotData(
                    show: false,
                  ),
                ),
                LineChartBarData(
                  spots: [
                    FlSpot(0, 7),
                    FlSpot(1, 3),
                    FlSpot(2, 4),
                    FlSpot(3, 0),
                    FlSpot(4, 3),
                    FlSpot(5, 4),
                    FlSpot(6, 5),
                    FlSpot(7, 3),
                    FlSpot(8, 2),
                    FlSpot(9, 4),
                    FlSpot(10, 1),
                    FlSpot(11, 3),
                  ],
                  isCurved: false,
                  barWidth: 2,
                  colors: [
                    Colors.red,
                  ],
                  dotData: FlDotData(
                    show: false,
                  ),
                ),
              ],
              betweenBarsData: [
                BetweenBarsData(
                  fromIndex: 0,
                  toIndex: 2,
                  colors: [Colors.red.withOpacity(0.3)],
                )
              ],
              minY: 0,
              titlesData: FlTitlesData(
                bottomTitles: SideTitles(
                    rotateAngle: 90,
                    showTitles: true,
                    textStyle:
                        TextStyle(fontSize: 10, color: Colors.purple, fontWeight: FontWeight.bold),
                    getTitles: (value) {
                      switch (value.toInt()) {
                        case 0:
                          return 'Jan';
                        case 1:
                          return 'Feb';
                        case 2:
                          return 'Mar';
                        case 3:
                          return 'Apr';
                        case 4:
                          return 'May';
                        case 5:
                          return 'Jun';
                        case 6:
                          return 'Jul';
                        case 7:
                          return 'Aug';
                        case 8:
                          return 'Sep';
                        case 9:
                          return 'Oct';
                        case 10:
                          return 'Nov';
                        case 11:
                          return 'Dec';
                        default:
                          return '';
                      }
                    }),
                leftTitles: SideTitles(
                  showTitles: true,
                  getTitles: (value) {
                    return '\$ ${value + 0.5}';
                  },
                ),
              ),
              gridData: FlGridData(
                show: true,
                checkToShowHorizontalLine: (double value) {
                  return value == 1 || value == 6 || value == 4 || value == 5;
                },
              ),
            ),
          ),
        );
      }
    }