-
Notifications
You must be signed in to change notification settings - Fork 7
Feature/provenance updates #804
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
Changes from 11 commits
66ba8b0
e40d613
e89180f
ecd6496
9c54013
7bdd560
1aa1a6b
3acd566
a1706ef
b03188a
3df4303
7256b21
b2f2fec
90fc19f
dddd5cb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,18 @@ | ||
| import { SpinnerSize } from "@fluentui/react"; | ||
| import { Edge, ReactFlow, EdgeTypes, useNodesState, useEdgesState } from "@xyflow/react"; | ||
| import { DefaultButton, Icon, SpinnerSize } from "@fluentui/react"; | ||
| import { | ||
| Edge, | ||
| ReactFlow, | ||
| EdgeTypes, | ||
| useNodesState, | ||
| useEdgesState, | ||
| Controls, | ||
| useReactFlow, | ||
| ReactFlowProvider, | ||
| } from "@xyflow/react"; | ||
| import "@xyflow/react/dist/style.css"; | ||
| import classNames from "classnames"; | ||
| import React from "react"; | ||
| import { useSelector } from "react-redux"; | ||
| import { useDispatch, useSelector } from "react-redux"; | ||
|
|
||
| import DefaultEdge from "./Edges/DefaultEdge"; | ||
| import FileNode from "./Nodes/FileNode"; | ||
|
|
@@ -19,6 +28,7 @@ import { | |
| import { interaction, selection } from "../../state"; | ||
|
|
||
| import styles from "./NetworkGraph.module.css"; | ||
| import buttonStyles from "../Buttons/TertiaryButton.module.css"; | ||
|
|
||
| interface NetworkGraphProps { | ||
| className?: string; | ||
|
|
@@ -37,20 +47,8 @@ const NODE_TYPES = { | |
| * Component for rendering a graph at the given origin | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is awesome! What do you think about one step further so that no user of the component has to really think about it? This way they would import an already wrapped graph, but that part is shoved away nicely (IMO)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That makes sense to me! Implemented in dddd5cb, I was split on whether or not to rename the import in RelationshipDiagram but left it as is for now, open to changing it |
||
| */ | ||
| export default function NetworkGraph(props: NetworkGraphProps) { | ||
| const graph = useSelector(interaction.selectors.getGraph); | ||
| const isLoading = useSelector(interaction.selectors.isGraphLoading); | ||
| const refreshKey = useSelector(interaction.selectors.getGraphRefreshKey); | ||
| const provenanceSource = useSelector(selection.selectors.getSelectedSourceProvenance); | ||
| const [edges, setEdges, onEdgesChange] = useEdgesState<Edge<AnnotationEdge>>([]); | ||
| const [nodes, setNodes, onNodesChange] = useNodesState<FileNodeType | MetadataNodeType>([]); | ||
|
|
||
| // Unfortunately we have to have some notion of state at a high level for control from the components | ||
| // and at the dagre level for when the user does a drag action causing this duplication of efforts | ||
| React.useEffect(() => { | ||
| setEdges(graph.edges); | ||
| setNodes(graph.nodes); | ||
| }, [graph, setEdges, setNodes, refreshKey]); | ||
|
|
||
| // The option to open this graph shouldn't even appear when a | ||
| // source isn't available so this shouldn't ever happen | ||
| if (!provenanceSource) { | ||
|
|
@@ -65,26 +63,73 @@ export default function NetworkGraph(props: NetworkGraphProps) { | |
| ); | ||
| } | ||
|
|
||
| // The ReactFlow component can only access state (useReactFlow) if it's the child of a ReactFlowProvider | ||
| // See https://reactflow.dev/learn/troubleshooting/common-errors#001 | ||
| function ReactFlowComponent() { | ||
|
aswallace marked this conversation as resolved.
Outdated
|
||
| const dispatch = useDispatch(); | ||
| const [edges, setEdges, onEdgesChange] = useEdgesState<Edge<AnnotationEdge>>([]); | ||
| const [nodes, setNodes, onNodesChange] = useNodesState<FileNodeType | MetadataNodeType>([]); | ||
| const graph = useSelector(interaction.selectors.getGraph); | ||
| const refreshKey = useSelector(interaction.selectors.getGraphRefreshKey); | ||
| // Unfortunately we have to have some notion of state at a high level for control from the components | ||
| // and at the dagre level for when the user does a drag action causing this duplication of efforts | ||
| React.useEffect(() => { | ||
| let cancel = false; | ||
| if (!cancel) { | ||
| setEdges(graph.edges); | ||
| setNodes(graph.nodes); | ||
| } | ||
| return function cleanup() { | ||
| cancel = true; | ||
| }; | ||
| }, [graph, setEdges, setNodes, refreshKey]); | ||
| const { fitView } = useReactFlow(); | ||
| const onClickReset = () => { | ||
| graph.resetLayout(); // return to default layout if any | ||
| fitView(); // reset zoom | ||
| dispatch(interaction.actions.refreshGraph()); | ||
| }; | ||
| return ( | ||
| <> | ||
| <DefaultButton | ||
|
SeanDuHare marked this conversation as resolved.
Outdated
|
||
| className={classNames(buttonStyles.button, styles.refreshButton)} | ||
| title="Reset graph to initial state" | ||
| onClick={onClickReset} | ||
| > | ||
| <Icon iconName="Refresh" /> | ||
| Reset view | ||
| </DefaultButton> | ||
| <ReactFlow | ||
| fitView | ||
| onlyRenderVisibleElements | ||
| className={styles.graph} | ||
| edgesFocusable={false} | ||
| nodesDraggable={false} | ||
| nodesConnectable={false} | ||
| nodesFocusable={false} | ||
| elementsSelectable={true} | ||
| edgesReconnectable={false} | ||
| colorMode="dark" | ||
| nodes={nodes} | ||
| edges={edges} | ||
| edgeTypes={EDGE_TYPES} | ||
| nodeTypes={NODE_TYPES} | ||
| proOptions={{ hideAttribution: true }} | ||
| onNodesChange={onNodesChange} | ||
| onEdgesChange={onEdgesChange} | ||
| > | ||
| <Controls showInteractive={false} /> | ||
| </ReactFlow> | ||
| </> | ||
| ); | ||
| } | ||
|
|
||
| // The wrapped ReactFlow component | ||
| return ( | ||
| <div className={props.className}> | ||
| <ReactFlow | ||
| fitView | ||
| onlyRenderVisibleElements | ||
| className={styles.graph} | ||
| edgesFocusable={false} | ||
| nodesConnectable={false} | ||
| nodesFocusable={false} | ||
| elementsSelectable={false} | ||
| edgesReconnectable={false} | ||
| colorMode="dark" | ||
| nodes={nodes} | ||
| edges={edges} | ||
| edgeTypes={EDGE_TYPES} | ||
| nodeTypes={NODE_TYPES} | ||
| proOptions={{ hideAttribution: true }} | ||
| onNodesChange={onNodesChange} | ||
| onEdgesChange={onEdgesChange} | ||
| /> | ||
| <div className={classNames(props.className, styles.reactFlow)}> | ||
| <ReactFlowProvider> | ||
| <ReactFlowComponent /> | ||
| </ReactFlowProvider> | ||
| </div> | ||
| ); | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.