flutterclippingfl-chart

Flutter how to add a clipper to fl_chart (CustomPainter)


I have a fl_chart (pub), which is displayed below in the gifs. When transitioning data the painter paints outside of the chart's bounds. How could I add a clipper (or some other fix) to the chart below, so this bug does not occur? There is some code at the bottom & some images. fl_chart uses a CustomPainter to draw the charts, so maybe I could override something in the source code?


My quick fix (I removed the transition animation, but I'd like to use the animation):

fl_chart quick fix


Ignore the label bug on the y axis (on the left)

(If you don't see the bug look close on the right side)

I would like to use a transition like this, but without the chart going outside the boundaries:

bugged fl_chart


Here is the code:

LineChartData mainData() {
    return LineChartData(
      lineTouchData: LineTouchData(
        touchTooltipData: LineTouchTooltipData(
          fitInsideHorizontally: true,
          tooltipBgColor: Colors.white,
          getTooltipItems: (List<LineBarSpot> touchedBarSpots) {
            return touchedBarSpots.map((barSpot) {
              return LineTooltipItem(
                '${barSpot.y.toInt()}',
                TextStyle(
                  fontFamily: 'Jost*',
                  fontSize: 15,
                  color: Colors.black,
                ),
              );
            }).toList();
          }
        ),
        getTouchedSpotIndicator: (LineChartBarData barData, List<int> spotIndexes) {
          return spotIndexes.map((spotIndex) {
            return TouchedSpotIndicatorData(
              FlLine(
                color: const Color.fromARGB(255, 77, 77, 77),
                strokeWidth: 1,
                dashArray: [4,4],
              ),
              FlDotData(
                getDotPainter: (spot, percent, barData, index) {
                  return FlDotCirclePainter(
                    radius: 5.5,
                    color: gradientColors[0],
                    strokeWidth: 2,
                    strokeColor: Colors.white,
                  );
                },
              ),
            );
          }).toList();
        }
      ),
      gridData: FlGridData(
        show: true,
        getDrawingHorizontalLine: (value) {
          return FlLine(
            color: const Color.fromARGB(255, 98, 95, 161),
            strokeWidth: 1,
            dashArray: [4,4]
          );
        },
      ),
      titlesData: FlTitlesData(
        show: true,
        bottomTitles: SideTitles(
          showTitles: true,
          reservedSize: 14,
          textStyle:
          const TextStyle(
            color: Color.fromARGB(255, 181, 181, 181),
            fontWeight: FontWeight.w300,
            fontFamily: 'Jost*',
            fontSize: 13,
          ),
            getTitles: (value) {
              return _labels[widget.timeType][value.toInt()] ?? '';
            },
        ),
        leftTitles: SideTitles(
          showTitles: true,
          textStyle: const TextStyle(
            color: Color.fromARGB(255, 181, 181, 181),
            fontWeight: FontWeight.w300,
            fontFamily: 'Jost*',
            fontSize: 16,
          ),
          getTitles: (value) {
            return (value.toInt()).toString();
          },
          reservedSize: 28,
          margin: 12,
        ),
      ),
      borderData:
      FlBorderData(
        show: true,
        border: Border.symmetric(
          horizontal: BorderSide(
            color: const Color.fromARGB(255, 170, 170, 170),
            width: 1.2
          ),
        ),
      ),
      minX: 0,
      maxX: _data[widget.timeType].length.toDouble()-1, //length of data set
      minY: _data[widget.timeType].reduce(min).toDouble() - 1,  //set to lowest v
      maxY: _data[widget.timeType].reduce(max).toDouble() + 1,  //set to highest v
      lineBarsData: [
        LineChartBarData(
          spots: [
            for (int i = 0; i < _data[widget.timeType].length; i++)
              FlSpot(i.toDouble(), _data[widget.timeType][i].toDouble())
          ],
          //FlSpot(2.6, 4),
          isCurved: true,
          colors: [
            gradientColors[0],
          ],
          barWidth: 2,
          isStrokeCapRound: true,
          dotData: FlDotData(
            show: false,
          ),
          belowBarData: BarAreaData(
            show: true,
            colors: gradientColors,
            gradientColorStops: [0, 0.5, 1.0],
            gradientFrom: const Offset(0, 0),
            gradientTo: const Offset(0, 1),
          ),
        ),
      ],
    );
  }

Solution

  • there is a clipData property in the LinechartData

    try to set it as FlClipData.all().