Skip to content

Commit

Permalink
Merge pull request #1630 from MahtabBukhari/Blueprint_Render_all_edge…
Browse files Browse the repository at this point in the history
…s_from_the_schema_response_

Blueprint render all edges from the schema response
  • Loading branch information
Rassl authored Jun 20, 2024
2 parents d54f092 + 8db312d commit 2593b0e
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useFrame } from '@react-three/fiber'
import { forceCenter, forceCollide, forceLink, forceManyBody, forceSimulation } from 'd3-force-3d'
import { useEffect, useState } from 'react'
import { useEffect, useState, useCallback } from 'react'
import { usePrevious } from '~/hooks/usePrevious'
import { SchemaLink } from '~/network/fetchSourcesData'
import { ForceSimulation } from '~/transformers/forceSimulation'
Expand Down Expand Up @@ -29,6 +29,46 @@ export const ForceGraph = ({
const prevSchemas = usePrevious<SchemaExtended[]>(schemasWithPositions)
const prevLinks = usePrevious<SchemaLink[]>(filteredLinks)

// Custom force to handle link separation
const linkSeparationForce = useCallback(
() => (alpha: number) => {
filteredLinks.forEach((link, i) => {
for (let j = i + 1; j < filteredLinks.length; j += 1) {
const otherLink = filteredLinks[j]

if (link.source === otherLink.source && link.target === otherLink.target) {
const linkSource = schemasWithPositions.find((node) => node.ref_id === link.source)
const linkTarget = schemasWithPositions.find((node) => node.ref_id === link.target)
const otherLinkSource = schemasWithPositions.find((node) => node.ref_id === otherLink.source)
const otherLinkTarget = schemasWithPositions.find((node) => node.ref_id === otherLink.target)

if (linkSource && linkTarget && otherLinkSource && otherLinkTarget) {
const dx = (otherLinkTarget.x ?? 0) - (linkTarget.x ?? 0)
const dy = (otherLinkTarget.y ?? 0) - (linkTarget.y ?? 0)
const dz = (otherLinkTarget.z ?? 0) - (linkTarget.z ?? 0)

const distance = Math.sqrt(dx * dx + dy * dy + dz * dz)
const minDistance = 10 // Minimum distance to avoid overlap

if (distance < minDistance) {
const angle = Math.atan2(dy, dx)
const separation = ((minDistance - distance) / distance) * alpha
const displacementX = Math.cos(angle) * separation
const displacementY = Math.sin(angle) * separation

otherLinkTarget.x = (otherLinkTarget.x ?? 0) + displacementX
otherLinkTarget.y = (otherLinkTarget.y ?? 0) + displacementY
linkTarget.x = (linkTarget.x ?? 0) - displacementX
linkTarget.y = (linkTarget.y ?? 0) - displacementY
}
}
}
}
})
},
[filteredLinks, schemasWithPositions],
)

useEffect(() => {
if (!schemasWithPositions.length || !filteredLinks.length) {
return
Expand All @@ -49,12 +89,13 @@ export const ForceGraph = ({
.force(
'link',
forceLink(links)
// .links(linksData)
.id((d: SchemaExtended) => d.ref_id),
.id((d: SchemaExtended) => d.ref_id)
.distance(100),
)
.force('charge', forceManyBody())
.force('center', forceCenter())
.force('collide', forceCollide(NODE_RADIUS + 1))
.force('collide', forceCollide(NODE_RADIUS + 5))
.force('linkSeparation', linkSeparationForce())
.alpha(0.5)
.restart()

Expand All @@ -68,15 +109,16 @@ export const ForceGraph = ({
.force(
'link',
forceLink(links)
// .links(linksData)
.id((d: SchemaExtended) => d.ref_id),
.id((d: SchemaExtended) => d.ref_id)
.distance(100),
)
.force('charge', forceManyBody())
.force('center', forceCenter())
.force('collide', forceCollide(0))
.force('collide', forceCollide(NODE_RADIUS + 5))
.force('linkSeparation', linkSeparationForce())

setSimulation2d(simulation)
}, [schemasWithPositions, simulation2d, filteredLinks, prevSchemas, prevLinks])
}, [schemasWithPositions, simulation2d, filteredLinks, prevSchemas, prevLinks, linkSeparationForce])

useFrame(() => {
if (simulation2d) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ export const Body = () => {

const linksFiltered = links.filter(
(link) =>
link.edge_type === 'CHILD_OF' &&
schemasWithChildren.some((schema) => schema.ref_id === link.source) &&
schemasWithChildren.some((schema) => schema.ref_id === link.target),
)
Expand Down

0 comments on commit 2593b0e

Please sign in to comment.