4

I want to show data from a List in a line chart. The Problem is that the width is too small. So I want that you can scroll horizontal to see everything. How to do this with the Package fl_chart?

Here is my Code, i build the spots from a List.

  @override
  Widget build(BuildContext context) {
    return LineChart(
        LineChartData(
            lineBarsData: [
          LineChartBarData(
              spots: [
            for (int i = reversedList.length - 1; i >= 0; i--)
              FlSpot(i.toDouble(), reversedList[i].weight),
          ])
        ]));
  }
}
Dalon
  • 566
  • 8
  • 26

2 Answers2

4

Set the width of your LineChart to the width you need and wrap the LineChart() widget in a SingleChildScrollView() and set scrollDirection: Axis.horizontal

Edit: I think you need to wrap the LineChart() in a Container() with fixed width first. Otherwise the Chart may try to extend towards infinity.

MindStudio
  • 706
  • 1
  • 4
  • 13
  • Thank you, but the with is still a fixed value and when the data grow (user can dynamically add more data) the width is too small. How can i relate the with to the data in my list, so that when the list gets bigger the width also increase? – Dalon Jul 17 '21 at 16:10
  • 1
    just calculate the width dynamically: `width: reversedList.length*20` for example – MindStudio Jul 19 '21 at 00:49
0

One possibility is to make the x-axis dynamic.

 @observable
  int xMinValue = 0;
  
  @action
  void updateXMinValue(int newValue) {
    xMinValue = newValue;
  }

That way you can generate the bars in a specific range

for (int i = controller.xMinValue; i <= indexController; i++) {
      rawBarGroups.add(makeGroupData(
        x: i,
        bar1: widget.chartDataSet[i].bar1));
    }

Finally, you can change this range from a swipe movement in the graph component, one way to do this is using the GestureDetector.

GestureDetector(
      onHorizontalDragEnd: (DragEndDetails details) {
        if (details.primaryVelocity! > 0 && controller.xMinValue > 0) {
          controller.updateXMinValue(controller.xMinValue - 1);
        } else if (details.primaryVelocity! < 0 && widget.chartDataSet.first.index! > controller.xMinValue + 7) {
          controller.updateXMinValue(controller.xMinValue + 1);
        }
      },
      child: BarChart(
        BarChartData( ...

In a graph with a large number of spots, this solution can become a usability problem as navigation tends to be a little slower by using the swipe gesture. In these cases I recommend using a solution closer to a zoom in the graph, you can find an example here: https://github.com/imaNNeo/fl_chart/issues/71#issuecomment-1414267612