@@ -34,6 +34,13 @@ import DetailDrawer from "./DetailDrawer";
34
34
import { SearchResult } from "../models/search-result" ;
35
35
import agent from "../api/agent" ;
36
36
import APISearchDrawer from "./APISearchDrawer" ;
37
+ import SpriteText from "three-spritetext" ;
38
+
39
+ type Coords = {
40
+ x : number ;
41
+ y : number ;
42
+ z : number ;
43
+ } ;
37
44
38
45
interface GraphViewerProps {
39
46
data : CustomGraphData ;
@@ -98,6 +105,7 @@ const GraphViewer: React.FC<GraphViewerProps> = ({
98
105
[ ]
99
106
) ;
100
107
const [ showLabels , setShowLabels ] = useState ( false ) ;
108
+ const [ showLinkLabels , setShowLinkLabels ] = useState ( false ) ;
101
109
const [ showHighlight , setShowHighlight ] = useState ( true ) ;
102
110
const graphRef = useRef < any > ( ) ;
103
111
const extraRenderers = [ new CSS2DRenderer ( ) as any as Renderer ] ;
@@ -432,16 +440,15 @@ const GraphViewer: React.FC<GraphViewerProps> = ({
432
440
if ( ! showLabels ) return ; // Only render the label if showLabels is true
433
441
434
442
const label = node . name || "" ;
435
- const fontSize = 10 ; // Smaller font size
436
- const padding = 2 ; // Adjust padding to fit the smaller font size
443
+ const fontSize = 4 ;
444
+ const padding = 2 ;
437
445
ctx . font = `${ fontSize } px Sans-Serif` ;
438
446
439
447
// Set the styles based on the theme mode
440
448
const backgroundColor =
441
449
theme . palette . mode === "dark"
442
450
? "rgba(0, 0, 0, 0.6)"
443
451
: "rgba(255, 255, 255, 0.6)" ;
444
- // const textColor = theme.palette.mode === "dark" ? "white" : "black";
445
452
446
453
// Calculate label dimensions
447
454
const textWidth = ctx . measureText ( label ) . width ;
@@ -546,7 +553,7 @@ const GraphViewer: React.FC<GraphViewerProps> = ({
546
553
zIndex : 1400 ,
547
554
display : "flex" ,
548
555
flexDirection : "column" ,
549
- gap : 1 , // Add some spacing between elements
556
+ gap : 2 ,
550
557
alignItems : "flex-end" ,
551
558
} }
552
559
>
@@ -558,23 +565,32 @@ const GraphViewer: React.FC<GraphViewerProps> = ({
558
565
>
559
566
Search Nodes/Links
560
567
</ Button >
561
- < FormControlLabel
568
+ { /* <FormControlLabel
562
569
control={
563
570
<Switch
564
571
checked={graphType === "3d"}
565
572
onChange={onToggleGraphType}
566
573
/>
567
574
}
568
575
label="3D View"
569
- />
570
- < FormControlLabel
576
+ /> */ }
577
+ { /* <FormControlLabel
571
578
control={
572
579
<Switch
573
580
checked={showLabels}
574
581
onChange={() => setShowLabels(!showLabels)}
575
582
/>
576
583
}
577
- label = "Show Labels"
584
+ label="Show Node Labels"
585
+ />
586
+ <FormControlLabel
587
+ control={
588
+ <Switch
589
+ checked={showLinkLabels}
590
+ onChange={() => setShowLinkLabels(!showLinkLabels)}
591
+ />
592
+ }
593
+ label="Show Relationship Labels"
578
594
/>
579
595
<FormControlLabel
580
596
control={
@@ -584,14 +600,60 @@ const GraphViewer: React.FC<GraphViewerProps> = ({
584
600
/>
585
601
}
586
602
label="Show Highlight"
587
- />
603
+ /> */ }
588
604
< Tooltip title = { isFullscreen ? "Exit Full Screen" : "Full Screen" } >
589
605
< IconButton onClick = { onToggleFullscreen } color = "inherit" >
590
606
{ isFullscreen ? < FullscreenExitIcon /> : < FullscreenIcon /> }
591
607
</ IconButton >
592
608
</ Tooltip >
593
609
</ Box >
594
610
611
+ < Box
612
+ sx = { {
613
+ display : "flex" ,
614
+ flexDirection : "column" ,
615
+ gap : 1 ,
616
+ alignItems : "flex-start" ,
617
+ } }
618
+ >
619
+ < FormControlLabel
620
+ control = {
621
+ < Switch
622
+ checked = { graphType === "3d" }
623
+ onChange = { onToggleGraphType }
624
+ />
625
+ }
626
+ label = "3D View"
627
+ />
628
+ < FormControlLabel
629
+ control = {
630
+ < Switch
631
+ checked = { showLabels }
632
+ onChange = { ( ) => setShowLabels ( ! showLabels ) }
633
+ />
634
+ }
635
+ label = "Show Node Labels"
636
+ />
637
+ < FormControlLabel
638
+ control = {
639
+ < Switch
640
+ checked = { showLinkLabels }
641
+ onChange = { ( ) => setShowLinkLabels ( ! showLinkLabels ) }
642
+ />
643
+ }
644
+ label = "Show Link Labels"
645
+ />
646
+ < FormControlLabel
647
+ control = {
648
+ < Switch
649
+ checked = { showHighlight }
650
+ onChange = { ( ) => setShowHighlight ( ! showHighlight ) }
651
+ />
652
+ }
653
+ label = "Show Highlight"
654
+ />
655
+ </ Box >
656
+
595
657
< FormGroup >
596
658
< FormControlLabel
597
659
control = {
@@ -721,6 +783,38 @@ const GraphViewer: React.FC<GraphViewerProps> = ({
721
783
renderNodeLabel ( node as CustomNode , ctx ) ;
722
784
}
723
785
} }
786
+ linkCanvasObjectMode = { ( ) => ( showLinkLabels ? "after" : undefined ) }
787
+ linkCanvasObject = { ( link , ctx ) => {
788
+ if ( showLinkLabels ) {
789
+ const label = link . type || "" ;
790
+ const fontSize = 4 ;
791
+ ctx . font = `${ fontSize } px Sans-Serif` ;
792
+ ctx . fillStyle =
793
+ theme . palette . mode === "dark" ? "lightgray" : "darkgray" ;
794
+ const source =
795
+ typeof link . source !== "string"
796
+ ? ( link . source as CustomNode )
797
+ : null ;
798
+ const target =
799
+ typeof link . target !== "string"
800
+ ? ( link . target as CustomNode )
801
+ : null ;
802
+
803
+ if (
804
+ source &&
805
+ target &&
806
+ source . x !== undefined &&
807
+ target . x !== undefined &&
808
+ source . y !== undefined &&
809
+ target . y !== undefined
810
+ ) {
811
+ const textWidth = ctx . measureText ( label ) . width ;
812
+ const posX = ( source . x + target . x ) / 2 - textWidth / 2 ;
813
+ const posY = ( source . y + target . y ) / 2 ;
814
+ ctx . fillText ( label , posX , posY ) ;
815
+ }
816
+ }
817
+ } }
724
818
onNodeHover = { showHighlight ? handleNodeHover : undefined }
725
819
onLinkHover = { showHighlight ? handleLinkHover : undefined }
726
820
onNodeClick = { handleNodeClick }
@@ -750,6 +844,27 @@ const GraphViewer: React.FC<GraphViewerProps> = ({
750
844
onLinkClick = { handleLinkClick }
751
845
backgroundColor = { getBackgroundColor ( ) }
752
846
linkColor = { get3DLinkColor }
847
+ linkThreeObjectExtend = { true }
848
+ linkThreeObject = { ( link ) => {
849
+ if ( ! showLinkLabels ) new THREE . Object3D ( ) ;
850
+ const sprite = new SpriteText ( `${ link . type } ` ) ;
851
+ sprite . color = "lightgrey" ;
852
+ sprite . textHeight = 1.5 ;
853
+ return sprite ;
854
+ } }
855
+ linkPositionUpdate = { ( sprite , { start, end } ) => {
856
+ if ( ! showLinkLabels ) return ;
857
+
858
+ const middlePos = [ "x" , "y" , "z" ] . reduce ( ( acc , c ) => {
859
+ acc [ c as keyof Coords ] =
860
+ start [ c as keyof Coords ] +
861
+ ( end [ c as keyof Coords ] - start [ c as keyof Coords ] ) / 2 ;
862
+ return acc ;
863
+ } , { } as Coords ) ;
864
+
865
+ // Position sprite
866
+ Object . assign ( sprite . position , middlePos ) ;
867
+ } }
753
868
/>
754
869
) }
755
870
< Box
0 commit comments