11
2- import { ObsidianRenderer , ObsidianLink , LinkPair , GltLink , DataviewLinkType } from 'src/types' ;
2+ import { ObsidianRenderer , ObsidianLink , LinkPair , GltLink , DataviewLinkType , GltLegendGraphic } from 'src/types' ;
33import { getAPI } from 'obsidian-dataview' ;
4- import { Text , TextStyle , Graphics } from 'pixi.js' ;
4+ import { Text , TextStyle , Graphics , Color } from 'pixi.js' ;
55// @ts -ignore
66import extractLinks from 'markdown-link-extractor' ;
77
@@ -11,7 +11,7 @@ export class LinkManager {
1111 api = getAPI ( ) ;
1212 currentTheme : string ;
1313 textColor : string ;
14- tagColors : Map < string , number > ;
14+ tagColors : Map < string , GltLegendGraphic > ;
1515 categoricalColors : number [ ] = [
1616 0xF44336 , // Red
1717 0x03A9F4 , // Light Blue
@@ -46,7 +46,7 @@ export class LinkManager {
4646
4747 constructor ( ) {
4848 this . linksMap = new Map < string , GltLink > ( ) ;
49- this . tagColors = new Map < string , number > ( ) ;
49+ this . tagColors = new Map < string , GltLegendGraphic > ( ) ;
5050
5151 // Detect changes to the theme.
5252 this . detectThemeChange ( ) ;
@@ -106,15 +106,15 @@ export class LinkManager {
106106 }
107107 }
108108
109- addLink ( renderer : ObsidianRenderer , obLink : ObsidianLink , tagColors : boolean ) : void {
109+ addLink ( renderer : ObsidianRenderer , obLink : ObsidianLink , tagColors : boolean , tagLegend : boolean ) : void {
110110 const key = this . generateKey ( obLink . source . id , obLink . target . id ) ;
111111 const reverseKey = this . generateKey ( obLink . target . id , obLink . source . id ) ;
112112 const pairStatus = ( obLink . source . id !== obLink . target . id ) && this . linksMap . has ( reverseKey ) ? LinkPair . Second : LinkPair . None ;
113113 const newLink : GltLink = {
114114 obsidianLink : obLink ,
115115 pairStatus : pairStatus ,
116116 pixiText : this . initializeLinkText ( renderer , obLink , pairStatus ) ,
117- pixiGraphics : tagColors ? this . initializeLinkGraphics ( renderer , obLink , pairStatus ) : null ,
117+ pixiGraphics : tagColors ? this . initializeLinkGraphics ( renderer , obLink , tagLegend ) : null ,
118118 } ;
119119
120120 this . linksMap . set ( key , newLink ) ;
@@ -133,9 +133,7 @@ export class LinkManager {
133133
134134 const gltLink = this . linksMap . get ( key ) ;
135135
136- let text ;
137136 if ( gltLink && gltLink . pixiText && renderer . px && renderer . px . stage && renderer . px . stage . children && renderer . px . stage . children . includes ( gltLink . pixiText ) ) {
138- text = gltLink . pixiText . text ;
139137 renderer . px . stage . removeChild ( gltLink . pixiText ) ;
140138 gltLink . pixiText . destroy ( ) ;
141139 }
@@ -145,12 +143,27 @@ export class LinkManager {
145143 gltLink . pixiGraphics . destroy ( ) ;
146144 }
147145
148- let colorKey = text ?. replace ( / \r ? \n / g, "" ) ;
146+ let colorKey = gltLink ?. pixiText ?. text ?. replace ( / \r ? \n / g, "" ) ;
149147 if ( colorKey ) {
150148 if ( this . tagColors . has ( colorKey ) ) {
151- this . tagColors . delete ( colorKey ) ;
152- this . yOffset -= this . lineHeight ;
153- this . currentTagColorIndex -= 1 ;
149+ const legendGraphic = this . tagColors . get ( colorKey ) ;
150+ if ( legendGraphic ) {
151+ legendGraphic . nUsing -= 1 ;
152+ if ( legendGraphic . nUsing < 1 ) {
153+ this . yOffset -= this . lineHeight ;
154+ this . currentTagColorIndex -= 1 ;
155+ if ( this . currentTagColorIndex < 0 ) this . currentTagColorIndex = this . categoricalColors . length - 1 ;
156+ if ( legendGraphic . legendText && renderer . px && renderer . px . stage && renderer . px . stage . children && renderer . px . stage . children . includes ( legendGraphic . legendText ) ) {
157+ renderer . px . stage . removeChild ( legendGraphic . legendText ) ;
158+ legendGraphic . legendText . destroy ( ) ;
159+ }
160+ if ( legendGraphic . legendGraphics && renderer . px && renderer . px . stage && renderer . px . stage . children && renderer . px . stage . children . includes ( legendGraphic . legendGraphics ) ) {
161+ renderer . px . stage . removeChild ( legendGraphic . legendGraphics ) ;
162+ legendGraphic . legendGraphics . destroy ( ) ;
163+ }
164+ this . tagColors . delete ( colorKey ) ;
165+ }
166+ }
154167 }
155168 }
156169
@@ -181,7 +194,7 @@ export class LinkManager {
181194 }
182195
183196 // Update the position of the text on the graph
184- updateLinkText ( renderer : ObsidianRenderer , link : ObsidianLink ) : void {
197+ updateLinkText ( renderer : ObsidianRenderer , link : ObsidianLink , tagNames : boolean ) : void {
185198 if ( ! renderer || ! link || ! link . source || ! link . target ) {
186199 // If any of these are null, exit the function
187200 return ;
@@ -198,7 +211,6 @@ export class LinkManager {
198211 // Calculate the mid-point of the link
199212 const midX : number = ( link . source . x + link . target . x ) / 2 ;
200213 const midY : number = ( link . source . y + link . target . y ) / 2 ;
201-
202214 // Transform the mid-point coordinates based on the renderer's pan and scale
203215 const { x, y } = this . getLinkToTextCoordinates ( midX , midY , renderer . panX , renderer . panY , renderer . scale ) ;
204216 if ( text && renderer . px && renderer . px . stage && renderer . px . stage . children && renderer . px . stage . children . includes ( text ) ) {
@@ -207,6 +219,11 @@ export class LinkManager {
207219 text . y = y ;
208220 text . scale . set ( 1 / ( 3 * renderer . nodeScale ) ) ;
209221 text . style . fill = this . textColor ;
222+ if ( tagNames ) {
223+ text . alpha = 0.9 ;
224+ } else {
225+ text . alpha = 0.0 ;
226+ }
210227 }
211228 }
212229
@@ -227,45 +244,24 @@ export class LinkManager {
227244 let { nx, ny} = this . calculateNormal ( link . source . x , link . source . y , link . target . x , link . target . y ) ;
228245 let { px, py} = this . calculateParallel ( link . source . x , link . source . y , link . target . x , link . target . y ) ;
229246
230- nx *= Math . sqrt ( renderer . scale ) ;
231- ny *= Math . sqrt ( renderer . scale ) ;
247+ nx *= 1.5 * Math . sqrt ( renderer . scale ) ;
248+ ny *= 1.5 * Math . sqrt ( renderer . scale ) ;
232249
233250 px *= 8 * Math . sqrt ( renderer . scale ) ;
234251 py *= 8 * Math . sqrt ( renderer . scale ) ;
235252
236253
237254 let { x :x1 , y :y1 } = this . getLinkToTextCoordinates ( link . source . x , link . source . y , renderer . panX , renderer . panY , renderer . scale ) ;
238255 let { x :x2 , y :y2 } = this . getLinkToTextCoordinates ( link . target . x , link . target . y , renderer . panX , renderer . panY , renderer . scale ) ;
239- x1 += nx + px ;
240- x2 += nx - px ;
241- y1 += ny + py ;
242- y2 += ny - py ;
243-
244-
245-
246- let color ;
247-
248- // Get the text to display for the link
249- let linkString : string | null = this . getMetadataKeyForLink ( link . source . id , link . target . id ) ;
250- if ( linkString === null ) {
251-
252- } else {
253-
254-
255- if ( link . source . id === link . target . id ) {
256- linkString = "" ;
257- }
258-
259-
260- if ( ! this . tagColors . has ( linkString ) ) {
261- color = 0x000000 ;
262- } else {
263- color = this . tagColors . get ( linkString ) ;
264- }
265- }
256+ x1 += nx + ( link . source . weight / 36 + 1 ) * px ;
257+ x2 += nx - ( link . target . weight / 36 + 1 ) * px ;
258+ y1 += ny + ( link . source . weight / 36 + 1 ) * py ;
259+ y2 += ny - ( link . target . weight / 36 + 1 ) * py ;
266260
267261
268262 if ( graphics && renderer . px && renderer . px . stage && renderer . px . stage . children && renderer . px . stage . children . includes ( graphics ) ) {
263+ // @ts -ignore
264+ const color = graphics . _lineStyle . color ;
269265 // Now, update the line whenever needed without creating a new graphics object each time
270266 graphics . clear ( ) ; // Clear the previous drawing to prepare for the update
271267 graphics . lineStyle ( 3 / Math . sqrt ( renderer . nodeScale ) , color ) ; // Set the line style (width: 2px, color: black, alpha: 1)
@@ -297,7 +293,6 @@ export class LinkManager {
297293
298294 }
299295
300-
301296 // Define the style for the text
302297 const textStyle : TextStyle = new TextStyle ( {
303298 fontFamily : 'Arial' ,
@@ -308,39 +303,35 @@ export class LinkManager {
308303 const text : Text = new Text ( linkString , textStyle ) ;
309304
310305 text . zIndex = 1 ;
311- text . alpha = 0.9 ;
312306 text . anchor . set ( 0.5 , 0.5 ) ;
313307
314308
315309
316- this . updateLinkText ( renderer , link ) ;
310+ this . updateLinkText ( renderer , link , false ) ;
317311 renderer . px . stage . addChild ( text ) ;
318312
319313 return text
320314 }
321315
322316 // Create or update text for a given link
323- private initializeLinkGraphics ( renderer : ObsidianRenderer , link : ObsidianLink , pairStatus : LinkPair ) : Graphics | null {
317+ private initializeLinkGraphics ( renderer : ObsidianRenderer , link : ObsidianLink , tagLegend : boolean ) : Graphics | null {
324318
325319 // Get the text to display for the link
326320 let linkString : string | null = this . getMetadataKeyForLink ( link . source . id , link . target . id ) ;
327321 if ( linkString === null ) {
328322 return null ;
329323 } //doesn't add if link is null
330324
325+ let color ;
331326
332327 if ( link . source . id === link . target . id ) {
333328 linkString = "" ;
334329 } else {
335330
336- let color ;
337331
338-
339-
340-
341- if ( ! this . tagColors . has ( linkString ) ) {
332+ if ( ! this . tagColors . has ( linkString ) ) { // this tag is not in the map yet
342333 color = this . categoricalColors [ this . currentTagColorIndex ] ;
343- this . tagColors . set ( linkString , color ) ;
334+
344335 // Increment and wrap the index to cycle through colors
345336 this . currentTagColorIndex = ( this . currentTagColorIndex + 1 ) % this . categoricalColors . length ;
346337
@@ -359,13 +350,34 @@ export class LinkManager {
359350 graphicsL . lineTo ( lineStartX + this . lineLength , this . yOffset + ( this . lineHeight / 2 ) ) ; // 40 pixels wide line
360351 renderer . px . stage . addChild ( graphicsL ) ;
361352 this . yOffset += this . lineHeight ;
362- } else {
363- color = this . tagColors . get ( linkString ) ;
353+
354+ if ( ! tagLegend ) {
355+ graphicsL . alpha = 0.0 ;
356+ textL . alpha = 0.0 ;
357+ }
358+ const newLegendGraphic : GltLegendGraphic = {
359+ color : color ,
360+ legendText : textL ,
361+ legendGraphics : graphicsL ,
362+ nUsing : 0 ,
363+ } ;
364+
365+ this . tagColors . set ( linkString , newLegendGraphic ) ;
366+ } else { // this tag is in the map already
367+ const legendGraphic = this . tagColors . get ( linkString )
368+
369+ if ( legendGraphic ) {
370+ color = legendGraphic ?. color ;
371+ legendGraphic . nUsing += 1 ;
372+ } else {
373+ color = 0xFFFFFF ;
374+ }
364375 }
365376 }
366377
367378
368379 const graphics = new Graphics ( ) ;
380+ graphics . lineStyle ( 3 / Math . sqrt ( renderer . nodeScale ) , color )
369381 graphics . zIndex = 0 ;
370382 renderer . px . stage . addChild ( graphics ) ; // Add the line to the stage
371383
@@ -401,29 +413,8 @@ export class LinkManager {
401413 // Remove all text nodes from the graph
402414 destroyMap ( renderer : ObsidianRenderer ) : void {
403415 if ( this . linksMap . size > 0 ) {
404- this . linksMap . forEach ( ( gltLink , linkKey ) => {
405- let text ;
406- if ( gltLink && gltLink . pixiText && renderer . px && renderer . px . stage && renderer . px . stage . children && renderer . px . stage . children . includes ( gltLink . pixiText ) ) {
407- text = gltLink . pixiText . text ;
408- renderer . px . stage . removeChild ( gltLink . pixiText ) ;
409- gltLink . pixiText . destroy ( ) ;
410- }
411-
412- if ( gltLink && gltLink . pixiGraphics && renderer . px && renderer . px . stage && renderer . px . stage . children && renderer . px . stage . children . includes ( gltLink . pixiGraphics ) ) {
413- renderer . px . stage . removeChild ( gltLink . pixiGraphics ) ;
414- gltLink . pixiGraphics . destroy ( ) ;
415- }
416-
417- let colorKey = text ?. replace ( / \r ? \n / g, "" ) ;
418- if ( colorKey ) {
419- if ( this . tagColors . has ( colorKey ) ) {
420- this . tagColors . delete ( colorKey ) ;
421- this . yOffset -= this . lineHeight ;
422- this . currentTagColorIndex -= 1 ;
423- }
424- }
425-
426- this . linksMap . delete ( linkKey ) ;
416+ this . linksMap . forEach ( ( gltLink , linkKey ) => {
417+ this . removeLink ( renderer , gltLink . obsidianLink )
427418 } ) ;
428419 }
429420 }
0 commit comments