← Retour

📊 Tuto DataViz - Créer une app mobile avec Swift Charts et SwiftUI

~7 min

Nous allons voir ensemble comment créer une application mobile en Swift et afficher des données publique grâce à Swift Charts, un framework pour afficher des graphiques simplement.

Swift Charts est un nouveau framework, présenté par Apple en 2022, qui permet de créer facilement de magnifiques représentations visuelles pour vos données. Illustrations de plusieurs téléphones avec des graphiques Nous sommes entouré de données, mais il est difficile pour les développeurs d’avoir le temps et les ressources de les mettre en valeurs dans les applications mobiles**. Pourtant montrer des données aux utilisateurs est un vrai + dans votre UX (Expérience utilisateur).**

Apple l’a bien compris, tout comme ils l’ont déjà fait avec le Machine Learning depuis 2017, leur objectif avec Swift Charts est de rendre accessible la visualisation de données aux développeurs. Le framework est très simple d’accès et permet de rapidement visualiser des données sans être fort en statistique ou en maths (c’est pratique pour moi en tout cas).

C’est parti !

1. Récupérer le projet Xcode

Télécharger le projet via ce lien, allez dans le dossier ChartSample-Starter qui sera notre point de départ.

On va travailler avec un jeu de donnée simplifiée ( summarizedDataSet.csv ) qui traite des 🚨 infractions en France par département entre 2016 et 2021. Ces données sont trouvable facilement ici sur data.gouv.fr.

TW: On va utiliser des données réelles et qui peuvent interpeller certaines personnes. L'intérêt ici est surtout d'avoir des données réelles et cohérentes. Et puis j'avais envie depuis un moment d'utiliser ce jeu de données alors let's go

Image de 2 gendarmes de dosJ’espère que la gendarmerie sera contente de notre App

2. Créer un graphique

Le jeu de donnée

Nous avons récupéré dans le jeu de données très complet de base, un petit échantillon qui correspond à ce que je voulais montrer.

N’hésitez pas à vous promener dans les milliers de lignes du fichier de base pour modifier cet extrait du jeu de donnée à votre envie, pour votre département par exemple.

Illustration du jeu de donnéeNotre jeu de données

Le code

La première étape pour créer un graphique est de construire des structures de données en Swift propres et claires.

Pour l’exercice je les ai créé pour vous (🥺 je sais), ils sont dans le fichier DataModels.swift.

Et voilà à quoi cela ressemble :

//DataModels.swift

//Structure pour le graphique de répartition des infractions par années
struct DataPerYear : Identifiable {
    let id = UUID()
    // Classe
    let year: String
    
    // Nombres de faits survenus
    let occurences: Int
}

//Structure pour le graphique de répartition des infractions par département
struct DataPerLocalization: Identifiable {
    let id = UUID()
    
    // Le département concerné
    let dept: String
    
    // Nombres de faits survenus
    let occurences: Int
}
...

Ces structures représentent 1 ligne de donnée, nous aurons donc plusieurs tableaux Swift à gérer pour créer nos graphiques et explorer les données.

3. Afficher notre premier graphique

Vous allez voir c’est super difficile (non). On va créer pour chaque élément, Chart(data) va ici agir comme un ForEach(data) et nous donner une variable set représentant chaque ligne du tableau.

A noter qu’il est aussi possible d’imbriquer plusieurs ForEach dans la closure de l’élément Chart pour plus de contrôle

Chart(dataYear) { set in
	BarMark(
            x: .value("Année", set.year),
			y: .value("Occurence", set.occurences)
     )
}

Oui c’est tout. Ensuite nous créons pour chaque itération de la boucle une vue BarMark qui prend en paramètre x: et y: qui sont les coordonnées de notre point de donnée dans l’espace du graphique.

Le framework prend en charge la mise à l’échelle de nos données dans l’espace en pixels de l’écran du téléphone automatiquement, et ce grâce à l’utilisation de .value(labelKey: LocalizedStringKey, value: Plottable). LabelKey représentera le nom de votre donnée, très important pour l’accessibilité et pour le framework. Plottable quant à lui peut être de quasi tout les types primitifs, y compris String.

Le framework fait tout le boulot à notre place, voici le graphique : Ouiiii le premier graphique ! Et le code complet de cette première vue :

import SwiftUI
import Charts

struct ContentView: View {
 @State var dataYear = [DataPerYear]()
    
    var body: some View {
      		
            List {
                Section("Nombre d'infractions depuis 2016") {
					//Notre graphique
					Chart(dataYear) { set in
                        BarMark(x: .value("Année", set.year),
                                y: .value("Occurence", set.occurences)
                        )
                    }.frame(height: 300)
                    
                }
            }
     
    }

4. Composer sa visualisation

Un point sur la composition avec Apple Charts

Le principe de ce Framework est de vous donner des briques simples et compatibles entres-elles pour créer des graphiques plus complexes.

Par exemple, rajoutons une vision plus claire de l’évolution des infractions. Toujours sur ce même graphique, il nous suffit d’ajouter d’autres “Mark”, ici nous avons déjà des BarMark (graphique en barre) qui correspondent à chaque ligne de données.

Il existe plusieurs “Mark” que vous pouvez ajouter, et composer :

  • LineMark (Courbe)
  • BarMark (Barre)
  • RuleMark (Trait)
  • RectangleMark (Rectangle)
  • AreaMark (Aire / Zone)
  • PointMark (Point)

Les noms sont assez explicite mais pour plus de détails je vous renvoi sur la documentation d’Apple à ce sujet.

Ajoutons une nouvelle visualisation !

Nous allons ajouter une ligne pour comprendre plus visuellement l’évolution à travers le temps. Graphique avec Ligne, Barres et Points Pour cela rien de plus simple, il suffit de copier-coller notre BarMark en changeant simplement ”Bar” en ”Line” et hop !

//Le code à rajouter dans notre Chart()
LineMark(
 	x: .value("Année", set.year),
	y: .value("Occurence", set.occurences)
 )
 //Permet d'adoucir la courbe
 .interpolationMethod(.catmullRom(alpha: 0.2)) 

Pour ajouter des points sur la courbe, il suffit de… Oui ajouter le même code mais avec ”Point” au lieu de ”Line“.

Voilà le code final de ce graphique :

import SwiftUI
import Charts

struct ContentView: View {
 @State var dataYear = [DataPerYear]()
    
    var body: some View {
            List {
                Section("Nombre d'infractions depuis 2016") {
					//Notre graphique
					Chart(dataYear) { set in
                        BarMark(x: .value("Année", set.year),
                                y: .value("Occurence", set.occurences)
                        )
                        .opacity(0.3) //Pour mieux voir notre ligne
                        //Notre ligne
                        LineMark(x: .value("Année", set.year),
                                      y: .value("Occurence", set.occurences)
                            )
                            .interpolationMethod(
                            		.catmullRom(alpha: 0.2)
                                    )
                         //Les points de données
                         PointMark(
                                 x: .value("Année", set.year),
                                 y: .value("Occurence", set.occurences)
                            )
                    }.frame(height: 300)
                    
                }
            }
     
    }

Comme vous pouvez le constater, c’est plutôt simple.

De plus chaque élément du graphique reste une vue SwiftUI, vous pouvez donc appliquer des modifiers comme n’importe quelle autre vue.

5. S’adapter à la donnée

Nous allons ici tenter d’afficher les infractions par type depuis 2016. Avec la même technique. Illustration du jeu de donnéeIntéressons nous au dernier tableau ici Voyons ce que cela donne :

Chart(dataType) { set in
            BarMark(
               x: .value("Type", set.type),
               y: .value("Occurence", set.occurences)
            )
    }

Voila le résultat, c’est pas très beau :/ Il y a comme un problème ici, impossible de lire correctement la légende sur l’axe des abscisses (x).

💡 La solution ? Inverser les axes.

//On inverse les valeurs de x: et y:
BarMark(x: .value("Occurence", set.occurences),
		y: .value("Type", set.type)
)

Les occurrences des infractions seront maintenant sur l’abscisse (x) et les types d’infractions sur l’ordonnée (y).

🪄 Remarquez comme le framework place correctement les légendes sur chaque barre de donnée, magique !

Graphique de répartition des infractions par type depuis 2016 J’ai réalisé d’autres modifications sur le graphique pour vous donner un florilège de ce que l’on modifie généralement sur un graphique :

  • Les couleurs, avec un dégradé
  • Le format des nombres
  • Le rayon des bordures des barres
  • La hauteur des barres

Le framework peut deviner plein de choses, mais pas comment vous souhaitez afficher certains éléments.

Le principal n’est pas d’avoir de la donnée, mais comment l’afficher pour qu’elle soit compréhensible et utile d’un coup d’oeil.

Je vous laisserai découvrir comment j’ai fais ces modifications dans le dossier ChartSample-Final avec le code qui va bien.

6. A votre tour !

Nous avions une troisième donnée à afficher, la répartition par département.

A vous de jouer, tentez de réaliser le dernier graphique comme suit :

Graphique représentant les infractions par département depuis 2016