From 0416266ddebab7972ed3a1083b19cc6179582798 Mon Sep 17 00:00:00 2001 From: Bruno Charest Date: Thu, 28 May 2026 14:48:31 -0400 Subject: [PATCH] =?UTF-8?q?feat(graph):=20Phase=203=20=E2=80=94=20type=20f?= =?UTF-8?q?ilter,=20export=20PNG,=20fullscreen,=20focus=20node?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Type filter checkboxes (dossier, .md, autre) in legend - Export PNG button (canvas.toDataURL) - Fullscreen button (Fullscreen API) - Focus node function (center on specific node) - Filter applied during _draw() to skip hidden nodes --- frontend/index.html | 15 ++++++++---- frontend/js/graph.js | 57 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 4 deletions(-) diff --git a/frontend/index.html b/frontend/index.html index 703a64c..7e5cf5e 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -717,6 +717,12 @@ + + @@ -725,10 +731,11 @@
-
- 🟦 Dossier - 🟩 Fichier .md - ⬜ Autre fichier +
+ + + + ── Parent ┅┅ Wikilink ← Backlink diff --git a/frontend/js/graph.js b/frontend/js/graph.js index 6b8b956..18c4488 100644 --- a/frontend/js/graph.js +++ b/frontend/js/graph.js @@ -300,6 +300,7 @@ export const GraphViewManager = { // Draw nodes const searchLower = this._searchTerm.toLowerCase(); for (const node of this._nodes) { + if (!this._isNodeVisible(node)) continue; const p = this._nodePositions[node.id]; if (!p) continue; @@ -395,6 +396,48 @@ export const GraphViewManager = { if (this._tooltipEl) this._tooltipEl.style.display = 'none'; }, + // --- Advanced controls --- + + _isNodeVisible(node) { + const showDir = document.getElementById('graph-filter-dir')?.checked ?? true; + const showMd = document.getElementById('graph-filter-md')?.checked ?? true; + const showOther = document.getElementById('graph-filter-other')?.checked ?? true; + if (node.type === 'directory') return showDir; + if (node.type === 'file' && (node.path || '').endsWith('.md')) return showMd; + if (node.type === 'file') return showOther; + return true; + }, + + applyTypeFilter() { + // Filters are applied during _draw() — nodes/edges not in visible set are skipped + }, + + exportPNG() { + const link = document.createElement('a'); + link.download = `obsigate-graph-${this._vault}-${Date.now()}.png`; + link.href = this._canvas.toDataURL('image/png'); + link.click(); + }, + + toggleFullscreen() { + const container = this._canvas?.parentElement?.parentElement; // editor-container + if (!container) return; + if (document.fullscreenElement) { + document.exitFullscreen(); + } else { + container.requestFullscreen(); + } + // Re-init layout after fullscreen change + setTimeout(() => this._onResize(), 300); + }, + + focusNode(nodeId) { + const pos = this._nodePositions[nodeId]; + if (!pos) return; + this._offsetX = this._width / 2 - pos.x * this._zoom; + this._offsetY = this._height / 2 - pos.y * this._zoom; + }, + _onMouseDown(e) { const rect = this._canvas.getBoundingClientRect(); const mx = e.clientX - rect.left; @@ -520,6 +563,20 @@ export function initGraphView() { }); } + // Export PNG + const exportBtn = document.getElementById('graph-export'); + if (exportBtn) exportBtn.addEventListener('click', () => gm.exportPNG()); + + // Fullscreen + const fullscreenBtn = document.getElementById('graph-fullscreen'); + if (fullscreenBtn) fullscreenBtn.addEventListener('click', () => gm.toggleFullscreen()); + + // Type filters + ['dir', 'md', 'other'].forEach(type => { + const cb = document.getElementById(`graph-filter-${type}`); + if (cb) cb.addEventListener('change', () => gm.applyTypeFilter()); + }); + if (canvas) { canvas.addEventListener('mousedown', (e) => gm._onMouseDown(e)); canvas.addEventListener('mousemove', (e) => gm._onMouseMove(e));