diff --git a/Changelog.md b/Changelog.md
index 4a74004..ba241f9 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -2,6 +2,20 @@
## [Niet vrijgegeven]
+### Opgelost
+- Het laatste label op de x-as viel over zijn buurman heen (`mei '26` en `26`
+ over elkaar). De stap werd vanaf het begin van de reeks geteld en het laatste
+ punt werd daar los bovenop geforceerd, zodat het op willekeurige afstand van
+ zijn voorganger landde — bij een reeks die niet toevallig op een veelvoud
+ uitkwam, pal ernaast. De stap telt nu terug vanaf het laatste punt: dat valt
+ daarmee per definitie op een stap en houdt volle tussenruimte, zonder dat er
+ nog een uitzondering voor nodig is
+- De breedte waarop de grafiek rekent ging van 46 naar 54px per label, zodat er
+ lucht tussen staat in plaats van kop-aan-kop. Over reekslengtes van 13 tot 120
+ punten blijft de tussenruimte nu minimaal 57px
+
+## [1.0.9] - 2026-09-17
+
### Gewijzigd
- De x-as van beide grafieken toont korte maandlabels (`sep '26`) in plaats van
een volledige datum bij elk punt, en ze staan rechtop in plaats van 45 graden
diff --git a/README.md b/README.md
index c1bae42..3c62ffe 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ Eigen vermogen · Schulden · Voortgang · Gebruikersbeheer



-
+

@@ -181,6 +181,16 @@ inleglijn is per definitie gelijk aan de KPI "Totaal geïnvesteerde fiat" — be
rekenen het oudste voortgangsmoment als startinleg en tellen daar de stortingen
per rij bij op.
+De x-as noemt maanden (`sep '26`), niet losse datums: de grafiek rekent uit
+hoeveel labels er naast elkaar passen en toont er zoveel, terugtellend vanaf het
+laatste punt zodat dat er altijd bij staat. Bij een langere reeks dunt hij
+vanzelf verder uit. De exacte dag lees je in de tooltip. De vermogenslijn is een
+Catmull-Rom spline; de inleglijn krijgt bewust rechte segmenten, omdat een
+spline tussen twee punten iets buiten hun bereik uitschiet en dat bij een reeks
+die nooit terugloopt een daling zou tekenen die er niet is. Beide lijnen delen
+de tekenhulp in
+[`frontend/src/utils/grafiek.js`](frontend/src/utils/grafiek.js).
+
Onder **Instellingen** kies je een van de negen kleurthema's. Thema en
licht/donker staan los van elkaar: het thema levert het accent, de schakelaar de
ondergrond. De paletten staan in
@@ -233,7 +243,8 @@ vibefinance/
│ ├── main.jsx
│ ├── version.js # Draaiende versie (__APP_VERSION__ uit de build)
│ ├── constants/ # index.js (kleuren, tabs, begindata), themas.js
-│ ├── utils/ # format.js (bedragen/datums), storage.js
+│ ├── utils/ # format.js (bedragen/datums), storage.js,
+│ │ # grafiek.js (SVG-padberekening)
│ ├── hooks/ # useTheme, useUpdateCheck, useKolomBreedtes
│ ├── context/ # AppContext (global state + API sync + backup)
│ ├── components/
diff --git a/frontend/package.json b/frontend/package.json
index 5b171cc..1fe3c98 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -1,6 +1,6 @@
{
"name": "vibefinance-frontend",
- "version": "1.0.8",
+ "version": "1.0.10-dev",
"private": true,
"type": "module",
"scripts": {
diff --git a/frontend/src/pages/DashboardTab.jsx b/frontend/src/pages/DashboardTab.jsx
index b5d952b..7e79f1b 100644
--- a/frontend/src/pages/DashboardTab.jsx
+++ b/frontend/src/pages/DashboardTab.jsx
@@ -179,9 +179,13 @@ 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))));
+ // Eén label "sep '26" is bij deze lettergrootte ongeveer 54px breed inclusief
+ // wat lucht ernaast. Zoveel passen er naast elkaar; de rest wordt
+ // overgeslagen. De stap telt vanaf het láátste punt terug, niet vanaf het
+ // eerste: dat punt is de datum waar je naar kijkt en moet er altijd bij staan.
+ // Forceerden we hem er los bovenop, dan botste hij op willekeurige afstand
+ // tegen zijn voorganger — precies wat er eerst misging.
+ const labelStap = Math.max(1, Math.ceil(vData.length / Math.max(1, Math.floor(iW / 54))));
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);
@@ -316,7 +320,9 @@ function MiniLineChart({ vData, fiatData, darkMode, T }) {
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;
+ // Terugtellen vanaf het eind: het laatste punt valt zo vanzelf op een
+ // stap en houdt volle afstand tot zijn voorganger.
+ if ((xs.length - 1 - i) % labelStap !== 0) return null;
return (
pts.map((p) => p[l.key] ?? 0));
const dataMin = Math.min(...allVals);
const dataMax = Math.max(...allVals);
@@ -116,7 +118,8 @@ function SvgLineChart({ pts, lines, T, H = 200 }) {
onleesbare band. De exacte dag staat in de tooltip op elk punt. */}
{pts.map((p, i) => {
const laatste = i === pts.length - 1;
- if (i % labelStap !== 0 && !laatste) return null;
+ // Terugtellen vanaf het eind, zodat het laatste punt op een stap valt.
+ if ((pts.length - 1 - i) % labelStap !== 0) return null;
return (