mirror of
https://github.com/AykutSarac/jsoncrack.com.git
synced 2025-01-27 15:22:56 +08:00
refactor parser
This commit is contained in:
parent
e488ff524c
commit
5914ae94eb
@ -3,7 +3,7 @@ import { CanvasDirection } from "reaflow";
|
||||
import { Graph } from "src/components/Graph";
|
||||
import { getChildrenEdges } from "src/utils/getChildrenEdges";
|
||||
import { getOutgoers } from "src/utils/getOutgoers";
|
||||
import { parser } from "src/utils/jsonParser";
|
||||
import { parser } from "src/utils/core/jsonParser";
|
||||
import create from "zustand";
|
||||
import useJson from "./useJson";
|
||||
|
||||
|
11
src/utils/core/addEdgeToGraph.ts
Normal file
11
src/utils/core/addEdgeToGraph.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { Graph } from "./jsonParser";
|
||||
|
||||
export const addEdgeToGraph = (graph: Graph, from: string, to: string) => {
|
||||
graph.edges = graph.edges.concat([
|
||||
{
|
||||
id: `e${from}-${to}`,
|
||||
from: from,
|
||||
to: to,
|
||||
},
|
||||
]);
|
||||
};
|
27
src/utils/core/addNodeToGraph.ts
Normal file
27
src/utils/core/addNodeToGraph.ts
Normal file
@ -0,0 +1,27 @@
|
||||
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;
|
||||
};
|
51
src/utils/core/calculateNodeSize.ts
Normal file
51
src/utils/core/calculateNodeSize.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import useGraph from "src/store/useGraph";
|
||||
import useStored from "src/store/useStored";
|
||||
|
||||
export const calculateNodeSize = (text: string | [string, string][], isParent = false) => {
|
||||
// Get the current state of the application
|
||||
const isFolded = useGraph.getState().foldNodes;
|
||||
const isImagePreview = useStored.getState().imagePreview;
|
||||
|
||||
// Initialize variables
|
||||
let lineCounts = 1;
|
||||
let lineLengths: number[] = [];
|
||||
|
||||
// Calculate the number of lines and the length of each line
|
||||
if (typeof text === "string") {
|
||||
lineLengths.push(text.length);
|
||||
} else {
|
||||
lineCounts = text.map(([k, v]) => {
|
||||
const length = `${k}: ${v}`.length;
|
||||
const line = length > 150 ? 150 : length;
|
||||
lineLengths.push(line);
|
||||
return `${k}: ${v}`;
|
||||
}).length;
|
||||
}
|
||||
|
||||
// Get the longest line
|
||||
const longestLine = Math.max(...lineLengths);
|
||||
|
||||
// Calculate the width of the node
|
||||
const getWidth = () => {
|
||||
if (text.length === 0) return 35;
|
||||
if (Array.isArray(text) && !text.length) return 40;
|
||||
if (!isFolded) return 35 + longestLine * 7.8 + (isParent ? 60 : 0);
|
||||
if (isParent && isFolded) return 170;
|
||||
return 200;
|
||||
};
|
||||
|
||||
// Calculate the height of the node
|
||||
const getHeight = () => {
|
||||
if (lineCounts * 17.8 < 30) return 40;
|
||||
return (lineCounts + 1) * 18;
|
||||
};
|
||||
|
||||
// Check if text matches URL pattern
|
||||
const isImage =
|
||||
!Array.isArray(text) && /(https?:\/\/.*\.(?:png|jpg|gif))/i.test(text) && isImagePreview;
|
||||
|
||||
return {
|
||||
width: isImage ? 80 : getWidth(),
|
||||
height: isImage ? 80 : getHeight(),
|
||||
};
|
||||
};
|
84
src/utils/core/jsonParser.ts
Normal file
84
src/utils/core/jsonParser.ts
Normal file
@ -0,0 +1,84 @@
|
||||
import { parseTree } from "jsonc-parser";
|
||||
import { addEdgeToGraph } from "./addEdgeToGraph";
|
||||
import { addNodeToGraph } from "./addNodeToGraph";
|
||||
import { calculateNodeSize } from "./calculateNodeSize";
|
||||
import { traverse } from "./traverse";
|
||||
|
||||
export type Graph = {
|
||||
nodes: NodeData[];
|
||||
edges: EdgeData[];
|
||||
};
|
||||
|
||||
export type States = {
|
||||
parentName: string;
|
||||
bracketOpen: { id: string; type: string }[];
|
||||
objectsFromArray: number[];
|
||||
objectsFromArrayId: number;
|
||||
notHaveParent: string[];
|
||||
brothersNode: [string, string][];
|
||||
brothersParentId: string | undefined;
|
||||
brotherKey: string;
|
||||
brothersNodeProps: {
|
||||
id: string;
|
||||
parentId: string | undefined;
|
||||
objectsFromArrayId: number | undefined;
|
||||
}[];
|
||||
};
|
||||
|
||||
export const parser = (jsonStr: string) => {
|
||||
try {
|
||||
let json = parseTree(jsonStr);
|
||||
|
||||
const graph: Graph = {
|
||||
nodes: [],
|
||||
edges: [],
|
||||
};
|
||||
|
||||
const states: States = {
|
||||
parentName: "",
|
||||
bracketOpen: [],
|
||||
objectsFromArray: [],
|
||||
objectsFromArrayId: 0,
|
||||
notHaveParent: [],
|
||||
brothersNode: [],
|
||||
brothersParentId: undefined,
|
||||
brotherKey: "",
|
||||
brothersNodeProps: [],
|
||||
};
|
||||
|
||||
if (json) {
|
||||
traverse(graph, 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return graph;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return {
|
||||
nodes: [],
|
||||
edges: [],
|
||||
};
|
||||
}
|
||||
};
|
226
src/utils/core/traverse.ts
Normal file
226
src/utils/core/traverse.ts
Normal file
@ -0,0 +1,226 @@
|
||||
import { Node, NodeType } from "jsonc-parser";
|
||||
import { addEdgeToGraph } from "./addEdgeToGraph";
|
||||
import { addNodeToGraph } from "./addNodeToGraph";
|
||||
import { calculateNodeSize } from "./calculateNodeSize";
|
||||
import { Graph, States } from "./jsonParser";
|
||||
|
||||
const isPrimitiveOrNullType = (type?: NodeType) => {
|
||||
return type === "boolean" || type === "string" || type === "number" || type === "null";
|
||||
};
|
||||
|
||||
const alignChildren = (a: Node, b: Node) => {
|
||||
if (
|
||||
isPrimitiveOrNullType(a?.children?.[1]?.type) &&
|
||||
!isPrimitiveOrNullType(b?.children?.[1]?.type)
|
||||
) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
export const traverse = (
|
||||
graph: Graph,
|
||||
states: States,
|
||||
objectToTraverse: Node,
|
||||
parentType?: string,
|
||||
myParentId?: string,
|
||||
nextType?: string
|
||||
) => {
|
||||
let { type, children, value } = objectToTraverse;
|
||||
|
||||
if (!children) {
|
||||
if (value !== undefined) {
|
||||
if (parentType === "property" && nextType !== "object" && nextType !== "array") {
|
||||
states.brothersParentId = myParentId;
|
||||
if (nextType === undefined) {
|
||||
// add key and value to brothers node
|
||||
states.brothersNode = [...states.brothersNode, [states.brotherKey, value]];
|
||||
} else {
|
||||
states.brotherKey = value;
|
||||
}
|
||||
} else if (parentType === "array") {
|
||||
const { width, height } = calculateNodeSize(String(value), false);
|
||||
const nodeFromArrayId = addNodeToGraph(graph, String(value), width, height, false);
|
||||
if (myParentId) {
|
||||
addEdgeToGraph(graph, myParentId, nodeFromArrayId);
|
||||
}
|
||||
}
|
||||
if (nextType && parentType !== "array") {
|
||||
if (nextType === "object" || nextType === "array") {
|
||||
states.parentName = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (children) {
|
||||
let parentId: string | undefined;
|
||||
|
||||
if (type !== "property" && states.parentName !== "") {
|
||||
// add last brothers node and add parent node
|
||||
|
||||
if (states.brothersNode.length > 0) {
|
||||
// add or concat brothers node of same parent
|
||||
let findBrothersNode = states.brothersNodeProps.find(
|
||||
e =>
|
||||
e.parentId === states.brothersParentId &&
|
||||
e.objectsFromArrayId === states.objectsFromArray[states.objectsFromArray.length - 1]
|
||||
);
|
||||
if (findBrothersNode) {
|
||||
let ModifyNodes = [...graph.nodes];
|
||||
let findNode = graph.nodes.findIndex(e => e.id === findBrothersNode?.id);
|
||||
|
||||
if (ModifyNodes[findNode]) {
|
||||
ModifyNodes[findNode].text = ModifyNodes[findNode].text.concat(states.brothersNode);
|
||||
const { width, height } = calculateNodeSize(ModifyNodes[findNode].text, false);
|
||||
ModifyNodes[findNode].width = width;
|
||||
ModifyNodes[findNode].height = height;
|
||||
graph.nodes = [...ModifyNodes];
|
||||
states.brothersNode = [];
|
||||
}
|
||||
} else {
|
||||
const { width, height } = calculateNodeSize(states.brothersNode, false);
|
||||
const brothersNodeId = addNodeToGraph(graph, states.brothersNode, width, height, false);
|
||||
states.brothersNode = [];
|
||||
|
||||
if (states.brothersParentId) {
|
||||
addEdgeToGraph(graph, states.brothersParentId, brothersNodeId);
|
||||
} else {
|
||||
states.notHaveParent = [...states.notHaveParent, brothersNodeId];
|
||||
}
|
||||
|
||||
states.brothersNodeProps = [
|
||||
...states.brothersNodeProps,
|
||||
{
|
||||
id: brothersNodeId,
|
||||
parentId: states.brothersParentId,
|
||||
objectsFromArrayId: states.objectsFromArray[states.objectsFromArray.length - 1],
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// 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 }];
|
||||
states.parentName = "";
|
||||
|
||||
// add edges from parent node
|
||||
let brothersProps = states.brothersNodeProps.filter(
|
||||
e =>
|
||||
e.parentId === myParentId &&
|
||||
e.objectsFromArrayId === states.objectsFromArray[states.objectsFromArray.length - 1]
|
||||
);
|
||||
if (
|
||||
(brothersProps.length > 0 &&
|
||||
states.bracketOpen[states.bracketOpen.length - 2] &&
|
||||
states.bracketOpen[states.bracketOpen.length - 2].type !== "object") ||
|
||||
(brothersProps.length > 0 && states.bracketOpen.length === 1)
|
||||
) {
|
||||
addEdgeToGraph(graph, brothersProps[brothersProps.length - 1].id, parentId);
|
||||
} else if (myParentId) {
|
||||
addEdgeToGraph(graph, myParentId, parentId);
|
||||
} else {
|
||||
states.notHaveParent = [...states.notHaveParent, parentId];
|
||||
}
|
||||
} else if (parentType === "array") {
|
||||
states.objectsFromArray = [...states.objectsFromArray, states.objectsFromArrayId++];
|
||||
}
|
||||
(type === "object" ? children.sort(alignChildren) : children).forEach(
|
||||
(branch, index, array) => {
|
||||
if (array[index + 1]) {
|
||||
traverse(
|
||||
graph,
|
||||
states,
|
||||
branch,
|
||||
type,
|
||||
states.bracketOpen[states.bracketOpen.length - 1]
|
||||
? states.bracketOpen[states.bracketOpen.length - 1].id
|
||||
: undefined,
|
||||
array[index + 1].type
|
||||
);
|
||||
} else {
|
||||
traverse(
|
||||
graph,
|
||||
states,
|
||||
branch,
|
||||
type,
|
||||
states.bracketOpen[states.bracketOpen.length - 1]
|
||||
? states.bracketOpen[states.bracketOpen.length - 1].id
|
||||
: undefined
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
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(
|
||||
e =>
|
||||
e.parentId === states.brothersParentId &&
|
||||
e.objectsFromArrayId === states.objectsFromArray[states.objectsFromArray.length - 1]
|
||||
);
|
||||
if (findBrothersNode) {
|
||||
let ModifyNodes = [...graph.nodes];
|
||||
let findNode = graph.nodes.findIndex(e => e.id === findBrothersNode?.id);
|
||||
|
||||
if (ModifyNodes[findNode]) {
|
||||
ModifyNodes[findNode].text = ModifyNodes[findNode].text.concat(states.brothersNode);
|
||||
const { width, height } = calculateNodeSize(ModifyNodes[findNode].text, false);
|
||||
ModifyNodes[findNode].width = width;
|
||||
ModifyNodes[findNode].height = height;
|
||||
graph.nodes = [...ModifyNodes];
|
||||
states.brothersNode = [];
|
||||
}
|
||||
} else {
|
||||
const { width, height } = calculateNodeSize(states.brothersNode, false);
|
||||
const brothersNodeId = addNodeToGraph(graph, states.brothersNode, width, height, false);
|
||||
states.brothersNode = [];
|
||||
|
||||
if (states.brothersParentId) {
|
||||
addEdgeToGraph(graph, states.brothersParentId, brothersNodeId);
|
||||
} else {
|
||||
states.notHaveParent = [...states.notHaveParent, brothersNodeId];
|
||||
}
|
||||
|
||||
states.brothersNodeProps = [
|
||||
...states.brothersNodeProps,
|
||||
{
|
||||
id: brothersNodeId,
|
||||
parentId: states.brothersParentId,
|
||||
objectsFromArrayId: states.objectsFromArray[states.objectsFromArray.length - 1],
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// close brackets
|
||||
if (parentType !== "array") {
|
||||
if (states.bracketOpen.length > 0) {
|
||||
let newBracketOpen = [...states.bracketOpen];
|
||||
newBracketOpen.splice(newBracketOpen.length - 1);
|
||||
states.bracketOpen = [...newBracketOpen];
|
||||
}
|
||||
} else if (parentType === "array") {
|
||||
if (states.objectsFromArray.length > 0) {
|
||||
let newobjectsFromArray = [...states.objectsFromArray];
|
||||
newobjectsFromArray.splice(newobjectsFromArray.length - 1);
|
||||
states.objectsFromArray = [...newobjectsFromArray];
|
||||
}
|
||||
}
|
||||
|
||||
if (parentId) {
|
||||
let myChildrens = graph.edges.filter(e => e.from === parentId);
|
||||
let myIndex = graph.nodes.findIndex(e => e.id === parentId);
|
||||
|
||||
let ModifyNodes = [...graph.nodes];
|
||||
if (ModifyNodes[myIndex]) {
|
||||
ModifyNodes[myIndex].data.childrenCount = myChildrens.length;
|
||||
graph.nodes = [...ModifyNodes];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
@ -1,357 +0,0 @@
|
||||
import { Node, NodeType, parseTree } from "jsonc-parser";
|
||||
import useGraph from "src/store/useGraph";
|
||||
import useStored from "src/store/useStored";
|
||||
|
||||
const calculateSize = (text: string | [string, string][], isParent = false) => {
|
||||
const isFolded = useGraph.getState().foldNodes;
|
||||
const isImagePreview = useStored.getState().imagePreview;
|
||||
let lineCounts = 1;
|
||||
let lineLengths: number[] = [];
|
||||
|
||||
if (typeof text === "string") {
|
||||
lineLengths.push(text.length);
|
||||
} else {
|
||||
lineCounts = text.map(([k, v]) => {
|
||||
const length = `${k}: ${v}`.length;
|
||||
const line = length > 150 ? 150 : length;
|
||||
lineLengths.push(line);
|
||||
return `${k}: ${v}`;
|
||||
}).length;
|
||||
}
|
||||
|
||||
const longestLine = Math.max(...lineLengths);
|
||||
|
||||
const getWidth = () => {
|
||||
if (text.length === 0) return 35;
|
||||
if (Array.isArray(text) && !text.length) return 40;
|
||||
if (!isFolded) return 35 + longestLine * 7.8 + (isParent ? 60 : 0);
|
||||
if (isParent && isFolded) return 170;
|
||||
return 200;
|
||||
};
|
||||
|
||||
const getHeight = () => {
|
||||
if (lineCounts * 17.8 < 30) return 40;
|
||||
return (lineCounts + 1) * 18;
|
||||
};
|
||||
|
||||
const isImage =
|
||||
!Array.isArray(text) && /(https?:\/\/.*\.(?:png|jpg|gif))/i.test(text) && isImagePreview;
|
||||
|
||||
return {
|
||||
width: isImage ? 80 : getWidth(),
|
||||
height: isImage ? 80 : getHeight(),
|
||||
};
|
||||
};
|
||||
|
||||
export const parser = (jsonStr: string) => {
|
||||
try {
|
||||
let json = parseTree(jsonStr);
|
||||
let nodes: NodeData[] = [];
|
||||
let edges: EdgeData[] = [];
|
||||
|
||||
const addNodes = (
|
||||
text: any,
|
||||
width: number,
|
||||
height: number,
|
||||
parent: "string" | "number" | "boolean" | "object" | "array" | "null" | false,
|
||||
isEmpty?: boolean
|
||||
) => {
|
||||
let actualId = String(nodes.length + 1);
|
||||
nodes = [
|
||||
...nodes,
|
||||
{
|
||||
id: actualId,
|
||||
text: text,
|
||||
width: width,
|
||||
height: height,
|
||||
data: {
|
||||
parent: parent === "array" || parent === "object" ? parent : false,
|
||||
childrenCount: parent ? 1 : 0,
|
||||
isEmpty: isEmpty,
|
||||
},
|
||||
},
|
||||
];
|
||||
return actualId;
|
||||
};
|
||||
|
||||
const addEdges = (from: string, to: string) => {
|
||||
edges = [
|
||||
...edges,
|
||||
{
|
||||
id: `e${from}-${to}`,
|
||||
from: from,
|
||||
to: to,
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
const isPrimitiveOrNullType = (type?: NodeType) => {
|
||||
return (
|
||||
type === "boolean" ||
|
||||
type === "string" ||
|
||||
type === "number" ||
|
||||
type === "null"
|
||||
);
|
||||
};
|
||||
|
||||
const alignChildren = (a: Node, b: Node) => {
|
||||
if (
|
||||
isPrimitiveOrNullType(a?.children?.[1]?.type) &&
|
||||
!isPrimitiveOrNullType(b?.children?.[1]?.type)
|
||||
) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
let parentName: string = "";
|
||||
let bracketOpen: { id: string; type: string }[] = [];
|
||||
let objectsFromArray: number[] = [];
|
||||
let objectsFromArrayId = 0;
|
||||
let notHaveParent: string[] = [];
|
||||
let brothersNode: [string, string][] = [];
|
||||
let brothersParentId: string | undefined = "";
|
||||
let brotherKey: string = "";
|
||||
let brothersNodeProps: {
|
||||
id: string;
|
||||
parentId: string | undefined;
|
||||
objectsFromArrayId: number | undefined;
|
||||
}[] = [];
|
||||
|
||||
const traverse = (
|
||||
objectToTraverse: Node,
|
||||
parentType?: string,
|
||||
myParentId?: string,
|
||||
nextType?: string
|
||||
) => {
|
||||
let { type, children, value } = objectToTraverse;
|
||||
|
||||
if (!children) {
|
||||
if (value !== undefined) {
|
||||
if (parentType === "property" && nextType !== "object" && nextType !== "array") {
|
||||
brothersParentId = myParentId;
|
||||
if (nextType === undefined) {
|
||||
// add key and value to brothers node
|
||||
brothersNode = [...brothersNode, [brotherKey, value]];
|
||||
} else {
|
||||
brotherKey = value;
|
||||
}
|
||||
} else if (parentType === "array") {
|
||||
const { width, height } = calculateSize(String(value), false);
|
||||
const nodeFromArrayId = addNodes(String(value), width, height, false);
|
||||
if (myParentId) {
|
||||
addEdges(myParentId, nodeFromArrayId);
|
||||
}
|
||||
}
|
||||
if (nextType && parentType !== "array") {
|
||||
if (nextType === "object" || nextType === "array") {
|
||||
parentName = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (children) {
|
||||
let parentId: string | undefined;
|
||||
|
||||
if (type !== "property" && parentName !== "") {
|
||||
// add last brothers node and add parent node
|
||||
|
||||
if (brothersNode.length > 0) {
|
||||
// add or concat brothers node of same parent
|
||||
let findBrothersNode = brothersNodeProps.find(
|
||||
e =>
|
||||
e.parentId === brothersParentId &&
|
||||
e.objectsFromArrayId === objectsFromArray[objectsFromArray.length - 1]
|
||||
);
|
||||
if (findBrothersNode) {
|
||||
let ModifyNodes = [...nodes];
|
||||
let findNode = nodes.findIndex(e => e.id === findBrothersNode?.id);
|
||||
|
||||
if (ModifyNodes[findNode]) {
|
||||
ModifyNodes[findNode].text = ModifyNodes[findNode].text.concat(brothersNode);
|
||||
const { width, height } = calculateSize(ModifyNodes[findNode].text, false);
|
||||
ModifyNodes[findNode].width = width;
|
||||
ModifyNodes[findNode].height = height;
|
||||
nodes = [...ModifyNodes];
|
||||
brothersNode = [];
|
||||
}
|
||||
} else {
|
||||
const { width, height } = calculateSize(brothersNode, false);
|
||||
const brothersNodeId = addNodes(brothersNode, width, height, false);
|
||||
brothersNode = [];
|
||||
|
||||
if (brothersParentId) {
|
||||
addEdges(brothersParentId, brothersNodeId);
|
||||
} else {
|
||||
notHaveParent = [...notHaveParent, brothersNodeId];
|
||||
}
|
||||
|
||||
brothersNodeProps = [
|
||||
...brothersNodeProps,
|
||||
{
|
||||
id: brothersNodeId,
|
||||
parentId: brothersParentId,
|
||||
objectsFromArrayId: objectsFromArray[objectsFromArray.length - 1],
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// add parent node
|
||||
const { width, height } = calculateSize(parentName, true);
|
||||
parentId = addNodes(parentName, width, height, type);
|
||||
bracketOpen = [...bracketOpen, { id: parentId, type: type }];
|
||||
parentName = "";
|
||||
|
||||
// add edges from parent node
|
||||
let brothersProps = brothersNodeProps.filter(
|
||||
e =>
|
||||
e.parentId === myParentId &&
|
||||
e.objectsFromArrayId === objectsFromArray[objectsFromArray.length - 1]
|
||||
);
|
||||
if (
|
||||
(brothersProps.length > 0 &&
|
||||
bracketOpen[bracketOpen.length - 2] &&
|
||||
bracketOpen[bracketOpen.length - 2].type !== "object") ||
|
||||
(brothersProps.length > 0 && bracketOpen.length === 1)
|
||||
) {
|
||||
addEdges(brothersProps[brothersProps.length - 1].id, parentId);
|
||||
} else if (myParentId) {
|
||||
addEdges(myParentId, parentId);
|
||||
} else {
|
||||
notHaveParent = [...notHaveParent, parentId];
|
||||
}
|
||||
} else if (parentType === "array") {
|
||||
objectsFromArray = [...objectsFromArray, objectsFromArrayId++];
|
||||
}
|
||||
(type === "object" ? children.sort(alignChildren) : children).forEach(
|
||||
(branch, index, array) => {
|
||||
if (array[index + 1]) {
|
||||
traverse(
|
||||
branch,
|
||||
type,
|
||||
bracketOpen[bracketOpen.length - 1]
|
||||
? bracketOpen[bracketOpen.length - 1].id
|
||||
: undefined,
|
||||
array[index + 1].type
|
||||
);
|
||||
} else {
|
||||
traverse(
|
||||
branch,
|
||||
type,
|
||||
bracketOpen[bracketOpen.length - 1]
|
||||
? bracketOpen[bracketOpen.length - 1].id
|
||||
: undefined
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (type !== "property") {
|
||||
// when children end
|
||||
|
||||
// add or concat brothers node when it is the last parent node
|
||||
if (brothersNode.length > 0) {
|
||||
let findBrothersNode = brothersNodeProps.find(
|
||||
e =>
|
||||
e.parentId === brothersParentId &&
|
||||
e.objectsFromArrayId === objectsFromArray[objectsFromArray.length - 1]
|
||||
);
|
||||
if (findBrothersNode) {
|
||||
let ModifyNodes = [...nodes];
|
||||
let findNode = nodes.findIndex(e => e.id === findBrothersNode?.id);
|
||||
|
||||
if (ModifyNodes[findNode]) {
|
||||
ModifyNodes[findNode].text = ModifyNodes[findNode].text.concat(brothersNode);
|
||||
const { width, height } = calculateSize(ModifyNodes[findNode].text, false);
|
||||
ModifyNodes[findNode].width = width;
|
||||
ModifyNodes[findNode].height = height;
|
||||
nodes = [...ModifyNodes];
|
||||
brothersNode = [];
|
||||
}
|
||||
} else {
|
||||
const { width, height } = calculateSize(brothersNode, false);
|
||||
const brothersNodeId = addNodes(brothersNode, width, height, false);
|
||||
brothersNode = [];
|
||||
|
||||
if (brothersParentId) {
|
||||
addEdges(brothersParentId, brothersNodeId);
|
||||
} else {
|
||||
notHaveParent = [...notHaveParent, brothersNodeId];
|
||||
}
|
||||
|
||||
brothersNodeProps = [
|
||||
...brothersNodeProps,
|
||||
{
|
||||
id: brothersNodeId,
|
||||
parentId: brothersParentId,
|
||||
objectsFromArrayId: objectsFromArray[objectsFromArray.length - 1],
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// close brackets
|
||||
if (parentType !== "array") {
|
||||
if (bracketOpen.length > 0) {
|
||||
let newBracketOpen = [...bracketOpen];
|
||||
newBracketOpen.splice(newBracketOpen.length - 1);
|
||||
bracketOpen = [...newBracketOpen];
|
||||
}
|
||||
} else if (parentType === "array") {
|
||||
if (objectsFromArray.length > 0) {
|
||||
let newobjectsFromArray = [...objectsFromArray];
|
||||
newobjectsFromArray.splice(newobjectsFromArray.length - 1);
|
||||
objectsFromArray = [...newobjectsFromArray];
|
||||
}
|
||||
}
|
||||
|
||||
if (parentId) {
|
||||
let myChildrens = edges.filter(e => e.from === parentId);
|
||||
let myIndex = nodes.findIndex(e => e.id === parentId);
|
||||
|
||||
let ModifyNodes = [...nodes];
|
||||
if (ModifyNodes[myIndex]) {
|
||||
ModifyNodes[myIndex].data.childrenCount = myChildrens.length;
|
||||
nodes = [...ModifyNodes];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (json) {
|
||||
traverse(json);
|
||||
|
||||
if (notHaveParent.length > 1) {
|
||||
if (json.type !== "array") {
|
||||
const text = "";
|
||||
const { width, height } = calculateSize(text, false);
|
||||
const emptyId = addNodes(text, width, height, false, true);
|
||||
notHaveParent.forEach(children => {
|
||||
addEdges(emptyId, children);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (nodes.length === 0) {
|
||||
if (json.type === "array") {
|
||||
const text = "[]";
|
||||
const { width, height } = calculateSize(text, false);
|
||||
addNodes(text, width, height, false);
|
||||
} else {
|
||||
const text = "{}";
|
||||
const { width, height } = calculateSize(text, false);
|
||||
addNodes(text, width, height, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { nodes, edges };
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return {
|
||||
nodes: [],
|
||||
edges: [],
|
||||
};
|
||||
}
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user