fix(spa): only render graph once in global

Signed-off-by: Aaron Pham <contact@aarnphm.xyz>
This commit is contained in:
Aaron Pham 2024-08-15 04:16:42 -04:00
parent dd4b1cd604
commit b88be2f767
No known key found for this signature in database
GPG Key ID: 18974753009D2BFA
2 changed files with 29 additions and 14 deletions

View File

@ -64,7 +64,7 @@ export default ((opts?: GraphOptions) => {
<div class={classNames(displayClass, "graph")}>
<h3>{i18n(cfg.locale).components.graph.title}</h3>
<div class="graph-outer">
<canvas id="graph-container" data-cfg={JSON.stringify(localGraph)}></canvas>
<div id="graph-container" data-cfg={JSON.stringify(localGraph)}></div>
<svg
version="1.1"
id="global-graph-icon"

View File

@ -2,7 +2,7 @@ import type { ContentDetails } from "../../plugins/emitters/contentIndex"
import * as d3 from "d3"
import * as PIXI from "pixi.js"
import * as TWEEN from "@tweenjs/tween.js"
import { registerEscapeHandler } from "./util"
import { registerEscapeHandler, removeAllChildren } from "./util"
import { FullSlug, SimpleSlug, getFullSlug, resolveRelative, simplifySlug } from "../../util/path"
type NodeData = {
@ -58,12 +58,16 @@ function animate(time: number) {
}
requestAnimationFrame(animate)
async function renderGraph(container: string, fullSlug: FullSlug) {
const canvas = document.getElementById(container) as HTMLCanvasElement | null
if (!canvas) return
async function renderGraph(container: string, fullSlug: FullSlug, global?: boolean) {
const slug = simplifySlug(fullSlug)
const visited = getVisited()
const graph = document.getElementById(container)
if (!graph) return
global = global ?? false
if (!global) {
removeAllChildren(graph)
}
let {
drag: enableDrag,
@ -78,7 +82,7 @@ async function renderGraph(container: string, fullSlug: FullSlug) {
removeTags,
showTags,
focusOnHover,
} = JSON.parse(canvas.dataset["cfg"]!)
} = JSON.parse(graph.dataset["cfg"]!)
const data: Map<SimpleSlug, ContentDetails> = new Map(
Object.entries<ContentDetails>(await fetchData).map(([k, v]) => [
@ -133,8 +137,6 @@ async function renderGraph(container: string, fullSlug: FullSlug) {
if (showTags) tags.forEach((tag) => neighbourhood.add(tag))
}
// XXX: How does links got morphed into LinkNodes here?
// links => LinkData[], where as links.filter(l => neighbourhood.has(l.source) && neighbourhood.has(l.target)) => LinkNodes[]
const graphData: { nodes: NodeData[]; links: LinkNodes[] } = {
nodes: [...neighbourhood].map((url) => {
const text = url.startsWith("tags/") ? "#" + url.substring(5) : (data.get(url)?.title ?? url)
@ -165,8 +167,8 @@ async function renderGraph(container: string, fullSlug: FullSlug) {
d3.forceCollide((n) => nodeRadius(n)),
)
const width = canvas.offsetWidth
const height = Math.max(canvas.offsetHeight, 250)
const width = graph.offsetWidth
const height = Math.max(graph.offsetHeight, 250)
const computedStyleMap = new Map<string, string>()
for (let i of [
"--secondary",
@ -178,7 +180,7 @@ async function renderGraph(container: string, fullSlug: FullSlug) {
"--darkgray",
"--bodyFont",
]) {
computedStyleMap.set(i, getComputedStyle(canvas).getPropertyValue(i))
computedStyleMap.set(i, getComputedStyle(graph).getPropertyValue(i))
}
// calculate color
@ -304,7 +306,7 @@ async function renderGraph(container: string, fullSlug: FullSlug) {
await app.init({
width,
height,
canvas: canvas,
canvas: global ? (graph as HTMLCanvasElement) : undefined,
antialias: true,
autoStart: false,
autoDensity: true,
@ -314,6 +316,10 @@ async function renderGraph(container: string, fullSlug: FullSlug) {
eventMode: "static",
})
if (!global) {
graph.appendChild(app.canvas)
}
const stage = app.stage
stage.interactive = false
@ -454,7 +460,16 @@ async function renderGraph(container: string, fullSlug: FullSlug) {
}
}),
)
} else {
graphData.nodes.forEach((node) => {
if (!node.gfx) return
node.gfx.on("click", () => {
const targ = resolveRelative(fullSlug, node.id)
window.spaNavigate(new URL(targ, window.location.toString()))
})
})
}
if (enableZoom) {
d3.select<HTMLCanvasElement, NodeData>(app.canvas).call(
d3
@ -520,7 +535,7 @@ document.addEventListener("nav", async (e: CustomEventMap["nav"]) => {
sidebar.style.zIndex = "1"
}
renderGraph("global-graph-container", slug)
renderGraph("global-graph-container", slug, true)
registerEscapeHandler(container, hideGlobalGraph)
}