fl_chart icon indicating copy to clipboard operation
fl_chart copied to clipboard

bottomTitles - Last title overflowed

Open dospringer opened this issue 3 years ago • 10 comments

Describe the bug The problem is, that the last title on the x-axis on SideTitle overflowed. Is there a way that the last title don't overflowed?

Screenshot Bildschirmfoto 2021-03-15 um 14 28 25

Versions Flutter: (Channel master, 2.1.0-13.0.pre.64) fl_chart: ^0.20.1

To Reproduce

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:fl_chart/fl_chart.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      showPerformanceOverlay: false,
      theme: ThemeData(
        primaryColor: const Color(0xff262545),
        primaryColorDark: const Color(0xff201f39),
        brightness: Brightness.dark,
      ),
      home: const MyHomePage(title: 'fl_chart'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  final _controller = PageController(initialPage: 0);
  final _pages = [
    LineChartPage(),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: PageView(
          physics: kIsWeb
              ? NeverScrollableScrollPhysics()
              : AlwaysScrollableScrollPhysics(),
          controller: _controller,
          children: _pages,
        ),
      ),
    );
  }
}

class LineChartPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: const Color(0xff262545),
      child: ListView(
        children: <Widget>[
          const Align(
            alignment: Alignment.centerLeft,
            child: Padding(
              padding: EdgeInsets.only(
                left: 36.0,
                top: 24,
              ),
            ),
          ),
          const SizedBox(
            height: 8,
          ),
          Padding(
            padding: const EdgeInsets.only(
              left: 28,
              right: 28,
            ),
            child: LineChartSample1(),
          ),
        ],
      ),
    );
  }
}

class LineChartSample1 extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => LineChartSample1State();
}

class LineChartSample1State extends State<LineChartSample1> {
  bool isShowingMainData;

  @override
  void initState() {
    super.initState();
    isShowingMainData = true;
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      height: MediaQuery.of(context).size.height * 0.9,
      decoration: const BoxDecoration(
        borderRadius: BorderRadius.all(Radius.circular(18)),
        gradient: LinearGradient(
          colors: [
            Color(0xff2c274c),
            Color(0xff46426c),
          ],
          begin: Alignment.bottomCenter,
          end: Alignment.topCenter,
        ),
      ),
      child: Stack(
        children: <Widget>[
          Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: <Widget>[
              const SizedBox(
                height: 37,
              ),
              const SizedBox(
                height: 37,
              ),
              Expanded(
                child: Padding(
                  padding: const EdgeInsets.only(right: 16.0, left: 6.0),
                  child: LineChart(
                    sampleData1(),
                  ),
                ),
              ),
              const SizedBox(
                height: 10,
              ),
            ],
          ),
        ],
      ),
    );
  }
}

LineChartData sampleData1() {
  return LineChartData(
    lineTouchData: LineTouchData(
      touchTooltipData: LineTouchTooltipData(
        tooltipBgColor: Colors.blueGrey.withOpacity(0.8),
      ),
      touchCallback: (LineTouchResponse touchResponse) {},
      handleBuiltInTouches: true,
    ),
    gridData: FlGridData(
      show: false,
    ),
    titlesData: FlTitlesData(
      bottomTitles: SideTitles(
        showTitles: true,
        reservedSize: 22,
        getTextStyles: (value) => const TextStyle(
          color: Color(0xff72719b),
          fontWeight: FontWeight.bold,
          fontSize: 16,
        ),
        margin: 10,
        getTitles: (value) {
          switch (value.toInt()) {
            case 1:
              return '30 September 2020';
            case 7:
              return '30 Oktocber 2020';
            case 13:
              return '30 December 2020';
          }
          return '';
        },
      ),
      leftTitles: SideTitles(
        showTitles: true,
        getTextStyles: (value) => const TextStyle(
          color: Color(0xff75729e),
          fontWeight: FontWeight.bold,
          fontSize: 14,
        ),
        getTitles: (value) {
          switch (value.toInt()) {
            case 1:
              return '1m';
            case 2:
              return '2m';
            case 3:
              return '3m';
            case 4:
              return '5m';
          }
          return '';
        },
        margin: 8,
        reservedSize: 30,
      ),
    ),
    borderData: FlBorderData(
      show: true,
      border: const Border(
        bottom: BorderSide(
          color: Color(0xff4e4965),
          width: 4,
        ),
        left: BorderSide(
          color: Colors.transparent,
        ),
        right: BorderSide(
          color: Colors.transparent,
        ),
        top: BorderSide(
          color: Colors.transparent,
        ),
      ),
    ),
    minX: 0,
    maxX: 13,
    maxY: 4,
    minY: 0,
    lineBarsData: linesBarData1(),
  );
}

List<LineChartBarData> linesBarData1() {
  final LineChartBarData lineChartBarData1 = LineChartBarData(
    spots: [
      FlSpot(1, 1),
      FlSpot(3, 1.5),
      FlSpot(5, 1.4),
      FlSpot(7, 3.4),
      FlSpot(10, 2),
      FlSpot(12, 2.2),
      FlSpot(13, 1.8),
    ],
    isCurved: true,
    colors: [
      const Color(0xff4af699),
    ],
    barWidth: 8,
    isStrokeCapRound: true,
    dotData: FlDotData(
      show: false,
    ),
    belowBarData: BarAreaData(
      show: false,
    ),
  );
  return [
    lineChartBarData1,
  ];
}

dospringer avatar Mar 15 '21 13:03 dospringer

Using v0.30 I get the same issue. The last tile is displayed 2 times Any workaround ? IMG_C7A68CFB31AC-1

fvisticot avatar Mar 29 '21 19:03 fvisticot

Using v0.30 I get the same issue. The last tile is displayed 2 times Any workaround ? IMG_C7A68CFB31AC-1

I found a solution: checkToShowTitle: (double minValue, double maxValue, SideTitles sideTitles, double appliedInterval, double value) { if (value == maxValue) return false; return true; },

fvisticot avatar Mar 29 '21 20:03 fvisticot

That is the correct solution.

imaNNeo avatar Apr 01 '21 09:04 imaNNeo

This is not solution, you just hide the last element, what about overflowing the chart box? How can I stack last x title to the right side of chart? @imaNNeoFighT @dospringer

JRakhimov avatar Apr 11 '21 06:04 JRakhimov

Yes you are right @JRakhimov, I have tried it and it just hide the last title.

But when you look at my screenshot at the start of the issue, it would be nice to change the position or have no overflow in the bottomTitles 👍

dospringer avatar Apr 11 '21 07:04 dospringer

I found that the position for bottom titles set in line_chart_painter.dart line 983, and changed this value only for last title, this is quick fix, but not the best solution @dospringer

x -= horizontalSeek == data.maxX ? tp.width : tp.width / 2;

JRakhimov avatar Apr 11 '21 08:04 JRakhimov

Guys, you are right. We need to find a solution.

imaNNeo avatar Apr 15 '21 18:04 imaNNeo

I have similar problem where if we are not using right tile bottom tiles will get overlapped. For workaround you have to use rightTiles.

 rightTitles: SideTitles(showTitles: true, getTitles: (_) => ''),

Hope it helps until this issue is solved.

2shrestha22 avatar Aug 11 '21 04:08 2shrestha22

@imaNNeoFighT I think we can close this issue, correct? See https://github.com/imaNNeoFighT/fl_chart/pull/781

dospringer avatar Mar 23 '22 11:03 dospringer

@dospringer this is still a problem for me.

#781 looks like it was closed without a resolution as an incomplete solution.

daveols avatar Mar 24 '22 01:03 daveols

Guys, you are right. We need to find a solution.

I have created a pr #1257 to solve this issue. Please review it.

dhiyaaulauliyaa avatar Feb 08 '23 11:02 dhiyaaulauliyaa

It looks like you didnt solve the issue just created a work around that works but only in specific conditions (when the titls are small max 3 letters each) using last version to date btw I created a separate issue #1635 image

majbar-emir avatar Apr 14 '24 08:04 majbar-emir