fix: use radial force for knowledge graph

This commit is contained in:
lofyer
2026-08-10 22:57:31 +08:00
parent 2cc76fc960
commit cb0319c4d1
2 changed files with 47 additions and 14 deletions
+25 -8
View File
@@ -176,19 +176,29 @@ function createPresentation(
})) }))
}, },
layout: { layout: {
type: 'circular', type: 'd3-force',
animate: false, animate: false,
ordering: 'topology', centerStrength: 0.8,
startAngle: -Math.PI / 2, linkDistance: dense ? 44 : 64,
endAngle: Math.PI * 1.5, edgeStrength: dense ? 0.28 : 0.4,
clockwise: true, edgeIterations: 2,
divisions: 1, nodeStrength: dense ? -45 : -70,
angleRatio: 1, theta: 0.8,
preventOverlap: true,
collideStrength: 0.9,
collideIterations: 2,
nodeSize: (datum: Record<string, unknown>) => { nodeSize: (datum: Record<string, unknown>) => {
const metadata = datum.data as G6NodeMetadata | undefined const metadata = datum.data as G6NodeMetadata | undefined
return metadata?.size ?? 24 return metadata?.size ?? 24
}, },
nodeSpacing: dense ? 20 : 28 nodeSpacing: dense ? 10 : 14,
x: false,
y: false,
radialRadius: 0,
radialStrength: dense ? 0.055 : 0.04,
alphaMin: 0.015,
alphaDecay: 0.045,
velocityDecay: 0.42
}, },
node: { node: {
type: 'circle', type: 'circle',
@@ -474,6 +484,13 @@ export function KnowledgeGraphChart({
return return
} }
renderedRevisionRef.current = dataRevision renderedRevisionRef.current = dataRevision
await graph.fitView(
{
when: 'always',
direction: 'both'
},
false
)
appliedZoomRef.current = graph.getZoom() appliedZoomRef.current = graph.getZoom()
const states = Object.fromEntries( const states = Object.fromEntries(
nodesRef.current.map((node) => [ nodesRef.current.map((node) => [
+22 -6
View File
@@ -18,6 +18,7 @@ const g6Mock = vi.hoisted(() => {
const graph = { const graph = {
destroy: vi.fn(), destroy: vi.fn(),
draw: vi.fn(async () => undefined), draw: vi.fn(async () => undefined),
fitView: vi.fn(async () => undefined),
getElementPosition: vi.fn(() => [240, 320]), getElementPosition: vi.fn(() => [240, 320]),
getZoom: vi.fn(() => 1), getZoom: vi.fn(() => 1),
off: vi.fn((eventName: string) => handlers.delete(eventName)), off: vi.fn((eventName: string) => handlers.delete(eventName)),
@@ -472,9 +473,13 @@ describe('KnowledgeWorkspace', () => {
}, },
layout: expect.objectContaining({ layout: expect.objectContaining({
animate: false, animate: false,
angleRatio: 1, centerStrength: 0.8,
ordering: 'topology', linkDistance: 64,
type: 'circular' nodeStrength: -70,
preventOverlap: true,
radialRadius: 0,
radialStrength: 0.04,
type: 'd3-force'
}), }),
behaviors: expect.arrayContaining([ behaviors: expect.arrayContaining([
'drag-canvas', 'drag-canvas',
@@ -500,6 +505,13 @@ describe('KnowledgeWorkspace', () => {
}, },
false false
) )
expect(g6Mock.graph.fitView).toHaveBeenCalledWith(
{
when: 'always',
direction: 'both'
},
false
)
const stableRenderCallCount = g6Mock.graph.render.mock.calls.length const stableRenderCallCount = g6Mock.graph.render.mock.calls.length
rerender(<KnowledgeWorkspace {...createProps({ onMoveNode })} />) rerender(<KnowledgeWorkspace {...createProps({ onMoveNode })} />)
expect(g6Mock.graph.render).toHaveBeenCalledTimes(stableRenderCallCount) expect(g6Mock.graph.render).toHaveBeenCalledTimes(stableRenderCallCount)
@@ -661,9 +673,13 @@ describe('KnowledgeWorkspace', () => {
}), }),
layout: expect.objectContaining({ layout: expect.objectContaining({
animate: false, animate: false,
nodeSpacing: 20, linkDistance: 44,
ordering: 'topology', nodeSpacing: 10,
type: 'circular' nodeStrength: -45,
preventOverlap: true,
radialRadius: 0,
radialStrength: 0.055,
type: 'd3-force'
}), }),
behaviors: expect.arrayContaining([ behaviors: expect.arrayContaining([
expect.objectContaining({ expect.objectContaining({