mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-25 07:17:04 +08:00 
			
		
		
		
	chore(react): add back note map link configuration
This commit is contained in:
		
							parent
							
								
									ad5ff6e41a
								
							
						
					
					
						commit
						2d29d1b41f
					
				
					 5 changed files with 57 additions and 57 deletions
				
			
		|  | @ -169,7 +169,7 @@ const entityMap: Record<string, string> = { | |||
|     "=": "=" | ||||
| }; | ||||
| 
 | ||||
| function escapeHtml(str: string) { | ||||
| export function escapeHtml(str: string) { | ||||
|     return str.replace(/[&<>"'`=\/]/g, (s) => entityMap[s]); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -34,14 +34,10 @@ export default class NoteMapWidget extends NoteContextAwareWidget { | |||
|     private fixNodes: boolean; | ||||
|     private widgetMode: WidgetMode; | ||||
| 
 | ||||
|     private themeStyle!: string; | ||||
|     private $container!: JQuery<HTMLElement>; | ||||
|     private $styleResolver!: JQuery<HTMLElement>; | ||||
|     private $fixNodesButton!: JQuery<HTMLElement>; | ||||
|     graph!: ForceGraph; | ||||
|     private noteIdToSizeMap!: Record<string, number>; | ||||
|     private zoomLevel!: number; | ||||
|     private nodes!: Node[]; | ||||
| 
 | ||||
|     constructor(widgetMode: WidgetMode) { | ||||
|         super(); | ||||
|  | @ -117,13 +113,6 @@ export default class NoteMapWidget extends NoteContextAwareWidget { | |||
|                 } | ||||
|             }); | ||||
| 
 | ||||
|         if (this.mapType === "link") { | ||||
|             this.graph | ||||
|                 .linkLabel((l) => `${esc((l as Link).source.name)} - <strong>${esc((l as Link).name)}</strong> - ${esc((l as Link).target.name)}`) | ||||
|                 .linkCanvasObject((link, ctx) => this.paintLink(link as Link, ctx)) | ||||
|                 .linkCanvasObjectMode(() => "after"); | ||||
|         } | ||||
| 
 | ||||
|         const nodeLinkRatio = data.nodes.length / data.links.length; | ||||
|         const magnifiedRatio = Math.pow(nodeLinkRatio, 1.5); | ||||
|         const charge = -20 / magnifiedRatio; | ||||
|  | @ -148,45 +137,6 @@ export default class NoteMapWidget extends NoteContextAwareWidget { | |||
|         this.zoomLevel = level; | ||||
|     } | ||||
| 
 | ||||
|     paintLink(link: Link, ctx: CanvasRenderingContext2D) { | ||||
|         if (this.zoomLevel < 5) { | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         ctx.font = `3px ${this.cssData.fontFamily}`; | ||||
|         ctx.textAlign = "center"; | ||||
|         ctx.textBaseline = "middle"; | ||||
|         ctx.fillStyle = this.cssData.mutedTextColor; | ||||
| 
 | ||||
|         const { source, target } = link; | ||||
|         if (typeof source !== "object" || typeof target !== "object") { | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         if (source.x && source.y && target.x && target.y) { | ||||
|             const x = (source.x + target.x) / 2; | ||||
|             const y = (source.y + target.y) / 2; | ||||
|             ctx.save(); | ||||
|             ctx.translate(x, y); | ||||
| 
 | ||||
|             const deltaY = source.y - target.y; | ||||
|             const deltaX = source.x - target.x; | ||||
| 
 | ||||
|             let angle = Math.atan2(deltaY, deltaX); | ||||
|             let moveY = 2; | ||||
| 
 | ||||
|             if (angle < -Math.PI / 2 || angle > Math.PI / 2) { | ||||
|                 angle += Math.PI; | ||||
|                 moveY = -2; | ||||
|             } | ||||
| 
 | ||||
|             ctx.rotate(angle); | ||||
|             ctx.fillText(link.name, 0, moveY); | ||||
|         } | ||||
| 
 | ||||
|         ctx.restore(); | ||||
|     } | ||||
| 
 | ||||
|     renderData(data: Data) { | ||||
|         if (this.widgetMode === "ribbon" && this.note?.type !== "search") { | ||||
|             setTimeout(() => { | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| import { useEffect, useRef, useState } from "preact/hooks"; | ||||
| import "./NoteMap.css"; | ||||
| import { getMapRootNoteId, getThemeStyle, NoteMapWidgetMode, rgb2hex } from "./utils"; | ||||
| import { getMapRootNoteId, getThemeStyle, MapType, NoteMapWidgetMode, rgb2hex } from "./utils"; | ||||
| import { RefObject } from "preact"; | ||||
| import FNote from "../../entities/fnote"; | ||||
| import { useElementSize, useNoteContext, useNoteLabel } from "../react/hooks"; | ||||
|  | @ -16,8 +16,6 @@ interface NoteMapProps { | |||
|     parentRef: RefObject<HTMLElement>; | ||||
| } | ||||
| 
 | ||||
| type MapType = "tree" | "link"; | ||||
| 
 | ||||
| export default function NoteMap({ note, widgetMode, parentRef }: NoteMapProps) { | ||||
|     const containerRef = useRef<HTMLDivElement>(null); | ||||
|     const styleResolverRef = useRef<HTMLDivElement>(null); | ||||
|  | @ -50,7 +48,8 @@ export default function NoteMap({ note, widgetMode, parentRef }: NoteMapProps) { | |||
|                 noteIdToSizeMap: notesAndRelations.noteIdToSizeMap, | ||||
|                 notesAndRelations, | ||||
|                 themeStyle: getThemeStyle(), | ||||
|                 widgetMode | ||||
|                 widgetMode, | ||||
|                 mapType | ||||
|             }); | ||||
|             graph.graphData(notesAndRelations); | ||||
|         }); | ||||
|  |  | |||
|  | @ -1,7 +1,8 @@ | |||
| import type ForceGraph from "force-graph"; | ||||
| import { Link, Node, NotesAndRelationsData } from "./data"; | ||||
| import { NodeObject } from "force-graph"; | ||||
| import { getColorForNode, NoteMapWidgetMode } from "./utils"; | ||||
| import { getColorForNode, MapType, NoteMapWidgetMode } from "./utils"; | ||||
| import { escapeHtml } from "../../services/utils"; | ||||
| 
 | ||||
| export interface CssData { | ||||
|     fontFamily: string; | ||||
|  | @ -16,9 +17,10 @@ interface RenderData { | |||
|     themeStyle: "light" | "dark"; | ||||
|     widgetMode: NoteMapWidgetMode; | ||||
|     notesAndRelations: NotesAndRelationsData; | ||||
|     mapType: MapType; | ||||
| } | ||||
| 
 | ||||
| export function setupRendering(graph: ForceGraph, { noteId, themeStyle, widgetMode, noteIdToSizeMap, notesAndRelations, cssData }: RenderData) { | ||||
| export function setupRendering(graph: ForceGraph, { noteId, themeStyle, widgetMode, noteIdToSizeMap, notesAndRelations, cssData, mapType }: RenderData) { | ||||
|     // variables for the hover effect. We have to save the neighbours of a hovered node in a set. Also we need to save the links as well as the hovered node itself
 | ||||
|     const neighbours = new Set(); | ||||
|     const highlightLinks = new Set(); | ||||
|  | @ -57,6 +59,46 @@ export function setupRendering(graph: ForceGraph, { noteId, themeStyle, widgetMo | |||
|         ctx.fillText(title, x, y + Math.round(size * 1.5)); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     function paintLink(link: Link, ctx: CanvasRenderingContext2D) { | ||||
|         if (zoomLevel < 5) { | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         ctx.font = `3px ${cssData.fontFamily}`; | ||||
|         ctx.textAlign = "center"; | ||||
|         ctx.textBaseline = "middle"; | ||||
|         ctx.fillStyle = cssData.mutedTextColor; | ||||
| 
 | ||||
|         const { source, target } = link; | ||||
|         if (typeof source !== "object" || typeof target !== "object") { | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         if (source.x && source.y && target.x && target.y) { | ||||
|             const x = (source.x + target.x) / 2; | ||||
|             const y = (source.y + target.y) / 2; | ||||
|             ctx.save(); | ||||
|             ctx.translate(x, y); | ||||
| 
 | ||||
|             const deltaY = source.y - target.y; | ||||
|             const deltaX = source.x - target.x; | ||||
| 
 | ||||
|             let angle = Math.atan2(deltaY, deltaX); | ||||
|             let moveY = 2; | ||||
| 
 | ||||
|             if (angle < -Math.PI / 2 || angle > Math.PI / 2) { | ||||
|                 angle += Math.PI; | ||||
|                 moveY = -2; | ||||
|             } | ||||
| 
 | ||||
|             ctx.rotate(angle); | ||||
|             ctx.fillText(link.name, 0, moveY); | ||||
|         } | ||||
| 
 | ||||
|         ctx.restore(); | ||||
|     } | ||||
| 
 | ||||
|     // main code for highlighting hovered nodes and neighbours. here we "style" the nodes. the nodes are rendered several hundred times per second.
 | ||||
|     graph | ||||
|         .d3AlphaDecay(0.01) | ||||
|  | @ -92,5 +134,13 @@ export function setupRendering(graph: ForceGraph, { noteId, themeStyle, widgetMo | |||
|             highlightLinks.clear(); | ||||
|         }) | ||||
|         .onZoom((zoom) => zoomLevel = zoom.k); | ||||
| 
 | ||||
|     // Link-specific config
 | ||||
|     if (mapType) { | ||||
|         graph | ||||
|             .linkLabel((l) => `${escapeHtml((l as Link).source.name)} - <strong>${escapeHtml((l as Link).name)}</strong> - ${escapeHtml((l as Link).target.name)}`) | ||||
|             .linkCanvasObject((link, ctx) => paintLink(link as Link, ctx)) | ||||
|             .linkCanvasObjectMode(() => "after"); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ import hoisted_note from "../../services/hoisted_note"; | |||
| import { Node } from "./data"; | ||||
| 
 | ||||
| export type NoteMapWidgetMode = "ribbon" | "hoisted"; | ||||
| export type MapType = "tree" | "link"; | ||||
| 
 | ||||
| export function rgb2hex(rgb: string) { | ||||
|     return `#${(rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/) || []) | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue