diff --git a/frontend/src/components/visualizer/useVisualizerData3D.ts b/frontend/src/components/visualizer/useVisualizerData3D.ts index 5d1cf86..dfdea30 100644 --- a/frontend/src/components/visualizer/useVisualizerData3D.ts +++ b/frontend/src/components/visualizer/useVisualizerData3D.ts @@ -78,6 +78,9 @@ function buildInitialRenderNode(node: PacketNetworkNode): GraphNode { x: 0, y: 0, z: 0, + fx: 0, + fy: 0, + fz: 0, vx: 0, vy: 0, vz: 0, @@ -244,6 +247,9 @@ export function useVisualizerData3D({ existing.x = 0; existing.y = 0; existing.z = 0; + existing.fx = 0; + existing.fy = 0; + existing.fz = 0; existing.vx = 0; existing.vy = 0; existing.vz = 0; diff --git a/frontend/src/test/useVisualizerData3D.test.ts b/frontend/src/test/useVisualizerData3D.test.ts index c27946d..2f5d94c 100644 --- a/frontend/src/test/useVisualizerData3D.test.ts +++ b/frontend/src/test/useVisualizerData3D.test.ts @@ -123,6 +123,31 @@ afterEach(() => { }); describe('useVisualizerData3D', () => { + it('hard-pins the self node at the origin', async () => { + const selfKey = 'ffffffffffff0000000000000000000000000000000000000000000000000000'; + + const { result } = renderVisualizerData({ + packets: [], + contacts: [], + config: createConfig(selfKey), + }); + + await waitFor(() => expect(result.current.nodes.get('self')).toBeDefined()); + + const selfNode = result.current.nodes.get('self'); + expect(selfNode).toMatchObject({ + x: 0, + y: 0, + z: 0, + fx: 0, + fy: 0, + fz: 0, + vx: 0, + vy: 0, + vz: 0, + }); + }); + it('keeps canonical adjacency stable when ambiguous repeaters are shown or hidden', async () => { const selfKey = 'ffffffffffff0000000000000000000000000000000000000000000000000000'; const aliceKey = 'aaaaaaaaaaaa0000000000000000000000000000000000000000000000000000';