iOS styled line chart in flutter

35 Views Asked by At

I am wanting my flutter app to have a similar style to the standard iOS design.

One thing I am wanting to do is to have an 'iOS styled' line chart.

This is the design I am trying to go for, but it seems very hard to replicate. enter image description here

I have managed to replicate something similar but i'm getting stuck on the next steps.

Some particular parts I am having trouble with:

  • Vertical grey line at the end of the data but overlapped by the grey circle.
  • Rigged steps but also curved?
  • X axis labels "00:00" and 23:30" with the grey dots inbetween them.

What I tried:

class IOSStyleLineChart extends StatelessWidget {
  const IOSStyleLineChart({super.key});

  @override
  Widget build(BuildContext context) {
List<Map<String, dynamic>> data = [
  {
    "time": DateTime.now().subtract(Duration(
        hours: DateTime.now().hour, minutes: DateTime.now().minute)),
    "xp": 0
  },
  {
    "time": DateTime.now().subtract(const Duration(hours: 4, minutes: 0)),
    "xp": 10
  },
  {
    "time": DateTime.now().subtract(const Duration(hours: 3, minutes: 30)),
    "xp": 24
  },
  {
    "time": DateTime.now().subtract(const Duration(hours: 2, minutes: 15)),
    "xp": 400
  },
  {
    "time": DateTime.now().subtract(const Duration(hours: 2, minutes: 1)),
    "xp": 500
  },
  {
    "time": DateTime.now().subtract(const Duration(hours: 1, minutes: 45)),
    "xp": 700
  },
  {
    "time": DateTime.now().subtract(const Duration(hours: 1, minutes: 0)),
    "xp": 750
  },
  {
    "time": DateTime.now().subtract(Duration(
        hours: DateTime.now().hour - 23,
        minutes: DateTime.now().minute - 30)),
    "xp": 800
  },
];

List<FlSpot> spots = data.map((datum) {
  final time = datum["time"] as DateTime;
  final xp = datum["xp"] as int;
  double hours = time.hour.toDouble();
  double minutes = time.minute / 60;
  return FlSpot(hours + minutes, xp.toDouble());
}).toList();

return LineChart(
  LineChartData(
    minX: 0,
    maxX: 24,
    gridData: const FlGridData(show: false),
    titlesData: const FlTitlesData(show: false),
    borderData: FlBorderData(show: false),
    lineBarsData: [
      LineChartBarData(
        isStepLineChart: true,
        spots: spots,
        barWidth: 4,
        dotData: FlDotData(
          show: true,
          getDotPainter: (spot, percent, barData, index) {
            if (index == barData.spots.length - 1) {
              return FlDotCirclePainter(
                radius: 4,
                color: CupertinoColors.destructiveRed,
                strokeWidth: 2,
                strokeColor: CupertinoColors.white,
              );
            } else {
              return FlDotCirclePainter(
                radius: 0,
                color: CupertinoColors.destructiveRed,
              );
            }
          },
        ),
        belowBarData: BarAreaData(show: false),
        color: CupertinoColors.destructiveRed,
      ),
    ],
  ),
);

} }

1

There are 1 best solutions below

2
baliman On

I think you have to use cupertino styling but not sure