mojojojo
mojojojo

Reputation: 177

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),
];


Upvotes: 1

Views: 4296

Answers (2)

mouad kaaib
mouad kaaib

Reputation: 351

you can achieve that with the following two steps:

1 - add the property reservedSize: y to FlTitlesData() and put the height intead of y.

2 - instead of returning Text widget in getTitlesWidget function wrap it in RotatedBox(), and set the property quarterTurns to -1 or 1.

                          FlTitlesData(
                              topTitles: AxisTitles(
                                  sideTitles: SideTitles(showTitles: false)),
                              rightTitles: AxisTitles(
                                  sideTitles: SideTitles(showTitles: false)),
                              bottomTitles: AxisTitles(
                                  sideTitles: SideTitles(
                                reservedSize: 40,
                                showTitles: true,
                                getTitlesWidget: (value, meta) {
                                  String text = '';
                                  switch (value.toInt()) {
                                    case 1:
                                      text = 'Mon';
                                      break;
                                    case 2:
                                      text = 'Tue';
                                      break;
                                    case 3:
                                      text = 'Wed';
                                      break;
                                    case 4:
                                      text = 'Thu';
                                      break;
                                    case 5:
                                      text = 'Fri';
                                      break;
                                    case 6:
                                      text = 'Sat';
                                      break;
                                    case 7:
                                      text = 'Sun';
                                      break;
                                  }

                                  return RotatedBox(
                                    quarterTurns: -1,
                                    child: Text(text),
                                  );
                                },
                              )))

i hope this will work for you as it worked for me.

Upvotes: 0

chunhunghan
chunhunghan

Reputation: 54377

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;
            },
          ),
        ),
      ),
    );
  }
}

Upvotes: 2

Related Questions