summaryrefslogtreecommitdiff
path: root/pages/index.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'pages/index.tsx')
-rw-r--r--pages/index.tsx119
1 files changed, 95 insertions, 24 deletions
diff --git a/pages/index.tsx b/pages/index.tsx
index e0e8b6e..3540a4c 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -22,10 +22,19 @@ import { useAnimation } from '@lilib/hooks'
import { Box, useTheme } from '@chakra-ui/react'
-import { initialPhysics, initialFilter, initialVisuals } from '../components/config'
+import {
+ initialPhysics,
+ initialFilter,
+ initialVisuals,
+ initialBehavior,
+} from '../components/config'
import { Tweaks } from '../components/tweaks'
import { ThemeContext, ThemeContextProps } from './themecontext'
+import SpriteText from 'three-spritetext'
+
+import ReconnectingWebSocket from 'reconnecting-websocket'
+
// react-force-graph fails on import when server-rendered
// https://github.com/vasturiano/react-force-graph/issues/155
const ForceGraph2D = (
@@ -62,6 +71,7 @@ export function GraphPage() {
const [visuals, setVisuals] = usePersistantState('visuals', initialVisuals)
const [graphData, setGraphData] = useState<GraphData | null>(null)
const [emacsNodeId, setEmacsNodeId] = useState<string | null>(null)
+ const [behavior, setBehavior] = usePersistantState('behavior', initialBehavior)
const nodeByIdRef = useRef<NodeById>({})
const linksByNodeIdRef = useRef<LinksByNodeId>({})
@@ -113,10 +123,23 @@ export function GraphPage() {
const orgRoamGraphDataClone = JSON.parse(JSON.stringify(orgRoamGraphDataWithFileLinks))
setGraphData(orgRoamGraphDataClone)
}
+
const { setEmacsTheme } = useContext(ThemeContext)
+
+ const [threeDim, setThreeDim] = useState(false)
+
+ const graph2dRef = useRef<any>(null)
+ const graph3dRef = useRef<any>(null)
+
useEffect(() => {
+<<<<<<< HEAD
+ const fg = threeDim ? graph3dRef.current : graph2dRef.current
+ const socket = new ReconnectingWebSocket('ws://localhost:35903')
+ socket.addEventListener('open', (event) => {
+=======
const socket = new WebSocket('ws://localhost:35903')
socket.addEventListener('open', () => {
+>>>>>>> 4e3d884c402b7dc7d12f0cae88a9a312b10f166f
console.log('Connection with Emacs established')
})
socket.addEventListener('message', (event) => {
@@ -131,14 +154,18 @@ export function GraphPage() {
case 'follow':
return setEmacsNodeId(message.data.id)
case 'zoom': {
+ console.log(message)
const links = linksByNodeIdRef.current[message.data.id!] ?? []
const nodes = Object.fromEntries(
[
- message.commandData.id! as string,
+ message.data.id! as string,
...links.flatMap((link) => [link.source, link.target]),
].map((nodeId) => [nodeId, {}]),
)
- /* zoomToFit(500, 200, (node: OrgRoamNode)=>nodes[node.id!]) */
+ fg.zoomToFit(2000, 200, (node: OrgRoamNode) => nodes[node.id!])
+ }
+ case 'toggle': {
+ /* setBehavior({ ...behavior, followLocalorZoom: !behavior.followLocalOrZoom }) */
}
default:
return console.error('unknown message type', message.type)
@@ -147,7 +174,16 @@ export function GraphPage() {
})
}, [])
+<<<<<<< HEAD
+ useEffect(() => {
+ if (!emacsNodeId) {
+ return
+ }
+ //fetchGraphData()
+ }, [emacsNodeId])
+=======
const [threeDim, setThreeDim] = useState(false)
+>>>>>>> 4e3d884c402b7dc7d12f0cae88a9a312b10f166f
if (!graphData) {
return null
@@ -178,6 +214,9 @@ export function GraphPage() {
emacsNodeId,
filter,
visuals,
+ behavior,
+ graph2dRef,
+ graph3dRef,
}}
/>
</Box>
@@ -194,14 +233,25 @@ export interface GraphProps {
filter: typeof initialFilter
emacsNodeId: string | null
visuals: typeof initialVisuals
+ behavior: typeof initialBehavior
+ graph2dRef: any
+ graph3dRef: any
}
export const Graph = function (props: GraphProps) {
- const { physics, graphData, threeDim, linksByNodeId, filter, emacsNodeId, nodeById, visuals } =
- props
-
- const graph2dRef = useRef<any>(null)
- const graph3dRef = useRef<any>(null)
+ const {
+ physics,
+ graphData,
+ threeDim,
+ linksByNodeId,
+ filter,
+ emacsNodeId,
+ nodeById,
+ visuals,
+ behavior,
+ graph2dRef,
+ graph3dRef,
+ } = props
// react-force-graph does not track window size
// https://github.com/vasturiano/react-force-graph/issues/233
@@ -215,33 +265,43 @@ export const Graph = function (props: GraphProps) {
if (!emacsNodeId) {
return
}
- switch (physics.follow) {
- case 'Local':
- setScope({ nodeIds: [emacsNodeId] })
- break
- case 'Zoom':
- default:
+ const fg = threeDim ? graph3dRef.current : graph2dRef.current
+ if (behavior.followLocalOrZoom) {
+ setScope({ nodeIds: [emacsNodeId] })
+ } else {
+ fg?.zoomToFit(1000, 200, (node: NodeObject) => getNeighborNodes(emacsNodeId)[node.id!])
+ setHoverNode(nodeById[emacsNodeId] as NodeObject)
}
}, [emacsNodeId])
- const centralHighlightedNode = hoverNode
+ const getNeighborNodes = (id: string) => {
+ const links = linksByNodeId[id]! ?? []
+ return Object.fromEntries(
+ [id as string, ...links.flatMap((link) => [link.source, link.target])].map((nodeId) => [
+ nodeId,
+ {},
+ ]),
+ )
+ }
+ const centralHighlightedNode = useRef<NodeObject | null>(null)
+ centralHighlightedNode.current = hoverNode
const highlightedNodes = useMemo(() => {
- if (!centralHighlightedNode) {
+ if (!centralHighlightedNode.current) {
return {}
}
- const links = linksByNodeId[centralHighlightedNode.id!]
+ const links = linksByNodeId[centralHighlightedNode.current.id!]
if (!links) {
return {}
}
return Object.fromEntries(
[
- centralHighlightedNode.id! as string,
+ centralHighlightedNode.current.id! as string,
...links.flatMap((link) => [link.source, link.target]),
].map((nodeId) => [nodeId, {}]),
)
- }, [centralHighlightedNode, linksByNodeId])
+ }, [centralHighlightedNode.current, linksByNodeId])
const filteredNodes = useMemo(() => {
return graphData.nodes.filter((node) => {
@@ -590,13 +650,13 @@ export const Graph = function (props: GraphProps) {
linkColor: (link) => {
const sourceId = typeof link.source === 'object' ? link.source.id! : (link.source as string)
const targetId = typeof link.target === 'object' ? link.target.id! : (link.target as string)
- const linkIsHighlighted = isLinkRelatedToNode(link, centralHighlightedNode)
+ const linkIsHighlighted = isLinkRelatedToNode(link, centralHighlightedNode.current)
const linkWasHighlighted = isLinkRelatedToNode(link, lastHoverNode.current)
const needsHighlighting = linkIsHighlighted || linkWasHighlighted
return getLinkColor(sourceId as string, targetId as string, needsHighlighting)
},
linkWidth: (link) => {
- const linkIsHighlighted = isLinkRelatedToNode(link, centralHighlightedNode)
+ const linkIsHighlighted = isLinkRelatedToNode(link, centralHighlightedNode.current)
const linkWasHighlighted = isLinkRelatedToNode(link, lastHoverNode.current)
return linkIsHighlighted || linkWasHighlighted
@@ -647,6 +707,18 @@ export const Graph = function (props: GraphProps) {
nodeOpacity={physics.nodeOpacity}
nodeResolution={physics.nodeResolution}
linkOpacity={physics.linkOpacity}
+ nodeThreeObject={(node: OrgRoamNode) => {
+ if (!physics.labels) {
+ return
+ }
+ if (physics.labels === 1 && !highlightedNodes[node.id!]) {
+ return
+ }
+ const sprite = new SpriteText(node.title.substring(0, 30))
+ sprite.color = '#ffffff'
+ sprite.textHeight = 8
+ return sprite
+ }}
/>
) : (
<ForceGraph2D ref={graph2dRef} {...graphCommonProps} />
@@ -655,10 +727,9 @@ export const Graph = function (props: GraphProps) {
)
}
-function isLinkRelatedToNode(link: LinkObject, centralHighlightedNode: NodeObject | null) {
+function isLinkRelatedToNode(link: LinkObject, node: NodeObject | null) {
return (
- (link.source as NodeObject).id! === centralHighlightedNode?.id! ||
- (link.target as NodeObject).id! === centralHighlightedNode?.id!
+ (link.source as NodeObject).id! === node?.id! || (link.target as NodeObject).id! === node?.id!
)
}