Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions src/components/graph/GraphPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { selectedNewsIdAtom } from '#/shared/store/atoms'
import { highlightedNodeAtom } from '#/store/graph/atoms'
import { useNewsImpactQuery } from '#/apis/analysis/queries'
import { sizeOf } from '#/shared/utils/format'
import { fullLayout, graphIndex, radialLayout, tierOf } from '#/utils/graph/layout'
import { fullLayout, radialLayout, tierOf } from '#/utils/graph/layout'
import type { LayoutPoint } from '#/utils/graph/layout'
import { bfsBuild, buildGraphIndex } from '#/shared/utils/graphIndex'
import type { GraphIndex } from '#/shared/utils/graphIndex'
Expand Down Expand Up @@ -77,6 +77,11 @@ export interface Scene2 {
ghint: string
legendMode: 'focus' | 'all'
backchip: string | null
/** 이 씬의 노드 메타데이터(marketCap/kind/ticker 등)를 조회할 인덱스.
* focus 모드는 해당 뉴스의 impactGraph에서 매번 새로 만든 인덱스, all 모드는
* graph.json 기반 fullGraphIndex — 두 데이터셋이 서로 다른 id 체계라 씬마다
* 자기 데이터에 맞는 인덱스를 반드시 함께 실어 보내야 한다. */
index: GraphIndex
}

function polarityEdgeState(polarity: 1 | -1, tier: 1 | 2): EdgeVisualState {
Expand Down Expand Up @@ -156,6 +161,7 @@ function buildFocusScene(impactGraph: NewsImpactGraph): Scene2 {
: `기점에서 최대 ${maxHop}단계까지 파급`,
legendMode: 'focus',
backchip: null,
index,
}
}

Expand Down Expand Up @@ -193,6 +199,7 @@ export function buildAllScene(
'진한 카드일수록 연결이 많은 핵심 노드입니다 · 노드를 클릭해 보세요',
legendMode: 'all',
backchip: null,
index: fullGraphIndex,
}
}

Expand Down Expand Up @@ -258,22 +265,25 @@ export function buildAllScene(
ghint: `${origin.name} · 1단계 ${hop1}개, 2단계 ${hop2}개로 파급`,
legendMode: 'all',
backchip: '← 전체 보기',
index: fullGraphIndex,
}
}

interface GraphCanvasProps {
scene2: Scene2
mode: 'focus' | 'all'
index: GraphIndex
title?: string
}

export function GraphCanvas({
scene2,
mode,
index,
title = '관계 그래프',
}: GraphCanvasProps) {
// 씬마다 자기 데이터에 맞는 인덱스를 실어 보낸다(focus=뉴스별 impactGraph,
// all=graph.json) — 두 데이터셋의 id 체계가 다르므로 고정된 전역 인덱스를
// 쓰면 다른 쪽 모드에서 노드를 못 찾아 undefined.marketCap 등으로 터진다.
const index = scene2.index
Comment on lines +283 to +286

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

씬별 index 변경 시 노드·엣지 캐시를 무효화해야 합니다.

scene2.index를 새로 읽어도 prevNodesRefprevEdgesRef는 유지됩니다. 이후 id와 시각 상태가 같으면 이전 객체를 재사용하므로, 뉴스 전환 시 새 인덱스의 노드명·크기·위치 또는 엣지 polarity 색상이 반영되지 않을 수 있습니다. 캐시 항목에 index identity를 포함하거나, 인덱스가 바뀔 때 두 캐시를 초기화하세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/graph/GraphPanel.tsx` around lines 283 - 286, Update the cache
handling around the scene2.index assignment so changing the scene-specific index
invalidates both prevNodesRef and prevEdgesRef before cached objects can be
reused. Track the previous index identity and clear both caches whenever the
index changes, preserving cache reuse when the same index remains active.

const { zoomIn, zoomOut, fitView } = useReactFlow()
const [highlightedNode, setHighlightedNode] = useAtom(highlightedNodeAtom)
const [hoverId, setHoverId] = useState<string | null>(null)
Expand Down Expand Up @@ -641,7 +651,7 @@ export default function GraphPanel() {
<section className="panel col-graph">
<ReactFlowProvider>
{scene2 ? (
<GraphCanvas scene2={scene2} mode="focus" index={graphIndex} />
<GraphCanvas scene2={scene2} mode="focus" />
) : (
<div
className="pbody flex items-center justify-center text-sm font-medium"
Expand Down
14 changes: 2 additions & 12 deletions src/components/graph/NetworkView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,7 @@ import { useAtom } from 'jotai'
import { introPlayedAtom } from '#/shared/store/atoms'
import { highlightedNodeAtom } from '#/store/graph/atoms'
import { FULL_GRAPH_EDGES, FULL_GRAPH_NODES } from '#/mocks/graph/fullGraph'
import {
GraphCanvas,
buildAllScene,
FULL_LAYOUT,
fullGraphIndex,
} from './GraphPanel'
import { GraphCanvas, buildAllScene, FULL_LAYOUT } from './GraphPanel'
import './graph.css'

const FULL_GRAPH = { nodes: FULL_GRAPH_NODES, edges: FULL_GRAPH_EDGES }
Expand Down Expand Up @@ -38,12 +33,7 @@ export default function NetworkView() {
return (
<section className="panel col-graph">
<ReactFlowProvider>
<GraphCanvas
scene2={scene2}
mode="all"
index={fullGraphIndex}
title="전체 관계망"
/>
<GraphCanvas scene2={scene2} mode="all" title="전체 관계망" />
</ReactFlowProvider>
</section>
)
Expand Down
5 changes: 0 additions & 5 deletions src/utils/graph/layout.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { ONTOLOGY_EDGES, ONTOLOGY_NODES } from '#/mocks/graph/data'
import { buildGraphIndex } from '#/shared/utils/graphIndex'
import type { GraphIndex } from '#/shared/utils/graphIndex'
import { RADIUS, SECTOR_CENTERS } from '#/constants/graph/layout'
import type { OntologyNode } from '#/types/graph'
Expand All @@ -14,9 +12,6 @@ export interface LayoutPoint {
y: number
}

/** 전체 온톨로지 인덱스. 정적 데이터 기준으로 한 번만 계산해 캐시한다. */
export const graphIndex = buildGraphIndex(ONTOLOGY_NODES, ONTOLOGY_EDGES)

/** 파급 경로: 기점 중앙, hop 레벨별 동심원(타원) 배치 */
export function radialLayout(
ids: string[],
Expand Down