diff --git a/react/src/components/graph/InvestigationGraph.tsx b/react/src/components/graph/InvestigationGraph.tsx index 3f0c529..cb82a4c 100644 --- a/react/src/components/graph/InvestigationGraph.tsx +++ b/react/src/components/graph/InvestigationGraph.tsx @@ -1,18 +1,18 @@ -import { useState, useMemo } from 'react' -import ReactFlow, { useNodesState, useEdgesState, MarkerType } from 'reactflow' -import 'reactflow/dist/style.css' -import WorkNode from './nodes/WorkNode.tsx' -import AuthorNode from './nodes/AuthorNode.tsx' -import NoteNode from './nodes/NoteNode.tsx' -import WorkEdge from './edges/WorkEdge.tsx' -import AuthorshipEdge from './edges/AuthorshipEdge.tsx' +import { useState, useMemo, useEffect } from "react"; +import ReactFlow, { useNodesState, useEdgesState, MarkerType } from "reactflow"; +import "reactflow/dist/style.css"; +import WorkNode from "./nodes/WorkNode.tsx"; +import AuthorNode from "./nodes/AuthorNode.tsx"; +import NoteNode from "./nodes/NoteNode.tsx"; +import WorkEdge from "./edges/WorkEdge.tsx"; +import AuthorshipEdge from "./edges/AuthorshipEdge.tsx"; interface Props { - workNodes: WorkNode[] - authorNodes: AuthorNode[] + workNodes: WorkNode[]; + authorNodes: AuthorNode[]; // noteNodes: NoteNode[]; - workEdges: WorkEdge[] - authorshipEdges: AuthorshipEdge[] + workEdges: WorkEdge[]; + authorshipEdges: AuthorshipEdge[]; } function InvestigationGraph({ @@ -20,19 +20,20 @@ function InvestigationGraph({ authorNodes, // noteNodes, workEdges, - authorshipEdges + authorshipEdges, }: Props) { const nodeTypes = useMemo( () => ({ work: WorkNode, - author: AuthorNode + author: AuthorNode, // note: NoteNode, }), [] - ) + ); - const initialNodes = [] - const initialEdges = [] + + const initialNodes = []; + const initialEdges = []; // works for (let i = 0; i <= workNodes.length - 1; i++) { @@ -41,10 +42,10 @@ function InvestigationGraph({ id: `work-${workNodes[i].id}`, position: { x: workNodes[i].xCoordinate, y: workNodes[i].yCoordinate }, data: { - workData: workNodes[i] + workData: workNodes[i], }, - type: 'work' - }) + type: "work", + }); } } @@ -55,13 +56,13 @@ function InvestigationGraph({ id: `author-${authorNodes[i].id}`, position: { x: authorNodes[i].xCoordinate, - y: authorNodes[i].yCoordinate + y: authorNodes[i].yCoordinate, }, data: { - authorData: authorNodes[i] + authorData: authorNodes[i], }, - type: 'author' - }) + type: "author", + }); } } @@ -72,18 +73,18 @@ function InvestigationGraph({ source: `work-${workEdges[i].citationNode.id}`, target: `work-${workEdges[i].referenceNode.id}`, id: `workedge-${workEdges[i].id}`, - label: 'hello', + label: "citation/reference", style: { strokeWidth: 2, - stroke: '#FF0072' + stroke: "#FF0072", }, markerStart: { type: MarkerType.ArrowClosed, width: 20, height: 20, - color: '#FF0072' - } - }) + color: "#FF0072", + }, + }); } } @@ -94,20 +95,20 @@ function InvestigationGraph({ source: `author-${authorshipEdges[i].authorNode.id}`, target: `work-${authorshipEdges[i].workNode.id}`, id: `authorshipedge-${authorshipEdges[i].id}`, - label: 'bbq chips', + label: "authored", style: { strokeWidth: 4, - stroke: '#008000' - } - }) + stroke: "#008000", + }, + }); } } - const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes) - const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges) + const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); + const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); return ( -
+
- ) + ); } -export default InvestigationGraph +export default InvestigationGraph; diff --git a/react/src/components/graph/nodes/WorkNode.tsx b/react/src/components/graph/nodes/WorkNode.tsx index 6eb8cfb..e1fa701 100644 --- a/react/src/components/graph/nodes/WorkNode.tsx +++ b/react/src/components/graph/nodes/WorkNode.tsx @@ -7,6 +7,7 @@ import { USE_INVESTIGATION_GRAPH } from "../../../hooks/useInvestigationGraph"; import WorkDetails from "./WorkDetails"; import { ADD_REFERENCES } from "../../../hooks/ADD_REFERENCES"; import { ADD_CITATIONS } from "../../../hooks/ADD_CITATIONS"; +import { UPDATE_WORK_NODE } from "../../../hooks/UPDATE_WORK_NODE"; interface WorkNode { id: number; @@ -18,9 +19,35 @@ interface WorkNode { function WorkNode({ data }) { const [isExpanded, setIsExpanded] = useState(false); const ref = useRef(null); + const noderef = useRef(null); const [contentHeight, setContentHeight] = useState(0); + const [xCoordinate, setXCoordinate] = useState(data.workData.xCoordinate); + const [yCoordinate, setYCoordinate] = useState(data.workData.yCoordinate); const { investigationId } = useParams(); + const [updateNode] = useMutation(UPDATE_WORK_NODE, { + variables: { + workNodeId: data.workData.id.toString(), + xCoordinate: xCoordinate, + yCoordinate: yCoordinate, + visible: true, + }, + }); + + useEffect(() => { + const interval = setInterval(() => { + let translateMatrix = + noderef.current.parentElement.style.transform.split(", "); + let x = Number(translateMatrix[0].split("(")[1].split("px")[0]); + let y = Number(translateMatrix[1].split("px")[0]); + setXCoordinate(x); + setYCoordinate(y); + updateNode(); + }, 10000); + + return () => clearInterval(interval); + }, []); + const toggleIsExpanded = useCallback(() => { setIsExpanded((isExpanded) => !isExpanded); }, []); @@ -55,6 +82,7 @@ function WorkNode({ data }) { ? "#FBD87F" : "#B5F8FE", }} + ref={noderef} > diff --git a/react/src/hooks/UPDATE_WORK_NODE.tsx b/react/src/hooks/UPDATE_WORK_NODE.tsx new file mode 100644 index 0000000..97b38e3 --- /dev/null +++ b/react/src/hooks/UPDATE_WORK_NODE.tsx @@ -0,0 +1,24 @@ +import { useMutation, gql } from "@apollo/client"; + +export const UPDATE_WORK_NODE = gql` + mutation ( + $workNodeId: String! + $xCoordinate: Int + $yCoordinate: Int + $visible: Boolean + ) { + updateWorkNode( + input: { + workNodeId: $workNodeId + xCoordinate: $xCoordinate + yCoordinate: $yCoordinate + visible: $visible + } + ) { + id + xCoordinate + yCoordinate + visible + } + } +`;