bugfix dashboard
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { useState } from "react";
|
||||
import { useApp } from "../context/AppContext.jsx";
|
||||
import { fmt, pct, fmtDatum } from "../utils/format.js";
|
||||
import { fmt, pct, fmtDatum, fmtMaand } from "../utils/format.js";
|
||||
import { crPath } from "../utils/grafiek.js";
|
||||
import { GREEN, RED, GOLD } from "../constants/index.js";
|
||||
|
||||
|
||||
@@ -164,28 +165,12 @@ function Legenda({ kleur, label }) {
|
||||
);
|
||||
}
|
||||
|
||||
// ── Smooth Catmull-Rom bezier path ──────────────────────────────────────────
|
||||
function crPath(xs, ys, t = 0.4) {
|
||||
if (xs.length < 2) return "";
|
||||
let d = `M ${xs[0]},${ys[0]}`;
|
||||
for (let i = 0; i < xs.length - 1; i++) {
|
||||
const p0 = i > 0 ? [xs[i-1], ys[i-1]] : [xs[i], ys[i]];
|
||||
const p1 = [xs[i], ys[i]];
|
||||
const p2 = [xs[i+1], ys[i+1]];
|
||||
const p3 = i < xs.length - 2 ? [xs[i+2], ys[i+2]] : [xs[i+1], ys[i+1]];
|
||||
const cp1x = (p1[0] + (p2[0] - p0[0]) * t).toFixed(2);
|
||||
const cp1y = (p1[1] + (p2[1] - p0[1]) * t).toFixed(2);
|
||||
const cp2x = (p2[0] - (p3[0] - p1[0]) * t).toFixed(2);
|
||||
const cp2y = (p2[1] - (p3[1] - p1[1]) * t).toFixed(2);
|
||||
d += ` C ${cp1x},${cp1y} ${cp2x},${cp2y} ${p2[0]},${p2[1]}`;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
// ── Mini inline SVG grafiek ────────────────────────────────────────────────────
|
||||
function MiniLineChart({ vData, fiatData, darkMode, T }) {
|
||||
const [hovered, setHovered] = useState(null);
|
||||
const W = 700, H = 230, pl = 62, pr = 16, pt = 16, pb = 52;
|
||||
// pb was 52 voor gedraaide datumlabels. Die staan nu rechtop en zijn korter,
|
||||
// dus er is minder hoogte nodig en houdt de lijn zelf meer ruimte over.
|
||||
const W = 700, H = 230, pl = 62, pr = 16, pt = 16, pb = 30;
|
||||
const vals = vData.map((d) => d.nettoWaarde || 0);
|
||||
const fVals = fiatData;
|
||||
// Beide reeksen staan in euro's op dezelfde as, dus het bereik moet ze allebei
|
||||
@@ -194,6 +179,9 @@ function MiniLineChart({ vData, fiatData, darkMode, T }) {
|
||||
const mx = Math.max(...vals, ...fVals) * 1.05;
|
||||
const rng = mx - mn || 1;
|
||||
const iW = W - pl - pr, iH = H - pt - pb;
|
||||
// Eén label "sep '26" is bij deze lettergrootte ongeveer 46px breed. Zoveel
|
||||
// passen er dus naast elkaar; de rest wordt overgeslagen.
|
||||
const labelStap = Math.max(1, Math.ceil(vData.length / Math.max(1, Math.floor(iW / 46))));
|
||||
const xs = vData.map((_, i) => pl + (i / Math.max(vData.length - 1, 1)) * iW);
|
||||
const ys = vals.map((v) => pt + (1 - (v - mn) / rng) * iH);
|
||||
const fYs = fVals.map((v) => pt + (1 - (v - mn) / rng) * iH);
|
||||
@@ -320,13 +308,26 @@ function MiniLineChart({ vData, fiatData, darkMode, T }) {
|
||||
</g>
|
||||
)}
|
||||
|
||||
{/* X-as labels */}
|
||||
{xs.map((x, i) => (
|
||||
<text key={i} x={x} y={H - pb + 16} fill={lc} fontSize="8"
|
||||
textAnchor="end" transform={`rotate(-45, ${x}, ${H - pb + 16})`}>
|
||||
{fmtDatum(vData[i].datum)}
|
||||
</text>
|
||||
))}
|
||||
{/* X-as: korte maandlabels, rechtop. Elk punt een volledige datum geven
|
||||
liep bij een lange reeks over in een onleesbare band — tien tekens
|
||||
gedraaid kost ~45px en er passen er maar een stuk of veertien. De
|
||||
grafiek rekent nu uit hoeveel er passen en toont elke n-de; het
|
||||
laatste punt staat er altijd bij, want dat is de datum waar je naar
|
||||
kijkt. De exacte dag lees je in de tooltip. */}
|
||||
{xs.map((x, i) => {
|
||||
const laatste = i === xs.length - 1;
|
||||
if (i % labelStap !== 0 && !laatste) return null;
|
||||
return (
|
||||
<g key={i}>
|
||||
<line x1={x} y1={pt + iH} x2={x} y2={pt + iH + 4}
|
||||
stroke={lc} strokeOpacity="0.5" strokeWidth="1" />
|
||||
<text x={x} y={pt + iH + 17} fill={lc} fontSize="9"
|
||||
textAnchor={i === 0 ? "start" : laatste ? "end" : "middle"}>
|
||||
{fmtMaand(vData[i].datum)}
|
||||
</text>
|
||||
</g>
|
||||
);
|
||||
})}
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user