link map WIP

This commit is contained in:
zadam 2021-05-30 23:21:34 +02:00
parent f5573fcad4
commit b351157a6a
2 changed files with 21 additions and 35 deletions

View File

@ -24,20 +24,22 @@ export default class LinkMap {
await libraryLoader.requireLibrary(libraryLoader.FORCE_GRAPH); await libraryLoader.requireLibrary(libraryLoader.FORCE_GRAPH);
this.graph = ForceGraph()(this.$linkMapContainer[0]) this.graph = ForceGraph()(this.$linkMapContainer[0])
.width(this.options.width)
.height(this.options.height)
.onZoom(zoom => this.setZoomLevel(zoom.k)) .onZoom(zoom => this.setZoomLevel(zoom.k))
.nodeRelSize(7) .nodeRelSize(7)
.nodeCanvasObject((node, ctx) => this.paintNode(node, this.stringToColor(node.type), ctx)) .nodeCanvasObject((node, ctx) => this.paintNode(node, this.stringToColor(node.type), ctx))
.nodePointerAreaPaint((node, ctx) => this.paintNode(node, this.stringToColor(node.type), ctx)) .nodePointerAreaPaint((node, ctx) => this.paintNode(node, this.stringToColor(node.type), ctx))
.nodeLabel(node => this.getNodeLabel(node)) .nodeLabel(node => node.name)
.nodePointerAreaPaint((node, color, ctx) => { .nodePointerAreaPaint((node, color, ctx) => {
ctx.fillStyle = color; ctx.fillStyle = color;
ctx.beginPath(); ctx.beginPath();
ctx.arc(node.x, node.y, 5, 0, 2 * Math.PI, false); ctx.arc(node.x, node.y, 5, 0, 2 * Math.PI, false);
ctx.fill(); ctx.fill();
}) })
.linkLabel(l => `${this.getNodeLabel(l.source)} - <strong>${l.type}</strong> - ${this.getNodeLabel(l.target)}`) .linkLabel(l => `${l.source.name} - <strong>${l.name}</strong> - ${l.target.name}`)
.linkCanvasObject((link, ctx) => this.paintLink(link, ctx)) .linkCanvasObject((link, ctx) => this.paintLink(link, ctx))
.linkCanvasObjectMode("after") .linkCanvasObjectMode(() => "after")
.linkDirectionalArrowLength(4) .linkDirectionalArrowLength(4)
.linkDirectionalArrowRelPos(1) .linkDirectionalArrowRelPos(1)
.linkWidth(2) .linkWidth(2)
@ -116,11 +118,11 @@ export default class LinkMap {
} }
paintLink(link, ctx) { paintLink(link, ctx) {
if (this.zoomLevel < 2) { if (this.zoomLevel < 3) {
return; return;
} }
ctx.font = '3px Sans-Serif'; ctx.font = '3px MontserratLight';
ctx.textAlign = 'center'; ctx.textAlign = 'center';
ctx.textBaseline = 'middle'; ctx.textBaseline = 'middle';
ctx.fillStyle = "grey"; ctx.fillStyle = "grey";
@ -137,13 +139,15 @@ export default class LinkMap {
const deltaX = source.x - target.x; const deltaX = source.x - target.x;
let angle = Math.atan2(deltaY, deltaX); let angle = Math.atan2(deltaY, deltaX);
let moveY = 2;
if (angle < -Math.PI / 2 || angle > Math.PI / 2) { if (angle < -Math.PI / 2 || angle > Math.PI / 2) {
angle += Math.PI; angle += Math.PI;
moveY = -2;
} }
ctx.rotate(angle); ctx.rotate(angle);
ctx.fillText(link.name, 0, 0); ctx.fillText(link.name, 0, moveY);
ctx.restore(); ctx.restore();
} }
@ -152,7 +156,7 @@ export default class LinkMap {
ctx.fillStyle = color; ctx.fillStyle = color;
ctx.beginPath(); ctx.beginPath();
ctx.arc(x, y, 5, 0, 2 * Math.PI, false); ctx.arc(x, y, 4, 0, 2 * Math.PI, false);
ctx.fill(); ctx.fill();
if (this.zoomLevel < 2) { if (this.zoomLevel < 2) {
@ -161,24 +165,24 @@ export default class LinkMap {
if (!node.expanded) { if (!node.expanded) {
ctx.fillStyle = color; ctx.fillStyle = color;
ctx.font = 10 + 'px Sans-Serif'; ctx.font = 10 + 'px MontserratLight';
ctx.textAlign = 'center'; ctx.textAlign = 'center';
ctx.textBaseline = 'middle'; ctx.textBaseline = 'middle';
ctx.fillText("+", x, y + 1); ctx.fillText("+", x, y + 1);
} }
ctx.fillStyle = "#555"; ctx.fillStyle = "#555";
ctx.font = 3 + 'px Sans-Serif'; ctx.font = 5 + 'px MontserratLight';
ctx.textAlign = 'center'; ctx.textAlign = 'center';
ctx.textBaseline = 'middle'; ctx.textBaseline = 'middle';
let title = node.name; let title = node.name;
if (title.length > 10) { if (title.length > 15) {
title = title.substr(0, 10) + "..."; title = title.substr(0, 15) + "...";
} }
ctx.fillText(title, x, y + 8); ctx.fillText(title, x, y + 7);
} }
stringToColor(str) { stringToColor(str) {
@ -193,22 +197,4 @@ export default class LinkMap {
} }
return colour; return colour;
} }
getNodeLabel(node) {
if (node.type === node.name) {
return node.type;
}
else {
return `${node.type}: ${node.name}`;
}
}
shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
const temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
} }

View File

@ -9,7 +9,7 @@ const TPL = `
} }
.link-map-container { .link-map-container {
max-height: 300px; height: 300px;
} }
.open-full-dialog-button { .open-full-dialog-button {
@ -22,11 +22,9 @@ const TPL = `
<button class="bx bx-expand icon-action open-full-dialog-button" title="Show Link Map dialog"></button> <button class="bx bx-expand icon-action open-full-dialog-button" title="Show Link Map dialog"></button>
<div class="link-map-container" style="height: 300px;"></div> <div class="link-map-container"></div>
</div>`; </div>`;
let linkMapContainerIdCtr = 1;
export default class LinkMapWidget extends NoteContextAwareWidget { export default class LinkMapWidget extends NoteContextAwareWidget {
isEnabled() { isEnabled() {
return this.note; return this.note;
@ -55,7 +53,9 @@ export default class LinkMapWidget extends NoteContextAwareWidget {
this.linkMapService = new LinkMapServiceClass(note, $linkMapContainer, { this.linkMapService = new LinkMapServiceClass(note, $linkMapContainer, {
maxDepth: 3, maxDepth: 3,
zoom: 0.6 zoom: 0.6,
width: $linkMapContainer.width(),
height: $linkMapContainer.height()
}); });
await this.linkMapService.render(); await this.linkMapService.render();