Creare grafici in Flutter con graphic

Mattepuffo's logo
Creare grafici in Flutter con graphic

Creare grafici in Flutter con graphic

graphic è una delle varie librerie per Flutter per la creazione di grafici.

Non è difficilissima da usare, ma a livello grafico c'è di meglio.

Comunque, per seguire l'esempio dovete installare due librerie:

flutter pub add graphic intl

Il secondo step è creare un file data.dart e metterci dentro tutti i dati.

Ovviamente chiamatelo come volete; non lo riporto tutto perchè troppo lungo, ma questo è link dove trovare il file.

Detto ciò, qui sotto un esempio con tre grafici:

import 'package:flutter/material.dart';
import 'package:graphic/graphic.dart';
import 'package:intl/intl.dart';

import '../data.dart';

final _monthDayFormat = DateFormat('MM-dd');

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(
          seedColor: Colors.deepPurple,
        ),
        useMaterial3: true,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Center(
        child: Column(
          children: [
            Container(
              margin: const EdgeInsets.only(top: 10),
              width: 350,
              height: 300,
              child: Chart(
                data: timeSeriesSales,
                variables: {
                  'time': Variable(
                    accessor: (TimeSeriesSales datum) => datum.time,
                    scale: TimeScale(
                      formatter: (time) => _monthDayFormat.format(time),
                    ),
                  ),
                  'sales': Variable(
                    accessor: (TimeSeriesSales datum) => datum.sales,
                  ),
                },
                marks: [
                  LineMark(
                    shape: ShapeEncode(
                      value: BasicLineShape(
                        dash: [5, 2],
                      ),
                    ),
                    selected: {
                      'touchMove': {1}
                    },
                  ),
                ],
                coord: RectCoord(
                  color: const Color(0xffdddddd),
                ),
                axes: [
                  Defaults.horizontalAxis,
                  Defaults.verticalAxis,
                ],
                selections: {
                  'touchMove': PointSelection(
                    on: {
                      GestureType.scaleUpdate,
                      GestureType.tapDown,
                      GestureType.longPressMoveUpdate
                    },
                    dim: Dim.x,
                  ),
                },
                tooltip: TooltipGuide(
                  followPointer: [false, true],
                  align: Alignment.topLeft,
                  offset: const Offset(-20, -20),
                ),
                crosshair: CrosshairGuide(
                  followPointer: [false, true],
                ),
              ),
            ),
            Container(
              margin: const EdgeInsets.only(top: 10),
              width: 350,
              height: 300,
              child: Chart(
                data: invalidData,
                variables: {
                  'Date': Variable(
                    accessor: (Map map) => map['Date'] as String,
                    scale: OrdinalScale(tickCount: 5),
                  ),
                  'Close': Variable(
                    accessor: (Map map) => (map['Close'] ?? double.nan) as num,
                  ),
                },
                marks: [
                  AreaMark(
                    shape: ShapeEncode(value: BasicAreaShape(smooth: true)),
                    color: ColorEncode(
                      value: Defaults.colors10.first.withAlpha(80),
                    ),
                  ),
                  LineMark(
                    shape: ShapeEncode(value: BasicLineShape(smooth: true)),
                    size: SizeEncode(value: 0.5),
                  ),
                ],
                axes: [
                  Defaults.horizontalAxis,
                  Defaults.verticalAxis,
                ],
                selections: {
                  'touchMove': PointSelection(
                    on: {
                      GestureType.scaleUpdate,
                      GestureType.tapDown,
                      GestureType.longPressMoveUpdate
                    },
                    dim: Dim.x,
                  ),
                },
                tooltip: TooltipGuide(
                  followPointer: [false, true],
                  align: Alignment.topLeft,
                  offset: const Offset(-20, -20),
                ),
                crosshair: CrosshairGuide(followPointer: [false, true]),
              ),
            ),
            Container(
              margin: const EdgeInsets.only(top: 10),
              width: 350,
              height: 300,
              child: Chart(
                data: scatterData,
                variables: {
                  '0': Variable(
                    accessor: (List datum) => datum[0] as num,
                  ),
                  '1': Variable(
                    accessor: (List datum) => datum[1] as num,
                  ),
                  '2': Variable(
                    accessor: (List datum) => datum[2] as num,
                  ),
                  '4': Variable(
                    accessor: (List datum) => datum[4].toString(),
                  ),
                },
                marks: [
                  PointMark(
                    size: SizeEncode(variable: '2', values: [5, 20]),
                    color: ColorEncode(
                      variable: '4',
                      values: Defaults.colors10,
                      updaters: {
                        'choose': {true: (_) => Colors.red}
                      },
                    ),
                    shape: ShapeEncode(
                      variable: '4',
                      values: [
                        CircleShape(hollow: true),
                        SquareShape(hollow: true),
                      ],
                    ),
                  ),
                ],
                axes: [
                  Defaults.horizontalAxis,
                  Defaults.verticalAxis,
                ],
                coord: RectCoord(
                  horizontalRange: [0.05, 0.95],
                  verticalRange: [0.05, 0.95],
                  horizontalRangeUpdater: Defaults.horizontalRangeEvent,
                  verticalRangeUpdater: Defaults.verticalRangeEvent,
                ),
                selections: {'choose': PointSelection(toggle: true)},
                tooltip: TooltipGuide(
                  anchor: (_) => Offset.zero,
                  align: Alignment.bottomRight,
                  multiTuples: true,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Enjoy!


Condividi

Commentami!