From 9d8d238912dec82ed8310eb67d0b2587f571b6db Mon Sep 17 00:00:00 2001
From: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 24 Mar 2025 00:57:45 +0000
Subject: [PATCH] chore(deps): bump the production-dependencies group across 1 directory with 4 updates (#1867)
---
quartz/components/scripts/graph.inline.ts | 122 ++++++++++++++++++++++++++++------------
1 files changed, 85 insertions(+), 37 deletions(-)
diff --git a/quartz/components/scripts/graph.inline.ts b/quartz/components/scripts/graph.inline.ts
index 5e8d48c..a669b05 100644
--- a/quartz/components/scripts/graph.inline.ts
+++ b/quartz/components/scripts/graph.inline.ts
@@ -8,6 +8,7 @@
forceCenter,
forceLink,
forceCollide,
+ forceRadial,
zoomIdentity,
select,
drag,
@@ -67,11 +68,9 @@
stop: () => void
}
-async function renderGraph(container: string, fullSlug: FullSlug) {
+async function renderGraph(graph: HTMLElement, fullSlug: FullSlug) {
const slug = simplifySlug(fullSlug)
const visited = getVisited()
- const graph = document.getElementById(container)
- if (!graph) return
removeAllChildren(graph)
let {
@@ -87,6 +86,7 @@
removeTags,
showTags,
focusOnHover,
+ enableRadial,
} = JSON.parse(graph.dataset["cfg"]!) as D3Config
const data: Map<SimpleSlug, ContentDetails> = new Map(
@@ -161,6 +161,9 @@
})),
}
+ const width = graph.offsetWidth
+ const height = Math.max(graph.offsetHeight, 250)
+
// we virtualize the simulation and use pixi to actually render it
const simulation: Simulation<NodeData, LinkData> = forceSimulation<NodeData>(graphData.nodes)
.force("charge", forceManyBody().strength(-100 * repelForce))
@@ -168,8 +171,8 @@
.force("link", forceLink(graphData.links).distance(linkDistance))
.force("collide", forceCollide<NodeData>((n) => nodeRadius(n)).iterations(3))
- const width = graph.offsetWidth
- const height = Math.max(graph.offsetHeight, 250)
+ const radius = (Math.min(width, height) / 2) * 0.8
+ if (enableRadial) simulation.force("radial", forceRadial(radius).strength(0.2))
// precompute style prop strings as pixi doesn't support css variables
const cssVars = [
@@ -363,9 +366,9 @@
const stage = app.stage
stage.interactive = false
- const labelsContainer = new Container<Text>({ zIndex: 3 })
- const nodesContainer = new Container<Graphics>({ zIndex: 2 })
- const linkContainer = new Container<Graphics>({ zIndex: 1 })
+ const labelsContainer = new Container<Text>({ zIndex: 3, isRenderGroup: true })
+ const nodesContainer = new Container<Graphics>({ zIndex: 2, isRenderGroup: true })
+ const linkContainer = new Container<Graphics>({ zIndex: 1, isRenderGroup: true })
stage.addChild(nodesContainer, labelsContainer, linkContainer)
for (const n of graphData.nodes) {
@@ -397,7 +400,6 @@
})
.circle(0, 0, nodeRadius(n))
.fill({ color: isTagNode ? computedStyleMap["--light"] : color(n) })
- .stroke({ width: isTagNode ? 2 : 0, color: color(n) })
.on("pointerover", (e) => {
updateHoverInfo(e.target.label)
oldLabelOpacity = label.alpha
@@ -413,6 +415,10 @@
}
})
+ if (isTagNode) {
+ gfx.stroke({ width: 2, color: computedStyleMap["--tertiary"] })
+ }
+
nodesContainer.addChild(gfx)
labelsContainer.addChild(label)
@@ -517,7 +523,9 @@
)
}
+ let stopAnimation = false
function animate(time: number) {
+ if (stopAnimation) return
for (const n of nodeRenderData) {
const { x, y } = n.simulationData
if (!x || !y) continue
@@ -541,61 +549,101 @@
requestAnimationFrame(animate)
}
- const graphAnimationFrameHandle = requestAnimationFrame(animate)
- window.addCleanup(() => cancelAnimationFrame(graphAnimationFrameHandle))
+ requestAnimationFrame(animate)
+ return () => {
+ stopAnimation = true
+ app.destroy()
+ }
+}
+
+let localGraphCleanups: (() => void)[] = []
+let globalGraphCleanups: (() => void)[] = []
+
+function cleanupLocalGraphs() {
+ for (const cleanup of localGraphCleanups) {
+ cleanup()
+ }
+ localGraphCleanups = []
+}
+
+function cleanupGlobalGraphs() {
+ for (const cleanup of globalGraphCleanups) {
+ cleanup()
+ }
+ globalGraphCleanups = []
}
document.addEventListener("nav", async (e: CustomEventMap["nav"]) => {
const slug = e.detail.url
addToVisited(simplifySlug(slug))
- await renderGraph("graph-container", slug)
- // Function to re-render the graph when the theme changes
- const handleThemeChange = () => {
- renderGraph("graph-container", slug)
+ async function renderLocalGraph() {
+ cleanupLocalGraphs()
+ const localGraphContainers = document.getElementsByClassName("graph-container")
+ for (const container of localGraphContainers) {
+ localGraphCleanups.push(await renderGraph(container as HTMLElement, slug))
+ }
}
- // event listener for theme change
- document.addEventListener("themechange", handleThemeChange)
+ await renderLocalGraph()
+ const handleThemeChange = () => {
+ void renderLocalGraph()
+ }
- // cleanup for the event listener
+ document.addEventListener("themechange", handleThemeChange)
window.addCleanup(() => {
document.removeEventListener("themechange", handleThemeChange)
})
- const container = document.getElementById("global-graph-outer")
- const sidebar = container?.closest(".sidebar") as HTMLElement
-
- function renderGlobalGraph() {
+ const containers = [...document.getElementsByClassName("global-graph-outer")] as HTMLElement[]
+ async function renderGlobalGraph() {
const slug = getFullSlug(window)
- container?.classList.add("active")
- if (sidebar) {
- sidebar.style.zIndex = "1"
- }
+ for (const container of containers) {
+ container.classList.add("active")
+ const sidebar = container.closest(".sidebar") as HTMLElement
+ if (sidebar) {
+ sidebar.style.zIndex = "1"
+ }
- renderGraph("global-graph-container", slug)
- registerEscapeHandler(container, hideGlobalGraph)
+ const graphContainer = container.querySelector(".global-graph-container") as HTMLElement
+ registerEscapeHandler(container, hideGlobalGraph)
+ if (graphContainer) {
+ globalGraphCleanups.push(await renderGraph(graphContainer, slug))
+ }
+ }
}
function hideGlobalGraph() {
- container?.classList.remove("active")
- if (sidebar) {
- sidebar.style.zIndex = "unset"
+ cleanupGlobalGraphs()
+ for (const container of containers) {
+ container.classList.remove("active")
+ const sidebar = container.closest(".sidebar") as HTMLElement
+ if (sidebar) {
+ sidebar.style.zIndex = ""
+ }
}
}
async function shortcutHandler(e: HTMLElementEventMap["keydown"]) {
if (e.key === "g" && (e.ctrlKey || e.metaKey) && !e.shiftKey) {
e.preventDefault()
- const globalGraphOpen = container?.classList.contains("active")
- globalGraphOpen ? hideGlobalGraph() : renderGlobalGraph()
+ const anyGlobalGraphOpen = containers.some((container) =>
+ container.classList.contains("active"),
+ )
+ anyGlobalGraphOpen ? hideGlobalGraph() : renderGlobalGraph()
}
}
- const containerIcon = document.getElementById("global-graph-icon")
- containerIcon?.addEventListener("click", renderGlobalGraph)
- window.addCleanup(() => containerIcon?.removeEventListener("click", renderGlobalGraph))
+ const containerIcons = document.getElementsByClassName("global-graph-icon")
+ Array.from(containerIcons).forEach((icon) => {
+ icon.addEventListener("click", renderGlobalGraph)
+ window.addCleanup(() => icon.removeEventListener("click", renderGlobalGraph))
+ })
document.addEventListener("keydown", shortcutHandler)
- window.addCleanup(() => document.removeEventListener("keydown", shortcutHandler))
+ window.addCleanup(() => {
+ document.removeEventListener("keydown", shortcutHandler)
+ cleanupLocalGraphs()
+ cleanupGlobalGraphs()
+ })
})
--
Gitblit v1.10.0