@@ -3,33 +3,45 @@ import { getAPI, Page } from 'obsidian-dataview';
33import * as PIXI from 'pixi.js' ;
44
55export default class GraphLinkTypesPlugin extends Plugin {
6+ // Retrieve the Dataview API
67 api = getAPI ( ) ;
8+ // A map to keep track of the text nodes created for each link
79 nodeTextMap : Map < string , PIXI . Text > = new Map ( ) ;
810
11+ // Lifecycle method called when the plugin is loaded
912 async onload ( ) : Promise < void > {
13+ // Check if the Dataview API is available
1014 if ( this . api ) {
15+ // Register an event to start the update loop when the layout changes
1116 this . registerEvent ( this . app . workspace . on ( 'layout-change' , ( ) => {
1217 this . startUpdateLoop ( ) ;
1318 } ) ) ;
1419
20+ // Add a command to the command palette
1521 this . addCommand ( {
1622 id : 'print-link-type' ,
1723 name : 'Print Link Type' ,
24+ // Command callback to start the update loop with verbosity
1825 callback : ( ) => this . startUpdateLoop ( 1 )
1926 } ) ;
2027 } else {
2128 console . error ( "Dataview plugin is not available." ) ;
2229 }
2330 }
2431
32+ // Get the metadata key for a link between two pages
2533 getMetadataKeyForLink ( sourceId : string , targetId : string ) : string | null {
34+ // Retrieve the source page
2635 const sourcePage : Page | undefined = this . api . page ( sourceId ) ;
2736 if ( ! sourcePage ) return null ;
2837
38+ // Loop through the properties of the source page
2939 for ( const [ key , value ] of Object . entries ( sourcePage ) ) {
40+ // Check if the value is a link and matches the targetId
3041 if ( this . isLink ( value ) && value . path === targetId ) {
3142 return key ;
3243 }
44+ // Check if the value is an array of links and find a match
3345 if ( Array . isArray ( value ) ) {
3446 for ( const link of value ) {
3547 if ( this . isLink ( link ) && link . path === targetId ) {
@@ -41,55 +53,69 @@ export default class GraphLinkTypesPlugin extends Plugin {
4153 return null ;
4254 }
4355
56+ // Utility function to check if a value is a link
4457 isLink ( value : any ) : boolean {
4558 return typeof value === 'object' && value . hasOwnProperty ( 'path' ) ;
4659 }
4760
61+ // Find the graph view leaf in the workspace
4862 findGraphLeaf ( ) : WorkspaceLeaf | null {
4963 const graphLeaves : WorkspaceLeaf [ ] = this . app . workspace . getLeavesOfType ( 'graph' ) ;
64+ // Ensure there is exactly one graph leaf open
5065 return graphLeaves . length === 1 ? graphLeaves [ 0 ] : null ;
5166 }
5267
68+ // Create or update text for a given link
5369 createTextForLink ( renderer : any , link : any ) : void {
70+ // Get the text to display for the link
5471 const linkString : string | null = this . getMetadataKeyForLink ( link . source . id , link . target . id ) ;
5572 if ( linkString === null ) return ;
5673
5774 const linkKey : string = `${ link . source . id } -${ link . target . id } ` ;
5875
76+ // If text already exists for this link, remove it
5977 if ( this . nodeTextMap . has ( linkKey ) ) {
6078 const existingText = this . nodeTextMap . get ( linkKey ) ! ;
6179 renderer . px . stage . removeChild ( existingText ) ;
6280 existingText . destroy ( ) ;
6381 }
6482
83+ // Define the style for the text
6584 const textStyle : PIXI . TextStyle = new PIXI . TextStyle ( {
6685 fontFamily : 'Arial' ,
6786 fontSize : 36 ,
6887 fill : 0x000000
6988 } ) ;
89+ // Create new text node
7090 const text : PIXI . Text = new PIXI . Text ( linkString , textStyle ) ;
7191 text . alpha = 0.7 ;
7292 text . anchor . set ( 0.5 , 0.5 ) ;
93+ // Add the text node to the map and the renderer
7394 this . nodeTextMap . set ( linkKey , text ) ;
7495
7596 this . updateTextPosition ( renderer , link ) ;
7697 renderer . px . stage . addChild ( text ) ;
7798 }
7899
100+ // Update the position of the text on the graph
79101 updateTextPosition ( renderer : any , link : any ) : void {
80102 const linkKey : string = `${ link . source . id } -${ link . target . id } ` ;
81103 const text : PIXI . Text | undefined = this . nodeTextMap . get ( linkKey ) ;
82104 if ( ! text || ! link . source || ! link . target ) {
83105 return ;
84106 }
107+ // Calculate the mid-point of the link
85108 const midX : number = ( link . source . x + link . target . x ) / 2 ;
86109 const midY : number = ( link . source . y + link . target . y ) / 2 ;
110+ // Transform the mid-point coordinates based on the renderer's pan and scale
87111 const { x, y } = this . getLinkToTextCoordinates ( midX , midY , renderer . panX , renderer . panY , renderer . scale ) ;
112+ // Set the position and scale of the text
88113 text . x = x ;
89114 text . y = y ;
90115 text . scale . set ( 1 / ( 3 * renderer . nodeScale ) ) ;
91116 }
92117
118+ // Remove all text nodes from the graph
93119 destroyMap ( renderer : any ) : void {
94120 console . log ( "Destroying Map" ) ;
95121 if ( this . nodeTextMap . size > 0 ) {
@@ -103,27 +129,40 @@ export default class GraphLinkTypesPlugin extends Plugin {
103129 }
104130 }
105131
132+ // Function to start the update loop for rendering.
106133 startUpdateLoop ( verbosity : number = 0 ) : void {
134+ // Find the graph leaf in the workspace.
107135 const graphLeaf : WorkspaceLeaf | null = this . findGraphLeaf ( ) ;
108136 if ( ! graphLeaf ) {
137+ // Show a notice if no graph is found.
109138 if ( verbosity > 0 ) {
110139 new Notice ( "No graph or multiple graphs present." ) ;
111140 }
112141 return ;
113142 }
143+ // Get the renderer from the graph leaf.
114144 const renderer : any = graphLeaf . view . renderer ;
145+ // Remove existing text from the graph.
115146 this . destroyMap ( renderer ) ;
147+ // Create text for each link in the graph.
116148 renderer . links . forEach ( ( link : any ) => this . createTextForLink ( renderer , link ) ) ;
149+ // Call the function to update positions in the next animation frame.
117150 requestAnimationFrame ( this . updatePositions . bind ( this ) ) ;
118151 }
119152
153+
154+
155+ // Function to continuously update the positions of text objects.
120156 updatePositions ( ) : void {
157+ // Find the graph leaf in the workspace.
121158 const graphLeaf : WorkspaceLeaf | null = this . findGraphLeaf ( ) ;
122159 if ( ! graphLeaf ) {
123160 return ;
124161 }
162+ // Get the renderer from the graph leaf.
125163 const renderer : any = graphLeaf . view . renderer ;
126164
165+ // For each link in the graph, update the position of its text.
127166 renderer . links . forEach ( ( link : any ) => {
128167 const linkKey : string = `${ link . source . id } -${ link . target . id } ` ;
129168 if ( ! this . nodeTextMap . has ( linkKey ) ) {
@@ -132,10 +171,13 @@ export default class GraphLinkTypesPlugin extends Plugin {
132171 this . updateTextPosition ( renderer , link ) ;
133172 } ) ;
134173
174+ // Continue updating positions in the next animation frame.
135175 requestAnimationFrame ( this . updatePositions . bind ( this ) ) ;
136176 }
137177
178+ // Function to calculate the coordinates for placing the link text.
138179 getLinkToTextCoordinates ( linkX : number , linkY : number , panX : number , panY : number , scale : number ) : { x : number , y : number } {
180+ // Apply scaling and panning to calculate the actual position.
139181 return { x : linkX * scale + panX , y : linkY * scale + panY } ;
140182 }
141183}
0 commit comments