mirror of
https://github.com/R0m1k3/CollectFlow.git
synced 2026-10-11 17:26:32 +02:00
Carte tendance : deuxieme courbe du nombre de magasins vendeurs
Une quantite qui monte parce que le produit est diffuse dans plus de magasins ne raconte pas la meme histoire qu'une quantite qui monte a diffusion constante. La courbe des quantites seule ne permettait pas de distinguer un succes produit d'un simple elargissement. - computeStoresSeries() : serie « magasins vendeurs » sur la MEME fenetre 12 mois que la tendance, avec la meme regle du tout ou rien — les 12 cles doivent etre presentes, sinon null. Un mois non extrait ne doit pas se lire comme « zero magasin », ce qui simulerait un arret de diffusion. - nbMagReseauByMonth remonte du cache (metricsByMonth, deja stocke par la sync) jusqu'a la ligne de grille. - NetworkLineChart accepte une serie `stores` optionnelle. DEUX ECHELLES INDEPENDANTES : les quantites se comptent en milliers, les magasins plafonnent a ~270. Sur une echelle commune la courbe des magasins serait ecrasee sur l'axe et ne montrerait rien. Chaque serie est normalisee sur son propre maximum, rappele dans la legende — c'est la FORME des deux courbes qu'on compare, pas leurs hauteurs. La courbe des magasins est pointillee et indigo, pour ne jamais entrer en collision avec le vert/rouge/gris de la tendance. Branchee sur la carte de la Grille et sur celle de la fiche produit. La sparkline de la colonne reste a une seule courbe : 46x18 px, deux traces y seraient illisibles. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DfqUihgixw4K1AmJhizWiu
This commit is contained in:
6 files changed
+160
-8
No files matched your search
@@ -9,7 +9,7 @@ import {
|
||||
} from "lucide-react";
|
||||
import { HeatmapCell } from "@/features/grid/components/heatmap-cell";
|
||||
import { NetworkLineChart, DualLineChart, TrendSparkline } from "@/features/grid/components/network-charts";
|
||||
import { computeNetworkTrend, trendLabel, TREND_COLOR, NB_MAGASINS_RESEAU } from "@/features/grid/lib/network-trend";
|
||||
import { computeNetworkTrend, computeStoresSeries, trendLabel, TREND_COLOR, NB_MAGASINS_RESEAU } from "@/features/grid/lib/network-trend";
|
||||
import { formatMonthLabel, formatDate, SITE_LABELS, ffMonthToQlik } from "@/features/grid/lib/months";
|
||||
import { useQlikSyncJob } from "@/features/qlik-sync/use-qlik-sync-job";
|
||||
import { computeComparatif, indiceVerdict, normalizeMargePct } from "@/features/produits/lib/compare-reseau";
|
||||
@@ -149,6 +149,17 @@ export function ProduitFicheView({ fiche, backQuery }: { fiche: ProduitFiche; ba
|
||||
const totauxAffiches = magasin === "TOTAL" ? fiche.totaux : (fiche.totauxParSite[magasin] ?? { qte: 0, ca: 0, marge: 0, tauxMarge: 0 });
|
||||
|
||||
const trend = useMemo(() => computeNetworkTrend(reseau?.qteByMonth ?? null), [reseau]);
|
||||
/** Nombre de magasins vendeurs par mois — deuxième courbe de la carte tendance. */
|
||||
const magasinsParMois = useMemo(() => {
|
||||
const detailMensuel = reseau?.metricsByMonth;
|
||||
if (!detailMensuel) return null;
|
||||
const parMois: Record<string, number> = {};
|
||||
for (const [mois, mesures] of Object.entries(detailMensuel)) {
|
||||
const nb = Number(mesures?.nbMag);
|
||||
if (Number.isFinite(nb)) parMois[mois] = nb;
|
||||
}
|
||||
return computeStoresSeries(parMois);
|
||||
}, [reseau]);
|
||||
const comparatif = useMemo(() => computeComparatif(fiche), [fiche]);
|
||||
const verdict = indiceVerdict(comparatif.indiceQte);
|
||||
|
||||
@@ -280,7 +291,12 @@ export function ProduitFicheView({ fiche, backQuery }: { fiche: ProduitFiche; ba
|
||||
<div className="text-[10px] font-semibold uppercase tracking-wide mb-1" style={{ color: "var(--text-muted)" }}>
|
||||
Quantités vendues réseau, mois par mois
|
||||
</div>
|
||||
<NetworkLineChart labels={trend.labels} values={trend.values} color={TREND_COLOR[trend.direction]} />
|
||||
<NetworkLineChart
|
||||
labels={trend.labels}
|
||||
values={trend.values}
|
||||
color={TREND_COLOR[trend.direction]}
|
||||
stores={magasinsParMois?.values}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
Reference in new issue
Block a user