Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix filtered entities #741

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
- **Removed** unused `hidden` flag from schema types
([#737](https://github.com/aws/graph-explorer/pull/737))
- **Improved** entity filtering logic reducing re-renders
([#739](https://github.com/aws/graph-explorer/pull/739))
([#739](https://github.com/aws/graph-explorer/pull/739),
[741](https://github.com/aws/graph-explorer/pull/741))

## Release 1.13.0

Expand Down
16 changes: 6 additions & 10 deletions packages/graph-explorer/src/components/Graph/hooks/useRunLayout.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import cytoscape from "cytoscape";
import isEqual from "lodash/isEqual";
import { useEffect, useRef } from "react";
import type { CytoscapeType, GraphNode } from "../Graph.model";
import { runLayout } from "../helpers/layout";
Expand Down Expand Up @@ -27,22 +26,19 @@ function useUpdateLayout({
mounted,
nodes,
}: UseUpdateLayout) {
const previousNodesRef = useRef<typeof nodes>([]);
const previousNodesRef = useRef(new Set<string>());
const previousLayoutRef = useRef(layout);
const previousGraphStructureVersionRef = useRef(graphStructureVersion);

useEffect(() => {
if (cy && layout && mounted && cy.nodes().length) {
const prevIds: string[] = previousNodesRef.current.map(node => {
return node.data.id;
});

const shouldLock =
previousLayoutRef.current === layout &&
!isEqual(previousNodesRef.current, nodes);
previousGraphStructureVersionRef.current !== graphStructureVersion;

if (shouldLock) {
cy.nodes()
.filter(cyNode => prevIds.includes(cyNode.data().id))
.filter(cyNode => previousNodesRef.current.has(cyNode.data().id))
.forEach(node => {
node.lock();
});
Expand All @@ -53,13 +49,13 @@ function useUpdateLayout({

if (shouldLock) {
cy.nodes()
.filter(cyNode => prevIds.includes(cyNode.data().id))
.filter(cyNode => previousNodesRef.current.has(cyNode.data().id))
.forEach(node => {
node.unlock();
});
}

previousNodesRef.current = nodes;
previousNodesRef.current = new Set(nodes.map(node => node.data.id));
previousLayoutRef.current = layout;
}
// nodes variable is not a dependency because
Expand Down
6 changes: 0 additions & 6 deletions packages/graph-explorer/src/core/StateProvider/edges.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ export const edgesSelector = selector<Edges>({
};
// Clean all dependent states
get(edgesSelectedIdsAtom).size > 0 && set(edgesSelectedIdsAtom, cleanFn);
get(edgesHiddenIdsAtom).size > 0 && set(edgesHiddenIdsAtom, cleanFn);
get(edgesOutOfFocusIdsAtom).size > 0 &&
set(edgesOutOfFocusIdsAtom, cleanFn);
get(edgesFilteredIdsAtom).size > 0 && set(edgesFilteredIdsAtom, cleanFn);
Expand All @@ -60,11 +59,6 @@ export const edgesSelectedIdsAtom = atom<Set<EdgeId>>({
default: new Set(),
});

export const edgesHiddenIdsAtom = atom<Set<EdgeId>>({
key: "edges-hidden-ids",
default: new Set(),
});

export const edgesOutOfFocusIdsAtom = atom<Set<EdgeId>>({
key: "edges-out-of-focus-ids",
default: new Set(),
Expand Down
16 changes: 11 additions & 5 deletions packages/graph-explorer/src/core/StateProvider/entitiesSelector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@ import isEqualWith from "lodash/isEqualWith";
import type { GetRecoilValue, RecoilState, SetRecoilState } from "recoil";
import { selector } from "recoil";
import type { Edge, EdgeId, Vertex, VertexId } from "@/types/entities";
import { edgesAtom, edgesSelectedIdsAtom, edgesSelector } from "./edges";
import {
edgesAtom,
edgesSelectedIdsAtom,
edgesSelector,
filteredEdgesSelector,
} from "./edges";
import {
filteredNodesSelector,
nodesAtom,
nodesHiddenIdsAtom,
nodesFilteredIdsAtom,
nodesSelectedIdsAtom,
nodesSelector,
} from "./nodes";
Expand Down Expand Up @@ -52,8 +58,8 @@ const entitiesSelector = selector<Entities>({
key: "entities",
get: ({ get }) => {
return {
nodes: get(nodesAtom),
edges: get(edgesAtom),
nodes: get(filteredNodesSelector),
edges: get(filteredEdgesSelector),
};
},
set: ({ get, set }, newEntities) => {
Expand Down Expand Up @@ -158,7 +164,7 @@ const entitiesSelector = selector<Entities>({

// When a node is removed, we should delete its id from other nodes-state sets
if (deletedNodesIds.size > 0) {
[nodesSelectedIdsAtom, nodesHiddenIdsAtom].forEach(selector => {
[nodesSelectedIdsAtom, nodesFilteredIdsAtom].forEach(selector => {
removeFromSetIfDeleted(
{
get,
Expand Down
6 changes: 0 additions & 6 deletions packages/graph-explorer/src/core/StateProvider/nodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ export const nodesSelector = selector<Map<VertexId, Vertex>>({
};
// Clean all dependent states
get(nodesSelectedIdsAtom).size > 0 && set(nodesSelectedIdsAtom, cleanFn);
get(nodesHiddenIdsAtom).size > 0 && set(nodesHiddenIdsAtom, cleanFn);
get(nodesOutOfFocusIdsAtom).size > 0 &&
set(nodesOutOfFocusIdsAtom, cleanFn);
get(nodesFilteredIdsAtom).size > 0 && set(nodesFilteredIdsAtom, cleanFn);
Expand All @@ -56,11 +55,6 @@ export const nodesSelectedIdsAtom = atom<Set<VertexId>>({
default: new Set(),
});

export const nodesHiddenIdsAtom = atom<Set<VertexId>>({
key: "nodes-hidden-ids",
default: new Set(),
});

export const nodesOutOfFocusIdsAtom = atom<Set<VertexId>>({
key: "nodes-out-of-focus-ids",
default: new Set(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@ import { useRecoilCallback } from "recoil";
import {
edgesAtom,
edgesFilteredIdsAtom,
edgesHiddenIdsAtom,
edgesOutOfFocusIdsAtom,
edgesSelectedIdsAtom,
edgesTypesFilteredAtom,
} from "./edges";
import {
nodesAtom,
nodesFilteredIdsAtom,
nodesHiddenIdsAtom,
nodesOutOfFocusIdsAtom,
nodesSelectedIdsAtom,
nodesTypesFilteredAtom,
Expand All @@ -28,13 +26,11 @@ export default function useResetState() {
() => {
reset(nodesAtom);
reset(nodesSelectedIdsAtom);
reset(nodesHiddenIdsAtom);
reset(nodesOutOfFocusIdsAtom);
reset(nodesFilteredIdsAtom);
reset(nodesTypesFilteredAtom);
reset(edgesAtom);
reset(edgesSelectedIdsAtom);
reset(edgesHiddenIdsAtom);
reset(edgesOutOfFocusIdsAtom);
reset(edgesFilteredIdsAtom);
reset(edgesTypesFilteredAtom);
Expand Down
36 changes: 5 additions & 31 deletions packages/graph-explorer/src/hooks/useEntities.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,7 @@
import { useMemo } from "react";
import { SetterOrUpdater, useRecoilValue, useSetRecoilState } from "recoil";
import type { Edge, EdgeId, Vertex, VertexId } from "@/types/entities";
import entitiesSelector, {
Entities,
} from "@/core/StateProvider/entitiesSelector";
import { filteredNodesSelector, filteredEdgesSelector } from "@/core";
import { useRecoilState } from "recoil";
import entitiesSelector from "@/core/StateProvider/entitiesSelector";

type ProcessedEntities = {
nodes: Map<VertexId, Vertex>;
edges: Map<EdgeId, Edge>;
};

/** Returns the current set of filtered entities. */
export default function useEntities(): [
ProcessedEntities,
SetterOrUpdater<Entities>,
] {
const setEntities = useSetRecoilState(entitiesSelector);

const filteredNodes = useRecoilValue(filteredNodesSelector);
const filteredEdges = useRecoilValue(filteredEdgesSelector);

const filteredEntities = useMemo(
() => ({
nodes: filteredNodes,
edges: filteredEdges,
}),
[filteredEdges, filteredNodes]
);

return [filteredEntities, setEntities];
/** Returns the current set of entities. */
export default function useEntities() {
return useRecoilState(entitiesSelector);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
} from "@/components/Tabular/controls";
import Tabular from "@/components/Tabular/Tabular";
import {
edgesHiddenIdsAtom,
edgesFilteredIdsAtom,
edgesOutOfFocusIdsAtom,
edgesSelectedIdsAtom,
} from "@/core/StateProvider/edges";
Expand All @@ -28,7 +28,7 @@ const EdgesTabular = forwardRef<TabularInstance<ToggleEdge>, any>(
const edges = useDisplayEdgesInCanvas();
const setEdgesOut = useSetRecoilState(edgesOutOfFocusIdsAtom);
const [hiddenEdgesIds, setHiddenEdgesIds] =
useRecoilState(edgesHiddenIdsAtom);
useRecoilState(edgesFilteredIdsAtom);
const setSelectedNodesIds = useSetRecoilState(nodesSelectedIdsAtom);
const [selectedEdgesIds, setSelectedEdgesIds] =
useRecoilState(edgesSelectedIdsAtom);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import Tabular from "@/components/Tabular/Tabular";
import { DisplayVertex, useDisplayVerticesInCanvas } from "@/core";
import { edgesSelectedIdsAtom } from "@/core/StateProvider/edges";
import {
nodesHiddenIdsAtom,
nodesFilteredIdsAtom,
nodesOutOfFocusIdsAtom,
nodesSelectedIdsAtom,
} from "@/core/StateProvider/nodes";
Expand All @@ -31,7 +31,7 @@ const NodesTabular = forwardRef<TabularInstance<ToggleVertex>, any>(
const displayNodes = useDisplayVerticesInCanvas();
const setNodesOut = useSetRecoilState(nodesOutOfFocusIdsAtom);
const [hiddenNodesIds, setHiddenNodesIds] =
useRecoilState(nodesHiddenIdsAtom);
useRecoilState(nodesFilteredIdsAtom);
const [selectedNodesIds, setSelectedNodesIds] =
useRecoilState(nodesSelectedIdsAtom);
const setSelectedEdgesIds = useSetRecoilState(edgesSelectedIdsAtom);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,10 @@ import InfoIcon from "@/components/icons/InfoIcon";
import ScreenshotIcon from "@/components/icons/ScreenshotIcon";
import Select from "@/components/Select";
import {
edgesHiddenIdsAtom,
edgesOutOfFocusIdsAtom,
edgesSelectedIdsAtom,
} from "@/core/StateProvider/edges";
import {
nodesHiddenIdsAtom,
nodesOutOfFocusIdsAtom,
nodesSelectedIdsAtom,
} from "@/core/StateProvider/nodes";
Expand Down Expand Up @@ -99,11 +97,9 @@ export default function GraphViewer({

const [nodesSelectedIds, setNodesSelectedIds] =
useRecoilState(nodesSelectedIdsAtom);
const hiddenNodesIds = useRecoilValue(nodesHiddenIdsAtom);

const [edgesSelectedIds, setEdgesSelectedIds] =
useRecoilState(edgesSelectedIdsAtom);
const hiddenEdgesIds = useRecoilValue(edgesHiddenIdsAtom);
const nodesOutIds = useRecoilValue(nodesOutOfFocusIdsAtom);
const edgesOutIds = useRecoilValue(edgesOutOfFocusIdsAtom);

Expand Down Expand Up @@ -250,9 +246,7 @@ export default function GraphViewer({
badgesEnabled={false}
getNodeBadges={getNodeBadges(nodesOutIds)}
selectedNodesIds={nodesSelectedIds}
hiddenNodesIds={hiddenNodesIds}
selectedEdgesIds={edgesSelectedIds}
hiddenEdgesIds={hiddenEdgesIds}
outOfFocusNodesIds={nodesOutIds}
outOfFocusEdgesIds={edgesOutIds}
onSelectedElementIdsChange={onSelectedElementIdsChange}
Expand Down
Loading