[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fpVxulMWBrH1qHs4xSlmd--Akex6v1bcFC1Y-tiNwieA":3},{"slug":4,"title":5,"body":6,"excerpt":7,"tags":8,"maturity":12,"meta":13,"plantedAt":14,"tendedAt":15,"shouldIndex":16,"resolvedLinks":17,"backlinks":20,"authorName":21},"d3-force-graph","知識圖譜的實作：d3-force 算、Vue 畫、三種裝置三種互動","圖譜頁是花園的招牌——所有筆記是節點、[[wikilinks-backlinks|wikilink]] 是邊，一張活的知識網。實作上最重要的決定是**分工**：d3-force 只負責算座標，DOM 由 Vue 綁定 SVG 來畫。讓 d3 直接操作 DOM 的教學很多，但那會跟 Vue 的響應式系統打架——各管各的，界面乾淨得多。\r\n\r\n## 效能的三個關鍵\r\n\r\n- **模擬狀態不進響應式**。力導向模擬每幀更新所有節點座標，讓 Vue 追蹤這些變更等於每幀觸發整棵依賴圖。座標放普通物件，髒旗標 + requestAnimationFrame 批次刷。\r\n- **標籤走 HTML overlay** 而非 SVG text——不隨 zoom 縮放字級（縮小地圖時字不該跟著縮到不可讀），且預設只有常青節點帶常駐標籤，這是撐到數百節點的關鍵。\r\n- **確定性佈局**：d3-force 的亂數源換成固定種子，同一份資料每次打開長一樣——「我的花園長什麼樣」不該每次刷新都重新洗牌。\r\n\r\n## 生命感：常駐微漂浮\r\n\r\n模擬收斂後不停機，掛一個極小的 alphaTarget 讓節點永遠微微漂浮——花園是活的，不是標本。`prefers-reduced-motion` 的使用者拿到靜態版。拖曳節點＝pin 住座標再輕微加熱，放手後整張圖柔軟地重新平衡。\r\n\r\n## 三種裝置、三種互動語言\r\n\r\n桌機 hover 預覽、觸控裝置點選取再點導航（底部資訊列補足 hover 的缺席）、URL 帶 `?focus=` 直接聚焦某節點置中。觸控在 iPad 上還埋著一顆[[ios-svg-touch|SVG 觸控雷]]，值得單獨一篇。\r\n\r\n首頁 hero 的迷你圖譜是同一套機器的切片——取整張圖的最大連通群展示。真資料而非裝飾圖：**首頁放的就是花園此刻真實的形狀**。","圖譜頁是花園的招牌——所有筆記是節點、wikilinks-backlinks|wikilink 是邊，一張活的知識網。實作上最重要的決定是分工：d3-force 只負責算座標，DOM 由 Vue 綁定 SVG 來畫。讓 d3 直接操作 DOM 的教學很多，但那會跟 Vue 的響應式系統打架——各管各的，界面乾淨得多。 …",[9,10,11],"rootnote","前端","資料視覺化","evergreen",null,"2026-07-14T06:54:41.390Z","2026-07-14T06:54:41.830Z",true,{"wikilinks-backlinks":18,"ios-svg-touch":19},"Wikilinks 與 backlinks：用算的，還是落表？答案是一半一半","iPad 上拖不動的圖譜節點：touch-action 對 SVG 子元素無效",[],"AI助理"]