mirror of
https://github.com/R0m1k3/CollectFlow.git
synced 2026-10-23 15:08:12 +02:00
style(grille): agrandit la carte de tendance, illisible en l'état
Les textes du graphique tournaient entre 8,5 et 10 px : titres de séries, « max N », valeurs annotées, mois de l'axe, infobulle, ainsi que les légendes des trois tuiles. Difficile à lire. Typographie relevée d'un cran partout : titres de séries 9,5 → 13, maximum 9 → 11,5, valeurs sur les points 9 → 12,5, mois 8,5 → 11, infobulle 9 → 11,5, tuiles 10 → 12 avec la valeur à 26 px, tableau 11 → 13. Le dessin suit la typographie plutôt que de la subir : bandeau de facette 15 → 21, axe 18 → 24, écart 12 → 14, infobulle élargie à 196 avec un interligne de 17 — sans quoi titres et courbes se seraient chevauchés. La carte passe à max-w-2xl pour absorber le tout sans comprimer le graphique. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y26nRZxTR57K7h8yqsF675
This commit is contained in:
2 files changed
+30
-28
No files matched your search
@@ -260,17 +260,17 @@ function TuileStat({ label, valeur, indice, couleur, icone: Icone }: {
|
|||||||
icone?: React.ComponentType<{ className?: string; style?: React.CSSProperties }>;
|
icone?: React.ComponentType<{ className?: string; style?: React.CSSProperties }>;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<div className="rounded-xl px-3 py-2.5 flex-1 min-w-[140px]" style={{ background: "var(--bg-elevated)", border: "1px solid var(--border)" }}>
|
<div className="rounded-xl px-3.5 py-3 flex-1 min-w-[160px]" style={{ background: "var(--bg-elevated)", border: "1px solid var(--border)" }}>
|
||||||
<div className="text-[10px] font-semibold uppercase tracking-wide" style={{ color: "var(--text-muted)" }}>
|
<div className="text-[12px] font-semibold uppercase tracking-wide" style={{ color: "var(--text-muted)" }}>
|
||||||
{label}
|
{label}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-1.5 mt-0.5">
|
<div className="flex items-center gap-1.5 mt-1">
|
||||||
{Icone && <Icone className="w-4 h-4 shrink-0" style={{ color: couleur ?? "var(--text-primary)" }} />}
|
{Icone && <Icone className="w-5 h-5 shrink-0" style={{ color: couleur ?? "var(--text-primary)" }} />}
|
||||||
<span className="text-[20px] font-bold leading-tight" style={{ color: couleur ?? "var(--text-primary)" }}>
|
<span className="text-[26px] font-bold leading-tight" style={{ color: couleur ?? "var(--text-primary)" }}>
|
||||||
{valeur}
|
{valeur}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{indice && <div className="text-[10px] mt-0.5" style={{ color: "var(--text-muted)" }}>{indice}</div>}
|
{indice && <div className="text-[12px] mt-1 leading-snug" style={{ color: "var(--text-muted)" }}>{indice}</div>}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -300,12 +300,12 @@ function NetworkMonthlyModal({ row, onClose }: { row: ProductRow; onClose: () =>
|
|||||||
: "—";
|
: "—";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DialogContent className="max-w-xl" style={{ background: "var(--bg-surface)", border: "1px solid var(--border)" }} onInteractOutside={onClose}>
|
<DialogContent className="max-w-2xl" style={{ background: "var(--bg-surface)", border: "1px solid var(--border)" }} onInteractOutside={onClose}>
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle className="text-base leading-snug pr-6" style={{ color: "var(--text-primary)" }}>
|
<DialogTitle className="text-lg leading-snug pr-6" style={{ color: "var(--text-primary)" }}>
|
||||||
{row.libelle1}
|
{row.libelle1}
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
<p className="text-[12px] mt-0.5" style={{ color: "var(--text-muted)" }}>
|
<p className="text-[13px] mt-1" style={{ color: "var(--text-muted)" }}>
|
||||||
Réseau · 12 mois glissants, mois en cours exclu
|
Réseau · 12 mois glissants, mois en cours exclu
|
||||||
</p>
|
</p>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
|||||||
@@ -135,7 +135,9 @@ export function NetworkLineChart({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const W = 520;
|
const W = 520;
|
||||||
const padL = 16, padR = 16, axeH = 18, enteteH = 15, ecart = 12;
|
// Bandeau et axe dimensionnés pour la typographie ci-dessous : agrandir les
|
||||||
|
// polices sans élargir ces bandes ferait chevaucher titres et courbes.
|
||||||
|
const padL = 16, padR = 16, axeH = 24, enteteH = 21, ecart = 14;
|
||||||
const plotW = W - padL - padR;
|
const plotW = W - padL - padR;
|
||||||
const H = facettes.reduce((t, f) => t + enteteH + f.hauteur + ecart, 0) - ecart + axeH;
|
const H = facettes.reduce((t, f) => t + enteteH + f.hauteur + ecart, 0) - ecart + axeH;
|
||||||
|
|
||||||
@@ -170,7 +172,7 @@ export function NetworkLineChart({
|
|||||||
key={v}
|
key={v}
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setVue(v)}
|
onClick={() => setVue(v)}
|
||||||
className="px-2.5 py-0.5 text-[10px] font-semibold rounded-md transition-colors capitalize"
|
className="px-3 py-1 text-[12px] font-semibold rounded-md transition-colors capitalize"
|
||||||
style={vue === v
|
style={vue === v
|
||||||
? { background: "var(--bg-surface)", color: "var(--text-primary)" }
|
? { background: "var(--bg-surface)", color: "var(--text-primary)" }
|
||||||
: { color: "var(--text-muted)" }}
|
: { color: "var(--text-muted)" }}
|
||||||
@@ -204,11 +206,11 @@ export function NetworkLineChart({
|
|||||||
return (
|
return (
|
||||||
<g key={f.titre}>
|
<g key={f.titre}>
|
||||||
{/* Bandeau de facette : repère coloré + titre + maximum, en encre neutre */}
|
{/* Bandeau de facette : repère coloré + titre + maximum, en encre neutre */}
|
||||||
<rect x={padL} y={f.hautEntete + 3} width={12} height={3} rx={1.5} fill={f.couleur} />
|
<rect x={padL} y={f.hautEntete + 6} width={14} height={4} rx={2} fill={f.couleur} />
|
||||||
<text x={padL + 18} y={f.hautEntete + 7} fontSize={9.5} fontWeight={600} fill="var(--text-secondary)" dominantBaseline="middle">
|
<text x={padL + 20} y={f.hautEntete + 9} fontSize={13} fontWeight={700} fill="var(--text-secondary)" dominantBaseline="middle">
|
||||||
{f.titre}
|
{f.titre}
|
||||||
</text>
|
</text>
|
||||||
<text x={padL + plotW} y={f.hautEntete + 7} textAnchor="end" fontSize={9} fill="var(--text-muted)" dominantBaseline="middle">
|
<text x={padL + plotW} y={f.hautEntete + 9} textAnchor="end" fontSize={11.5} fill="var(--text-muted)" dominantBaseline="middle">
|
||||||
max {fmt(f.max, f.decimales ?? 0)}{f.unite ?? ""}
|
max {fmt(f.max, f.decimales ?? 0)}{f.unite ?? ""}
|
||||||
</text>
|
</text>
|
||||||
|
|
||||||
@@ -242,14 +244,14 @@ export function NetworkLineChart({
|
|||||||
// bandeau de la facette (constaté au rendu : « 58 » par-dessus
|
// bandeau de la facette (constaté au rendu : « 58 » par-dessus
|
||||||
// « Qté / magasin »). Dans ce cas elle bascule SOUS le point.
|
// « Qté / magasin »). Dans ce cas elle bascule SOUS le point.
|
||||||
const yPoint = f.y(f.valeurs[i]);
|
const yPoint = f.y(f.valeurs[i]);
|
||||||
const dessus = yPoint - 8 >= f.haut + 8;
|
const dessus = yPoint - 11 >= f.haut + 8;
|
||||||
return (
|
return (
|
||||||
<text
|
<text
|
||||||
key={`lab-${f.titre}-${i}`}
|
key={`lab-${f.titre}-${i}`}
|
||||||
x={x(i)}
|
x={x(i)}
|
||||||
y={dessus ? yPoint - 8 : yPoint + 13}
|
y={dessus ? yPoint - 10 : yPoint + 16}
|
||||||
textAnchor={ancrage(i)}
|
textAnchor={ancrage(i)}
|
||||||
fontSize={9}
|
fontSize={12.5}
|
||||||
fontWeight={700}
|
fontWeight={700}
|
||||||
fill="var(--text-primary)"
|
fill="var(--text-primary)"
|
||||||
>
|
>
|
||||||
@@ -283,9 +285,9 @@ export function NetworkLineChart({
|
|||||||
<text
|
<text
|
||||||
key={`mois-${lab}`}
|
key={`mois-${lab}`}
|
||||||
x={x(i)}
|
x={x(i)}
|
||||||
y={H - 5}
|
y={H - 7}
|
||||||
textAnchor={ancrage(i)}
|
textAnchor={ancrage(i)}
|
||||||
fontSize={8.5}
|
fontSize={11}
|
||||||
fill={survol === i ? "var(--text-primary)" : "var(--text-muted)"}
|
fill={survol === i ? "var(--text-primary)" : "var(--text-muted)"}
|
||||||
fontWeight={survol === i ? 700 : 400}
|
fontWeight={survol === i ? 700 : 400}
|
||||||
>
|
>
|
||||||
@@ -300,8 +302,8 @@ export function NetworkLineChart({
|
|||||||
plus jamais. `pointerEvents=none` laisse passer le survol vers les
|
plus jamais. `pointerEvents=none` laisse passer le survol vers les
|
||||||
cibles en dessous. */}
|
cibles en dessous. */}
|
||||||
{survol != null && (() => {
|
{survol != null && (() => {
|
||||||
const largeur = 158;
|
const largeur = 196;
|
||||||
const hauteur = 16 + disposees.length * 13 + 8;
|
const hauteur = 22 + disposees.length * 17 + 8;
|
||||||
// La bulle bascule à gauche du réticule quand elle déborderait à droite.
|
// La bulle bascule à gauche du réticule quand elle déborderait à droite.
|
||||||
const gauche = x(survol) + 10 + largeur > W - 4;
|
const gauche = x(survol) + 10 + largeur > W - 4;
|
||||||
const bx = gauche ? x(survol) - 10 - largeur : x(survol) + 10;
|
const bx = gauche ? x(survol) - 10 - largeur : x(survol) + 10;
|
||||||
@@ -311,18 +313,18 @@ export function NetworkLineChart({
|
|||||||
x={bx} y={4} width={largeur} height={hauteur} rx={8}
|
x={bx} y={4} width={largeur} height={hauteur} rx={8}
|
||||||
fill="var(--bg-elevated)" stroke="var(--border)" strokeWidth={1}
|
fill="var(--bg-elevated)" stroke="var(--border)" strokeWidth={1}
|
||||||
/>
|
/>
|
||||||
<text x={bx + 9} y={17} fontSize={9.5} fontWeight={700} fill="var(--text-primary)">
|
<text x={bx + 11} y={21} fontSize={12.5} fontWeight={700} fill="var(--text-primary)">
|
||||||
{fmtMonthShort(labels[survol])}
|
{fmtMonthShort(labels[survol])}
|
||||||
</text>
|
</text>
|
||||||
{disposees.map((f, k) => (
|
{disposees.map((f, k) => (
|
||||||
<g key={`bulle-${f.titre}`}>
|
<g key={`bulle-${f.titre}`}>
|
||||||
<rect x={bx + 9} y={26 + k * 13} width={8} height={3} rx={1.5} fill={f.couleur} />
|
<rect x={bx + 11} y={33 + k * 17} width={10} height={4} rx={2} fill={f.couleur} />
|
||||||
<text x={bx + 22} y={30 + k * 13} fontSize={9} fill="var(--text-secondary)">
|
<text x={bx + 26} y={38 + k * 17} fontSize={11.5} fill="var(--text-secondary)">
|
||||||
{f.titre}
|
{f.titre}
|
||||||
</text>
|
</text>
|
||||||
<text
|
<text
|
||||||
x={bx + largeur - 9} y={30 + k * 13}
|
x={bx + largeur - 11} y={38 + k * 17}
|
||||||
textAnchor="end" fontSize={9} fontWeight={700} fill="var(--text-primary)"
|
textAnchor="end" fontSize={11.5} fontWeight={700} fill="var(--text-primary)"
|
||||||
>
|
>
|
||||||
{fmt(f.valeurs[survol], f.decimales ?? 0)}
|
{fmt(f.valeurs[survol], f.decimales ?? 0)}
|
||||||
</text>
|
</text>
|
||||||
@@ -353,7 +355,7 @@ export function NetworkLineChart({
|
|||||||
du graphique et défile à l'intérieur : la carte garde sa taille, et
|
du graphique et défile à l'intérieur : la carte garde sa taille, et
|
||||||
aucune valeur n'est réservée au survol. */
|
aucune valeur n'est réservée au survol. */
|
||||||
<div style={{ height: H }} className="overflow-y-auto overflow-x-auto">
|
<div style={{ height: H }} className="overflow-y-auto overflow-x-auto">
|
||||||
<table className="w-full text-[11px] tabular-nums" style={{ borderCollapse: "collapse" }}>
|
<table className="w-full text-[13px] tabular-nums" style={{ borderCollapse: "collapse" }}>
|
||||||
<thead className="sticky top-0" style={{ background: "var(--bg-surface)" }}>
|
<thead className="sticky top-0" style={{ background: "var(--bg-surface)" }}>
|
||||||
<tr style={{ color: "var(--text-muted)" }}>
|
<tr style={{ color: "var(--text-muted)" }}>
|
||||||
<th className="text-left font-medium py-1 pr-2">Mois</th>
|
<th className="text-left font-medium py-1 pr-2">Mois</th>
|
||||||
@@ -408,7 +410,7 @@ export function DualLineChart({
|
|||||||
<div className="w-full overflow-x-auto">
|
<div className="w-full overflow-x-auto">
|
||||||
<div className="flex items-center gap-4 mb-1">
|
<div className="flex items-center gap-4 mb-1">
|
||||||
{series.map((s) => (
|
{series.map((s) => (
|
||||||
<span key={s.name} className="flex items-center gap-1.5 text-[11px]" style={{ color: "var(--text-secondary)" }}>
|
<span key={s.name} className="flex items-center gap-1.5 text-[12px]" style={{ color: "var(--text-secondary)" }}>
|
||||||
<span className="inline-block w-3 h-[3px] rounded-full" style={{ background: s.color }} />
|
<span className="inline-block w-3 h-[3px] rounded-full" style={{ background: s.color }} />
|
||||||
{s.name}
|
{s.name}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
Reference in new issue
Block a user