From f5cb1b241031913c10313fdceffd6fa2205c4fef Mon Sep 17 00:00:00 2001 From: "junren.chan" Date: Sat, 8 Feb 2025 17:17:35 +0800 Subject: [PATCH] :sparkles: Implement rendering of global graph --- src/plugin/context.ts | 2 + src/plugin/hooks/useGraphManager.ts | 16 ++++-- .../theme/VaultusaurusGraph/GraphContent.tsx | 22 +++++--- src/plugin/theme/VaultusaurusGraph/index.tsx | 50 +++++++++++++++---- 4 files changed, 70 insertions(+), 20 deletions(-) diff --git a/src/plugin/context.ts b/src/plugin/context.ts index 2562371..80bb127 100644 --- a/src/plugin/context.ts +++ b/src/plugin/context.ts @@ -14,6 +14,8 @@ export const GraphContext = createContext({ simulation: null, expanded: false, setExpanded: () => {}, + globalModal: false, + setGlobalModal: () => {}, containerWidth: 0, containerHeight: 0, }, diff --git a/src/plugin/hooks/useGraphManager.ts b/src/plugin/hooks/useGraphManager.ts index 4788bae..12ece0f 100644 --- a/src/plugin/hooks/useGraphManager.ts +++ b/src/plugin/hooks/useGraphManager.ts @@ -9,7 +9,11 @@ import { Simulation, } from "d3-force"; import { useEffect, useMemo, useRef, useState } from "react"; -export default function useGraphManager(rawData: GraphInfo) { +export default function useGraphManager( + rawData: GraphInfo, + global: boolean, + minimizeCallback?: () => void +) { const graphData = useMemo(() => structuredClone(rawData), [rawData]); const [nodes, setNodes] = useState<{ [key: string]: ObsidianNoteNode }>( @@ -24,9 +28,10 @@ export default function useGraphManager(rawData: GraphInfo) { useRef>(null); const [expanded, setExpanded] = useState(false); + const [globalModal, setGlobalModal] = useState(false); - const containerWidth = expanded ? 1200 : 280; - const containerHeight = expanded ? (containerWidth * 9) / 16 : 280; + const containerWidth = global ? 1800 : expanded ? 1200 : 280; + const containerHeight = expanded || global ? (containerWidth * 9) / 16 : 280; const LINK_DISTANCE = expanded ? 20 : 10; useEffect(() => { @@ -67,6 +72,9 @@ export default function useGraphManager(rawData: GraphInfo) { const handleKeyDown = (event: KeyboardEvent) => { if (event.key === "Escape") { setExpanded(false); + if (minimizeCallback) { + minimizeCallback(); + } } }; @@ -85,6 +93,8 @@ export default function useGraphManager(rawData: GraphInfo) { setExpanded, containerWidth, containerHeight, + globalModal, + setGlobalModal, }; } diff --git a/src/plugin/theme/VaultusaurusGraph/GraphContent.tsx b/src/plugin/theme/VaultusaurusGraph/GraphContent.tsx index 99e02e2..cddbf85 100644 --- a/src/plugin/theme/VaultusaurusGraph/GraphContent.tsx +++ b/src/plugin/theme/VaultusaurusGraph/GraphContent.tsx @@ -14,16 +14,23 @@ interface IGraphContent { expandable?: boolean; modal?: boolean; expanded?: boolean; + callback?: () => void; } export default function GraphContent({ expandable = true, modal = false, - enableGlobal = true, + callback = () => {}, }): ReactElement { const { graphStyle, graphManager } = useContext(GraphContext); - const { setExpanded, nodes, links, containerWidth, containerHeight } = - graphManager; + const { + setExpanded, + nodes, + links, + containerWidth, + containerHeight, + setGlobalModal, + } = graphManager; const inlineStyles = { "--vaultusaurus-graph-bg": graphStyle.graphBg, @@ -48,10 +55,10 @@ export default function GraphContent({ )} - {!modal && enableGlobal && ( + {!modal && ( @@ -59,7 +66,10 @@ export default function GraphContent({ {modal && ( diff --git a/src/plugin/theme/VaultusaurusGraph/index.tsx b/src/plugin/theme/VaultusaurusGraph/index.tsx index 2ff144a..7ef6dbf 100644 --- a/src/plugin/theme/VaultusaurusGraph/index.tsx +++ b/src/plugin/theme/VaultusaurusGraph/index.tsx @@ -12,31 +12,38 @@ import { ReactElement } from "react"; import { createPortal } from "react-dom"; import GraphContent from "./GraphContent"; -interface ILocalGraph { +interface IVaultusaurusGraph { customGraph?: GraphInfo; expandable?: boolean; - enableGlobal?: boolean; + global?: boolean; + minimizeGraphCallback?: () => void; } export default function VaultusaurusGraph({ - customGraph, - expandable, - enableGlobal, -}): ReactElement { + customGraph = null, + expandable = true, + global, + minimizeGraphCallback, +}): ReactElement { const globalData = usePluginData( "docusaurus-plugin-vaultusaurus" ) as VaultusaurusGlobalData; - const graphInfo: GraphInfo = - globalData.graphInfo[window.location.pathname] || customGraph; + const graphInfo: GraphInfo = global + ? globalData.globalGraphInfo + : globalData.graphInfo[window.location.pathname] || customGraph; if (!graphInfo) { return null; } const inputGraphStyle = globalData.graphStyle; - const graphManager = useGraphManager(graphInfo); + const graphManager = useGraphManager( + graphInfo, + global, + minimizeGraphCallback + ); const rawLinks = graphInfo?.links || []; - const expanded = graphManager.expanded; + const { expanded, globalModal, setGlobalModal } = graphManager; return ( + {global && ( +
minimizeGraphCallback()} + > + minimizeGraphCallback()} + /> +
+ )} {expanded && createPortal(
, document.body )} - + {globalModal && + createPortal( + setGlobalModal(false)} + />, + document.body + )} + + {!global && } ); }