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. 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
J’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.
Notre 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 laclosure
de l’élémentChart
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.
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. Inté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 !
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 :