mirror of
https://github.com/tcsenpai/obsidiangarden_netlify.git
synced 2025-06-06 20:55:21 +00:00
Port the graph to alpineJS (#119)
* Port the graph to alpinejs * removed whitespace * remove console log
This commit is contained in:
parent
80616447c8
commit
b2dc085f48
@ -1,12 +1,9 @@
|
|||||||
<script>
|
<script>
|
||||||
const getCssVar = (variable) => getComputedStyle(document.body).getPropertyValue(variable);
|
async function fetchGraphData() {
|
||||||
|
const graphData = await fetch('/graph.json').then(res => res.json());
|
||||||
function htmlDecode(input) {
|
const fullGraphData = filterFullGraphData(graphData);
|
||||||
var doc = new DOMParser().parseFromString(input, "text/html");
|
return {graphData, fullGraphData}
|
||||||
return doc.documentElement.textContent;
|
|
||||||
}
|
}
|
||||||
window.graphData = null;
|
|
||||||
window.maxGraphDepth = 1;
|
|
||||||
|
|
||||||
function getNextLevelNeighbours(existing, remaining) {
|
function getNextLevelNeighbours(existing, remaining) {
|
||||||
const keys = Object.values(existing).map((n) => n.neighbors).flat();
|
const keys = Object.values(existing).map((n) => n.neighbors).flat();
|
||||||
@ -23,8 +20,12 @@
|
|||||||
return existing, n_remaining;
|
return existing, n_remaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
function filterToDepth(data) {
|
function filterLocalGraphData(graphData, depth) {
|
||||||
let remaining = JSON.parse(JSON.stringify(data.nodes));
|
if (graphData == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
let remaining = JSON.parse(JSON.stringify(graphData.nodes));
|
||||||
|
let links = JSON.parse(JSON.stringify(graphData.links));
|
||||||
let currentLink = decodeURI(window.location.pathname);
|
let currentLink = decodeURI(window.location.pathname);
|
||||||
let currentNode = remaining[currentLink] || Object.values(remaining).find((v) => v.home);
|
let currentNode = remaining[currentLink] || Object.values(remaining).find((v) => v.home);
|
||||||
delete remaining[currentNode.url];
|
delete remaining[currentNode.url];
|
||||||
@ -35,7 +36,7 @@
|
|||||||
currentNode.current = true;
|
currentNode.current = true;
|
||||||
let existing = {};
|
let existing = {};
|
||||||
existing[currentNode.url] = currentNode;
|
existing[currentNode.url] = currentNode;
|
||||||
for (let i = 0; i < window.maxGraphDepth; i++) {
|
for (let i = 0; i < depth; i++) {
|
||||||
existing, remaining = getNextLevelNeighbours(existing, remaining);
|
existing, remaining = getNextLevelNeighbours(existing, remaining);
|
||||||
}
|
}
|
||||||
nodes = Object.values(existing);
|
nodes = Object.values(existing);
|
||||||
@ -43,16 +44,25 @@
|
|||||||
nodes = nodes.filter(n => !n.home);
|
nodes = nodes.filter(n => !n.home);
|
||||||
}
|
}
|
||||||
let ids = nodes.map((n) => n.id);
|
let ids = nodes.map((n) => n.id);
|
||||||
let graphData = {
|
return {
|
||||||
nodes,
|
nodes,
|
||||||
links: data.links.filter((con) => ids.indexOf(con.target) > -1 && ids.indexOf(con.source) > -1),
|
links: links.filter(function (con) {
|
||||||
|
return ids.indexOf(con.target) > -1 && ids.indexOf(con.source) > -1;
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
return graphData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var Graph;
|
function getCssVar(variable) {return getComputedStyle(document.body).getPropertyValue(variable)}
|
||||||
|
|
||||||
function renderGraph(graphData, id, delay) {
|
function htmlDecode(input) {
|
||||||
|
var doc = new DOMParser().parseFromString(input, "text/html");
|
||||||
|
return doc.documentElement.textContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderGraph(graphData, id, delay, fullScreen) {
|
||||||
|
if (graphData == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const el = document.getElementById(id);
|
const el = document.getElementById(id);
|
||||||
width = el.offsetWidth;
|
width = el.offsetWidth;
|
||||||
height = el.offsetHeight;
|
height = el.offsetHeight;
|
||||||
@ -60,7 +70,6 @@
|
|||||||
let hoverNode = null;
|
let hoverNode = null;
|
||||||
const color = getCssVar("--graph-main");
|
const color = getCssVar("--graph-main");
|
||||||
const mutedColor = getCssVar("--graph-muted");
|
const mutedColor = getCssVar("--graph-muted");
|
||||||
|
|
||||||
let Graph = ForceGraph()
|
let Graph = ForceGraph()
|
||||||
(el)
|
(el)
|
||||||
.graphData(graphData)
|
.graphData(graphData)
|
||||||
@ -131,86 +140,75 @@
|
|||||||
hoverNode = node || null;
|
hoverNode = node || null;
|
||||||
|
|
||||||
});
|
});
|
||||||
if (delay != null && graphData.nodes.length > 4) {
|
if (fullScreen || (delay != null && graphData.nodes.length > 4)) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
Graph.zoomToFit(5, 75);
|
Graph.zoomToFit(5, 75);
|
||||||
}, delay);
|
}, delay || 200);
|
||||||
}
|
}
|
||||||
return Graph;
|
return Graph;
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchGraphData() {
|
function renderLocalGraph(graphData, depth, fullScreen) {
|
||||||
fetch('/graph.json').then(res => res.json()).then(data => {
|
if (window.graph){
|
||||||
window.graphData = data;
|
window.graph._destructor();
|
||||||
Graph = renderGraph(filterToDepth(JSON.parse(JSON.stringify(data))), "link-graph", 1);
|
}
|
||||||
});
|
const data = filterLocalGraphData(graphData, depth);
|
||||||
|
return renderGraph(data, 'link-graph', null, fullScreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchGraphData();
|
function filterFullGraphData(graphData) {
|
||||||
window.document.getElementById('graph-depth').value = window.maxGraphDepth;
|
if (graphData == null) {
|
||||||
window.document.getElementById('depth-display').innerText = window.maxGraphDepth;
|
return null;
|
||||||
window.document.getElementById('graph-depth').addEventListener('input', (evt) => {
|
|
||||||
|
|
||||||
window.maxGraphDepth = evt.target.value;
|
|
||||||
window.document.getElementById('depth-display').innerText = window.maxGraphDepth;
|
|
||||||
if (Graph != null) {
|
|
||||||
Graph._destructor();
|
|
||||||
Graph = null;
|
|
||||||
}
|
}
|
||||||
Graph = renderGraph(filterToDepth(JSON.parse(JSON.stringify(window.graphData))), "link-graph", 1);
|
graphData = JSON.parse(JSON.stringify(graphData));
|
||||||
setTimeout(() => {
|
const hiddens = Object.values(graphData.nodes).filter((n) => n.hide).map((n) => n.id);
|
||||||
Graph.zoomToFit(5, 75);
|
const data = {
|
||||||
}, 1);
|
links: JSON.parse(JSON.stringify(graphData.links)).filter((l) => hiddens.indexOf(l.source) == -1 && hiddens.indexOf(l.target) == -1),
|
||||||
});
|
nodes: [...Object.values(graphData.nodes).filter((n) => !n.hide)]
|
||||||
|
}
|
||||||
window.fullGraph = null;
|
return data
|
||||||
function renderFullGraph() {
|
|
||||||
if (!window.fullGraph) {
|
|
||||||
const hiddens = Object.values(window.graphData.nodes).filter((n) => n.hide).map((n) => n.id);
|
|
||||||
const graphData = {
|
|
||||||
links: JSON.parse(JSON.stringify(window.graphData.links)).filter((l) => hiddens.indexOf(l.source) == -1 && hiddens.indexOf(l.target) == -1),
|
|
||||||
nodes: [...Object.values(window.graphData.nodes).filter((n) => !n.hide)]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let g = document.createElement('div');
|
function openFullGraph(fullGraphData) {
|
||||||
g.id = 'full-graph';
|
|
||||||
g.classList.add('show');
|
|
||||||
document.body.appendChild(g);
|
|
||||||
g.innerHTML = '<span id="full-graph-close"><i icon-name="x" aria-hidden="true"></i></span><div id="full-graph-container"></div>';
|
|
||||||
lucide.createIcons({
|
lucide.createIcons({
|
||||||
attrs: {
|
attrs: {
|
||||||
class: ["svg-icon"]
|
class: ["svg-icon"]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
window.fullGraph = renderGraph(graphData, "full-graph-container", 200);
|
return renderGraph(fullGraphData, "full-graph-container", 200, false);;
|
||||||
document.getElementById('full-graph-close').addEventListener('click', (evt) => {
|
|
||||||
g.classList.remove('show');
|
|
||||||
window.fullGraph._destructor();
|
|
||||||
window.fullGraph = null;
|
|
||||||
document.getElementById('full-graph').remove()
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function closefullGraph(fullGraph) {
|
||||||
|
if (fullGraph) {
|
||||||
|
fullGraph._destructor();
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
document.getElementById('graph-fs-btn').addEventListener('click', (evt) => {
|
|
||||||
const el = document.querySelector('.graph');
|
|
||||||
if (el.classList.contains('graph-fs')) {
|
|
||||||
el.classList.remove('graph-fs');
|
|
||||||
Graph.width(el.offsetWidth).height(el.offsetWidth);
|
|
||||||
} else {
|
|
||||||
el.classList.add('graph-fs');
|
|
||||||
Graph.width(el.offsetWidth).height(el.offsetWidth);
|
|
||||||
}
|
}
|
||||||
setTimeout(() => {
|
|
||||||
Graph.zoomToFit(5, 75);
|
|
||||||
}, 1);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById('global-graph-btn').addEventListener('click', (evt) => {
|
|
||||||
if (!window.fullGraph) {
|
|
||||||
renderFullGraph();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
<div x-init="{graphData, fullGraphData} = await fetchGraphData();" x-data="{ graphData: null, depth: 1, graph: null, fullGraph: null, showFullGraph: false, fullScreen: false, fullGraphData: null}" id="graph-component" x-bind:class="fullScreen ? 'graph graph-fs' : 'graph'" v-scope>
|
||||||
|
<div class="graph-title-container">
|
||||||
|
<div class="graph-title">Connected Pages</div>
|
||||||
|
<div id="graph-controls">
|
||||||
|
<div class="depth-control">
|
||||||
|
<label for="graph-depth">Depth</label>
|
||||||
|
<div class="slider">
|
||||||
|
<input x-model.number="depth" name="graph-depth" list="depthmarkers" type="range" step="1" min="1" max="3" id="graph-depth"/>
|
||||||
|
<datalist id="depthmarkers">
|
||||||
|
<option value="1" label="1"></option>
|
||||||
|
<option value="2" label="2"></option>
|
||||||
|
<option value="3" label="3"></option>
|
||||||
|
</datalist>
|
||||||
|
</div>
|
||||||
|
<span id="depth-display" x-text="depth"></span>
|
||||||
|
</div>
|
||||||
|
<div class="ctrl-right">
|
||||||
|
<span id="global-graph-btn" x-on:click="showFullGraph = true; setTimeout(() => {fullGraph = openFullGraph(fullGraphData)}, 100)"><i icon-name="globe" aria-hidden="true"></i></span>
|
||||||
|
<span id="graph-fs-btn" x-on:click="fullScreen = !fullScreen"><i icon-name="expand" aria-hidden="true"></i></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div x-effect="window.graph = renderLocalGraph(graphData, depth, fullScreen)" id="link-graph" ></div>
|
||||||
|
<div x-show="showFullGraph" id="full-graph" class="show">
|
||||||
|
<span id="full-graph-close" x-on:click="fullGraph = closefullGraph(fullGraph); showFullGraph = false;"><i icon-name="x" aria-hidden="true"></i></span><div id="full-graph-container"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -5,30 +5,7 @@
|
|||||||
{% include imp %}
|
{% include imp %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{%if settings.dgShowLocalGraph === true%}
|
{%if settings.dgShowLocalGraph === true%}
|
||||||
<div class="graph">
|
{%include "components/graphScript.njk"%}
|
||||||
<div class="graph-title-container">
|
|
||||||
<div class="graph-title">Connected Pages</div>
|
|
||||||
<div id="graph-controls">
|
|
||||||
<div class="depth-control">
|
|
||||||
<label for="graph-depth">Depth</label>
|
|
||||||
<div class="slider">
|
|
||||||
<input name="graph-depth" list="depthmarkers" type="range" step="1" min="1" max="3" id="graph-depth"/>
|
|
||||||
<datalist id="depthmarkers">
|
|
||||||
<option value="1" label="1"></option>
|
|
||||||
<option value="2" label="2"></option>
|
|
||||||
<option value="3" label="3"></option>
|
|
||||||
</datalist>
|
|
||||||
</div>
|
|
||||||
<span id="depth-display"></span>
|
|
||||||
</div>
|
|
||||||
<div class="ctrl-right">
|
|
||||||
<span id="global-graph-btn"><i icon-name="globe" aria-hidden="true"></i></span>
|
|
||||||
<span id="graph-fs-btn"><i icon-name="expand" aria-hidden="true"></i></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="link-graph"></div>
|
|
||||||
</div>
|
|
||||||
{%endif%}
|
{%endif%}
|
||||||
|
|
||||||
{%if settings.dgShowToc === true%}
|
{%if settings.dgShowToc === true%}
|
||||||
@ -90,7 +67,3 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
{%if settings.dgShowLocalGraph === true %}
|
|
||||||
{%include "components/graphScript.njk"%}
|
|
||||||
{% endif %}
|
|
Loading…
x
Reference in New Issue
Block a user