Merge branch 'main' into mona-sans

This commit is contained in:
AykutSarac 2022-12-08 19:56:49 +03:00
commit 5da20fa5be
8 changed files with 409 additions and 171 deletions

View File

@ -65,16 +65,16 @@ const TextNode: React.FC<CustomNodeProps> = ({
x={0} x={0}
y={0} y={0}
hideCollapse={hideCollapse} hideCollapse={hideCollapse}
hasCollapse={data.isParent && hasCollapse} hasCollapse={data.parent && hasCollapse}
ref={ref} ref={ref}
> >
<StyledTextNodeWrapper hasCollapse={data.isParent && !hideCollapse}> <StyledTextNodeWrapper hasCollapse={data.parent && !hideCollapse}>
{(!performanceMode || inViewport) && ( {(!performanceMode || inViewport) && (
<Styled.StyledKey <Styled.StyledKey
data-x={x} data-x={x}
data-y={y} data-y={y}
data-key={JSON.stringify(text)} data-key={JSON.stringify(text)}
parent={data.isParent} parent={data.parent}
> >
<Styled.StyledLinkItUrl> <Styled.StyledLinkItUrl>
{JSON.stringify(text).replaceAll('"', "")} {JSON.stringify(text).replaceAll('"', "")}
@ -82,13 +82,13 @@ const TextNode: React.FC<CustomNodeProps> = ({
</Styled.StyledKey> </Styled.StyledKey>
)} )}
{data.isParent && data.childrenCount > 0 && !hideChildrenCount && ( {data.parent && data.childrenCount > 0 && !hideChildrenCount && (
<Styled.StyledChildrenCount> <Styled.StyledChildrenCount>
({data.childrenCount}) ({data.childrenCount})
</Styled.StyledChildrenCount> </Styled.StyledChildrenCount>
)} )}
{inViewport && data.isParent && hasCollapse && !hideCollapse && ( {inViewport && data.parent && hasCollapse && !hideCollapse && (
<StyledExpand onClick={handleExpand}> <StyledExpand onClick={handleExpand}>
{isExpanded ? <MdLinkOff size={18} /> : <MdLink size={18} />} {isExpanded ? <MdLinkOff size={18} /> : <MdLink size={18} />}
</StyledExpand> </StyledExpand>

View File

@ -2,9 +2,11 @@ import { LinkItUrl } from "react-linkify-it";
import styled, { DefaultTheme } from "styled-components"; import styled, { DefaultTheme } from "styled-components";
function getTypeColor(value: string, theme: DefaultTheme) { function getTypeColor(value: string, theme: DefaultTheme) {
if (!Number.isNaN(+value)) return "#FD0079"; if (!Number.isNaN(+value)) return theme.NODE_COLORS.INTEGER;
if (value === "true") return theme.TEXT_POSITIVE; if (value === "true") return theme.NODE_COLORS.BOOL.TRUE;
if (value === "false") return theme.TEXT_DANGER; if (value === "false") return theme.NODE_COLORS.BOOL.FALSE;
if (value === "null") return theme.NODE_COLORS.NULL;
return theme.NODE_COLORS.NODE_VALUE;
} }
export const StyledLinkItUrl = styled(LinkItUrl)` export const StyledLinkItUrl = styled(LinkItUrl)`
@ -20,7 +22,7 @@ export const StyledForeignObject = styled.foreignObject<{
text-align: ${({ isObject }) => !isObject && "center"}; text-align: ${({ isObject }) => !isObject && "center"};
font-size: 12px; font-size: 12px;
overflow: hidden; overflow: hidden;
color: ${({ theme }) => theme.TEXT_NORMAL}; color: ${({ theme }) => theme.NODE_COLORS.TEXT};
pointer-events: none; pointer-events: none;
padding: ${({ isObject }) => isObject && "10px"}; padding: ${({ isObject }) => isObject && "10px"};
@ -51,15 +53,22 @@ export const StyledForeignObject = styled.foreignObject<{
} }
`; `;
function getKeyColor(theme: DefaultTheme, parent: boolean, objectKey: boolean) { function getKeyColor(
if (parent) return theme.NODE_KEY; theme: DefaultTheme,
if (objectKey) return theme.OBJECT_KEY; parent: "array" | "object" | false,
return theme.TEXT_POSITIVE; objectKey: boolean
) {
if (parent) {
if (parent === "array") return theme.NODE_COLORS.PARENT_ARR;
return theme.NODE_COLORS.PARENT_OBJ;
}
if (objectKey) return theme.NODE_COLORS.NODE_KEY;
return theme.NODE_COLORS.TEXT;
} }
export const StyledKey = styled.span<{ export const StyledKey = styled.span<{
objectKey?: boolean; objectKey?: boolean;
parent?: boolean; parent?: "array" | "object" | false;
value?: string; value?: string;
}>` }>`
display: inline; display: inline;
@ -90,7 +99,7 @@ export const StyledRow = styled.span.attrs<{
`; `;
export const StyledChildrenCount = styled.span` export const StyledChildrenCount = styled.span`
color: ${({ theme }) => theme.TEXT_POSITIVE}; color: ${({ theme }) => theme.NODE_COLORS.CHILD_COUNT};
padding: 10px; padding: 10px;
margin-left: -15px; margin-left: -15px;
`; `;

View File

@ -1,5 +1,3 @@
import { DefaultTheme } from "styled-components";
const fixedColors = { const fixedColors = {
CRIMSON: "#DC143C", CRIMSON: "#DC143C",
BLURPLE: "#5865F2", BLURPLE: "#5865F2",
@ -18,8 +16,44 @@ const fixedColors = {
TEXT_DANGER: "#db662e", TEXT_DANGER: "#db662e",
}; };
export const darkTheme: DefaultTheme = { const nodeColors = {
dark: {
NODE_COLORS: {
TEXT: "#35D073",
NODE_KEY: "#59b8ff",
NODE_VALUE: "#DCE5E7",
INTEGER: "#e8c479",
NULL: "#939598",
BOOL: {
FALSE: "#F85C50",
TRUE: "#00DC7D",
},
PARENT_ARR: "#FC9A40",
PARENT_OBJ: "#59b8ff",
CHILD_COUNT: "white",
},
},
light: {
NODE_COLORS: {
TEXT: "#748700",
NODE_KEY: "#761CEA",
NODE_VALUE: "#535353",
INTEGER: "#A771FE",
NULL: "#afafaf",
BOOL: {
FALSE: "#FF0000",
TRUE: "#748700",
},
PARENT_ARR: "#FF6B00",
PARENT_OBJ: "#761CEA",
CHILD_COUNT: "#535353",
},
},
};
export const darkTheme = {
...fixedColors, ...fixedColors,
...nodeColors.dark,
BLACK_SECONDARY: "#23272A", BLACK_SECONDARY: "#23272A",
SILVER_DARK: "#4D4D4D", SILVER_DARK: "#4D4D4D",
NODE_KEY: "#FAA81A", NODE_KEY: "#FAA81A",
@ -37,10 +71,11 @@ export const darkTheme: DefaultTheme = {
MODAL_BACKGROUND: "#36393E", MODAL_BACKGROUND: "#36393E",
TEXT_NORMAL: "#dcddde", TEXT_NORMAL: "#dcddde",
TEXT_POSITIVE: "hsl(139,calc(var(--saturation-factor, 1)*51.6%),52.2%)", TEXT_POSITIVE: "hsl(139,calc(var(--saturation-factor, 1)*51.6%),52.2%)",
} as const; };
export const lightTheme: DefaultTheme = { export const lightTheme = {
...fixedColors, ...fixedColors,
...nodeColors.light,
BLACK_SECONDARY: "#F2F2F2", BLACK_SECONDARY: "#F2F2F2",
SILVER_DARK: "#CCCCCC", SILVER_DARK: "#CCCCCC",
NODE_KEY: "#DC3790", NODE_KEY: "#DC3790",
@ -58,4 +93,11 @@ export const lightTheme: DefaultTheme = {
MODAL_BACKGROUND: "#FFFFFF", MODAL_BACKGROUND: "#FFFFFF",
TEXT_NORMAL: "#2e3338", TEXT_NORMAL: "#2e3338",
TEXT_POSITIVE: "#008736", TEXT_POSITIVE: "#008736",
} as const; };
const themeDs = {
...lightTheme,
...darkTheme,
};
export default themeDs;

View File

@ -62,15 +62,14 @@ const HeroSection = () => {
Help JSON Crack&apos;s Goals Help JSON Crack&apos;s Goals
<FaHeart /> <FaHeart />
</Styles.StyledSponsorButton> </Styles.StyledSponsorButton>
<Link <Styles.StyledSponsorButton
href="https://marketplace.visualstudio.com/items?itemName=AykutSarac.jsoncrack-vscode" href="https://marketplace.visualstudio.com/items?itemName=AykutSarac.jsoncrack-vscode"
passHref link
isBlue
> >
<Styles.StyledSponsorButton isBlue> GET IT ON VS CODE
GET IT ON VS CODE <SiVisualstudiocode />
<SiVisualstudiocode /> </Styles.StyledSponsorButton>
</Styles.StyledSponsorButton>
</Link>
<GoalsModal visible={isModalVisible} setVisible={setModalVisible} /> <GoalsModal visible={isModalVisible} setVisible={setModalVisible} />
</Styles.StyledButtonWrapper> </Styles.StyledButtonWrapper>
</Styles.StyledHeroSection> </Styles.StyledHeroSection>
@ -220,6 +219,13 @@ const EmbedSection = () => (
navigate and understand even complex JSON data, making it a valuable tool for navigate and understand even complex JSON data, making it a valuable tool for
anyone working with JSON. anyone working with JSON.
</Styles.StyledMinorTitle> </Styles.StyledMinorTitle>
<Styles.StyledButton
href="https://jsoncrack.com/embed"
status="SECONDARY"
link
>
LEARN TO EMBED
</Styles.StyledButton>
</Styles.StyledSectionArea> </Styles.StyledSectionArea>
<div> <div>
<Styles.StyledIframge <Styles.StyledIframge
@ -227,9 +233,16 @@ const EmbedSection = () => (
onLoad={e => { onLoad={e => {
const frame = e.currentTarget.contentWindow; const frame = e.currentTarget.contentWindow;
setTimeout(() => { setTimeout(() => {
frame?.postMessage({ frame?.postMessage(
json: defaultJson, {
}); json: defaultJson,
options: {
theme: "dark",
direction: "DOWN"
}
},
"*"
);
}, 500); }, 500);
}} }}
></Styles.StyledIframge> ></Styles.StyledIframge>

View File

@ -3,10 +3,11 @@ import dynamic from "next/dynamic";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import toast from "react-hot-toast"; import toast from "react-hot-toast";
import { baseURL } from "src/constants/data"; import { baseURL } from "src/constants/data";
import { darkTheme, lightTheme } from "src/constants/theme";
import { NodeModal } from "src/containers/Modals/NodeModal"; import { NodeModal } from "src/containers/Modals/NodeModal";
import useGraph from "src/store/useGraph"; import useGraph from "src/store/useGraph";
import { parser } from "src/utils/jsonParser"; import { parser } from "src/utils/jsonParser";
import styled from "styled-components"; import styled, { ThemeProvider } from "styled-components";
const Graph = dynamic<any>(() => import("src/components/Graph").then(c => c.Graph), { const Graph = dynamic<any>(() => import("src/components/Graph").then(c => c.Graph), {
ssr: false, ssr: false,
@ -62,11 +63,13 @@ const WidgetPage = () => {
const [isModalVisible, setModalVisible] = React.useState(false); const [isModalVisible, setModalVisible] = React.useState(false);
const [selectedNode, setSelectedNode] = React.useState<[string, string][]>([]); const [selectedNode, setSelectedNode] = React.useState<[string, string][]>([]);
const [theme, setTheme] = React.useState("dark");
const collapsedNodes = useGraph(state => state.collapsedNodes); const collapsedNodes = useGraph(state => state.collapsedNodes);
const collapsedEdges = useGraph(state => state.collapsedEdges); const collapsedEdges = useGraph(state => state.collapsedEdges);
const loading = useGraph(state => state.loading); const loading = useGraph(state => state.loading);
const setNodeEdges = useGraph(state => state.setNodeEdges); const setNodeEdges = useGraph(state => state.setNodeEdges);
const setDirection = useGraph(state => state.setDirection);
const openModal = React.useCallback(() => setModalVisible(true), []); const openModal = React.useCallback(() => setModalVisible(true), []);
@ -92,9 +95,20 @@ const WidgetPage = () => {
const handler = (event: EmbedMessage) => { const handler = (event: EmbedMessage) => {
try { try {
if (!event.data?.json) return; if (!event.data?.json) return;
const { nodes, edges } = parser(event.data.json); const { nodes, edges } = parser(event.data.json);
setNodeEdges(nodes, edges); const options = {
direction: "RIGHT",
theme,
...event.data.options,
};
setDirection(options.direction);
if (options.theme === "light" || options.theme === "dark")
setTheme(options.theme);
setNodeEdges(nodes, edges);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
toast.error("Invalid JSON!"); toast.error("Invalid JSON!");
@ -103,7 +117,7 @@ const WidgetPage = () => {
window.addEventListener("message", handler); window.addEventListener("message", handler);
return () => window.removeEventListener("message", handler); return () => window.removeEventListener("message", handler);
}, [setNodeEdges]); }, [setDirection, setNodeEdges, theme]);
if (query.json) if (query.json)
return ( return (
@ -117,7 +131,7 @@ const WidgetPage = () => {
); );
return ( return (
<> <ThemeProvider theme={theme === "dark" ? darkTheme : lightTheme}>
<Graph openModal={openModal} setSelectedNode={setSelectedNode} isWidget /> <Graph openModal={openModal} setSelectedNode={setSelectedNode} isWidget />
<NodeModal <NodeModal
selectedNode={selectedNode} selectedNode={selectedNode}
@ -127,7 +141,7 @@ const WidgetPage = () => {
<StyledAttribute href={`${baseURL}/editor`} target="_blank" rel="noreferrer"> <StyledAttribute href={`${baseURL}/editor`} target="_blank" rel="noreferrer">
jsoncrack.com jsoncrack.com
</StyledAttribute> </StyledAttribute>
</> </ThemeProvider>
); );
}; };

View File

@ -1,38 +1,8 @@
import theme from "src/constants/theme";
import "styled-components"; import "styled-components";
declare module "styled-components" { type CustomTheme = typeof theme;
export interface DefaultTheme {
BLURPLE: string;
FULL_WHITE: string;
BLACK: string;
BLACK_LIGHT: string;
BLACK_DARK: string;
BLACK_PRIMARY: string;
BLACK_SECONDARY: string;
CRIMSON: string;
DARK_SALMON: string;
DANGER: string;
LIGHTGREEN: string;
SEAGREEN: string;
ORANGE: string;
SILVER: string;
SILVER_DARK: string;
PRIMARY: string;
NODE_KEY: string;
OBJECT_KEY: string;
SIDEBAR_ICONS: string;
INTERACTIVE_NORMAL: string; declare module "styled-components" {
INTERACTIVE_HOVER: string; export interface DefaultTheme extends CustomTheme {}
INTERACTIVE_ACTIVE: string;
BACKGROUND_NODE: string;
BACKGROUND_TERTIARY: string;
BACKGROUND_SECONDARY: string;
BACKGROUND_PRIMARY: string;
BACKGROUND_MODIFIER_ACCENT: string;
MODAL_BACKGROUND: string;
TEXT_NORMAL: string;
TEXT_POSITIVE: string;
TEXT_DANGER: string;
}
} }

View File

@ -7,6 +7,11 @@ export const getOutgoers = (
const outgoerNodes: NodeData[] = []; const outgoerNodes: NodeData[] = [];
const matchingNodes: string[] = []; const matchingNodes: string[] = [];
if (parent.includes(nodeId)) {
const initialParentNode = nodes.find(n => n.id === nodeId);
if (initialParentNode) outgoerNodes.push(initialParentNode);
}
const runner = (nodeId: string) => { const runner = (nodeId: string) => {
const outgoerIds = edges.filter(e => e.from === nodeId).map(e => e.to); const outgoerIds = edges.filter(e => e.from === nodeId).map(e => e.to);
const nodeList = nodes.filter(n => { const nodeList = nodes.filter(n => {

View File

@ -1,4 +1,4 @@
import { parse } from "jsonc-parser"; import { Node, parseTree } from "jsonc-parser";
const calculateSize = ( const calculateSize = (
text: string | [string, string][], text: string | [string, string][],
@ -32,113 +32,303 @@ const calculateSize = (
}; };
}; };
const filterChild = ([_, v]) => { export const parser = (jsonStr: string, isFolded = false) => {
const isNull = v === null; try {
const isArray = Array.isArray(v) && v.length; let json = parseTree(jsonStr);
const isObject = v instanceof Object; let nodes: NodeData[] = [];
let edges: EdgeData[] = [];
return !isNull && (isArray || isObject); const addNodes = (
}; text: any,
width: number,
const filterValues = ([k, v]) => { height: number,
if (Array.isArray(v) || v instanceof Object) return false; parent: "string" | "number" | "boolean" | "object" | "array" | "null" | false,
return true; isEmpty?: boolean
}; ) => {
let actualId = String(nodes.length + 1);
function generateChildren(object: Object, isFolded = false, nextId: () => string) { nodes = [
if (!(object instanceof Object)) object = [object]; ...nodes,
return Object.entries(object)
.filter(filterChild)
.flatMap(([key, v]) => {
const { width, height } = calculateSize(key, true, isFolded);
const children = extract(v, isFolded, nextId);
return [
{ {
id: nextId(), id: actualId,
text: key, text: text,
children, width: width,
width, height: height,
height,
data: { data: {
isParent: true, parent: parent === "array" || parent === "object" ? parent : false,
childrenCount: children.length, childrenCount: parent ? 1 : 0,
isEmpty: isEmpty,
}, },
}, },
]; ];
}); return actualId;
}
function generateNodeData(object: Object) {
if (object instanceof Object) {
const entries = Object.entries(object).filter(filterValues);
return entries;
}
return String(object);
}
const extract = (
os: string[] | object[] | null,
isFolded = false,
nextId = (
id => () =>
String(++id)
)(0)
) => {
if (!os) return [];
return [os].flat().map(o => {
const text = generateNodeData(o);
const { width, height } = calculateSize(text, false, isFolded);
return {
id: nextId(),
text,
width,
height,
children: generateChildren(o, isFolded, nextId),
data: {
isParent: false,
childrenCount: 0,
isEmpty: !text.length,
},
}; };
});
};
const flatten = (xs: { id: string; children: never[] }[]) => const addEdges = (from: string, to: string) => {
xs.flatMap(({ children, ...rest }) => [rest, ...flatten(children)]); edges = [
...edges,
{
id: `e${from}-${to}`,
from: from,
to: to,
},
];
};
const relationships = (xs: { id: string; children: never[] }[]) => { let parentName: string = "";
return xs.flatMap(({ id: from, children = [] }) => [ let bracketOpen: { id: string; type: string }[] = [];
...children.map(({ id: to }) => ({ let objectsFromArray: number[] = [];
id: `e${from}-${to}`, let objectsFromArrayId = 0;
from, let notHaveParent: string[] = [];
to, let brothersNode: [string, string][] = [];
})), let brothersParentId: string | undefined = "";
...relationships(children), let brotherKey: string = "";
]); let brothersNodeProps: {
}; id: string;
parentId: string | undefined;
objectsFromArrayId: number | undefined;
}[] = [];
export const parser = (jsonStr: string, isFolded = false) => { const traverse = (
try { objectToTraverse: Node,
let json = parse(jsonStr); parentType?: string,
if (!Array.isArray(json)) json = [json]; myParentId?: string,
const nodes: NodeData[] = []; nextType?: string
const edges: EdgeData[] = []; ) => {
let { type, children, value } = objectToTraverse;
const mappedElements = extract(json, isFolded); if (!children) {
const res = [...flatten(mappedElements), ...relationships(mappedElements)]; 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, isFolded);
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;
res.forEach(data => { if (type !== "property" && parentName !== "") {
if (isNode(data)) { // add last brothers node and add parent node
nodes.push(data);
} else { if (brothersNode.length > 0) {
edges.push(data); // 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,
isFolded
);
ModifyNodes[findNode].width = width;
ModifyNodes[findNode].height = height;
nodes = [...ModifyNodes];
brothersNode = [];
}
} else {
const { width, height } = calculateSize(brothersNode, false, isFolded);
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, isFolded);
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++];
}
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,
isFolded
);
ModifyNodes[findNode].width = width;
ModifyNodes[findNode].height = height;
nodes = [...ModifyNodes];
brothersNode = [];
}
} else {
const { width, height } = calculateSize(brothersNode, false, isFolded);
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, isFolded);
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, isFolded);
addNodes(text, width, height, false);
} else {
const text = "{}";
const { width, height } = calculateSize(text, false, isFolded);
addNodes(text, width, height, false);
}
}
}
return { nodes, edges }; return { nodes, edges };
} catch (error) { } catch (error) {
@ -149,8 +339,3 @@ export const parser = (jsonStr: string, isFolded = false) => {
}; };
} }
}; };
function isNode(element: NodeData | EdgeData) {
if ("text" in element) return true;
return false;
}