Skip to content

Commit

Permalink
Merge pull request stakwork#2575 from stakwork/feature/selection-view…
Browse files Browse the repository at this point in the history
…-path

Feature/selection view path
  • Loading branch information
Rassl authored Dec 23, 2024
2 parents 806b854 + 9eb306d commit d426b53
Show file tree
Hide file tree
Showing 11 changed files with 262 additions and 175 deletions.
30 changes: 16 additions & 14 deletions src/components/Universe/Controls/CameraAnimations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const useCameraAnimations = (

const isUserDragging = useControlStore((s) => s.isUserDragging)

const { graphStyle, graphRadius, disableCameraRotation } = useGraphStore((s) => s)
const { graphRadius, disableCameraRotation } = useGraphStore((s) => s)

useEffect(() => {
if (!enabled) {
Expand All @@ -33,22 +33,24 @@ export const useCameraAnimations = (
}
}, [enabled])

useEffect(() => {
if (cameraControlsRef.current && graphRadius) {
if (graphStyle === 'sphere') {
cameraControlsRef.current.maxDistance = 8000
cameraControlsRef.current.minDistance = 200
cameraControlsRef.current.setTarget(0, 0, 500, true)
} else {
cameraControlsRef.current.maxDistance = cameraControlsRef.current.getDistanceToFitSphere(graphRadius + 200)
cameraControlsRef.current.minDistance = 100
}
}
}, [graphRadius, graphStyle, cameraControlsRef])
// useEffect(() => {
// if (cameraControlsRef.current && graphRadius) {
// cameraControlsRef.current.maxDistance = cameraControlsRef.current.getDistanceToFitSphere(graphRadius + 200)
// cameraControlsRef.current.minDistance = 100
// }
// }, [graphRadius, cameraControlsRef])

useEffect(() => {
if (!selectedNode && cameraControlsRef.current) {
cameraControlsRef.current.setLookAt(initialCameraPosition.x, initialCameraPosition.y, graphRadius, 0, 0, 0, true)
cameraControlsRef.current.setLookAt(
initialCameraPosition.x,
initialCameraPosition.y,
graphRadius + 200,
0,
0,
0,
true,
)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedNode, graphRadius])
Expand Down
5 changes: 3 additions & 2 deletions src/components/Universe/Graph/Connections/LineComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { memo, useEffect, useRef } from 'react'
import { Line2 } from 'three-stdlib'
import { useGraphStore } from '~/stores/useGraphStore'
import { LINE_WIDTH } from '../../constants'
import { fontProps } from '../Cubes/Text/constants'

type LineComponentProps = {
label: string
Expand Down Expand Up @@ -78,8 +79,8 @@ const _LineComponent = (props: LineComponentProps) => {
points={[sourceX, sourceY, sourceZ, targetX, targetY, targetZ]}
/>
<Billboard>
<Text anchorX="center" anchorY="middle" color="white" fontSize={10}>
{label}1
<Text anchorX="center" anchorY="middle" color="white" {...fontProps} fontSize={10}>
{label}
</Text>
</Billboard>
</group>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Line, Text } from '@react-three/drei'
import { memo, useRef } from 'react'
import { Line2 } from 'three-stdlib'
import { fontProps } from '../../../Text/constants'

type LineComponentProps = {
label: string
Expand Down Expand Up @@ -29,7 +30,9 @@ const _Connection = (props: LineComponentProps) => {
points={[sourceX, sourceY, sourceZ, targetX, targetY, targetZ]}
/>
<mesh>
<Text anchorX="center" anchorY="middle" color="white" fontSize={10}>
<planeGeometry args={[label.length * 6, 12]} />
<meshBasicMaterial color="black" />
<Text anchorX="center" anchorY="middle" color="white" {...fontProps} fontSize={6}>
{label}
</Text>
</mesh>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,16 @@ export const Node = ({ onClick, node, selected, rounded = true }: Props) => {
)
}

const Wrapper = styled(Flex)``
const Wrapper = styled(Flex)`
background: black;
`

const Text = styled(Flex)`
color: ${colors.white};
margin-left: 16px;
font-weight: 700;
width: 100px;
font-size: 16px;
`

const Tag = styled(Flex)<TagProps>`
Expand Down Expand Up @@ -90,8 +94,11 @@ const Tag = styled(Flex)<TagProps>`
`

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)`
Expand Down
175 changes: 126 additions & 49 deletions src/components/Universe/Graph/Cubes/SelectionDataNodes/index.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
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'
import { ForceSimulation } from '~/transformers/forceSimulation'
import { GraphData, Link, NodeExtended } from '~/types'
import { GraphData, Link, Node, NodeExtended } from '~/types'
import { LinkPosition } from '../..'
import { Connections } from './Connections'
import { Node } from './Node'
import { Node as GraphNode } from './Node'

const MAX_LENGTH = 6

export const SelectionDataNodes = memo(() => {
const [simulation2d, setSimulation2D] = useState<ForceSimulation | null>(null)

const { dataInitial } = useDataStore((s) => s)
const { dataInitial, nodesNormalized, addNewNode } = useDataStore((s) => s)
const selectedNode = useSelectedNode()
const groupRef = useRef<Group>(null)

Expand All @@ -31,28 +32,87 @@ export const SelectionDataNodes = memo(() => {

const { normalizedSchemasByType } = useSchemaStore((s) => s)

const { selectionGraphData, setSelectionData, setSelectedNode, setSelectionGraphRadius } = useGraphStore(
useShallow((s) => s),
)
const { selectionGraphData, selectionPath, setSelectionData, setSelectedNode, setSelectionGraphRadius } =
useGraphStore(useShallow((s) => s))

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 filteredNodes: NodeExtended[] = data.nodes.filter(
(node, index) => node.ref_id !== selectedNode.ref_id && index < 7,
)

const graphNodes = filteredNodes.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,
]

const links = data.edges.filter(
(link: Link) =>
nodes.some((node: NodeExtended) => node.ref_id === link.target) &&
nodes.some((node: NodeExtended) => node.ref_id === link.source),
)

setSelectionData({ nodes, links: links as unknown as GraphData['links'] })
setSimulation2D(null)
linksPositionRef.current = new Map()

//

addNewNode({ nodes: filteredNodes, edges: links })
}
} catch (error) {
console.error(error)
}
}
}

if (selectedNode) {
init()
}
}, [addNewNode, prevSelectedNodeId, selectedNode, setSelectionData])

useEffect(() => {
const structuredNodes = structuredClone(dataInitial?.nodes || [])
return

const structuredLinks = structuredClone(dataInitial?.links || [])

if (prevSelectedNodeId === selectedNode?.ref_id) {
return
}

const nodes = structuredNodes
.filter(
(f: NodeExtended) => f.ref_id === selectedNode?.ref_id || selectedNodeRelativeIds.includes(f?.ref_id || ''),
)
.map((n: NodeExtended) => {
const fixedPosition = n.ref_id === selectedNode?.ref_id ? { fx: 0, fy: 0, fz: 0 } : {}
const graphNodes: NodeExtended[] = selectedNodeRelativeIds
.filter((id) => !!nodesNormalized.get(id))
.map((id: string) => {
const node = nodesNormalized.get(id) as unknown as Node

return { ...n, x: 0, y: 0, z: 0, ...fixedPosition }
return { ...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,
]

if (nodes) {
const links = structuredLinks.filter(
(link: Link) =>
Expand All @@ -64,7 +124,7 @@ export const SelectionDataNodes = memo(() => {
setSimulation2D(null)
linksPositionRef.current = new Map()
}
}, [dataInitial, selectedNode, selectedNodeRelativeIds, setSelectionData, prevSelectedNodeId])
}, [dataInitial, selectedNode, selectedNodeRelativeIds, setSelectionData, prevSelectedNodeId, nodesNormalized])

useEffect(() => {
if (simulation2d || !selectionGraphData.nodes.length) {
Expand All @@ -84,8 +144,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()

Expand All @@ -94,13 +154,6 @@ export const SelectionDataNodes = memo(() => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectionGraphData, simulation2d])

useEffect(
() => () => {
setSelectionData({ nodes: [], links: [] })
},
[setSelectionData],
)

useEffect(() => {
if (!simulation2d) {
return
Expand All @@ -124,8 +177,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
Expand All @@ -139,26 +192,31 @@ export const SelectionDataNodes = memo(() => {
return
}

const { x: sx, y: sy, z: sz } = sourceNode
const { x: tx, y: ty, z: tz } = targetNode
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,
sz,
tx,
ty,
tz,
sz: 0,
tz: 0,
})

const midPoint = new Vector3((sx + tx) / 2, (sy + ty) / 2, (sz + tz) / 2)
const midPoint = new Vector3((sx + tx) / 2, (sy + ty) / 2, 0)

text.position.set(midPoint.x, midPoint.y, 1)

let angle = Math.atan2(ty - sy, tx - sx)

if (tx < sx || (Math.abs(tx - sx) < 0.01 && ty < sy)) {
angle += Math.PI
}

// Position the text
text.position.set(midPoint.x, midPoint.y, midPoint.z)
text.rotation.set(0, 0, angle)

// Set the line positions
Line.geometry.setPositions([sx, sy, sz, tx, ty, tz])
Line.geometry.setPositions([sx, sy, 0, tx, ty, 0])

const { material } = Line

Expand Down Expand Up @@ -191,18 +249,37 @@ export const SelectionDataNodes = memo(() => {
)

return (
<group ref={groupRef} name="simulation-2d-group">
{selectionGraphData?.nodes.map((node) => (
<mesh key={node.ref_id}>
<Html center sprite zIndexRange={[0, 0]}>
<Node node={node} onClick={() => handleSelect(node)} selected={node.ref_id === selectedNode?.ref_id} />
</Html>

<mesh />
</mesh>
))}
<Connections linksPosition={linksPositionRef.current} />
</group>
<>
<group ref={groupRef} name="simulation-2d-group">
{selectionGraphData?.nodes.map((node) => (
<mesh key={node.ref_id}>
<Html center sprite zIndexRange={[0, 0]}>
<GraphNode
node={node}
onClick={() => handleSelect(node)}
selected={node.ref_id === selectedNode?.ref_id}
/>
</Html>
</mesh>
))}
<Connections linksPosition={linksPositionRef.current} />
</group>
{false && (
<group>
{pathNodes.map((node) => (
<mesh key={node.ref_id} position={[node.fx || 0, node.fy || 0, node.fz || 0]}>
<Html center sprite zIndexRange={[0, 0]}>
<GraphNode
node={node}
onClick={() => handleSelect(node)}
selected={node.ref_id === selectedNode?.ref_id}
/>
</Html>
</mesh>
))}
</group>
)}
</>
)
})

Expand Down
Loading

0 comments on commit d426b53

Please sign in to comment.