mirror of
https://github.com/AykutSarac/jsoncrack.com.git
synced 2025-01-27 15:22:56 +08:00
Added a 'Collapse/Expand Graph' button
This commit is contained in:
parent
50a553a022
commit
a3e110a1ea
@ -11,7 +11,12 @@ import {
|
|||||||
AiOutlineLink,
|
AiOutlineLink,
|
||||||
AiOutlineEdit,
|
AiOutlineEdit,
|
||||||
} from "react-icons/ai";
|
} from "react-icons/ai";
|
||||||
import { CgArrowsMergeAltH, CgArrowsShrinkH } from "react-icons/cg";
|
import {
|
||||||
|
CgArrowsMergeAltH,
|
||||||
|
CgArrowsMergeAltV,
|
||||||
|
CgArrowsShrinkH,
|
||||||
|
CgArrowsShrinkV,
|
||||||
|
} from "react-icons/cg";
|
||||||
import { FiDownload } from "react-icons/fi";
|
import { FiDownload } from "react-icons/fi";
|
||||||
import { HiHeart } from "react-icons/hi";
|
import { HiHeart } from "react-icons/hi";
|
||||||
import { MdCenterFocusWeak } from "react-icons/md";
|
import { MdCenterFocusWeak } from "react-icons/md";
|
||||||
@ -22,6 +27,7 @@ import { DownloadModal } from "src/containers/Modals/DownloadModal";
|
|||||||
import { ImportModal } from "src/containers/Modals/ImportModal";
|
import { ImportModal } from "src/containers/Modals/ImportModal";
|
||||||
import { ShareModal } from "src/containers/Modals/ShareModal";
|
import { ShareModal } from "src/containers/Modals/ShareModal";
|
||||||
import useConfig from "src/hooks/store/useConfig";
|
import useConfig from "src/hooks/store/useConfig";
|
||||||
|
import useGraph from "src/hooks/store/useGraph";
|
||||||
import { getNextLayout } from "src/utils/getNextLayout";
|
import { getNextLayout } from "src/utils/getNextLayout";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import shallow from "zustand/shallow";
|
import shallow from "zustand/shallow";
|
||||||
@ -154,6 +160,8 @@ export const Sidebar: React.FC = () => {
|
|||||||
shallow
|
shallow
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { collapseGraph, expandGraph, graphCollapsed } = useGraph();
|
||||||
|
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
const a = document.createElement("a");
|
const a = document.createElement("a");
|
||||||
const file = new Blob([getJson()], { type: "text/plain" });
|
const file = new Blob([getJson()], { type: "text/plain" });
|
||||||
@ -163,9 +171,9 @@ export const Sidebar: React.FC = () => {
|
|||||||
a.click();
|
a.click();
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleExpandCollapse = () => {
|
const toggleExpandShrink = () => {
|
||||||
setConfig("expand", !expand);
|
setConfig("expand", !expand);
|
||||||
toast(`${expand ? "Collapsed" : "Expanded"} nodes.`);
|
toast(`${expand ? "Shrunk" : "Expanded"} nodes.`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleLayout = () => {
|
const toggleLayout = () => {
|
||||||
@ -173,6 +181,15 @@ export const Sidebar: React.FC = () => {
|
|||||||
setConfig("layout", nextLayout);
|
setConfig("layout", nextLayout);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const toggleExpandCollapseGraph = () => {
|
||||||
|
if (graphCollapsed) {
|
||||||
|
expandGraph();
|
||||||
|
} else {
|
||||||
|
collapseGraph();
|
||||||
|
}
|
||||||
|
toast(`${graphCollapsed ? "Expanded" : "Collapsed"} graph.`);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledSidebar>
|
<StyledSidebar>
|
||||||
<StyledTopWrapper>
|
<StyledTopWrapper>
|
||||||
@ -206,13 +223,21 @@ export const Sidebar: React.FC = () => {
|
|||||||
className="desktop"
|
className="desktop"
|
||||||
title={expand ? "Shrink Nodes" : "Expand Nodes"}
|
title={expand ? "Shrink Nodes" : "Expand Nodes"}
|
||||||
>
|
>
|
||||||
<StyledElement
|
<StyledElement title="Toggle Expand/Shrink" onClick={toggleExpandShrink}>
|
||||||
title="Toggle Expand/Collapse"
|
|
||||||
onClick={toggleExpandCollapse}
|
|
||||||
>
|
|
||||||
{expand ? <CgArrowsMergeAltH /> : <CgArrowsShrinkH />}
|
{expand ? <CgArrowsMergeAltH /> : <CgArrowsShrinkH />}
|
||||||
</StyledElement>
|
</StyledElement>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
<Tooltip
|
||||||
|
className="desktop"
|
||||||
|
title={graphCollapsed ? "Expand Graph" : "Collapse Graph"}
|
||||||
|
>
|
||||||
|
<StyledElement
|
||||||
|
title="Expand/Collapse Graph"
|
||||||
|
onClick={toggleExpandCollapseGraph}
|
||||||
|
>
|
||||||
|
{graphCollapsed ? <CgArrowsShrinkV /> : <CgArrowsMergeAltV />}
|
||||||
|
</StyledElement>
|
||||||
|
</Tooltip>
|
||||||
<Tooltip className="desktop" title="Save JSON">
|
<Tooltip className="desktop" title="Save JSON">
|
||||||
<StyledElement onClick={handleSave}>
|
<StyledElement onClick={handleSave}>
|
||||||
<AiOutlineSave />
|
<AiOutlineSave />
|
||||||
|
@ -5,6 +5,7 @@ import create from "zustand";
|
|||||||
|
|
||||||
const initialStates = {
|
const initialStates = {
|
||||||
loading: false,
|
loading: false,
|
||||||
|
graphCollapsed: false,
|
||||||
nodes: [] as NodeData[],
|
nodes: [] as NodeData[],
|
||||||
edges: [] as EdgeData[],
|
edges: [] as EdgeData[],
|
||||||
collapsedNodes: [] as string[],
|
collapsedNodes: [] as string[],
|
||||||
@ -18,6 +19,8 @@ interface GraphActions {
|
|||||||
setGraphValue: (key: keyof Graph, value: any) => void;
|
setGraphValue: (key: keyof Graph, value: any) => void;
|
||||||
expandNodes: (nodeId: string) => void;
|
expandNodes: (nodeId: string) => void;
|
||||||
collapseNodes: (nodeId: string) => void;
|
collapseNodes: (nodeId: string) => void;
|
||||||
|
collapseGraph: () => void;
|
||||||
|
expandGraph: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const useGraph = create<Graph & GraphActions>((set, get) => ({
|
const useGraph = create<Graph & GraphActions>((set, get) => ({
|
||||||
@ -53,6 +56,7 @@ const useGraph = create<Graph & GraphActions>((set, get) => ({
|
|||||||
collapsedParents,
|
collapsedParents,
|
||||||
collapsedNodes,
|
collapsedNodes,
|
||||||
collapsedEdges,
|
collapsedEdges,
|
||||||
|
graphCollapsed: false,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
collapseNodes: nodeId => {
|
collapseNodes: nodeId => {
|
||||||
@ -68,6 +72,42 @@ const useGraph = create<Graph & GraphActions>((set, get) => ({
|
|||||||
collapsedEdges: get().collapsedEdges.concat(edgeIds),
|
collapsedEdges: get().collapsedEdges.concat(edgeIds),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
collapseGraph: () => {
|
||||||
|
const edges = get().edges;
|
||||||
|
const tos = edges.map(edge => edge.to);
|
||||||
|
const froms = edges.map(edge => edge.from);
|
||||||
|
const parentNodesIds = froms.filter(id => !tos.includes(id));
|
||||||
|
const secondDegreeNodesIds = edges
|
||||||
|
.filter(edge => parentNodesIds.includes(edge.from))
|
||||||
|
.map(edge => edge.to);
|
||||||
|
|
||||||
|
set({
|
||||||
|
collapsedParents: get()
|
||||||
|
.nodes.filter(
|
||||||
|
node => !parentNodesIds.includes(node.id) && node.data.isParent
|
||||||
|
)
|
||||||
|
.map(node => node.id),
|
||||||
|
collapsedNodes: get()
|
||||||
|
.nodes.filter(
|
||||||
|
node =>
|
||||||
|
!parentNodesIds.includes(node.id) &&
|
||||||
|
!secondDegreeNodesIds.includes(node.id)
|
||||||
|
)
|
||||||
|
.map(node => node.id),
|
||||||
|
collapsedEdges: get()
|
||||||
|
.edges.filter(edge => !parentNodesIds.includes(edge.from))
|
||||||
|
.map(edge => edge.id),
|
||||||
|
graphCollapsed: true,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
expandGraph: () => {
|
||||||
|
set({
|
||||||
|
collapsedNodes: [],
|
||||||
|
collapsedEdges: [],
|
||||||
|
collapsedParents: [],
|
||||||
|
graphCollapsed: false,
|
||||||
|
});
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export default useGraph;
|
export default useGraph;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user