mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
link map WIP
This commit is contained in:
parent
87b16f3325
commit
4b96ada781
@ -1,6 +1,7 @@
|
|||||||
import server from '../services/server.js';
|
import server from '../services/server.js';
|
||||||
import noteDetailService from "../services/note_detail.js";
|
import noteDetailService from "../services/note_detail.js";
|
||||||
import libraryLoader from "../services/library_loader.js";
|
import libraryLoader from "../services/library_loader.js";
|
||||||
|
import treeCache from "../services/tree_cache.js";
|
||||||
|
|
||||||
const $linkMapContainer = $("#link-map-container");
|
const $linkMapContainer = $("#link-map-container");
|
||||||
|
|
||||||
@ -84,9 +85,12 @@ async function loadNotesAndRelations() {
|
|||||||
|
|
||||||
const noteIds = new Set(links.map(l => l.noteId).concat(links.map(l => l.targetNoteId)));
|
const noteIds = new Set(links.map(l => l.noteId).concat(links.map(l => l.targetNoteId)));
|
||||||
|
|
||||||
|
// preload all notes
|
||||||
|
const notes = await treeCache.getNotes(Array.from(noteIds));
|
||||||
|
|
||||||
const graph = new Springy.Graph();
|
const graph = new Springy.Graph();
|
||||||
graph.addNodes(...noteIds);
|
graph.addNodes(...noteIds);
|
||||||
graph.addEdges(links.map(l => [l.noteId, l.targetNoteId]));
|
graph.addEdges(...links.map(l => [l.noteId, l.targetNoteId]));
|
||||||
|
|
||||||
const layout = new Springy.Layout.ForceDirected(
|
const layout = new Springy.Layout.ForceDirected(
|
||||||
graph,
|
graph,
|
||||||
@ -95,10 +99,38 @@ async function loadNotesAndRelations() {
|
|||||||
0.5 // Damping
|
0.5 // Damping
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const renderer = new Springy.Renderer(
|
||||||
|
layout,
|
||||||
|
() => {},
|
||||||
|
() => {},
|
||||||
|
() => {},
|
||||||
|
() => {
|
||||||
|
layout.eachNode((node, point) => {
|
||||||
|
console.log(node, point.p);
|
||||||
|
|
||||||
for (const link of links) {
|
const note = notes.find(n => n.noteId === node.id);
|
||||||
|
|
||||||
}
|
const $noteBox = $("<div>")
|
||||||
|
.addClass("note-box")
|
||||||
|
.prop("id", noteIdToId(node.id))
|
||||||
|
.append($("<span>").addClass("title").append(note.title))
|
||||||
|
.css("left", (300 + point.p.x * 100) + "px")
|
||||||
|
.css("top", (300 + point.p.y * 100) + "px");
|
||||||
|
|
||||||
|
jsPlumbInstance.getContainer().appendChild($noteBox[0]);
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const link of links) {
|
||||||
|
const connection = jsPlumbInstance.connect({
|
||||||
|
source: noteIdToId(link.noteId),
|
||||||
|
target: noteIdToId(link.targetNoteId),
|
||||||
|
type: link.type
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
renderer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
function initJsPlumbInstance() {
|
function initJsPlumbInstance() {
|
||||||
@ -113,23 +145,27 @@ function initJsPlumbInstance() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.jsPlumbInstance = jsPlumb.getInstance({
|
jsPlumbInstance = jsPlumb.getInstance({
|
||||||
Endpoint: ["Dot", {radius: 2}],
|
Endpoint: ["Dot", {radius: 2}],
|
||||||
Connector: "StateMachine",
|
Connector: "StateMachine",
|
||||||
ConnectionOverlays: uniDirectionalOverlays,
|
ConnectionOverlays: uniDirectionalOverlays,
|
||||||
HoverPaintStyle: { stroke: "#777", strokeWidth: 1 },
|
HoverPaintStyle: { stroke: "#777", strokeWidth: 1 },
|
||||||
Container: this.$relationMapContainer.attr("id")
|
Container: $linkMapContainer.attr("id")
|
||||||
});
|
});
|
||||||
|
|
||||||
this.jsPlumbInstance.registerConnectionType("uniDirectional", { anchor:"Continuous", connector:"StateMachine", overlays: uniDirectionalOverlays });
|
jsPlumbInstance.registerConnectionType("uniDirectional", { anchor:"Continuous", connector:"StateMachine", overlays: uniDirectionalOverlays });
|
||||||
|
|
||||||
this.jsPlumbInstance.registerConnectionType("biDirectional", { anchor:"Continuous", connector:"StateMachine", overlays: biDirectionalOverlays });
|
jsPlumbInstance.registerConnectionType("biDirectional", { anchor:"Continuous", connector:"StateMachine", overlays: biDirectionalOverlays });
|
||||||
|
|
||||||
this.jsPlumbInstance.registerConnectionType("inverse", { anchor:"Continuous", connector:"StateMachine", overlays: inverseRelationsOverlays });
|
jsPlumbInstance.registerConnectionType("inverse", { anchor:"Continuous", connector:"StateMachine", overlays: inverseRelationsOverlays });
|
||||||
|
|
||||||
this.jsPlumbInstance.registerConnectionType("link", { anchor:"Continuous", connector:"StateMachine", overlays: linkOverlays });
|
jsPlumbInstance.registerConnectionType("link", { anchor:"Continuous", connector:"StateMachine", overlays: linkOverlays });
|
||||||
|
|
||||||
this.jsPlumbInstance.bind("connection", (info, originalEvent) => this.connectionCreatedHandler(info, originalEvent));
|
jsPlumbInstance.bind("connection", (info, originalEvent) => connectionCreatedHandler(info, originalEvent));
|
||||||
|
}
|
||||||
|
|
||||||
|
function noteIdToId(noteId) {
|
||||||
|
return "link-map-note-" + noteId;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -335,4 +335,10 @@ li.dropdown-submenu:hover > ul.dropdown-menu {
|
|||||||
.note-tab-row.note-tab-row-is-sorting .note-tab:not(.note-tab-is-dragging),
|
.note-tab-row.note-tab-row-is-sorting .note-tab:not(.note-tab-is-dragging),
|
||||||
.note-tab-row:not(.note-tab-row-is-sorting) .note-tab.note-tab-was-just-dragged {
|
.note-tab-row:not(.note-tab-row-is-sorting) .note-tab.note-tab-was-just-dragged {
|
||||||
transition: transform 120ms ease-in-out;
|
transition: transform 120ms ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#link-map-container {
|
||||||
|
position: relative;
|
||||||
|
height: 700px;
|
||||||
|
outline: none; /* remove dotted outline on click */
|
||||||
}
|
}
|
@ -14,7 +14,7 @@ async function getLinks(noteIds) {
|
|||||||
WHERE (noteId IN (???) OR value IN (???))
|
WHERE (noteId IN (???) OR value IN (???))
|
||||||
AND type = 'relation'
|
AND type = 'relation'
|
||||||
AND isDeleted = 0
|
AND isDeleted = 0
|
||||||
`, noteIds);
|
`, Array.from(noteIds));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getLinkMap(req) {
|
async function getLinkMap(req) {
|
||||||
@ -27,7 +27,7 @@ async function getLinkMap(req) {
|
|||||||
const newLinks = await getLinks(noteIds);
|
const newLinks = await getLinks(noteIds);
|
||||||
const newNoteIds = new Set(newLinks.map(l => l.noteId).concat(newLinks.map(l => l.targetNoteId)));
|
const newNoteIds = new Set(newLinks.map(l => l.noteId).concat(newLinks.map(l => l.targetNoteId)));
|
||||||
|
|
||||||
if (newNoteIds.length === noteIds.length) {
|
if (newNoteIds.size === noteIds.size) {
|
||||||
// no new note discovered, no need to search any further
|
// no new note discovered, no need to search any further
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user