Faire un graphique en colonnes (Column chart) dans Flutter


Avatar de Pierre Courtois

Maintenant que nous avons implémenté syncfusion_flutter_charts, voyons comment faire un graphique en colonne, aussi appelé Column chart, dans notre application Flutter.


À quoi sert un graphique en colonnes ?

Les graphiques en colonnes sont parfaits pour comparer des valeurs entre différentes catégories ou montrer des données discrètes. Chaque colonne représente une valeur associée à une catégorie, avec la hauteur indiquant l’ampleur. Ils sont idéaux pour :

  • Comparer des performances (ex. : ventes par mois).
  • Mettre en évidence des différences entre groupes (ex. : revenus par région).
  • Présenter des données statiques ou ponctuelles (ex. : scores d’une équipe).

Créer un column chart de base

Voici un exemple simple pour afficher des données de ventes annuelles.

Assurez-vous au préalable de bien avoir mis en place syncfusion_flutter_charts en ajoutant sa dépendance dans votre fichier pubspec.yaml.

import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_charts/charts.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Column Chart de base')),
        body: Center(
          child: SfCartesianChart(
            primaryXAxis: CategoryAxis(),
            series: <ColumnSeries<SalesData, String>>[
              ColumnSeries<SalesData, String>(
                dataSource: [
                  SalesData('Jan', 35),
                  SalesData('Fév', 28),
                  SalesData('Mar', 34),
                  SalesData('Avr', 32),
                  SalesData('Mai', 40),
                ],
                xValueMapper: (SalesData sales, _) => sales.month,
                yValueMapper: (SalesData sales, _) => sales.sales,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class SalesData {
  SalesData(this.month, this.sales);
  final String month;
  final double sales;
}

Voici les éléments minimum indispensables pour faire un graphique en colonnes dans Flutter :

  • SfCartesianChart : Le conteneur principal pour tout graphique cartésien (colonnes, lignes, etc.).
  • primaryXAxis : Définit l’axe horizontal. Sans cela, le graphique ne sait pas comment interpréter les données X (ici, CategoryAxis pour des mois textuels).
  • series : La liste des séries à afficher.
  • ColumnSeries : Permet de spécifier que le graphique que l’on souhaite afficher est de type colonnes.
  • dataSource : Les données brutes sous forme de liste d’objets, fournissant les points à afficher.
  • xValueMapper et yValueMapper : Relient les données aux axes X (catégories) et Y (valeurs). Sans ces mappers, le graphique ne peut pas associer les données aux axes.

Ajouter plusieurs colonnes au graphique

Vous pouvez rendre votre graphique en colonnes encore plus puissant en y affichant plusieurs séries de données pour comparer des catégories. Avec syncfusion_flutter_charts, il suffit d’ajouter plusieurs ColumnSeries à la liste series de SfCartesianChart. Chaque série peut avoir ses propres données, couleurs et légendes. Par défaut, les colonnes de différentes séries sont placées côte à côte grâce à la propriété enableSideBySideSeriesPlacement.

import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_charts/charts.dart';

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

class MyApp extends StatelessWidget {
  final TooltipBehavior _tooltip = TooltipBehavior(enable: true);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Column Chart avec plusieurs colonnes')),
        body: SfCartesianChart(
          title: ChartTitle(text: 'Ventes par région (2025)'),
          legend: Legend(isVisible: true), // Active la légende pour identifier les colonnes
          tooltipBehavior: _tooltip,
          primaryXAxis: CategoryAxis(
            title: AxisTitle(text: 'Mois'),
          ),
          primaryYAxis: NumericAxis(
            title: AxisTitle(text: 'Ventes (k€)'),
            minimum: 20,
            maximum: 50,
          ),
          series: <ColumnSeries<SalesData, String>>[
            // Première série : Région A
            ColumnSeries<SalesData, String>(
              name: 'Région A', // Nom pour la légende
              dataSource: [
                SalesData('Jan', 35),
                SalesData('Fév', 28),
                SalesData('Mar', 34),
                SalesData('Avr', 32),
                SalesData('Mai', 40),
              ],
              xValueMapper: (SalesData sales, _) => sales.month,
              yValueMapper: (SalesData sales, _) => sales.sales,
              color: Colors.blue, // Couleur des colonnes
              width: 0.8,
            ),
            // Deuxième série : Région B
            ColumnSeries<SalesData, String>(
              name: 'Région B', // Nom pour la légende
              dataSource: [
                SalesData('Jan', 25),
                SalesData('Fév', 30),
                SalesData('Mar', 27),
                SalesData('Avr', 35),
                SalesData('Mai', 38),
              ],
              xValueMapper: (SalesData sales, _) => sales.month,
              yValueMapper: (SalesData sales, _) => sales.sales,
              color: Colors.red, // Couleur différente pour distinction
              width: 0.8,
            ),
          ],
        ),
      ),
    );
  }
}

class SalesData {
  SalesData(this.month, this.sales);
  final String month;
  final double sales;
}

Si vos séries ont des échelles très différentes (ex. : une en milliers, l’autre en unités), vous pouvez ajouter deuxième axe Y supplémentaire.

Comment personnaliser votre graphique en colonnes ?

syncfusion_flutter_charts offre de nombreuses options pour personnaliser un Column Chart. Voici une liste détaillée avec des exemples.

Changer l’apparence des colonnes

Vous pouvez modifier la couleur, la largeur et la bordure des colonnes :

  • color : Définit la couleur de remplissage des colonnes. Accepte un Color (ex. : Colors.teal, Color.fromRGBO(255, 0, 0, 1)).
  • width : Contrôle la largeur relative des colonnes dans l’espace alloué à chaque catégorie. Valeur entre 0 et 1 (1 = pleine largeur, 0.5 = moitié de l’espace).
  • borderWidth : Épaisseur de la bordure autour des colonnes, en pixels (ex. : 2.0). Par défaut, 0 (pas de bordure).borderColor : Couleur de la bordure. Nécessite borderWidth > 0 pour être visible.
ColumnSeries<SalesData, String>(
  dataSource: /* ... */,
  xValueMapper: (SalesData sales, _) => sales.month,
  yValueMapper: (SalesData sales, _) => sales.sales,
  color: Colors.teal,
  width: 0.8, // 80% de l’espace disponible par colonne
  borderWidth: 2,
  borderColor: Colors.black,
),

Ajouter des coins arrondis

borderRadius : Arrondit les coins supérieurs des colonnes grâce au widget BorderRadius.

ColumnSeries<SalesData, String>(
  dataSource: /* ... */,
  xValueMapper: (SalesData sales, _) => sales.month,
  yValueMapper: (SalesData sales, _) => sales.sales,
  borderRadius: BorderRadius.circular(5), // Coins arrondis de 5 pixels
),

Colonnes multicolores

Utilisez pointColorMapper pour attribuer une couleur différente à chaque colonne :

class SalesData {
  SalesData(this.month, this.sales, this.color);
  final String month;
  final double sales;
  final Color color;
}

ColumnSeries<SalesData, String>(
  dataSource: [
    SalesData('Jan', 35, Colors.red),
    SalesData('Fév', 28, Colors.green),
    SalesData('Mar', 34, Colors.blue),
    SalesData('Avr', 32, Colors.yellow),
    SalesData('Mai', 40, Colors.purple),
  ],
  xValueMapper: (SalesData sales, _) => sales.month,
  yValueMapper: (SalesData sales, _) => sales.sales,
  pointColorMapper: (SalesData sales, _) => sales.color,
),

Pensez à ajouter une propriété Color à la classe qui va vous permettre de générer vos colonnes.

Ajouter plusieurs colonnes au graphique

Le widget SfCartesianChart vous permet d’afficher plusieurs séries de données pour comparer des catégories, chacune ayant leurs couleurs et leurs légendes.

Pour cela, utilisez la propriété enableSideBySideSeriesPlacement qui permet de placer les colonnes côte à côte quand a une valeur de true, et se superposent quand elle a une valeur de false.

SfCartesianChart(
  title: ChartTitle(text: 'Ventes par région (2025)'),
  legend: Legend(isVisible: true),
  primaryXAxis: CategoryAxis(title: AxisTitle(text: 'Mois')),
  primaryYAxis: NumericAxis(title: AxisTitle(text: 'Ventes (k€)')),
  series: <ColumnSeries<SalesData, String>>[
    ColumnSeries<SalesData, String>(
      name: 'Région A', // Nom dans la légende
      dataSource: [
        SalesData('Jan', 35),
        SalesData('Fév', 28),
        SalesData('Mar', 34),
      ],
      xValueMapper: (SalesData sales, _) => sales.month,
      yValueMapper: (SalesData sales, _) => sales.sales,
      color: Colors.blue,
    ),
    ColumnSeries<SalesData, String>(
      name: 'Région B',
      dataSource: [
        SalesData('Jan', 25),
        SalesData('Fév', 30),
        SalesData('Mar', 27),
      ],
      xValueMapper: (SalesData sales, _) => sales.month,
      yValueMapper: (SalesData sales, _) => sales.sales,
      color: Colors.red,
    ),
  ],
),

Ajouter des étiquettes de données

Avec dataLabelSettings, affichez les valeurs de vos colonnes directement au dessus :

  • isVisible : true pour afficher les étiquettes, false pour les cacher.
  • labelAlignment : Position de l’étiquette (ChartDataLabelAlignment.top, middle, bottom, etc.).
  • textStyle : Style du texte (ex. : TextStyle(fontSize: 12, color: Colors.black)).
ColumnSeries<SalesData, String>(
  dataSource: /* ... */,
  xValueMapper: (SalesData sales, _) => sales.month,
  yValueMapper: (SalesData sales, _) => sales.sales,
  dataLabelSettings: DataLabelSettings(
    isVisible: true,
    labelAlignment: ChartDataLabelAlignment.top,
    textStyle: TextStyle(fontSize: 12, color: Colors.black),
  ),
),

Personnaliser les axes

  • primaryXAxis : Définit le type de l’axe horizontal. Par exemple CategoryAxis (catégories textuelles), NumericAxis (nombres), etc.
    • title : Ajoute un titre via AxisTitle(text: ‘Mois’).
  • primaryYAxis : Axe vertical. Généralement NumericAxis pour les colonnes.
    • title : Titre de l’axe Y.
    • minimum : Valeur minimale (ex. : 0).
    • maximum : Valeur maximale (ex. : 50).
    • interval : Espacement entre les marques (ex. : 10).
SfCartesianChart(
  primaryXAxis: CategoryAxis(
    title: AxisTitle(text: 'Mois'), // Titre de l’axe X
  ),
  primaryYAxis: NumericAxis(
    title: AxisTitle(text: 'Ventes (k€)'), // Titre de l’axe Y
    minimum: 0, // Début à 0
    maximum: 50, // Fin à 50
    interval: 10, // Marques tous les 10 k€
  ),
  series: /* ... */,
),

Attention, les possibilités de personnalisation ne sont pas les mêmes selon le type d’axe. Voici les différentes variantes que vous pouvez utiliser :

TypeDonnées adaptéesExemple d’usage
NumericAxisNombres continusAnnées, quantités
CategoryAxisCatégories textuellesMois, noms de produits
DateTimeAxisDates/heures continuesVentes par jour
DateTimeCategoryAxisDates discrètesPremiers jours des mois
LogarithmicAxisDonnées exponentiellesCroissance logarithmique

Ajouter un titre et une légende

Vous pouvez également ajouter un titre et une légende à votre graphique, grâce aux propriétés suivantes :

  • title : Titre global du graphique via ChartTitle.
  • legend : Affiche une légende pour identifier les séries.
SfCartesianChart(
  title: ChartTitle(text: 'Ventes mensuelles 2025'), // Titre du graphique
  legend: Legend(isVisible: true), // Légende visible
  series: /* ... */,
),

Activer les interactions

Vous pouvez afficher des bulles informatives sur vos colonnes, grâce à la propriété tooltipBehavior. Pour cela, vous devrez créer un widget de type TooltipBehavior, contenant les éléments suivants :

  • enable : true pour activer.
  • color : Couleur de fond (ex. : Colors.grey).
  • textStyle : Style du texte dans la bulle.
class MyApp extends StatelessWidget {
  final TooltipBehavior _tooltip = TooltipBehavior(
    enable: true, // Active les tooltips
    color: Colors.grey[800], // Fond gris foncé
    textStyle: TextStyle(color: Colors.white), // Texte blanc
  );

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SfCartesianChart(
          tooltipBehavior: _tooltip,
          series: /* ... */,
        ),
      ),
    );
  }
}

Ajouter un deuxième axe Y avec la propriété axes

Quand vos lignes représentent des données avec des unités ou des échelles différentes (ex. : ventes en k€ et taux de croissance en %), un seul axe Y peut rendre le graphique illisible. Avec la propriété axes de SfCartesianChart, vous pouvez ajouter un deuxième axe des ordonnées (ou plus), puis l’associer à une série via yAxisName.

Voici un exemple où une colonne montre les ventes (k€) et une autre le taux de croissance (%) :

SfCartesianChart(
          title: ChartTitle(text: 'Ventes par région (2025)'),
          legend: Legend(
              isVisible:
                  true), // Active la légende pour identifier les colonnes
          tooltipBehavior: _tooltip,
          primaryXAxis: CategoryAxis(
            title: AxisTitle(text: 'Mois'),
          ),
          primaryYAxis: NumericAxis(
            title: AxisTitle(text: 'Ventes (k€)'),
            minimum: 20,
            maximum: 50,
          ),
          axes: <ChartAxis>[
            // Ajoute les axes supplémentaires
            NumericAxis(
              name: 'secondYAxis', // Nom unique pour cet axe
              title: AxisTitle(text: 'Taux de croissance (%)'),
              minimum: 0,
              maximum: 10,
              opposedPosition: true, // Place l’axe à droite
            ),
          ],
          series: <ColumnSeries<SalesData, String>>[
            // Première série : Région A
            ColumnSeries<SalesData, String>(
              dataSource: [
                SalesData('Jan', 35),
                SalesData('Fév', 28),
                SalesData('Mar', 34),
                SalesData('Avr', 32),
                SalesData('Mai', 40),
              ],
              dataLabelSettings: DataLabelSettings(
                isVisible: true,
                labelAlignment: ChartDataLabelAlignment.top,
                textStyle: TextStyle(fontSize: 12, color: Colors.black),
              ),
              xValueMapper: (SalesData sales, _) => sales.month,
              yValueMapper: (SalesData sales, _) => sales.sales,
              color: Colors.blue, // Couleur des colonnes
              width: 0.8,
            ),
            ColumnSeries<SalesData, String>(
              yAxisName: 'secondYAxis',
              dataSource: [
                SalesData('Jan', 0.5),
                SalesData('Fév', 1),
                SalesData('Mar', 3),
                SalesData('Avr', 1.5),
                SalesData('Mai', 4),
              ],
              dataLabelSettings: DataLabelSettings(
                isVisible: true,
                labelAlignment: ChartDataLabelAlignment.top,
                textStyle: TextStyle(fontSize: 12, color: Colors.black),
              ),
              xValueMapper: (SalesData sales, _) => sales.month,
              yValueMapper: (SalesData sales, _) => sales.sales,
              color: Colors.red, // Couleur des colonnes
              width: 0.8,
            ),
          ],
        ),

Modifier la durée de l’animation

Enfin, vous pouvez gérer la durée de l’animation d’entrée de votre graphique en colonnes, avec animationDuration (en millisecondes) :

LineSeries<SalesData, double>(
  dataSource: /* ... */,
  xValueMapper: (SalesData sales, _) => sales.year,
  yValueMapper: (SalesData sales, _) => sales.sales,
  animationDuration: 5000, // 5 seconde
),
Avatar de Pierre Courtois