User-facing persisted region + physics settings

All graph panel controls are now user-facing and server-persisted:
the old session-only dev number inputs are gone. GraphRenderSettings
gains nested regions/physics sections (backward compatible: old flat
files load with defaults), and RegionTuning/PhysicsTuning moved from
the renderer into core/render-settings.ts — one shape, one sanitizer,
one source for the store, the panel, and the renderer.

Physics/region clamps are sweep-validated safe ranges (each field at
both ends + all four corners settles cleanly on the real graph: no
NaN, no explosion — linkStrength caps at 4 since 8 explodes and 5
wobbles; friction floors at 0.1 since 0 never damps). Panel: log
sliders (default = geometric mean = position 50, step 5), off-zone
sliders for blur/cluster pull (position 0 = exactly 0), a fixed-set
dropdown for bitmap resolution, depth-anchor modes promoted to the
select.
This commit is contained in:
amosblomqvist
2026-09-13 17:06:18 +03:00
parent 0af63113f5
commit 04a0236c36
5 changed files with 492 additions and 247 deletions
+12 -9
View File
@@ -17,13 +17,16 @@ import {
fitTransform,
labelAlpha,
pickNearest,
sanitizePhysicsTuning,
sanitizeRegionTuning,
zoomRatioOf,
DEFAULT_PHYSICS_TUNING,
DEFAULT_REGION_TUNING,
LABELS_FADE_SPAN,
} from "../components/graph-canvas.ts";
import {
sanitizePhysicsTuning,
sanitizeRegionTuning,
DEFAULT_PHYSICS_TUNING,
DEFAULT_REGION_TUNING,
REGION_BITMAP_OPTIONS,
} from "../src/core/render-settings.ts";
describe("zoomRatioOf (the sigma-compatible camera ratio)", () => {
test("1 at fit zoom, smaller when zoomed in, larger when zoomed out", () => {
@@ -156,7 +159,7 @@ describe("sanitizeRegionTuning (dev number inputs)", () => {
const t = sanitizeRegionTuning({ dilation: Number.NaN, blur: -5, bitmap: 99999, edgeAlpha: 42 });
assert.equal(t.dilation, DEFAULT_REGION_TUNING.dilation); // NaN -> default
assert.equal(t.blur, 0);
assert.equal(t.bitmap, 1024);
assert.equal(t.bitmap, REGION_BITMAP_OPTIONS[REGION_BITMAP_OPTIONS.length - 1]); // 99999 snaps to the largest option
assert.equal(t.edgeAlpha, 1);
});
@@ -215,10 +218,10 @@ describe("sanitizePhysicsTuning (physics controls)", () => {
velocityDecay: 3,
});
assert.equal(t.chargeStrength, DEFAULT_PHYSICS_TUNING.chargeStrength);
assert.equal(t.linkStrength, 5);
assert.equal(t.linkDistance, 1);
assert.equal(t.gravity, 1);
assert.equal(t.linkStrength, 4); // sweep-validated cap (8 explodes, 5 wobbles)
assert.equal(t.linkDistance, 10);
assert.equal(t.gravity, 0.48);
assert.equal(t.clusterPull, 0);
assert.equal(t.velocityDecay, 0.99);
assert.equal(t.velocityDecay, 0.9);
});
});