From ec871e5fec02c2908c409d17e57b1411e5d81b28 Mon Sep 17 00:00:00 2001 From: AykutSarac Date: Wed, 8 Feb 2023 23:10:33 +0300 Subject: [PATCH] refactor: improve parser readability --- src/components/CustomNode/TextNode.tsx | 22 +++++++---- src/components/CustomNode/styles.tsx | 10 +++-- src/components/Sidebar/index.tsx | 1 - src/store/useGraph.tsx | 2 +- src/typings/types.d.ts | 2 +- src/utils/core/addNodeToGraph.ts | 53 ++++++++++++++------------ src/utils/core/jsonParser.ts | 52 +++++++++++-------------- src/utils/core/traverse.ts | 21 ++++------ 8 files changed, 80 insertions(+), 83 deletions(-) diff --git a/src/components/CustomNode/TextNode.tsx b/src/components/CustomNode/TextNode.tsx index d5af5e4..16ff9e3 100644 --- a/src/components/CustomNode/TextNode.tsx +++ b/src/components/CustomNode/TextNode.tsx @@ -41,10 +41,16 @@ const StyledImage = styled.img` `; const TextNode: React.FC = ({ node, x, y, hasCollapse = false }) => { - const { id, text, width, height, data } = node; + const { + id, + text, + width, + height, + data: { isParent, childrenCount, type }, + } = node; const ref = React.useRef(null); const hideCollapse = useStored(state => state.hideCollapse); - const childrenCount = useStored(state => state.childrenCount); + const showChildrenCount = useStored(state => state.childrenCount); const imagePreview = useStored(state => state.imagePreview); const expandNodes = useGraph(state => state.expandNodes); const collapseNodes = useGraph(state => state.collapseNodes); @@ -66,7 +72,7 @@ const TextNode: React.FC = ({ node, x, y, hasCollapse = false } height={height} x={0} y={0} - hasCollapse={data.parent && hasCollapse} + hasCollapse={isParent && hasCollapse} ref={ref} > {isImage ? ( @@ -75,21 +81,21 @@ const TextNode: React.FC = ({ node, x, y, hasCollapse = false } ) : ( - + {JSON.stringify(text).replaceAll('"', "")} - {data.parent && data.childrenCount > 0 && childrenCount && ( - ({data.childrenCount}) + {isParent && childrenCount > 0 && showChildrenCount && ( + ({childrenCount}) )} - {data.parent && hasCollapse && hideCollapse && ( + {isParent && hasCollapse && hideCollapse && ( {isExpanded ? : } diff --git a/src/components/CustomNode/styles.tsx b/src/components/CustomNode/styles.tsx index 6bbf140..3c5f318 100644 --- a/src/components/CustomNode/styles.tsx +++ b/src/components/CustomNode/styles.tsx @@ -56,9 +56,9 @@ export const StyledForeignObject = styled.foreignObject<{ } `; -function getKeyColor(theme: DefaultTheme, parent: "array" | "object" | false, objectKey: boolean) { +function getKeyColor(theme: DefaultTheme, parent: boolean, type: string, objectKey: boolean) { if (parent) { - if (parent === "array") return theme.NODE_COLORS.PARENT_ARR; + if (type === "array") return theme.NODE_COLORS.PARENT_ARR; return theme.NODE_COLORS.PARENT_OBJ; } if (objectKey) return theme.NODE_COLORS.NODE_KEY; @@ -67,13 +67,15 @@ function getKeyColor(theme: DefaultTheme, parent: "array" | "object" | false, ob export const StyledKey = styled.span<{ objectKey?: boolean; - parent?: "array" | "object" | false; + type: string; + parent: boolean; value?: string; }>` display: inline; flex: 1; font-weight: 500; - color: ${({ theme, objectKey = false, parent = false }) => getKeyColor(theme, parent, objectKey)}; + color: ${({ theme, type, objectKey = false, parent }) => + getKeyColor(theme, parent, type, objectKey)}; font-size: ${({ parent }) => parent && "14px"}; overflow: hidden; text-overflow: ellipsis; diff --git a/src/components/Sidebar/index.tsx b/src/components/Sidebar/index.tsx index 0317a77..0886417 100644 --- a/src/components/Sidebar/index.tsx +++ b/src/components/Sidebar/index.tsx @@ -149,7 +149,6 @@ export const Sidebar: React.FC = () => { const collapseGraph = useGraph(state => state.collapseGraph); const expandGraph = useGraph(state => state.expandGraph); - const centerView = useGraph(state => state.centerView); const toggleFold = useGraph(state => state.toggleFold); const toggleFullscreen = useGraph(state => state.toggleFullscreen); diff --git a/src/store/useGraph.tsx b/src/store/useGraph.tsx index 7dcb7ea..e547418 100644 --- a/src/store/useGraph.tsx +++ b/src/store/useGraph.tsx @@ -112,7 +112,7 @@ const useGraph = create((set, get) => ({ .map(edge => edge.to); const collapsedParents = get() - .nodes.filter(node => !parentNodesIds.includes(node.id) && node.data.parent) + .nodes.filter(node => !parentNodesIds.includes(node.id) && node.data.isParent) .map(node => node.id); const collapsedNodes = get() diff --git a/src/typings/types.d.ts b/src/typings/types.d.ts index 9dc69ea..9f00609 100644 --- a/src/typings/types.d.ts +++ b/src/typings/types.d.ts @@ -6,7 +6,7 @@ interface NodeData { text?: any; height?: number; width?: number; - parent?: string; + isParent?: string; ports?: PortData[]; icon?: IconData; nodePadding?: number | [number, number] | [number, number, number, number]; diff --git a/src/utils/core/addNodeToGraph.ts b/src/utils/core/addNodeToGraph.ts index 32c7138..52bf6fa 100644 --- a/src/utils/core/addNodeToGraph.ts +++ b/src/utils/core/addNodeToGraph.ts @@ -1,27 +1,32 @@ +import { calculateNodeSize } from "./calculateNodeSize"; import { Graph } from "./jsonParser"; -export const addNodeToGraph = ( - graph: Graph, - text: any, - width: number, - height: number, - parent: "string" | "number" | "boolean" | "object" | "array" | "null" | false, - isEmpty?: boolean -) => { - let actualId = String(graph.nodes.length + 1); - - graph.nodes = graph.nodes.concat([ - { - id: actualId, - text: text, - width: width, - height: height, - data: { - parent: parent === "array" || parent === "object" ? parent : false, - childrenCount: parent ? 1 : 0, - isEmpty: isEmpty, - }, - }, - ]); - return actualId; +type Props = { + graph: Graph; + text: any; + isEmpty?: boolean; + type?: "string" | "number" | "boolean" | "object" | "array" | "null"; +}; + +export const addNodeToGraph = ({ graph, text, type = "null", isEmpty = false }: Props) => { + let id = String(graph.nodes.length + 1); + const isParent = type === "array" || type === "object"; + const { width, height } = calculateNodeSize(text, isParent); + + const node = { + id, + text, + width, + height, + data: { + type, + isParent, + isEmpty, + childrenCount: isParent ? 1 : 0, + }, + }; + + graph.nodes = graph.nodes.concat([node]); + + return id; }; diff --git a/src/utils/core/jsonParser.ts b/src/utils/core/jsonParser.ts index be812c5..44edab1 100644 --- a/src/utils/core/jsonParser.ts +++ b/src/utils/core/jsonParser.ts @@ -1,7 +1,6 @@ import { parseTree } from "jsonc-parser"; import { addEdgeToGraph } from "./addEdgeToGraph"; import { addNodeToGraph } from "./addNodeToGraph"; -import { calculateNodeSize } from "./calculateNodeSize"; import { traverse } from "./traverse"; export type Graph = { @@ -23,16 +22,16 @@ export type States = { parentId: string | undefined; objectsFromArrayId: number | undefined; }[]; + graph: { + nodes: NodeData[]; + edges: EdgeData[]; + }; }; export const parser = (jsonStr: string) => { try { let json = parseTree(jsonStr); - - const graph: Graph = { - nodes: [], - edges: [], - }; + if (!json) throw "Invalid JSON"!; const states: States = { parentName: "", @@ -44,36 +43,29 @@ export const parser = (jsonStr: string) => { brothersParentId: undefined, brotherKey: "", brothersNodeProps: [], + graph: { + nodes: [], + edges: [], + }, }; - if (json) { - traverse(graph, states, json); + traverse(states, json); - if (states.notHaveParent.length > 1) { - if (json.type !== "array") { - const text = ""; - const { width, height } = calculateNodeSize(text, false); - const emptyId = addNodeToGraph(graph, text, width, height, false, true); - states.notHaveParent.forEach(children => { - addEdgeToGraph(graph, emptyId, children); - }); - } - } - - if (graph.nodes.length === 0) { - if (json.type === "array") { - const text = "[]"; - const { width, height } = calculateNodeSize(text, false); - addNodeToGraph(graph, text, width, height, false); - } else { - const text = "{}"; - const { width, height } = calculateNodeSize(text, false); - addNodeToGraph(graph, text, width, height, false); - } + if (states.notHaveParent.length > 1) { + if (json.type !== "array") { + const emptyId = addNodeToGraph({ graph: states.graph, text: "", isEmpty: true }); + states.notHaveParent.forEach(children => { + addEdgeToGraph(states.graph, emptyId, children); + }); } } - return graph; + if (states.graph.nodes.length === 0) { + if (json.type === "array") addNodeToGraph({ graph: states.graph, text: "[]" }); + else addNodeToGraph({ graph: states.graph, text: "{}" }); + } + + return states.graph; } catch (error) { console.error(error); return { diff --git a/src/utils/core/traverse.ts b/src/utils/core/traverse.ts index 2ed66b0..8b4e35b 100644 --- a/src/utils/core/traverse.ts +++ b/src/utils/core/traverse.ts @@ -2,7 +2,7 @@ import { Node, NodeType } from "jsonc-parser"; import { addEdgeToGraph } from "./addEdgeToGraph"; import { addNodeToGraph } from "./addNodeToGraph"; import { calculateNodeSize } from "./calculateNodeSize"; -import { Graph, States } from "./jsonParser"; +import { States } from "./jsonParser"; const isPrimitiveOrNullType = (type?: NodeType) => { return type === "boolean" || type === "string" || type === "number" || type === "null"; @@ -19,13 +19,13 @@ const alignChildren = (a: Node, b: Node) => { }; export const traverse = ( - graph: Graph, states: States, objectToTraverse: Node, parentType?: string, myParentId?: string, nextType?: string ) => { + const graph = states.graph; let { type, children, value } = objectToTraverse; if (!children) { @@ -39,8 +39,7 @@ export const traverse = ( states.brotherKey = value; } } else if (parentType === "array") { - const { width, height } = calculateNodeSize(String(value), false); - const nodeFromArrayId = addNodeToGraph(graph, String(value), width, height, false); + const nodeFromArrayId = addNodeToGraph({ graph, text: String(value) }); if (myParentId) { addEdgeToGraph(graph, myParentId, nodeFromArrayId); } @@ -77,8 +76,7 @@ export const traverse = ( states.brothersNode = []; } } else { - const { width, height } = calculateNodeSize(states.brothersNode, false); - const brothersNodeId = addNodeToGraph(graph, states.brothersNode, width, height, false); + const brothersNodeId = addNodeToGraph({ graph, text: states.brothersNode }); states.brothersNode = []; if (states.brothersParentId) { @@ -99,9 +97,8 @@ export const traverse = ( } // add parent node - const { width, height } = calculateNodeSize(states.parentName, true); - parentId = addNodeToGraph(graph, states.parentName, width, height, type); - states.bracketOpen = [...states.bracketOpen, { id: parentId, type: type }]; + parentId = addNodeToGraph({ graph, type, text: states.parentName }); + states.bracketOpen = [...states.bracketOpen, { id: parentId, type }]; states.parentName = ""; // add edges from parent node @@ -129,7 +126,6 @@ export const traverse = ( (branch, index, array) => { if (array[index + 1]) { traverse( - graph, states, branch, type, @@ -140,7 +136,6 @@ export const traverse = ( ); } else { traverse( - graph, states, branch, type, @@ -154,7 +149,6 @@ export const traverse = ( if (type !== "property") { // when children end - // add or concat brothers node when it is the last parent node if (states.brothersNode.length > 0) { let findBrothersNode = states.brothersNodeProps.find( @@ -175,8 +169,7 @@ export const traverse = ( states.brothersNode = []; } } else { - const { width, height } = calculateNodeSize(states.brothersNode, false); - const brothersNodeId = addNodeToGraph(graph, states.brothersNode, width, height, false); + const brothersNodeId = addNodeToGraph({ graph, text: states.brothersNode }); states.brothersNode = []; if (states.brothersParentId) {