Skip to content

Commit 335892e

Browse files
authored
Merge pull request #11 from noworneverev/feature/show-label
Add show link labels and improve layout
2 parents fb61b30 + f3351b8 commit 335892e

File tree

3 files changed

+143
-9
lines changed

3 files changed

+143
-9
lines changed

package-lock.json

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"react-scripts": "5.0.1",
3030
"react-table": "^7.8.0",
3131
"three": "^0.167.1",
32+
"three-spritetext": "^1.8.2",
3233
"typescript": "^4.9.5",
3334
"web-vitals": "^2.1.4"
3435
},

src/app/components/GraphViewer.tsx

Lines changed: 124 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ import DetailDrawer from "./DetailDrawer";
3434
import { SearchResult } from "../models/search-result";
3535
import agent from "../api/agent";
3636
import APISearchDrawer from "./APISearchDrawer";
37+
import SpriteText from "three-spritetext";
38+
39+
type Coords = {
40+
x: number;
41+
y: number;
42+
z: number;
43+
};
3744

3845
interface GraphViewerProps {
3946
data: CustomGraphData;
@@ -98,6 +105,7 @@ const GraphViewer: React.FC<GraphViewerProps> = ({
98105
[]
99106
);
100107
const [showLabels, setShowLabels] = useState(false);
108+
const [showLinkLabels, setShowLinkLabels] = useState(false);
101109
const [showHighlight, setShowHighlight] = useState(true);
102110
const graphRef = useRef<any>();
103111
const extraRenderers = [new CSS2DRenderer() as any as Renderer];
@@ -432,16 +440,15 @@ const GraphViewer: React.FC<GraphViewerProps> = ({
432440
if (!showLabels) return; // Only render the label if showLabels is true
433441

434442
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;
437445
ctx.font = `${fontSize}px Sans-Serif`;
438446

439447
// Set the styles based on the theme mode
440448
const backgroundColor =
441449
theme.palette.mode === "dark"
442450
? "rgba(0, 0, 0, 0.6)"
443451
: "rgba(255, 255, 255, 0.6)";
444-
// const textColor = theme.palette.mode === "dark" ? "white" : "black";
445452

446453
// Calculate label dimensions
447454
const textWidth = ctx.measureText(label).width;
@@ -546,7 +553,7 @@ const GraphViewer: React.FC<GraphViewerProps> = ({
546553
zIndex: 1400,
547554
display: "flex",
548555
flexDirection: "column",
549-
gap: 1, // Add some spacing between elements
556+
gap: 2,
550557
alignItems: "flex-end",
551558
}}
552559
>
@@ -558,23 +565,32 @@ const GraphViewer: React.FC<GraphViewerProps> = ({
558565
>
559566
Search Nodes/Links
560567
</Button>
561-
<FormControlLabel
568+
{/* <FormControlLabel
562569
control={
563570
<Switch
564571
checked={graphType === "3d"}
565572
onChange={onToggleGraphType}
566573
/>
567574
}
568575
label="3D View"
569-
/>
570-
<FormControlLabel
576+
/> */}
577+
{/* <FormControlLabel
571578
control={
572579
<Switch
573580
checked={showLabels}
574581
onChange={() => setShowLabels(!showLabels)}
575582
/>
576583
}
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"
578594
/>
579595
<FormControlLabel
580596
control={
@@ -584,14 +600,60 @@ const GraphViewer: React.FC<GraphViewerProps> = ({
584600
/>
585601
}
586602
label="Show Highlight"
587-
/>
603+
/> */}
588604
<Tooltip title={isFullscreen ? "Exit Full Screen" : "Full Screen"}>
589605
<IconButton onClick={onToggleFullscreen} color="inherit">
590606
{isFullscreen ? <FullscreenExitIcon /> : <FullscreenIcon />}
591607
</IconButton>
592608
</Tooltip>
593609
</Box>
594610

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+
595657
<FormGroup>
596658
<FormControlLabel
597659
control={
@@ -721,6 +783,38 @@ const GraphViewer: React.FC<GraphViewerProps> = ({
721783
renderNodeLabel(node as CustomNode, ctx);
722784
}
723785
}}
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+
}}
724818
onNodeHover={showHighlight ? handleNodeHover : undefined}
725819
onLinkHover={showHighlight ? handleLinkHover : undefined}
726820
onNodeClick={handleNodeClick}
@@ -750,6 +844,27 @@ const GraphViewer: React.FC<GraphViewerProps> = ({
750844
onLinkClick={handleLinkClick}
751845
backgroundColor={getBackgroundColor()}
752846
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+
}}
753868
/>
754869
)}
755870
<Box

0 commit comments

Comments
 (0)