Skip to content

Commit ba61df0

Browse files
author
Martarion-Code
committed
Improve UI of the app
I tried to change the appeareance of the nodes and content or label inside the nodes. I also add gap for buttons inside panel. I also remove the draggable feature of the nodes, because everytime user drag the node, fitView will get executed so that everytime user drag the node the viewport zoom to root node
1 parent 2af3859 commit ba61df0

File tree

5 files changed

+182
-67
lines changed

5 files changed

+182
-67
lines changed

src/App.css

Lines changed: 88 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,128 @@
1-
/* #root {
2-
max-width: 1280px;
3-
margin: 0 auto;
4-
padding: 2rem;
5-
text-align: center;
6-
}
7-
8-
.logo {
9-
height: 6em;
10-
padding: 1.5em;
11-
will-change: filter;
12-
transition: filter 300ms;
13-
}
14-
.logo:hover {
15-
filter: drop-shadow(0 0 2em #646cffaa);
16-
}
17-
.logo.react:hover {
18-
filter: drop-shadow(0 0 2em #61dafbaa);
19-
}
20-
21-
@keyframes logo-spin {
22-
from {
23-
transform: rotate(0deg);
24-
}
25-
to {
26-
transform: rotate(360deg);
27-
}
28-
}
291

30-
@media (prefers-reduced-motion: no-preference) {
31-
a:nth-of-type(2) .logo {
32-
animation: logo-spin infinite 20s linear;
33-
}
34-
}
352

36-
.card {
37-
padding: 2em;
3+
:root {
4+
--bg-sidebar-clr: #313131;
385
}
396

40-
.read-the-docs {
41-
color: #888;
42-
} */
43-
44-
html{
7+
html {
458
font-size: 16px;
469
}
4710

48-
.body{
11+
.body {
4912
margin: 0;
5013
padding: 0;
5114
}
5215

53-
.app-cont{
16+
.app-cont {
5417
width: 100vw;
5518
height: 100vh;
5619
display: flex;
5720
flex-direction: row-reverse;
5821
}
5922

60-
.sidebar{
23+
.sidebar {
6124
width: 20vw;
6225
min-height: 100vh;
63-
background-color: #1a1a1a;
26+
background-color: var(--bg-sidebar-clr);
6427
color: #fff;
6528
display: flex;
6629
flex-direction: column;
6730
}
6831

69-
.sidebar__text-cont{
32+
.sidebar__text-cont {
7033
flex-grow: 1;
71-
background: #313131;
34+
background: var(--bg-sidebar-clr);
7235
outline: none;
7336
border: none;
7437
flex-shrink: 1;
7538
color: #fff;
76-
font-size: .8rem;
77-
padding: .7rem;
39+
font-size: 0.8rem;
40+
padding: 0.7rem;
7841
}
79-
.sidebar__title-cont{
42+
.sidebar__title-cont {
8043
display: flex;
8144
justify-content: space-between;
8245
align-items: center;
8346
padding: 0 10px;
84-
8547
}
86-
.sidebar__title-cont h1{
48+
.sidebar__title-cont h1 {
8749
font-size: 1.3rem;
8850
}
8951

90-
91-
92-
.sidebar__title-cont button{
52+
.sidebar__title-cont button {
9353
margin: 1rem 0;
9454
font-size: 0.9rem;
95-
}
55+
}
56+
57+
.react-flow {
58+
background-color: #202021;
59+
}
60+
61+
.react-flow__background {
62+
color: #2f2f2f;
63+
}
64+
.react-flow__node {
65+
background: transparent;
66+
}
67+
68+
.react-flow__node-jsonVis {
69+
70+
background-color: transparent;
71+
position: relative;
72+
width: 200px;
73+
min-height: 50px;
74+
display: flex;
75+
justify-content: center;
76+
77+
}
78+
79+
.react-flow__handle {
80+
81+
opacity: 0;
82+
}
83+
84+
.react-flow__handle-top {
85+
top: 5% !important;
86+
}
87+
88+
.react-flow__handle-bottom {
89+
bottom: 5% !important;
90+
}
91+
92+
.react-flow__handle-right {
93+
right: 2% !important;
94+
}
95+
96+
.react-flow__handle-left {
97+
left: 2% !important;
98+
}
99+
100+
.react-flow__panel-1 {
101+
display: flex;
102+
gap: 2vw;
103+
}
104+
105+
.react-flow__node-jsonVis ul {
106+
list-style-type: none;
107+
padding: 0;
108+
margin: 0;
109+
}
110+
111+
.jsonVisNode__label{
112+
position: absolute;
113+
left: 0;
114+
top: 50%;
115+
transform: translateY(-50%);
116+
width: 200px;;
117+
display: flex;
118+
flex-wrap: wrap;
119+
color: #fff;
120+
padding: 1rem;
121+
border-radius: 10px;
122+
background-color: var(--bg-sidebar-clr);
123+
}
124+
125+
.jsonVisNode__label__key{
126+
color:#c39c6b;
127+
font-weight: 600;
128+
}

src/App.jsx

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,17 @@ import {
88
useReactFlow,
99
Panel,
1010
} from "reactflow";
11+
import JsonVisNode from "./Custom Nodes/jsonVisNode";
12+
13+
// we define the nodeTypes outside of the component to prevent re-renderings
14+
// you could also use useMemo inside the component
15+
const nodeTypes = { jsonVis: JsonVisNode };
16+
const edgeTypes = {
17+
jsonVis: JsonVisEdge,
18+
};
19+
20+
const defaultEdgeOpt = {type: 'jsonVis'}
21+
1122

1223
import { shallow } from "zustand/shallow";
1324

@@ -19,6 +30,7 @@ import convertJsonToTree from "./utils/convertJsonToTree";
1930
import convertTreeToNodes from "./utils/convertTreeToNodes";
2031

2132
import "reactflow/dist/style.css";
33+
import JsonVisEdge from "./Custom Edges/JsonVisEdge";
2234

2335
/**
2436
* Select which variable or func that will get used from store
@@ -42,8 +54,8 @@ const elk = new ELK();
4254
//Elk options for layouting the tree
4355
const elkOptions = {
4456
"elk.algorithm": "layered",
45-
"elk.layered.spacing.nodeNodeBetweenLayers": "100",
46-
"elk.spacing.nodeNode": "80",
57+
"elk.layered.spacing.nodeNodeBetweenLayers": "200",
58+
"elk.spacing.nodeNode": "150",
4759
"elk.edgeRouting": "SPLINES",
4860
};
4961

@@ -56,6 +68,7 @@ const elkOptions = {
5668
*/
5769
const getLayoutedElements = (nodes, edges, options = {}) => {
5870
const isHorizontal = options?.["elk.direction"] === "RIGHT";
71+
console.log(isHorizontal)
5972
const graph = {
6073
id: "root",
6174
layoutOptions: options,
@@ -64,14 +77,15 @@ const getLayoutedElements = (nodes, edges, options = {}) => {
6477
...node,
6578
targetPosition: isHorizontal ? "left" : "top",
6679
sourcePosition: isHorizontal ? "right" : "bottom",
67-
6880
//Hardcode a width and height for node so that elk can use it when layouting.
6981
width: 150,
7082
height: 50,
7183
})),
7284
edges: edges,
7385
};
7486

87+
// console.log(graph);
88+
7589
//Return promises
7690
return elk
7791
.layout(graph)
@@ -93,8 +107,8 @@ function App() {
93107
edges,
94108
setNodes,
95109
setEdges,
96-
onNodesChange,
97-
onEdgesChange,
110+
// onNodesChange,
111+
// onEdgesChange,
98112
needToRenderJson,
99113
} = useStore(selector, shallow);
100114

@@ -127,6 +141,8 @@ function App() {
127141
[nodes, edges] //So that the useCallback will rememoize the nodes and edges variable if it values changed.
128142
);
129143

144+
console.log(nodes);
145+
130146
//It will render before "layout" phase happening when rendering page. So that the page will outputing layouted nodes and edges
131147
useLayoutEffect(() => {
132148
const nodeTree = convertJsonToTree(needToRenderJson); //to convert json to tree
@@ -151,13 +167,16 @@ function App() {
151167
<ReactFlow
152168
nodes={nodes}
153169
edges={edges}
154-
onNodesChange={onNodesChange}
155-
onEdgesChange={onEdgesChange}
170+
// onNodesChange={onNodesChange}
171+
// onEdgesChange={onEdgesChange}
172+
nodeTypes={nodeTypes}
173+
edgeTypes={edgeTypes}
174+
defaultEdgeOptions={defaultEdgeOpt}
156175
>
157-
<Background gap={20} variant={BackgroundVariant.Lines}></Background>
176+
<Background gap={30} color={'#373737'} variant={BackgroundVariant.Lines}></Background>
158177
<Controls showInteractive={false}></Controls>
159-
<Panel position="top-right">
160-
<button onClick={() => onLayout({ direction: "DOWN" })}>
178+
<Panel position="top-right" className="react-flow__panel-1">
179+
<button onClick={() => onLayout({ direction: "DOWN" })} className="panel__btn">
161180
vertical layout
162181
</button>
163182

src/Custom Edges/JsonVisEdge.jsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { BaseEdge, getBezierPath } from 'reactflow';
2+
3+
function JsonVisEdge(props) {
4+
// eslint-disable-next-line react/prop-types
5+
const { sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition } = props;
6+
const [edgePath] = getBezierPath({
7+
sourceX,
8+
sourceY,
9+
sourcePosition, targetPosition,
10+
targetX,
11+
targetY,
12+
});
13+
14+
return <BaseEdge path={edgePath} {...props} />;
15+
}
16+
17+
export default JsonVisEdge;

src/Custom Nodes/JsonVisNode.jsx

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/* eslint-disable react/prop-types */
2+
3+
import {Handle} from 'reactflow';
4+
5+
// eslint-disable-next-line react/prop-types
6+
function JsonVisNode({data, targetPosition, sourcePosition}){
7+
8+
// console.log
9+
// console.log(data.label);
10+
let str;
11+
if(typeof data.label === 'object'){
12+
str = Object.entries(data.label);
13+
}else{
14+
str = data.label;
15+
}
16+
17+
// console.log(str);
18+
19+
// const strArr = (typeof data.label === 'object' ) ? data.label?.split(',')
20+
// console.log(strArr)
21+
return (
22+
<>
23+
<Handle type="target" position={targetPosition} ></Handle>
24+
<div className='jsonVisNode__label'>
25+
<ul>
26+
{
27+
(typeof data.label === 'object') ?
28+
Object.entries(data.label).map(([key, value], index) =>(
29+
<li key={index}>
30+
<span className="jsonVisNode__label__key">{key} : </span>
31+
<span>{String(value)}</span>
32+
</li>
33+
)) : str
34+
}
35+
</ul>
36+
</div>
37+
<Handle type="source" position={sourcePosition} ></Handle>
38+
</>
39+
40+
)
41+
}
42+
43+
44+
export default JsonVisNode;

src/utils/convertTreeToNodes.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ let edges = [];
66
function addRootNode(node) {
77
const newNode = {
88
id: node.id,
9-
data: { label: JSON.stringify(node.value) },
9+
data: { label: node.value },
1010
position: { x: 0, y: 0 },
11+
type: 'jsonVis',
1112
};
1213

1314
nodes = [...nodes, newNode];
@@ -20,8 +21,9 @@ function addChildNode(node, parentNode) {
2021
label:
2122
typeof node.value === "string" || typeof node.value === "number"
2223
? node.value
23-
: JSON.stringify(node.value),
24+
: node.value,
2425
},
26+
type: 'jsonVis',
2527
position: { x: 0, y: 0 },
2628
parent: parentNode.id,
2729
};

0 commit comments

Comments
 (0)