Fl_chart: How to make scrollable x axis in flchart so that it looks nice not so compact in nature?

Created on 28 Sep 2019  Â·  8Comments  Â·  Source: imaNNeoFighT/fl_chart

Bar chart is very compact in nature if there are many values on the x-axis. How to make it less compact if there are so many values on x-axis. I want it to horizontal scrollable?
Screenshot_20190928-152201

Fundamental enhancement

Most helpful comment

I left it open, and people can thumb it up, then I will do it with high priority.

All 8 comments

Hi,
I'm so happy to see your result :)
Unfortunately, currently we are not going to implement the scrollable feature,
I'm so busy these days and also pull requests are welcome, we will implement it in the future.
Cheers!
Thanks.

I left it open, and people can thumb it up, then I will do it with high priority.

@nimesh1997
You can put it in a Container bigger than the screen and put that Container in a SingleChildScrollView with scrollDirection: Axis.horizontal

@ZantsuRocks Greate solution, Thank you :)

@ZantsuRocks solution is really useful, but this is still a good feature to be implemented in the future. In my case, along with the scrolling behavior I need a callback to mark each bar as "touched" when the chart is scrolled.

@nimesh1997
You can put it in a Container bigger than the screen and put that Container in a SingleChildScrollView with scrollDirection: Axis.horizontal

This will get perfomance problem ,especially in web .

@nimesh1997
You can put it in a Container bigger than the screen and put that Container in a SingleChildScrollView with scrollDirection: Axis.horizontal

This is not working if I have a Sliver App Bar and the graph is placed in SliverChildListDelegate. I tried to change the width of container but it still is constant.

If anyone wants to achieve panning and mousewheel zooming, following code might help.
I have tested the following in flutter for windows and browser. In windows it works well and satisfies my needs. In browser however the panning is not good because of DragupdateDetails.primaryDelta comes in as 0 quite often and hence the panning is jittery.

Note this logic still has flaws like minX and maxX not being clamped to stop zooming etc. However I feel this is good start.

@imaNNeoFighT I am not sure if this is a performant way, but seems to achieve some results. Atleast in windows I didn't feel any jitter. 😄

Idea is as follows.

  1. Use a Listener widget to listen to mouse scroll events.

    • Increment and decrement minx and maxx by a fixed percentage of maxX, depending on the scroll direction.

    • Use a GestureDetector widget to detect horizontal drag event.

    • decrement both minX and maxX by a percentage if panning to the left. that is if primary delta is negative.

    • Increment both minX and maxX by a percentage if panning to the right. that is if primary delta is positive.

  2. Finally clip the plot to be within the bounds using the clipData: FlClipData.all() of the LineChartData. without this the plot is rendered outside the widget.

cnLXXH8TLX

Following example achieves panning and zooming only in x-axis. However the logic can be extended to yaxis as well.

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

class PlotData {
  List<double> result;
  double maxY;
  double minY;
  PlotData({
    required this.result,
    required this.maxY,
    required this.minY,
  });
}

class LinePlot extends StatefulWidget {
  final PlotData plotData;
  const LinePlot({
    required this.plotData,
    Key? key,
  }) : super(key: key);

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

class _LinePlotState extends State<LinePlot> {
  late double minX;
  late double maxX;
  @override
  void initState() {
    super.initState();
    minX = 0;
    maxX = widget.plotData.result.length.toDouble();
  }

  @override
  Widget build(BuildContext context) {
    return Listener(
      onPointerSignal: (signal) {
        if (signal is PointerScrollEvent) {
          setState(() {
            if (signal.scrollDelta.dy.isNegative) {
              minX += maxX * 0.05;
              maxX -= maxX * 0.05;
            } else {
              minX -= maxX * 0.05;
              maxX += maxX * 0.05;
            }
          });
        }
      },
      child: GestureDetector(
        onDoubleTap: () {
          setState(() {
            minX = 0;
            maxX = widget.plotData.result.length.toDouble();
          });
        },
        onHorizontalDragUpdate: (dragUpdDet) {
          setState(() {
            print(dragUpdDet.primaryDelta);
            double primDelta = dragUpdDet.primaryDelta ?? 0.0;
            if (primDelta != 0) {
              if (primDelta.isNegative) {
                minX += maxX * 0.005;
                maxX += maxX * 0.005;
              } else {
                minX -= maxX * 0.005;
                maxX -= maxX * 0.005;
              }
            }
          });
        },
        child: LineChart(
          LineChartData(
            minX: minX,
            maxX: maxX,
            maxY: widget.plotData.maxY + widget.plotData.maxY * 0.1,
            titlesData: FlTitlesData(
              bottomTitles: SideTitles(
                showTitles: true,
                interval: widget.plotData.result.length / 10,
              ),
              leftTitles: SideTitles(
                showTitles: true,
                margin: 5,
              ),
              topTitles: SideTitles(
                showTitles: false,
                margin: 5,
              ),
            ),
            gridData: FlGridData(
              drawHorizontalLine: false,
            ),
            clipData: FlClipData.all(),
            lineBarsData: [
              LineChartBarData(
                barWidth: 1,
                dotData: FlDotData(
                  show: false,
                ),
                spots: widget.plotData.result
                    .asMap()
                    .entries
                    .map((entry) => FlSpot(entry.key.toDouble(), entry.value))
                    .toList(),
              )
            ],
          ),
        ),
      ),
    );
  }
}

Was this page helpful?
0 / 5 - 0 ratings

Related issues

xSILENCEx picture xSILENCEx  Â·  4Comments

caioflores picture caioflores  Â·  6Comments

davidmarinangeli picture davidmarinangeli  Â·  6Comments

atreeon picture atreeon  Â·  4Comments

jitenders859 picture jitenders859  Â·  5Comments