feat: add 3D toggle and adjust theme
This commit is contained in:
parent
5405c3e12f
commit
13bb965b28
71
src/App.css
71
src/App.css
@ -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;
|
||||
|
@ -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,20 +28,46 @@ 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 (
|
||||
<GraphCanvas
|
||||
draggable
|
||||
ref={graphRef}
|
||||
nodes={data.nodes}
|
||||
edges={data.edges}
|
||||
selections={selections}
|
||||
actives={actives}
|
||||
onCanvasClick={onCanvasClick}
|
||||
onNodeClick={onNodeClick}
|
||||
/>
|
||||
<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}
|
||||
actives={actives}
|
||||
onCanvasClick={onCanvasClick}
|
||||
onNodeClick={onNodeClick}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
}
|
||||
|
59
src/NetworkTheme.tsx
Normal file
59
src/NetworkTheme.tsx
Normal 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'
|
||||
}
|
||||
}
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user