From 6df774eb51505487c7bd86783c091ec48556fd18 Mon Sep 17 00:00:00 2001 From: Aiden Bai Date: Fri, 29 Apr 2022 11:04:58 -0700 Subject: [PATCH] Fix graph not rendering --- assets/js/graph.js | 113 +++++++++++++++++++++--------------- assets/js/search.js | 6 +- layouts/partials/graph.html | 11 ---- layouts/partials/head.html | 17 +++++- 4 files changed, 85 insertions(+), 62 deletions(-) diff --git a/assets/js/graph.js b/assets/js/graph.js index 69f716c4d..a9268470c 100644 --- a/assets/js/graph.js +++ b/assets/js/graph.js @@ -7,6 +7,9 @@ async function drawGraph( enableLegend, enableZoom ) { + if (!document.getElementById('graph-container')) return; + document.getElementById('graph-container').textContent = ''; + const { index, links, content } = await fetchData; const curPage = url.replace(baseUrl, ''); @@ -87,13 +90,23 @@ async function drawGraph( .on('end', enableDrag ? dragended : noop); }; - const height = Math.max(document.getElementById("graph-container").offsetHeight, 250) - const width = document.getElementById("graph-container").offsetWidth + const height = Math.max( + document.getElementById('graph-container').offsetHeight, + 250 + ); + const width = document.getElementById('graph-container').offsetWidth; - const simulation = d3.forceSimulation(data.nodes) - .force("charge", d3.forceManyBody().strength(-30)) - .force("link", d3.forceLink(data.links).id(d => d.id).distance(40)) - .force("center", d3.forceCenter()); + const simulation = d3 + .forceSimulation(data.nodes) + .force('charge', d3.forceManyBody().strength(-30)) + .force( + 'link', + d3 + .forceLink(data.links) + .id((d) => d.id) + .distance(40) + ) + .force('center', d3.forceCenter()); const svg = d3 .select('#graph-container') @@ -149,20 +162,24 @@ async function drawGraph( // calculate radius const nodeRadius = (d) => { - const numOut = index.links[d.id]?.length || 0 - const numIn = index.backlinks[d.id]?.length || 0 - return 3 + (numOut + numIn) / 4 - } + const numOut = index.links[d.id]?.length || 0; + const numIn = index.backlinks[d.id]?.length || 0; + return 3 + (numOut + numIn) / 4; + }; // draw individual nodes - const node = graphNode.append("circle") - .attr("class", "node") - .attr("id", (d) => d.id) - .attr("r", nodeRadius) - .attr("fill", color) - .style("cursor", "pointer") - .on("click", (_, d) => { - window.location.href = `${baseUrl}/${decodeURI(d.id).replace(/\s+/g, '-')}/` + const node = graphNode + .append('circle') + .attr('class', 'node') + .attr('id', (d) => d.id) + .attr('r', nodeRadius) + .attr('fill', color) + .style('cursor', 'pointer') + .on('click', (_, d) => { + window.navigate( + new URL(`${baseUrl}${decodeURI(d.id).replace(/\s+/g, '-')}/`), + '.singlePage' + ); }) .on('mouseover', function (_, d) { d3.selectAll('.node') @@ -194,16 +211,13 @@ async function drawGraph( // show text for self d3.select(this.parentNode) .raise() - .select("text") + .select('text') .transition() .duration(200) - .style("opacity", 1) - .raise() - }).on("mouseleave", function(_, d) { - d3.selectAll(".node") - .transition() - .duration(200) - .attr("fill", color) + .style('opacity', 1); + }) + .on('mouseleave', function (_, d) { + d3.selectAll('.node').transition().duration(200).attr('fill', color); const currentId = d.id; const linkNodes = d3 @@ -221,32 +235,37 @@ async function drawGraph( .call(drag(simulation)); // draw labels - const labels = graphNode.append("text") - .attr("dx", 0) - .attr("dy", d => nodeRadius(d) + 8 + "px") - .attr("text-anchor", "middle") - .text((d) => content[d.id]?.title || d.id.replace("-", " ")) - .style("opacity", 0) - .style("pointer-events", "none") - .style("font-size", "0.4em") + const labels = graphNode + .append('text') + .attr('dx', 0) + .attr('dy', (d) => nodeRadius(d) + 8 + 'px') + .attr('text-anchor', 'middle') + .text((d) => content[d.id]?.title || d.id.replace('-', ' ')) + .style('opacity', 0) + .style('pointer-events', 'none') + .style('font-size', '0.4em') .raise() .call(drag(simulation)); // set panning if (enableZoom) { - svg.call(d3.zoom() - .extent([[0, 0], [width, height]]) - .scaleExtent([0.25, 4]) - .on("zoom", ({ transform }) => { - link.attr("transform", transform); - node.attr("transform", transform); - const scale = transform.k - const scaledOpacity = Math.max((scale - 1) / 3.75, 0) - labels - .attr("transform", transform) - .style("opacity", scaledOpacity) - })); + svg.call( + d3 + .zoom() + .extent([ + [0, 0], + [width, height], + ]) + .scaleExtent([0.25, 4]) + .on('zoom', ({ transform }) => { + link.attr('transform', transform); + node.attr('transform', transform); + const scale = transform.k; + const scaledOpacity = Math.max((scale - 1) / 3.75, 0); + labels.attr('transform', transform).style('opacity', scaledOpacity); + }) + ); } // progress the simulation @@ -259,6 +278,4 @@ async function drawGraph( node.attr('cx', (d) => d.x).attr('cy', (d) => d.y); labels.attr('x', (d) => d.x).attr('y', (d) => d.y); }); - - console.log(parseIdsFromLinks(links)); } diff --git a/assets/js/search.js b/assets/js/search.js index cfbe368f4..212b2c730 100644 --- a/assets/js/search.js +++ b/assets/js/search.js @@ -145,11 +145,13 @@ const removeMarkdown = ( }; const redir = (id, term) => { - navigate( + window.navigate( new URL( `${BASE_URL.slice(0, -1)}${id}#:~:text=${encodeURIComponent(term)}/` - ) + ), + '.singlePage' ); + closeSearch(); }; const formatForDisplay = (id) => ({ diff --git a/layouts/partials/graph.html b/layouts/partials/graph.html index 4a20e5437..b9f79763c 100644 --- a/layouts/partials/graph.html +++ b/layouts/partials/graph.html @@ -16,14 +16,3 @@ {{ $js := resources.Get "js/graph.js" | resources.Fingerprint "md5" }} - diff --git a/layouts/partials/head.html b/layouts/partials/head.html index 60edf37dc..eef6e642a 100644 --- a/layouts/partials/head.html +++ b/layouts/partials/head.html @@ -61,7 +61,22 @@ navigate, } from 'https://unpkg.com/million/dist/router.mjs'; window.navigate = navigate; - router({}, '.singlePage'); + router('.singlePage'); + const callback = () => { + requestAnimationFrame(() => { + drawGraph( + {{strings.TrimRight "/" .Page.Permalink}}, + {{strings.TrimRight "/" .Site.BaseURL}}, + {{$.Site.Data.graphConfig.paths}}, + {{$.Site.Data.graphConfig.depth}}, + {{$.Site.Data.graphConfig.enableDrag}}, + {{$.Site.Data.graphConfig.enableLegend}}, + {{$.Site.Data.graphConfig.enableZoom}} + ) + }) + } + window.addEventListener('million:navigate', callback); + window.addEventListener('DOMContentLoaded', callback); {{ template "_internal/google_analytics.html" . }}