Utilisant Matomo pour avoir des statistiques (complètement anonymisées) de visites sur mon site/blog, j’avais envie d’afficher quelques graphiques et infos sur mon tableau de bord sans avoir besoin de visiter l’interface Matomo.
- Récupérer les statistiques
- Préparer le graphique
- Construction du SVG
- Un peu de CSS pour rendre ça joli
Récupérer les statistiques
Cette partie est vraiment propre à Laravel et Matomo, vous pouvez vous en inspirer… ou complètement l’ignorer si vous avez un socle technique différent
J’ai utilisé le package Laravel Piwik pour récupérer les informations dont j’avais besoin, puis créé des graphiques en SVG manuellement, via un composant Laravel dédié.
La récupération des infos est une simple boucle pas optimisée qui utilise l’API Matomo pour obtenir un résumé des visites des 7 derniers jours :
Je peux alors injecter les données à mon composant qui va créer le graphique :
Préparer le graphique
Avant de générer le SVG il y a quelques calculs à faire pour s’assurer qu’il ait une tête convenable.
On commence donc par calculer la valeur maximale (on pourrait aussi calculer la valeur la plus basse pour supprimer l’espace en bas, si l’écart de valeurs est plus important que les valeurs elles-mêmes) et donc définir l’échelle sur l’axe des ordonnées.
On calcule aussi la largeur des intitulés sur l’axe des abscisses pour les placer correctement.
J’utilise aussi une "gouttière" ($gutter
) tout autour du composant, ainsi qu’entre l’axe des ordonnées et le graphique lui-même.
Certaines valeurs sont fixes pour assurer une cohérence entre les graphiques, mais peuvent être rendues paramétrables facilement en les définissant dans le constructeur.
Construction du SVG
Le code est plutôt simple, c’est du SVG assez basique et quelques balises Blade (système de template utilisé par Laravel) pour boucler et injecter les valeurs.
On commence donc par placer un rectangle pour le fond du graphique (histoire de décorer) puis on construit les échelles : l’axe horizontal d’abord puis l’axe vertical (même si l’ordre n’a pas vraiment d’importance).
Ensuite on boucle sur les données pour afficher une ligne, puis on recommence pour les points qui s’y superposent. On pourra leur donner un effet de contour pour cacher un bout de la ligne avec du CSS (et l’attribut stroke-width
qui est déjà présent ici).
Un peu de CSS pour rendre ça joli
Le SVG est assez monochrome, alors on n’oublie pas d’ajouter quelques couleurs pour coller au reste du site.
.chart {
display: block;
position: relative;
width: 100%;
margin: size(2) auto;
svg {
display: block;
width: 100%;
overflow: visible;
}
.grid {
stroke: color('gray', 500); // La fonction `color` est déclarée en SCSS pour utiliser un dégradé facilement
stroke-dasharray: 0;
stroke-width: 1px;
}
.labels {
text {
fill: color('gray', 600);
stroke-width: 0;
transform: translateY(.5em);
}
line {
stroke: color('gray', 200);
stroke-width: 1px;
}
}
.label-title {
stroke: color('gray', 500);
font-weight: 500;
}
.data-background {
fill: color('gray', 50);
}
.data {
circle {
fill: color('blue', 500);
stroke: color('gray', 50);
&:hover {
fill: color('blue', 700);
filter: drop-shadow(0 0 .5rem color('gray', 300));
}
}
polyline {
stroke: color('blue', 200);
}
}
}
Rien de bien compliqué ici, il sagit surtout de rendre le SVG responsive et d’appliquer quelques couleurs. Détail important pour donner le bon effet aux points qui cachent la ligne : on définit stroke
(pour le sélecteur .data circle
) de la même couleur que la propriété fill
du rectangle .data-background
.
Et voilà le résultat, avec le widget complet :
Belle montagne, n’est-ce pas ?