Merge branch 'uroybd-graph-hover'

This commit is contained in:
Ole Eskild Steensen 2023-02-14 17:00:07 +01:00
commit c3c27293d2
8 changed files with 207 additions and 109 deletions

View File

@ -5,5 +5,5 @@ See the README in the plugin repo for information on how to set it up.
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/oleeskild/digitalgarden) [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/oleeskild/digitalgarden)
--- ---
## Custom Styling ## Docs
I encourage you to change the default styling to make the site your own. Please modify the custom-style.scss when doing so to avoid future conflict when updating the template. Docs are available at [dg-docs.ole.dev](https://dg-docs.ole.dev/)

24
package-lock.json generated
View File

@ -785,9 +785,9 @@
"integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA=="
}, },
"node_modules/axios": { "node_modules/axios": {
"version": "1.2.6", "version": "1.3.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.2.6.tgz", "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.2.tgz",
"integrity": "sha512-rC/7F08XxZwjMV4iuWv+JpD3E0Ksqg9nac4IIg6RwNuF0JTeWoCo/mBNG54+tNhhI11G3/VDRbdDQTs9hGp4pQ==", "integrity": "sha512-1M3O703bYqYuPhbHeya5bnhpYVsDDRyQSabNja04mZtboLNSuZ4YrltestrLXfHgmzua4TpUqRiVKbiQuo2epw==",
"dependencies": { "dependencies": {
"follow-redirects": "^1.15.0", "follow-redirects": "^1.15.0",
"form-data": "^4.0.0", "form-data": "^4.0.0",
@ -5103,9 +5103,9 @@
} }
}, },
"node_modules/sass": { "node_modules/sass": {
"version": "1.57.1", "version": "1.58.0",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.57.1.tgz", "resolved": "https://registry.npmjs.org/sass/-/sass-1.58.0.tgz",
"integrity": "sha512-O2+LwLS79op7GI0xZ8fqzF7X2m/m8WFfI02dHOdsK5R2ECeS5F62zrwg/relM1rjSLy7Vd/DiMNIvPrQGsA0jw==", "integrity": "sha512-PiMJcP33DdKtZ/1jSjjqVIKihoDc6yWmYr9K/4r3fVVIEDAluD0q7XZiRKrNJcPK3qkLRF/79DND1H5q1LBjgg==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"chokidar": ">=3.0.0 <4.0.0", "chokidar": ">=3.0.0 <4.0.0",
@ -7153,9 +7153,9 @@
"integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA=="
}, },
"axios": { "axios": {
"version": "1.2.6", "version": "1.3.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.2.6.tgz", "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.2.tgz",
"integrity": "sha512-rC/7F08XxZwjMV4iuWv+JpD3E0Ksqg9nac4IIg6RwNuF0JTeWoCo/mBNG54+tNhhI11G3/VDRbdDQTs9hGp4pQ==", "integrity": "sha512-1M3O703bYqYuPhbHeya5bnhpYVsDDRyQSabNja04mZtboLNSuZ4YrltestrLXfHgmzua4TpUqRiVKbiQuo2epw==",
"requires": { "requires": {
"follow-redirects": "^1.15.0", "follow-redirects": "^1.15.0",
"form-data": "^4.0.0", "form-data": "^4.0.0",
@ -10502,9 +10502,9 @@
} }
}, },
"sass": { "sass": {
"version": "1.57.1", "version": "1.58.0",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.57.1.tgz", "resolved": "https://registry.npmjs.org/sass/-/sass-1.58.0.tgz",
"integrity": "sha512-O2+LwLS79op7GI0xZ8fqzF7X2m/m8WFfI02dHOdsK5R2ECeS5F62zrwg/relM1rjSLy7Vd/DiMNIvPrQGsA0jw==", "integrity": "sha512-PiMJcP33DdKtZ/1jSjjqVIKihoDc6yWmYr9K/4r3fVVIEDAluD0q7XZiRKrNJcPK3qkLRF/79DND1H5q1LBjgg==",
"dev": true, "dev": true,
"requires": { "requires": {
"chokidar": ">=3.0.0 <4.0.0", "chokidar": ">=3.0.0 <4.0.0",

View File

@ -50,9 +50,17 @@
var Graph; var Graph;
function renderGraph(graphData, id, width, height, delay) { function renderGraph(graphData, id, delay) {
const el = document.getElementById(id);
width = el.offsetWidth;
height = el.offsetHeight;
const highlightNodes = new Set();
let hoverNode = null;
const color = getCssVar("--text-accent");
const mutedColor = getCssVar("--text-muted");
let Graph = ForceGraph() let Graph = ForceGraph()
(document.getElementById(id)) (el)
.graphData(graphData) .graphData(graphData)
.nodeId('id') .nodeId('id')
.nodeLabel('title') .nodeLabel('title')
@ -63,15 +71,34 @@
.height(height) .height(height)
.linkDirectionalArrowLength(2) .linkDirectionalArrowLength(2)
.linkDirectionalArrowRelPos(0.5) .linkDirectionalArrowRelPos(0.5)
.linkColor(() => getCssVar("--text-muted") || getCssVar("--text-normal")) .autoPauseRedraw(false)
.linkColor((link) => {
if (hoverNode == null) {
return color;
}
if (link.source.id == hoverNode.id || link.target.id == hoverNode.id) {
return color;
} else {
return mutedColor;
}
})
.nodeCanvasObject((node, ctx) => { .nodeCanvasObject((node, ctx) => {
const color = getCssVar("--text-accent");
const numberOfNeighbours = (node.neighbors && node.neighbors.length) || 2; const numberOfNeighbours = (node.neighbors && node.neighbors.length) || 2;
const nodeR = Math.min(7, Math.max(numberOfNeighbours / 2, 2)); const nodeR = Math.min(7, Math.max(numberOfNeighbours / 2, 2));
ctx.beginPath(); ctx.beginPath();
ctx.arc(node.x, node.y, nodeR, 0, 2 * Math.PI, false); ctx.arc(node.x, node.y, nodeR, 0, 2 * Math.PI, false);
if (hoverNode == null) {
ctx.fillStyle = color; ctx.fillStyle = color;
} else {
if (node == hoverNode || highlightNodes.has(node.url)) {
ctx.fillStyle = color;
} else {
ctx.fillStyle = mutedColor;
}
}
ctx.fill(); ctx.fill();
if (node.current) { if (node.current) {
@ -92,8 +119,17 @@
}) })
.onNodeClick(node => { .onNodeClick(node => {
window.location = node.url; window.location = node.url;
})
.onNodeHover(node => {
highlightNodes.clear();
if (node) {
highlightNodes.add(node);
node.neighbors.forEach(neighbor => highlightNodes.add(neighbor));
}
hoverNode = node || null;
}); });
if (delay != null && graphData.nodes.length > 2) { if (delay != null && graphData.nodes.length > 4) {
setTimeout(() => { setTimeout(() => {
Graph.zoomToFit(5, 75); Graph.zoomToFit(5, 75);
}, delay); }, delay);
@ -104,7 +140,7 @@
function fetchGraphData() { function fetchGraphData() {
fetch('/graph.json').then(res => res.json()).then(data => { fetch('/graph.json').then(res => res.json()).then(data => {
window.graphData = data; window.graphData = data;
Graph = renderGraph(filterToDepth(JSON.parse(JSON.stringify(data))), "link-graph", 320, 320, 1); Graph = renderGraph(filterToDepth(JSON.parse(JSON.stringify(data))), "link-graph", 1);
}); });
} }
@ -119,8 +155,11 @@
Graph._destructor(); Graph._destructor();
Graph = null; Graph = null;
} }
renderGraph(filterToDepth(JSON.parse(JSON.stringify(window.graphData))), "link-graph", 320, 320, 1); Graph = renderGraph(filterToDepth(JSON.parse(JSON.stringify(window.graphData))), "link-graph", 1);
}) setTimeout(() => {
Graph.zoomToFit(5, 75);
}, 1);
});
window.fullGraph = null; window.fullGraph = null;
function renderFullGraph() { function renderFullGraph() {
@ -135,7 +174,7 @@
g.classList.add('show'); g.classList.add('show');
document.body.appendChild(g); document.body.appendChild(g);
g.innerHTML = '<i class="fa fa-times" id="full-graph-close" aria-hidden="true"></i><div id="full-graph-container"></div>'; g.innerHTML = '<i class="fa fa-times" id="full-graph-close" aria-hidden="true"></i><div id="full-graph-container"></div>';
window.fullGraph = renderGraph(graphData, "full-graph-container", g.offsetWidth, g.offsetHeight, 200); window.fullGraph = renderGraph(graphData, "full-graph-container", 200);
document.getElementById('full-graph-close').addEventListener('click', (evt) => { document.getElementById('full-graph-close').addEventListener('click', (evt) => {
g.classList.remove('show'); g.classList.remove('show');
window.fullGraph._destructor(); window.fullGraph._destructor();
@ -146,8 +185,23 @@
} }
document.getElementById('graph-full-btn').addEventListener('click', (evt) => { document.getElementById('graph-fs-btn').addEventListener('click', (evt) => {
if (!fullGraph) { 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(); renderFullGraph();
} }
}); });

View File

@ -19,7 +19,10 @@
</div> </div>
<span id="depth-display"></span> <span id="depth-display"></span>
</div> </div>
<i class="fa fa-arrows-alt" id="graph-full-btn" aria-hidden="true"></i> <div class="ctrl-right">
<i class="fa fa-globe" id="global-graph-btn" aria-hidden="true"></i>
<i class="fa fa-arrows-alt" id="graph-fs-btn" aria-hidden="true"></i>
</div>
</div> </div>
</div> </div>
<div id="link-graph"></div> <div id="link-graph"></div>

View File

@ -15,16 +15,15 @@ body {
margin-top: 90px; margin-top: 90px;
position: relative; position: relative;
@media(max-width: 800px) { @media (max-width: 800px) {
margin-top: 75px; margin-top: 75px;
} }
} }
.external-link { .external-link {
background-position: center right; background-position: center right;
background-repeat: no-repeat; background-repeat: no-repeat;
background-image: linear-gradient(transparent, transparent), url('/img/outgoing.svg'); background-image: linear-gradient(transparent, transparent), url("/img/outgoing.svg");
background-size: 13px; background-size: 13px;
padding-right: 16px; padding-right: 16px;
background-position-y: 4px; background-position-y: 4px;
@ -54,14 +53,56 @@ ul.task-list {
.sidebar { .sidebar {
position: fixed; position: fixed;
top: 50%; top: 75px;
transform: translateY(calc(-50% + 75px));
right: 0; right: 0;
height: 100%; height: 100%;
min-width: 25px; min-width: 25px;
display: flex; display: flex;
z-index: 3; z-index: 3;
max-width: 350px; max-width: 350px;
.graph {
width: 320px;
min-height: 320px;
#link-graph {
width: 320px;
height: 320px;
}
#graph-fs-btn {
margin-right: 10px;
}
}
.graph-fs {
position: fixed;
top: 50%;
left: 50%;
height: calc(100vmin - 100px);
width: calc(100vmin - 100px);
min-height: 350px;
min-width: 350px;
transform: translate(-50%, -50%);
z-index: 9999;
display: block;
background-color: var(--background-secondary);
border: 1px solid var(--text-accent);
border-radius: 5px;
padding-top: 5px;
#link-graph {
width: 100%;
height: 100%;
}
#graph-controls{
margin-top: 10px;
}
.graph-title {
display: none;
}
}
} }
.expand-line { .expand-line {
@ -91,7 +132,7 @@ ul.task-list {
font-size: 1rem; font-size: 1rem;
max-height: 220px; max-height: 220px;
overflow-y: auto; overflow-y: auto;
margin-bottom:10px; margin-bottom: 10px;
border-left: 1px solid var(--text-accent); border-left: 1px solid var(--text-accent);
ul { ul {
list-style-type: none; list-style-type: none;
@ -100,19 +141,19 @@ ul.task-list {
margin-bottom: 0; margin-bottom: 0;
} }
ul:not(:first-child) { ul:not(:first-child) {
margin-bottom:3px; margin-bottom: 3px;
} }
li{ li {
padding-top: 4px; padding-top: 4px;
&::before{ &::before {
content: '# ' !important; content: "# " !important;
color: var(--text-accent); color: var(--text-accent);
font-size: 0.8rem; font-size: 0.8rem;
} }
a{ a {
text-decoration: none; text-decoration: none;
&:hover{ &:hover {
text-decoration: underline; text-decoration: underline;
} }
} }
@ -149,7 +190,7 @@ ul.task-list {
border-left: 1px solid var(--text-accent); border-left: 1px solid var(--text-accent);
max-height: 200px; max-height: 200px;
overflow-y: auto; overflow-y: auto;
overflow-x:hidden; overflow-x: hidden;
} }
.backlink-card { .backlink-card {
@ -164,17 +205,16 @@ ul.task-list {
} }
} }
.no-backlinks-message{ .no-backlinks-message {
font-size: 0.8rem; font-size: 0.8rem;
color: var(--text-normal); color: var(--text-normal);
} }
.graph { .graph {
.graph-title-container { .graph-title-container {
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
width: 320px; width: 100%;
} }
.graph-title { .graph-title {
@ -195,9 +235,7 @@ ul.task-list {
width: fit-content; width: fit-content;
} }
@media (max-width: 1400px) {
@media(max-width: 1400px) {
#link-graph { #link-graph {
border-radius: 0 10px 10px 10px; border-radius: 0 10px 10px 10px;
} }
@ -213,7 +251,7 @@ ul.task-list {
justify-content: space-between; justify-content: space-between;
} }
.sidebar-container{ .sidebar-container {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
@ -221,7 +259,7 @@ ul.task-list {
.graph { .graph {
flex: 1; flex: 1;
.graph-title-container{ .graph-title-container {
justify-content: flex-start; justify-content: flex-start;
} }
} }
@ -230,8 +268,8 @@ ul.task-list {
display: none; display: none;
} }
} }
@media(max-width: 800px) { @media (max-width: 800px) {
.sidebar-container{ .sidebar-container {
display: flex; display: flex;
flex-direction: column-reverse; flex-direction: column-reverse;
} }
@ -252,7 +290,7 @@ ul.task-list {
h1 { h1 {
font-size: 32px !important; font-size: 32px !important;
} }
@media(max-width: 800px) { @media (max-width: 800px) {
h1 { h1 {
display: none; display: none;
} }
@ -269,7 +307,7 @@ ul.task-list {
justify-content: flex-end; justify-content: flex-end;
margin-bottom: -60px; margin-bottom: -60px;
@media(max-width: 800px) { @media (max-width: 800px) {
justify-content: center; justify-content: center;
} }
@ -290,11 +328,11 @@ ul.task-list {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
@media(max-width: 1400px) { @media (max-width: 1400px) {
position: fixed; position: fixed;
} }
@media(max-width: 800px) { @media (max-width: 800px) {
h1 { h1 {
font-size: 18px !important; font-size: 18px !important;
} }
@ -307,8 +345,7 @@ ul.task-list {
} }
.search-button { .search-button {
@media (max-width: 800px) {
@media(max-width: 800px) {
min-width: 36px; min-width: 36px;
margin: 10px 25px 10px 25px; margin: 10px 25px 10px 25px;
} }
@ -317,7 +354,7 @@ ul.task-list {
.search-text { .search-text {
display: flex; display: flex;
justify-content: center; justify-content: center;
@media(max-width: 800px){ @media (max-width: 800px) {
display: none; display: none;
} }
} }
@ -325,7 +362,7 @@ ul.task-list {
.notelink { .notelink {
padding: 5px 0 5px 25px; padding: 5px 0 5px 25px;
a{ a {
&:hover { &:hover {
text-decoration: underline !important; text-decoration: underline !important;
} }
@ -361,10 +398,9 @@ ul.task-list {
right: 0; right: 0;
left: 0; left: 0;
bottom: 0; bottom: 0;
z-index: 5 z-index: 5;
} }
.search-container { .search-container {
background-color: rgba(0, 0, 0, 0.5); background-color: rgba(0, 0, 0, 0.5);
position: fixed; position: fixed;
@ -400,7 +436,6 @@ ul.task-list {
font-size: 2rem; font-size: 2rem;
background-color: var(--background-primary); background-color: var(--background-primary);
color: var(--text-primary); color: var(--text-primary);
} }
.search-box input:focus { .search-box input:focus {
@ -425,7 +460,7 @@ ul.task-list {
font-size: 1.2rem; font-size: 1.2rem;
cursor: pointer; cursor: pointer;
&.active{ &.active {
border: 2px solid var(--text-accent); border: 2px solid var(--text-accent);
} }
} }
@ -459,25 +494,21 @@ ul.task-list {
border: 1px solid var(--text-normal); border: 1px solid var(--text-normal);
cursor: pointer; cursor: pointer;
>span { > span {
padding: 3px 3px 3px 10px; padding: 3px 3px 3px 10px;
} }
>i { > i {
margin-left: 10px; margin-left: 10px;
} }
&:hover { &:hover {
border: 1px solid var(--text-accent); border: 1px solid var(--text-accent);
} }
} }
.search-keys { .search-keys {
@media(max-width: 800px) { @media (max-width: 800px) {
display: none; display: none;
} }
} }
@ -491,7 +522,7 @@ ul.task-list {
padding: 0; padding: 0;
} }
.callout-fold{ .callout-fold {
cursor: pointer; cursor: pointer;
} }
@ -529,8 +560,6 @@ ul.task-list {
margin-right: -10px; margin-right: -10px;
} }
// Graph Controls // Graph Controls
.graph-title-container { .graph-title-container {
position: relative; position: relative;
@ -540,14 +569,21 @@ ul.task-list {
position: fixed; position: fixed;
top: 50%; top: 50%;
left: 50%; left: 50%;
height: 60vh; height: calc(100vmin - 100px);
width: 60vw; width: calc(100vmin - 100px);
min-height: 400px; min-height: 350px;
min-width: 400px; min-width: 350px;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
z-index: 9999; z-index: 9999;
display: none; display: none;
background-color: var(--background-secondary); background-color: var(--background-secondary);
border: 1px solid var(--text-accent);
border-radius: 5px;
#full-graph-container {
width: 100%;
height: 100%;
}
#full-graph-close { #full-graph-close {
position: absolute; position: absolute;
@ -580,6 +616,11 @@ ul.task-list {
color: var(--text-accent); color: var(--text-accent);
z-index: 9; z-index: 9;
i {
cursor: pointer;
padding-right: 10px;
}
.depth-control { .depth-control {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@ -604,8 +645,8 @@ ul.task-list {
#depth-display { #depth-display {
background-color: var(--text-accent); background-color: var(--text-accent);
color: white; color: white;
width: 1rem; width: 1.3rem;
height: 1rem; height: 1.3rem;
font-size: 0.8rem; font-size: 0.8rem;
display: flex; display: flex;
justify-content: center; justify-content: center;
@ -616,7 +657,7 @@ ul.task-list {
} }
} }
input[type=range]::-webkit-slider-thumb { input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none; -webkit-appearance: none;
margin-top: -10px; margin-top: -10px;
} }

View File

@ -5867,7 +5867,7 @@ body {
.callout[data-callout="quote"], .callout[data-callout="quote"],
.callout[data-callout="cite"] { .callout[data-callout="cite"] {
--callout-color: 158, 158, 158; --callout-color: 158, 158, 158;
--callout-icon: quote-glyph; --callout-icon: lucide-quote;
} }
.callout { .callout {
overflow: hidden; overflow: hidden;

View File

@ -168,7 +168,7 @@ p>code {
.callout[data-callout="quote"], .callout[data-callout="quote"],
.callout[data-callout="cite"] { .callout[data-callout="cite"] {
--callout-color: 158, 158, 158; --callout-color: 158, 158, 158;
--callout-icon: quote-glyph; --callout-icon: lucide-quote;
} }
.callout { .callout {
overflow: hidden; overflow: hidden;