prevent expand btn expanding all

This commit is contained in:
AykutSarac 2022-09-12 21:03:25 +03:00
parent 263696ed88
commit 41638eb35b
5 changed files with 42 additions and 22 deletions

View File

@ -5,7 +5,6 @@
## Enhancements:
- [ ] Prevent expand button expanding all nodes, should expand only target node
- [ ] Clear rewrite of [parsing algorithm](/src/utils/jsonParser.ts)
- [ ] Performance Optimization
- [ ] Fix `useInViewport` hook for performance

View File

@ -1,5 +1,5 @@
import React from "react";
import { MdCompareArrows } from "react-icons/md";
import { MdLink, MdLinkOff } from "react-icons/md";
import { useInViewport } from "react-in-viewport";
import { CustomNodeProps } from "src/components/CustomNode";
import useConfig from "src/hooks/store/useConfig";
@ -57,13 +57,15 @@ const TextNode: React.FC<TextNodeProps> = ({
const hideCollapse = useStored((state) => state.hideCollapse);
const expandNodes = useGraph((state) => state.expandNodes);
const collapseNodes = useGraph((state) => state.collapseNodes);
const [isExpanded, setIsExpanded] = React.useState(true);
const isExpanded = useGraph((state) =>
state.collapsedParents.includes(node.id)
);
const handleExpand = (e: React.MouseEvent<HTMLButtonElement>) => {
e.stopPropagation();
setIsExpanded(!isExpanded);
// setIsExpanded(!isExpanded);
if (isExpanded) collapseNodes(node.id);
if (!isExpanded) collapseNodes(node.id);
else expandNodes(node.id);
};
@ -94,7 +96,11 @@ const TextNode: React.FC<TextNodeProps> = ({
{inViewport && isParent && hasCollapse && !hideCollapse && (
<StyledExpand onClick={handleExpand}>
<MdCompareArrows size={18} />
{isExpanded ? (
<MdLinkOff size={18} />
) : (
<MdLink size={18} />
)}
</StyledExpand>
)}
</StyledTextNodeWrapper>

View File

@ -1,5 +1,6 @@
import React from "react";
import { Node, NodeProps } from "reaflow";
import useGraph from "src/hooks/store/useGraph";
import ObjectNode from "./ObjectNode";
import TextNode from "./TextNode";

View File

@ -7,6 +7,7 @@ export interface Graph {
edges: EdgeData[];
collapsedNodes: string[];
collapsedEdges: string[];
collapsedParents: string[];
}
interface GraphActions {
@ -20,6 +21,7 @@ const initialStates: Graph = {
edges: [],
collapsedNodes: [],
collapsedEdges: [],
collapsedParents: [],
};
const useGraph = create<Graph & GraphActions>((set, get) => ({
@ -31,29 +33,36 @@ const useGraph = create<Graph & GraphActions>((set, get) => ({
[key]: value,
}),
expandNodes: (nodeId) => {
const childrenNodes = getOutgoers(nodeId, get().nodes, get().edges);
const [childrenNodes, matchingNodes] = getOutgoers(
nodeId,
get().nodes,
get().edges,
get().collapsedParents
);
const childrenEdges = getChildrenEdges(childrenNodes, get().edges);
const nodeIds = childrenNodes.map((node) => node.id);
const nodeIds = childrenNodes.map((node) => node.id).concat(matchingNodes);
const edgeIds = childrenEdges.map((edge) => edge.id);
const collapsedParents = get().collapsedParents.filter((cp) => cp !== nodeId);
const collapsedNodes = get().collapsedNodes.filter((nodeId) => !nodeIds.includes(nodeId));
const collapsedEdges = get().collapsedEdges.filter((edgeId) => !edgeIds.includes(edgeId));
set({
collapsedNodes: get().collapsedNodes.filter(
(nodeId) => !nodeIds.includes(nodeId)
),
collapsedEdges: get().collapsedEdges.filter(
(edgeId) => !edgeIds.includes(edgeId)
),
collapsedParents,
collapsedNodes,
collapsedEdges,
});
},
collapseNodes: (nodeId) => {
const childrenNodes = getOutgoers(nodeId, get().nodes, get().edges);
const [childrenNodes] = getOutgoers(nodeId, get().nodes, get().edges);
const childrenEdges = getChildrenEdges(childrenNodes, get().edges);
const nodeIds = childrenNodes.map((node) => node.id);
const edgeIds = childrenEdges.map((edge) => edge.id);
set({
collapsedParents: get().collapsedParents.concat(nodeId),
collapsedNodes: get().collapsedNodes.concat(nodeIds),
collapsedEdges: get().collapsedEdges.concat(edgeIds),
});

View File

@ -1,18 +1,23 @@
export const getOutgoers = (
nodeId: string,
nodes: NodeData[],
edges: EdgeData[]
): NodeData[] => {
const allOutgoers: NodeData[] = [];
edges: EdgeData[],
parent: string[] = []
): [NodeData[], string[]] => {
const outgoerNodes: NodeData[] = [];
const matchingNodes: string[] = [];
const runner = (nodeId: string) => {
const outgoerIds = edges.filter((e) => e.from === nodeId).map((e) => e.to);
const nodeList = nodes.filter((n) => outgoerIds.includes(n.id));
allOutgoers.push(...nodeList);
const nodeList = nodes.filter((n) => {
if (parent.includes(n.id) && !matchingNodes.includes(n.id)) matchingNodes.push(n.id);
return outgoerIds.includes(n.id) && !parent.includes(n.id);
});
outgoerNodes.push(...nodeList);
nodeList.forEach((node) => runner(node.id));
};
runner(nodeId);
return allOutgoers;
return [outgoerNodes, matchingNodes];
};