note map refactoring

This commit is contained in:
zadam 2021-09-20 22:19:47 +02:00
parent 9c9a3fc030
commit e4ba7d65e8
8 changed files with 31 additions and 32 deletions

View File

@ -14,7 +14,8 @@ const NOTE_TYPE_ICONS = {
"render": "bx bx-extension", "render": "bx bx-extension",
"search": "bx bx-file-find", "search": "bx bx-file-find",
"relation-map": "bx bx-map-alt", "relation-map": "bx bx-map-alt",
"book": "bx bx-book" "book": "bx bx-book",
"note-map": "bx bx-map-alt"
}; };
/** /**

View File

@ -72,8 +72,8 @@ export default class DesktopLayout {
.command("jumpToNote")) .command("jumpToNote"))
.child(new OpenNoteButtonWidget() .child(new OpenNoteButtonWidget()
.icon("bx-map-alt") .icon("bx-map-alt")
.title("Global link map") .title("Global note map")
.targetNote('globallinkmap')) .targetNote('globalnotemap'))
.child(new ButtonWidget() .child(new ButtonWidget()
.icon("bx-history") .icon("bx-history")
.title("Show recent changes") .title("Show recent changes")

View File

@ -30,6 +30,7 @@ class TreeContextMenu {
{ title: "Code", command: command, type: "code", uiIcon: "code" }, { title: "Code", command: command, type: "code", uiIcon: "code" },
{ title: "Saved search", command: command, type: "search", uiIcon: "file-find" }, { title: "Saved search", command: command, type: "search", uiIcon: "file-find" },
{ title: "Relation Map", command: command, type: "relation-map", uiIcon: "map-alt" }, { title: "Relation Map", command: command, type: "relation-map", uiIcon: "map-alt" },
{ title: "Note Map", command: command, type: "note-map", uiIcon: "map-alt" },
{ title: "Render HTML note", command: command, type: "render", uiIcon: "extension" }, { title: "Render HTML note", command: command, type: "render", uiIcon: "extension" },
{ title: "Book", command: command, type: "book", uiIcon: "book" } { title: "Book", command: command, type: "book", uiIcon: "book" }
]; ];

View File

@ -20,7 +20,7 @@ import ReadOnlyTextTypeWidget from "./type_widgets/read_only_text.js";
import ReadOnlyCodeTypeWidget from "./type_widgets/read_only_code.js"; import ReadOnlyCodeTypeWidget from "./type_widgets/read_only_code.js";
import NoneTypeWidget from "./type_widgets/none.js"; import NoneTypeWidget from "./type_widgets/none.js";
import attributeService from "../services/attributes.js"; import attributeService from "../services/attributes.js";
import GlobalLinkMapTypeWidget from "./type_widgets/global_link_map.js"; import NoteMapTypeWidget from "./type_widgets/note_map.js";
const TPL = ` const TPL = `
<div class="note-detail"> <div class="note-detail">
@ -47,7 +47,7 @@ const typeWidgetClasses = {
'relation-map': RelationMapTypeWidget, 'relation-map': RelationMapTypeWidget,
'protected-session': ProtectedSessionTypeWidget, 'protected-session': ProtectedSessionTypeWidget,
'book': BookTypeWidget, 'book': BookTypeWidget,
'globallinkmap': GlobalLinkMapTypeWidget 'note-map': NoteMapTypeWidget
}; };
export default class NoteDetailWidget extends NoteContextAwareWidget { export default class NoteDetailWidget extends NoteContextAwareWidget {
@ -173,10 +173,6 @@ export default class NoteDetailWidget extends NoteContextAwareWidget {
type = 'editable-code'; type = 'editable-code';
} }
if (type === 'special') {
type = note.noteId;
}
if (note.isProtected && !protectedSessionHolder.isProtectedSessionAvailable()) { if (note.isProtected && !protectedSessionHolder.isProtectedSessionAvailable()) {
type = 'protected-session'; type = 'protected-session';
} }

View File

@ -3,13 +3,13 @@ import libraryLoader from "../../services/library_loader.js";
import server from "../../services/server.js"; import server from "../../services/server.js";
import attributeService from "../../services/attributes.js"; import attributeService from "../../services/attributes.js";
const TPL = `<div class="note-detail-global-link-map note-detail-printable" style="position: relative;"> const TPL = `<div class="note-detail-note-map note-detail-printable" style="position: relative;">
<style> <style>
.type-special .note-detail, .note-detail-global-link-map { .type-special .note-detail, .note-detail-note-map {
height: 100%; height: 100%;
} }
.map-switcher { .map-type-switcher {
position: absolute; position: absolute;
top: 10px; top: 10px;
right: 10px; right: 10px;
@ -17,30 +17,30 @@ const TPL = `<div class="note-detail-global-link-map note-detail-printable" styl
z-index: 1000; z-index: 1000;
} }
.map-switcher .bx { .map-type-switcher .bx {
font-size: x-large; font-size: x-large;
} }
</style> </style>
<div class="btn-group btn-group-sm map-switcher" role="group"> <div class="btn-group btn-group-sm map-type-switcher" role="group">
<button type="button" class="btn btn-secondary" title="Link Map" data-type="link"><span class="bx bx-network-chart"></span></button> <button type="button" class="btn btn-secondary" title="Link Map" data-type="link"><span class="bx bx-network-chart"></span></button>
<button type="button" class="btn btn-secondary" title="Tree map" data-type="tree"><span class="bx bx-sitemap"></span></button> <button type="button" class="btn btn-secondary" title="Tree map" data-type="tree"><span class="bx bx-sitemap"></span></button>
</div> </div>
<div class="link-map-container"></div> <div class="note-map-container"></div>
</div>`; </div>`;
export default class GlobalLinkMapTypeWidget extends TypeWidget { export default class NoteMapTypeWidget extends TypeWidget {
static getType() { return "globallinkmap"; } static getType() { return "note-map"; }
doRender() { doRender() {
this.$widget = $(TPL); this.$widget = $(TPL);
this.$container = this.$widget.find(".link-map-container"); this.$container = this.$widget.find(".note-map-container");
window.addEventListener('resize', () => this.setFullHeight(), false); window.addEventListener('resize', () => this.setFullHeight(), false);
this.$widget.find(".map-switcher button").on("click", async e => { this.$widget.find(".map-type-switcher button").on("click", async e => {
const type = $(e.target).closest("button").attr("data-type"); const type = $(e.target).closest("button").attr("data-type");
await attributeService.setLabel(this.noteId, 'mapType', type); await attributeService.setLabel(this.noteId, 'mapType', type);
@ -59,7 +59,7 @@ export default class GlobalLinkMapTypeWidget extends TypeWidget {
const height = $(window).height() - top; const height = $(window).height() - top;
const width = this.$widget.width(); const width = this.$widget.width();
this.$widget.find('.link-map-container') this.$widget.find('.note-map-container')
.css("height", height) .css("height", height)
.css("width", this.$widget.width()); .css("width", this.$widget.width());
@ -83,7 +83,6 @@ export default class GlobalLinkMapTypeWidget extends TypeWidget {
.onZoom(zoom => this.setZoomLevel(zoom.k)) .onZoom(zoom => this.setZoomLevel(zoom.k))
.d3AlphaDecay(0.01) .d3AlphaDecay(0.01)
.d3VelocityDecay(0.08) .d3VelocityDecay(0.08)
.nodeRelSize(node => this.noteIdToSizeMap[node.id])
.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 => node.name) .nodeLabel(node => node.name)
@ -91,7 +90,7 @@ export default class GlobalLinkMapTypeWidget extends TypeWidget {
.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, this.noteIdToSizeMap[node.id], 0, 2 * Math.PI, false);
ctx.fill(); ctx.fill();
}) })
.linkLabel(l => `${l.source.name} - <strong>${l.name}</strong> - ${l.target.name}`) .linkLabel(l => `${l.source.name} - <strong>${l.name}</strong> - ${l.target.name}`)
@ -106,7 +105,7 @@ export default class GlobalLinkMapTypeWidget extends TypeWidget {
// .dagMode("radialout") // .dagMode("radialout")
.onNodeClick(node => this.nodeClicked(node)); .onNodeClick(node => this.nodeClicked(node));
this.graph.d3Force('link').distance(5); this.graph.d3Force('link').distance(40);
// //
this.graph.d3Force('center').strength(0.01); this.graph.d3Force('center').strength(0.01);
// //
@ -115,7 +114,9 @@ export default class GlobalLinkMapTypeWidget extends TypeWidget {
this.graph.d3Force('charge').distanceMax(1000); this.graph.d3Force('charge').distanceMax(1000);
this.renderData(await this.loadNotesAndRelations()); const data = await this.loadNotesAndRelations();
this.renderData(data);
} }
stringToColor(str) { stringToColor(str) {
@ -215,7 +216,7 @@ export default class GlobalLinkMapTypeWidget extends TypeWidget {
ctx.restore(); ctx.restore();
} }
async loadNotesAndRelations(noteId, maxDepth) { async loadNotesAndRelations() {
this.linkIdToLinkMap = {}; this.linkIdToLinkMap = {};
this.noteIdToLinkCountMap = {}; this.noteIdToLinkCountMap = {};
@ -291,7 +292,7 @@ export default class GlobalLinkMapTypeWidget extends TypeWidget {
this.graph.graphData(data); this.graph.graphData(data);
if (zoomToFit && data.nodes.length > 1) { if (zoomToFit && data.nodes.length > 1) {
setTimeout(() => this.graph.zoomToFit(400, zoomPadding), 3000); setTimeout(() => this.graph.zoomToFit(400, zoomPadding), 1000);
} }
} }

View File

@ -148,7 +148,7 @@ function getGlobalTreeMap() {
const noteIds = new Set(); const noteIds = new Set();
const notes = Object.values(becca.notes) const notes = Object.values(becca.notes)
.filter(note => !note.isArchived) .filter(note => !note.isArchived && !note.hasLabel('excludeFromTreeMap'))
.map(note => [ .map(note => [
note.noteId, note.noteId,
note.isContentAvailable() ? note.title : '[protected]', note.isContentAvailable() ? note.title : '[protected]',

View File

@ -268,7 +268,7 @@ class ConsistencyChecks {
SELECT noteId, type SELECT noteId, type
FROM notes FROM notes
WHERE isDeleted = 0 WHERE isDeleted = 0
AND type NOT IN ('text', 'code', 'render', 'file', 'image', 'search', 'relation-map', 'book', 'special')`, AND type NOT IN ('text', 'code', 'render', 'file', 'image', 'search', 'relation-map', 'book', 'note-map')`,
({noteId, type}) => { ({noteId, type}) => {
if (this.autoFix) { if (this.autoFix) {
const note = becca.getNote(noteId); const note = becca.getNote(noteId);

View File

@ -82,13 +82,13 @@ function getSinglesNoteRoot() {
} }
function getGlobalLinkMapNote() { function getGlobalLinkMapNote() {
let globalLinkMapNote = becca.getNote('globallinkmap'); let globalLinkMapNote = becca.getNote('globalnotemap');
if (!globalLinkMapNote) { if (!globalLinkMapNote) {
globalLinkMapNote = noteService.createNewNote({ globalLinkMapNote = noteService.createNewNote({
noteId: 'globallinkmap', noteId: 'globalnotemap',
title: 'Global Link Map', title: 'Global Note Map',
type: 'special', type: 'note-map',
content: '', content: '',
parentNoteId: getSinglesNoteRoot().noteId parentNoteId: getSinglesNoteRoot().noteId
}).note; }).note;