diff --git a/templates/dashboard.html b/templates/dashboard.html index 9836de0..853102f 100644 --- a/templates/dashboard.html +++ b/templates/dashboard.html @@ -358,6 +358,9 @@ async function loadGraph() { graphState.totalEngrams = g.total_engrams || graphState.totalEngrams || 0; graphState.lastModified = g.max_modified || graphState.lastModified; _graphDraw(); + if (offset === 0 || (graphState.loadedEngrams && graphState.loadedEngrams % 9000 === 0)) { + fitGraphView({silent: true}); + } if (g.done || (maxEngrams && graphState.loadedEngrams >= maxEngrams)) break; offset = g.next_offset || (offset + limit); await new Promise(resolve => setTimeout(resolve, 16)); @@ -619,6 +622,12 @@ function _graphNodeRadius(n) { return Math.max(huge ? 1.4 : 3, Math.min(huge ? 9 : 18, base + Math.sqrt(d) * (huge ? 0.35 : 1) + bonus)); } +function _graphVisualRadius(n) { + // Fit can zoom out to show the full 58k+ cloud. Keep dots readable in + // screen space instead of shrinking them into invisible sub-pixels. + return _graphNodeRadius(n) / Math.max(0.08, graphState.zoom || 1); +} + function _graphNodeFill(n) { const d = graphState.degree.get(n.id) || 0; const t = Math.max(0, Math.min(0.55, d / 18)); // higher degree -> brighter @@ -690,7 +699,7 @@ function _graphWorldFromScreen(cx, cy) { function _graphHitTest(wx, wy) { for (let i = graphState.sim.length - 1; i >= 0; i--) { const n = graphState.sim[i]; - const r = _graphNodeRadius(n) + 2; + const r = _graphVisualRadius(n) + 2 / Math.max(0.08, graphState.zoom); const dx = wx - n.x; const dy = wy - n.y; if ((dx*dx + dy*dy) <= r*r) return n; @@ -1163,7 +1172,7 @@ function _graphDraw() { let matches = 0; for (const n of graphState.sim) { - const r = _graphNodeRadius(n); + const r = _graphVisualRadius(n); const isMatch = _graphMatches(n, term); if (isMatch) matches++; @@ -1260,7 +1269,7 @@ function resetGraphView() { _graphDraw(); } -function fitGraphView() { +function fitGraphView(opts = {}) { const canvas = _graphCanvas(); if (!graphState.sim.length) return; let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity; @@ -1270,12 +1279,13 @@ function fitGraphView() { } const w = Math.max(1, maxX - minX); const h = Math.max(1, maxY - minY); - const zx = (canvas.width - 40) / w; - const zy = (canvas.height - 40) / h; - graphState.zoom = Math.max(0.35, Math.min(2.5, Math.min(zx, zy))); + const pad = graphState.sim.length > 20000 ? 96 : 54; + const zx = (canvas.width - pad) / w; + const zy = (canvas.height - pad) / h; + graphState.zoom = Math.max(0.04, Math.min(2.5, Math.min(zx, zy))); graphState.panX = canvas.width / 2 - ((minX + maxX) / 2) * graphState.zoom; graphState.panY = canvas.height / 2 - ((minY + maxY) / 2) * graphState.zoom; - _graphDraw(); + if (!opts.silent) _graphDraw(); } function graphApplySearch(term) {