feat: add 3D toggle and adjust theme

This commit is contained in:
julius 2025-02-20 17:26:27 +01:00
parent 5405c3e12f
commit 13bb965b28
Signed by: julius
GPG Key ID: C80A63E6A5FD7092
3 changed files with 171 additions and 13 deletions

View File

@ -23,6 +23,77 @@ footer {
font-size: x-small;
}
.controls {
z-index: 9;
position: absolute;
top: 24;
left: 24;
padding: 16px;
.control {
display: flex;
flex-direction: row;
* {
margin: 0 4px;
}
}
}
/* The switch - the box around the slider */
.switch {
position: relative;
width: 68px;
height: 34px;
}
/* Hide default HTML checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
border-radius: 34px;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
border-radius: 50%;
-webkit-transition: .4s;
transition: .4s;
}
input:checked+.slider {
background-color: #2196F3;
}
input:focus+.slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked+.slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
.grey {
color: #444;

View File

@ -1,6 +1,7 @@
import { useEffect, useRef, useState } from "react";
import { ChangeEvent, useEffect, useRef, useState } from "react";
import { apiAuth } from "./api";
import { GraphCanvas, GraphCanvasRef, GraphEdge, GraphNode, useSelection } from "reagraph";
import { GraphCanvas, GraphCanvasRef, GraphEdge, GraphNode, recommendLayout, useSelection } from "reagraph";
import { customTheme } from "./NetworkTheme";
interface NetworkData {
nodes: GraphNode[],
@ -10,6 +11,7 @@ interface NetworkData {
export const GraphComponent = () => {
const [data, setData] = useState({ nodes: [], edges: [] } as NetworkData);
const [loading, setLoading] = useState(true);
const [threed, setThreed] = useState(false);
async function loadData() {
setLoading(true);
@ -26,13 +28,38 @@ export const GraphComponent = () => {
ref: graphRef,
nodes: data.nodes,
edges: data.edges,
pathSelectionType: 'out'
pathSelectionType: 'out',
});
function handleThreed() {
setThreed(!threed)
graphRef.current?.fitNodesInView();
graphRef.current?.centerGraph();
graphRef.current?.resetControls();
}
return (
<div style={{ position: 'absolute', top: 0, bottom: 0, left: 0, right: 0 }}>
<div className="controls" >
<div className="control" onClick={handleThreed}>
<span>2D</span>
<div className="switch">
<input type="checkbox" checked={threed} />
<span className="slider round"></span>
</div>
<span>3D</span>
</div>
</div>
<GraphCanvas
draggable
cameraMode={threed ? "rotate" : "pan"}
layoutType={threed ? "forceDirected3d" : "forceDirected2d"}
layoutOverrides={{
linkDistance: 200
}}
labelType="auto"
ref={graphRef}
theme={customTheme}
nodes={data.nodes}
edges={data.edges}
selections={selections}
@ -40,6 +67,7 @@ export const GraphComponent = () => {
onCanvasClick={onCanvasClick}
onNodeClick={onNodeClick}
/>
</div>
);
}

59
src/NetworkTheme.tsx Normal file
View File

@ -0,0 +1,59 @@
import { Theme } from "reagraph";
export const customTheme: Theme = {
canvas: {
background: 'aliceblue',
},
node: {
fill: '#69F',
activeFill: '#36C',
opacity: 1,
selectedOpacity: 1,
inactiveOpacity: 0.333,
label: {
color: '#404040',
stroke: 'white',
activeColor: 'black'
},
subLabel: {
color: '#ddd',
stroke: 'transparent',
activeColor: '#1DE9AC'
}
},
lasso: {
border: '1px solid #55aaff',
background: 'rgba(75, 160, 255, 0.1)'
},
ring: {
fill: '#69F',
activeFill: '#36C'
},
edge: {
fill: '#bed4ff',
activeFill: '#36C',
opacity: 1,
selectedOpacity: 1,
inactiveOpacity: 0.2,
label: {
stroke: '#fff',
color: '#2A6475',
activeColor: '#1DE9AC',
fontSize: 6
}
},
arrow: {
fill: '#bed4ff',
activeFill: '#36C'
},
cluster: {
stroke: '#D8E6EA',
opacity: 1,
selectedOpacity: 1,
inactiveOpacity: 0.1,
label: {
stroke: '#fff',
color: '#2A6475'
}
}
};