From 878cee5a48b9ba44686bee92f7e4a6b6a3d3d01f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A0=D0=B0=D1=81=D1=83=D0=BB?= Date: Mon, 23 Dec 2024 21:23:09 +0300 Subject: [PATCH] feat: updated selection graph --- .../Connections/Connection/index.tsx | 4 +- .../Cubes/SelectionDataNodes/Node/index.tsx | 9 +- .../Graph/Cubes/SelectionDataNodes/index.tsx | 147 +++++++++++------- src/components/Universe/Graph/Cubes/index.tsx | 2 - src/components/Universe/index.tsx | 2 +- 5 files changed, 105 insertions(+), 59 deletions(-) diff --git a/src/components/Universe/Graph/Cubes/SelectionDataNodes/Connections/Connection/index.tsx b/src/components/Universe/Graph/Cubes/SelectionDataNodes/Connections/Connection/index.tsx index 7372715c3..e43b44003 100644 --- a/src/components/Universe/Graph/Cubes/SelectionDataNodes/Connections/Connection/index.tsx +++ b/src/components/Universe/Graph/Cubes/SelectionDataNodes/Connections/Connection/index.tsx @@ -29,7 +29,9 @@ const _Connection = (props: LineComponentProps) => { points={[sourceX, sourceY, sourceZ, targetX, targetY, targetZ]} /> - + + + {label} diff --git a/src/components/Universe/Graph/Cubes/SelectionDataNodes/Node/index.tsx b/src/components/Universe/Graph/Cubes/SelectionDataNodes/Node/index.tsx index 3f04d8abf..fd8ebd191 100644 --- a/src/components/Universe/Graph/Cubes/SelectionDataNodes/Node/index.tsx +++ b/src/components/Universe/Graph/Cubes/SelectionDataNodes/Node/index.tsx @@ -63,6 +63,8 @@ const Text = styled(Flex)` color: ${colors.white}; margin-left: 16px; font-weight: 700; + width: 100px; + font-size: 16px; ` const Tag = styled(Flex)` @@ -90,8 +92,11 @@ const Tag = styled(Flex)` ` const Selected = styled(Tag)` - width: 300px; - height: 150px; + width: 200px; + height: 100px; + flex-direction: row; + justify-content: center; + align-items: center; ` const IconButton = styled(Flex)` diff --git a/src/components/Universe/Graph/Cubes/SelectionDataNodes/index.tsx b/src/components/Universe/Graph/Cubes/SelectionDataNodes/index.tsx index 5ff99efbd..3b529070e 100644 --- a/src/components/Universe/Graph/Cubes/SelectionDataNodes/index.tsx +++ b/src/components/Universe/Graph/Cubes/SelectionDataNodes/index.tsx @@ -1,10 +1,11 @@ import { Html } from '@react-three/drei' import { forceLink, forceManyBody, forceRadial, forceSimulation } from 'd3-force-3d' -import { memo, useCallback, useEffect, useRef, useState } from 'react' +import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react' import { Box3, Color, Group, Sphere, Vector3 } from 'three' import { Line2 } from 'three-stdlib' import { useShallow } from 'zustand/react/shallow' import { usePrevious } from '~/hooks/usePrevious' +import { fetchNodeEdges } from '~/network/fetchGraphData' import { useDataStore } from '~/stores/useDataStore' import { useGraphStore, useSelectedNode, useSelectedNodeRelativeIds } from '~/stores/useGraphStore' import { useSchemaStore } from '~/stores/useSchemaStore' @@ -19,7 +20,7 @@ const MAX_LENGTH = 6 export const SelectionDataNodes = memo(() => { const [simulation2d, setSimulation2D] = useState(null) - const { dataInitial, nodesNormalized } = useDataStore((s) => s) + const { dataInitial, nodesNormalized, addNewNode } = useDataStore((s) => s) const selectedNode = useSelectedNode() const groupRef = useRef(null) @@ -34,24 +35,62 @@ export const SelectionDataNodes = memo(() => { const { selectionGraphData, selectionPath, setSelectionData, setSelectedNode, setSelectionGraphRadius } = useGraphStore(useShallow((s) => s)) - console.log(selectionPath) + const pathNodes = useMemo(() => { + const nodes: NodeExtended[] = selectionPath + .slice(-3, -1) + .filter((id) => !!nodesNormalized.get(id)) + .map((i, index) => { + const node = nodesNormalized.get(i) as unknown as Node + + return { ...node, fx: 0, fy: -(index + 1) * 200, fz: 0, x: 0, y: 0, z: 0 } + }) + + return nodes + }, [nodesNormalized, selectionPath]) + + useEffect(() => { + const init = async () => { + if (selectedNode?.ref_id && selectedNode.ref_id !== prevSelectedNodeId) { + try { + const data = await fetchNodeEdges(selectedNode.ref_id, 0, 5) + + if (data) { + const graphNodes: NodeExtended[] = data.nodes + .filter((node) => node.ref_id !== selectedNode.ref_id) + .map((node: Node) => ({ ...node, x: 0, y: 0, z: 0 })) + + const nodes: NodeExtended[] = [ + ...graphNodes, + { ...selectedNode, x: 0, y: 0, z: 0, fx: 0, fy: 0, fz: 0 } as NodeExtended, + ] + + setSelectionData({ nodes, links: data.edges as unknown as GraphData['links'] }) + setSimulation2D(null) + linksPositionRef.current = new Map() + // + + addNewNode(data) + } + } catch (error) { + console.error(error) + } + } + } + + if (selectedNode) { + init() + } + }, [addNewNode, prevSelectedNodeId, selectedNode, setSelectionData]) useEffect(() => { + return + const structuredLinks = structuredClone(dataInitial?.links || []) if (prevSelectedNodeId === selectedNode?.ref_id) { return } - const pathNodes: NodeExtended[] = selectionPath - .slice(-3, -1) - .filter((id) => !!nodesNormalized.get(id)) - .map((i, index) => { - const node = nodesNormalized.get(i) as unknown as Node - - return { ...node, fx: -index * 50, fy: 0, fz: 0, x: 0, y: 0, z: 0 } - }) - const graphNodes: NodeExtended[] = selectedNodeRelativeIds .filter((id) => !!nodesNormalized.get(id)) .map((id: string) => { @@ -62,7 +101,6 @@ export const SelectionDataNodes = memo(() => { const nodes: NodeExtended[] = [ ...graphNodes, - ...pathNodes, { ...selectedNode, x: 0, y: 0, z: 0, fx: 0, fy: 0, fz: 0 } as NodeExtended, ] @@ -77,15 +115,7 @@ export const SelectionDataNodes = memo(() => { setSimulation2D(null) linksPositionRef.current = new Map() } - }, [ - dataInitial, - selectedNode, - selectedNodeRelativeIds, - setSelectionData, - prevSelectedNodeId, - selectionPath, - nodesNormalized, - ]) + }, [dataInitial, selectedNode, selectedNodeRelativeIds, setSelectionData, prevSelectedNodeId, nodesNormalized]) useEffect(() => { if (simulation2d || !selectionGraphData.nodes.length) { @@ -105,8 +135,8 @@ export const SelectionDataNodes = memo(() => { .id((d: NodeExtended) => d.ref_id) .distance(() => 150), ) - .force('radial', forceRadial(500, 0, 0, 0).strength(0)) - .force('charge', forceManyBody().strength(-1000)) + .force('radial', forceRadial(20, 0, 0, 0).strength(0)) + .force('charge', forceManyBody().strength(-500)) .alpha(1) .restart() @@ -115,13 +145,6 @@ export const SelectionDataNodes = memo(() => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [selectionGraphData, simulation2d]) - useEffect( - () => () => { - setSelectionData({ nodes: [], links: [] }) - }, - [setSelectionData], - ) - useEffect(() => { if (!simulation2d) { return @@ -145,8 +168,8 @@ export const SelectionDataNodes = memo(() => { const grConnections = groupRef.current.getObjectByName('simulation-3d-group__connections') as Group grConnections.children.forEach((g, i) => { - const r = g.children[0] // Assuming Line is the first child - const text = g.children[1] // Assuming Text is the second child + const r = g.children[0] + const text = g.children[1] if (r instanceof Line2) { const Line = r as Line2 @@ -163,7 +186,6 @@ export const SelectionDataNodes = memo(() => { const { x: sx, y: sy } = sourceNode const { x: tx, y: ty } = targetNode - // Set positions for the link linksPositionRef.current.set(link.ref_id, { sx, sy, @@ -175,16 +197,16 @@ export const SelectionDataNodes = memo(() => { const midPoint = new Vector3((sx + tx) / 2, (sy + ty) / 2, 0) - // Position the text - text.position.set(midPoint.x, midPoint.y, 1) + text.position.set(midPoint.x, midPoint.y, 2) + + let angle = Math.atan2(ty - sy, tx - sx) - // Calculate angle of rotation in 2D - const angle = Math.atan2(ty - sy, tx - sx) + if (tx < sx || (Math.abs(tx - sx) < 0.01 && ty < sy)) { + angle += Math.PI + } - // Apply rotation to the text - text.rotation.set(0, 0, angle) // Only Z-axis rotation needed for 2D alignment + text.rotation.set(0, 0, angle) - // Set the line positions Line.geometry.setPositions([sx, sy, 0, tx, ty, 0]) const { material } = Line @@ -218,18 +240,37 @@ export const SelectionDataNodes = memo(() => { ) return ( - - {selectionGraphData?.nodes.map((node) => ( - - - handleSelect(node)} selected={node.ref_id === selectedNode?.ref_id} /> - - - - - ))} - - + <> + + {selectionGraphData?.nodes.map((node) => ( + + + handleSelect(node)} + selected={node.ref_id === selectedNode?.ref_id} + /> + + + ))} + + + {false && ( + + {pathNodes.map((node) => ( + + + handleSelect(node)} + selected={node.ref_id === selectedNode?.ref_id} + /> + + + ))} + + )} + ) }) diff --git a/src/components/Universe/Graph/Cubes/index.tsx b/src/components/Universe/Graph/Cubes/index.tsx index 4b9672456..a66f4fd2a 100644 --- a/src/components/Universe/Graph/Cubes/index.tsx +++ b/src/components/Universe/Graph/Cubes/index.tsx @@ -10,7 +10,6 @@ import { colors } from '~/utils' import { COLORS_MAP } from '../constant' import { NodePoints } from './NodePoints' import { NodeWrapper } from './NodeWrapper' -import { RelevanceBadges } from './RelevanceBadges' const POINTER_IN_DELAY = 200 @@ -131,7 +130,6 @@ export const Cubes = memo(() => { - ) }) diff --git a/src/components/Universe/index.tsx b/src/components/Universe/index.tsx index 2226c8875..2ee57bdb2 100644 --- a/src/components/Universe/index.tsx +++ b/src/components/Universe/index.tsx @@ -178,7 +178,7 @@ const _Universe = () => { - +