@synertech/ui 0.41.0 → 0.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -160,6 +160,14 @@ import { cn } from "@synertech/ui";
160
160
  - `BulletChart` - Réalisé, objectif et plages qualitatives sur une seule ligne
161
161
  - `ChartFacets` - Petits multiples : un même graphique répété, à échelle partagée
162
162
  - `ChartScaleLegend` - La légende d'une rampe de couleur
163
+ - `ChartFilterBar` - Les filtres en une rangée au-dessus des graphiques qu'ils cadrent
164
+ - `ChartPeriodPicker` - La fenêtre d'un tableau de bord : préréglages nommés + calendrier
165
+ - `WaterfallChart` - Comment on passe de A à B : chaque contribution, positive ou négative
166
+ - `FunnelChart` - Des étapes ordonnées et leur déperdition (rampe ordinale)
167
+ - `DumbbellChart` - Avant → après par élément, ou une plage min–max
168
+ - `BoxPlot` - Médiane, quartiles, moustaches et valeurs aberrantes
169
+ - `CandlestickChart` - Ouverture, haut, bas, clôture (couleurs de statut)
170
+ - `GanttChart` - Des tâches dans le temps, avec dépendances et jalons
163
171
 
164
172
  ### Feedback & Overlays
165
173
 
@@ -628,6 +636,25 @@ const data = [
628
636
  bubble={{ key: "clients", range: [4, 18] }}
629
637
  trendLine
630
638
  />
639
+
640
+ // Histogramme — `bins` lit x.key comme une mesure, la range et la compte
641
+ <BarChart
642
+ data={sessions} // [{ duration: 42 }, { duration: 118 }, ...]
643
+ x={{ key: "duration", label: "Durée (s)" }}
644
+ series={[{ key: "sessions", label: "Sessions" }]} // nomme le COMPTE
645
+ bins={12} // ou true (auto), ou [0, 15, 30, 60, 120]
646
+ />
647
+
648
+ // Barres + ligne — une série typée, un seul axe
649
+ <BarChart
650
+ data={monthly}
651
+ x={{ key: "month" }}
652
+ series={[
653
+ { key: "commandes", label: "Commandes" },
654
+ { key: "retours", label: "Retours", type: "line" },
655
+ ]}
656
+ curve="monotone"
657
+ />
631
658
  ```
632
659
 
633
660
  ```tsx
@@ -654,6 +681,83 @@ const data = [
654
681
  normalize="row" // "row" (par défaut) | "shared" → ramène l'axe des valeurs
655
682
  />
656
683
 
684
+ // Cascade — chaque pas flotte entre le cumul avant et après lui
685
+ <WaterfallChart
686
+ data={budget} // [{ poste, montant, jalon? }, ...]
687
+ x={{ key: "poste" }}
688
+ value="montant"
689
+ total="jalon" // ligne de contrôle dessinée depuis zéro
690
+ start={0} // cumul d'ouverture
691
+ />
692
+
693
+ // Tunnel — étapes ORDONNÉES, donc rampe ordinale (jamais les créneaux)
694
+ <FunnelChart
695
+ data={stages} // [{ etape, utilisateurs }, ...]
696
+ x={{ key: "etape" }}
697
+ value="utilisateurs"
698
+ align="center" // "center" (silhouette) | "left" (comparaison)
699
+ showConversion // le ratio d'un pas au suivant : le constat
700
+ />
701
+
702
+ // Haltère — avant → après, ou une plage. L'écart EST la marque
703
+ <DumbbellChart
704
+ data={satisfaction}
705
+ x={{ key: "service" }}
706
+ series={[{ key: "avant", label: "2025" }, { key: "apres", label: "2026" }]}
707
+ sort="gap" // les plus gros mouvements en tête
708
+ />
709
+
710
+ // Boîte à moustaches — `values` (observations) ou `quantiles` (résumé)
711
+ <BoxPlot
712
+ data={teams} // [{ equipe, durees: [12, 14, ...] }, ...]
713
+ x={{ key: "equipe" }}
714
+ values="durees" // moustaches de Tukey + aberrations calculées
715
+ showMean // le losange : l'écart moyenne/médiane = la queue
716
+ />
717
+
718
+ // Chandeliers — couleurs de statut + corps creux/plein, jamais la teinte seule
719
+ <CandlestickChart
720
+ data={sessions}
721
+ x={{ key: "jour" }}
722
+ open="ouverture" high="haut" low="bas" close="cloture"
723
+ />
724
+
725
+ // Planning — dates, dépendances, jalons. Ce n'est pas un `Calendar`
726
+ <GanttChart
727
+ data={project}
728
+ x={{ key: "tache" }}
729
+ start="debut" end="fin"
730
+ id="id" dependencies="depend" // les flèches : ce qui bloque quoi
731
+ progress="avancement" // 0 à 1
732
+ milestone="jalon"
733
+ group="lot" // un créneau de palette par lot
734
+ today="2026-04-14"
735
+ />
736
+
737
+ // Annotations — ce qui s'est passé, dessiné là où ça s'est passé
738
+ // (`referenceLines` = un seuil sur l'axe des valeurs ; les annotations = un
739
+ // moment sur l'axe des catégories. Lisible sur LineChart, AreaChart, BarChart)
740
+ <LineChart
741
+ data={monthly}
742
+ series={[{ key: "revenue" }]}
743
+ x={{ key: "month" }}
744
+ annotations={[
745
+ { type: "band", from: "Fév", to: "Mar", label: "Campagne" },
746
+ { type: "line", x: "Mai", label: "Refonte du tunnel" },
747
+ { type: "point", x: "Août", y: 39900, label: "Record" },
748
+ ]}
749
+ />
750
+
751
+ // Trames — le canal de secours quand la teinte échoue (CVD sévère, impression
752
+ // en niveaux de gris, forced-colors). Jamais par défaut : c'est de l'a11y
753
+ <BarChart data={channels} series={channelSeries} x={{ key: "quarter" }} stack="stacked" patterns />
754
+
755
+ // La rangée de filtres — une seule, au-dessus de TOUS les graphiques
756
+ <ChartFilterBar actions={<Button size="sm">Exporter</Button>}>
757
+ <ChartPeriodPicker size="sm" value={period} onChange={setPeriod} />
758
+ <Select size="sm" options={regions} value={region} onValueChange={setRegion} />
759
+ </ChartFilterBar>
760
+
657
761
  // Petits multiples — le domaine est calculé sur l'ensemble et imposé à chaque panneau
658
762
  <ChartFacets data={rows} by="region" values={["revenue"]} columns={3}>
659
763
  {({ data, domain, label }) => (
@@ -691,6 +795,33 @@ const data = [
691
795
  - **La rampe divergente dit un sens, pas un jugement.** « Au-dessus » n'est pas
692
796
  « bon » : un délai qui glisse est au-dessus. Le jugement appartient aux
693
797
  couleurs de statut, toujours accompagnées d'un libellé.
798
+ - **Un `BarChart` combiné garde un seul axe.** Une série `type: "line"` partage
799
+ l'échelle des barres. Deux axes laissent deux mesures étrangères se croiser
800
+ là où le cadrage les place, ce qui se lit comme une corrélation inventée.
801
+ - **Un histogramme ne se trie pas.** `sort`, `stack` et `diverging` sont ignorés
802
+ avec `bins` : les seaux ont un ordre, et le réordonner détruit la forme.
803
+ - **Un tunnel encode une longueur, pas une surface.** Le trapèze classique
804
+ demande de comparer deux surfaces, ce que l'œil ne sait pas faire.
805
+ - **Un `BoxPlot` nourri d'un résumé ne dessine aucune valeur aberrante.** Les
806
+ bornes de Tukey ont besoin des observations ; le composant préfère ne rien
807
+ affirmer plutôt qu'inventer.
808
+ - **`DumbbellChart` et `BoxPlot` ne s'ancrent pas à zéro.** Ils se lisent à un
809
+ écart et à un étalement, pas à la longueur d'une marque depuis une base.
810
+ - **`CandlestickChart` porte le sens deux fois** : couleur de statut ET corps
811
+ creux (hausse) contre plein (baisse). Vert contre rouge est la pire paire
812
+ sous déficience de vision des couleurs.
813
+ - **`GanttChart` n'est pas un `Calendar`.** Le calendrier sélectionne une date
814
+ et la renvoie ; le planning se lit. Une ligne sans largeur est un jalon.
815
+ - **Les filtres vivent dans UNE rangée, au-dessus des graphiques.** Jamais dans
816
+ une carte, jamais par graphique : deux panneaux filtrés séparément répondent à
817
+ deux questions et rien à l'écran ne le dit.
818
+ - **Les trames ne sont jamais activées par défaut.** C'est une option
819
+ d'accessibilité, pas une décoration — et elles ne peignent que des identités :
820
+ une rampe (Heatmap, `diverging`, tunnel) encode une grandeur, ce qu'aucune
821
+ trame ne sait dire.
822
+ - **Les annotations se lisent sur l'axe des catégories.** Un `BarChart`
823
+ horizontal les ignore, avec un avertissement : un moment placé sur une liste
824
+ de noms n'en est plus un.
694
825
 
695
826
  ### Cartes KPI
696
827