From b63df651d22e7c367916dd589fe43c3374d18dce Mon Sep 17 00:00:00 2001 From: hunter-dev Date: Mon, 24 Aug 2026 20:59:29 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=9B=BE=E8=B0=B1=E6=8C=89=E5=88=86?= =?UTF-8?q?=E7=BB=84=E9=93=BA=E6=BB=A1=E7=94=BB=E5=B8=83=E5=9D=90=E6=A0=87?= =?UTF-8?q?=EF=BC=8C=E4=B8=8D=E5=86=8D=E6=8C=A4=E5=B7=A6=E4=B8=8A=E8=A7=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/desktop/src/main/ipc/handlers.ts | 2 +- .../src/renderer/features/graph/GraphView.tsx | 43 ++++++++----------- 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/apps/desktop/src/main/ipc/handlers.ts b/apps/desktop/src/main/ipc/handlers.ts index dd14d3c..9b70879 100644 --- a/apps/desktop/src/main/ipc/handlers.ts +++ b/apps/desktop/src/main/ipc/handlers.ts @@ -44,7 +44,7 @@ export function registerIpc(vault: VaultService) { ipcMain.handle(IPC.search, async (_e, p: { query: string }) => vault.searchService?.search(p.query) ?? []); ipcMain.handle(IPC.tagStats, async () => vault.searchService?.tagStats() ?? []); ipcMain.handle(IPC.graph, async () => { - const fs2 = vault.fileService; console.log('[GRAPH-HANDLER] fs2?', !!fs2); + const fs2 = vault.fileService; if (!fs2) return { nodes: [], edges: [] }; const tree = await fs2.listTree(); const gd = await buildGraphData(fs2.getRoot(), tree); return gd; diff --git a/apps/desktop/src/renderer/features/graph/GraphView.tsx b/apps/desktop/src/renderer/features/graph/GraphView.tsx index b427850..8309c81 100644 --- a/apps/desktop/src/renderer/features/graph/GraphView.tsx +++ b/apps/desktop/src/renderer/features/graph/GraphView.tsx @@ -6,20 +6,20 @@ import { useStore } from '../../store'; function truncate(s: string, n: number) { return s.length > n ? s.slice(0, n) + '…' : s; } +// 按顶层分组:每组一列,列内纵向均匀排开。坐标基于画布尺寸,保证铺满不挤。 function layoutNodes(nodes: GraphNode[], w: number, h: number) { const groups = new Map(); nodes.forEach(n => { const a = groups.get(n.group) ?? []; a.push(n); groups.set(n.group, a); }); const groupList = [...groups.entries()]; const positions = new Map(); - if (groupList.length === 0) return positions; - const margin = 100; - const usableW = Math.max(200, w - margin * 2); - const colWidth = usableW / groupList.length; - groupList.forEach(([group, items], gi) => { + if (groupList.length === 0 || w < 100 || h < 100) return positions; + const margin = 80; + const colWidth = (w - margin * 2) / Math.max(groupList.length, 1); + groupList.forEach(([, items], gi) => { const colX = margin + colWidth * gi + colWidth / 2; - const rowGap = items.length > 1 ? Math.min(80, (h - margin * 2) / (items.length - 1)) : 0; - const startY = h / 2 - ((items.length - 1) * rowGap) / 2; - items.forEach((n, ni) => positions.set(n.id, { x: colX, y: startY + ni * rowGap })); + const usableH = h - margin * 2; + const rowGap = items.length > 1 ? usableH / (items.length + 1) : 0; + items.forEach((n, ni) => positions.set(n.id, { x: colX, y: margin + rowGap * (ni + 1) })); }); return positions; } @@ -31,26 +31,19 @@ export function GraphView() { useEffect(() => { if (!containerRef.current) return; const el = containerRef.current; - const rect = el.getBoundingClientRect(); - const w = rect.width || 800, h = rect.height || 600; let g: Graph; try { g = new Graph({ container: el, - width: w, - height: h, + width: 1200, height: 700, autoResize: true, node: { style: { - size: 30, + size: 32, fill: (d: any) => (d.style && d.style.fill) || '#4a9eff', - stroke: '#6a8cff', - lineWidth: 2, + stroke: '#6a8cff', lineWidth: 2, labelText: (d: any) => truncate((d.data && d.data.title) || d.id, 12), - labelFill: '#eee', - labelFontSize: 12, - labelPlacement: 'bottom', - labelOffsetY: 6, + labelFill: '#eee', labelFontSize: 12, labelPlacement: 'bottom', labelOffsetY: 6, } } as any, edge: { style: { stroke: '#666', lineWidth: 1.5, endArrow: true } } as any, @@ -59,13 +52,13 @@ export function GraphView() { } catch (e) { console.error(e); return; } invoke(IPC.graph, undefined as never).then((data: GraphData) => { - const r = el.getBoundingClientRect(); - const cw = r.width || 800, ch = r.height || 600; - const pos = layoutNodes(data.nodes, cw, ch); + const rect = el.getBoundingClientRect(); + const w = rect.width || 1200, h = rect.height || 700; + const pos = layoutNodes(data.nodes, w, h); const nodes = data.nodes.map(n => ({ id: n.id, - x: pos.get(n.id)?.x ?? cw / 2, - y: pos.get(n.id)?.y ?? ch / 2, + x: pos.get(n.id)?.x ?? w / 2, + y: pos.get(n.id)?.y ?? h / 2, style: { fill: n.color, stroke: n.star ? '#ffd54a' : '#6a8cff' }, data: { title: n.title, star: n.star }, })); @@ -83,4 +76,4 @@ export function GraphView() {
); -} \ No newline at end of file +}