"use client"; import { useState, useMemo } from "react"; interface GraphNode { id: string; label: string; type: string; x: number; y: number; description?: string; } interface GraphEdge { source: string; target: string; label: string; } const TYPE_COLORS: Record = { PERSON: "#FF6B6B", ORGANIZATION: "#4ECDC4", LOCATION: "#45B7D1", EVENT: "#FFA07A", DATE: "#98D8C8", CONCEPT: "#AED6F1", WORK: "#F9E79F", QUERY: "#FF6B00", }; const SCENARIOS: { name: string; query: string; nodes: GraphNode[]; edges: GraphEdge[]; reasoning: string[]; }[] = [ { name: "Nationality Comparison", query: "Were Scott Derrickson and Ed Wood of the same nationality?", nodes: [ { id: "q", label: "Query", type: "QUERY", x: 450, y: 50, description: "Bridge question comparing two entities" }, { id: "sd", label: "Scott Derrickson", type: "PERSON", x: 200, y: 190, description: "American filmmaker, director of Sinister (2012)" }, { id: "ew", label: "Ed Wood", type: "PERSON", x: 700, y: 190, description: "American filmmaker, director of Plan 9 from Outer Space" }, { id: "us", label: "United States", type: "LOCATION", x: 450, y: 340, description: "Country — shared nationality node" }, { id: "denver", label: "Denver, CO", type: "LOCATION", x: 120, y: 340, description: "Birthplace of Scott Derrickson" }, { id: "pough", label: "Poughkeepsie, NY", type: "LOCATION", x: 780, y: 340, description: "Birthplace of Ed Wood" }, { id: "sinister", label: "Sinister (2012)", type: "WORK", x: 100, y: 200, description: "Horror film directed by Derrickson" }, { id: "planNine", label: "Plan 9 from Outer Space", type: "WORK", x: 800, y: 200, description: "Cult classic by Ed Wood" }, { id: "horror", label: "Horror Genre", type: "CONCEPT", x: 450, y: 460, description: "Shared genre concept" }, ], edges: [ { source: "q", target: "sd", label: "FOUND_ENTITY" }, { source: "q", target: "ew", label: "FOUND_ENTITY" }, { source: "sd", target: "denver", label: "BORN_IN" }, { source: "ew", target: "pough", label: "BORN_IN" }, { source: "denver", target: "us", label: "LOCATED_IN" }, { source: "pough", target: "us", label: "LOCATED_IN" }, { source: "sd", target: "sinister", label: "DIRECTED" }, { source: "ew", target: "planNine", label: "DIRECTED" }, { source: "sinister", target: "horror", label: "GENRE" }, { source: "planNine", target: "horror", label: "GENRE" }, ], reasoning: [ "Entry: Query identifies two key entities — Scott Derrickson and Ed Wood", "Hop 1: BORN_IN relationships — Derrickson → Denver, CO; Wood → Poughkeepsie, NY", "Hop 2: LOCATED_IN traversal — Both cities → United States", "Convergence: Both paths meet at 'United States' node — same nationality confirmed", ], }, { name: "Magazine Comparison", query: "Which magazine was started first, Arthur's Magazine or First for Women?", nodes: [ { id: "q", label: "Query", type: "QUERY", x: 450, y: 50, description: "Comparison question — temporal ordering" }, { id: "am", label: "Arthur's Magazine", type: "WORK", x: 220, y: 200, description: "American literary periodical" }, { id: "fw", label: "First for Women", type: "WORK", x: 680, y: 200, description: "American women's magazine" }, { id: "d1", label: "1844", type: "DATE", x: 220, y: 350, description: "Year Arthur's Magazine was founded" }, { id: "d2", label: "1989", type: "DATE", x: 680, y: 350, description: "Year First for Women was founded" }, { id: "pub", label: "Publishing", type: "CONCEPT", x: 450, y: 280, description: "Industry category" }, { id: "usa", label: "United States", type: "LOCATION", x: 450, y: 420, description: "Country of publication" }, ], edges: [ { source: "q", target: "am", label: "FOUND_ENTITY" }, { source: "q", target: "fw", label: "FOUND_ENTITY" }, { source: "am", target: "d1", label: "FOUNDED_IN" }, { source: "fw", target: "d2", label: "FOUNDED_IN" }, { source: "am", target: "pub", label: "INDUSTRY" }, { source: "fw", target: "pub", label: "INDUSTRY" }, { source: "am", target: "usa", label: "PUBLISHED_IN" }, { source: "fw", target: "usa", label: "PUBLISHED_IN" }, ], reasoning: [ "Entry: Two entities identified — Arthur's Magazine, First for Women", "Hop 1: FOUNDED_IN dates — Arthur's → 1844; First for Women → 1989", "Comparison: 1844 < 1989 — Arthur's Magazine predates by 145 years", "Answer: Arthur's Magazine was started first", ], }, ]; export function ExplorerContent() { const [scenarioIdx, setScenarioIdx] = useState(0); const [selectedNode, setSelectedNode] = useState(null); const [hops, setHops] = useState(2); const scenario = SCENARIOS[scenarioIdx]; const { nodes, edges, reasoning } = scenario; const nodeMap = useMemo(() => { const map: Record = {}; nodes.forEach((n) => { map[n.id] = n; }); return map; }, [nodes]); const selectedInfo = selectedNode ? nodeMap[selectedNode] : null; const connectedEdges = selectedNode ? edges.filter(e => e.source === selectedNode || e.target === selectedNode) : []; return (
{/* Scenario Selector */}
Scenario
{SCENARIOS.map((s, i) => ( ))}
“{scenario.query}”
{/* Graph Visualization — 3 cols */}
{/* Edges */} {edges.map((edge, i) => { const s = nodeMap[edge.source]; const t = nodeMap[edge.target]; if (!s || !t) return null; const isConnected = selectedNode && (edge.source === selectedNode || edge.target === selectedNode); const isHighlighted = !selectedNode || isConnected; const mx = (s.x + t.x) / 2; const my = (s.y + t.y) / 2 - 8; return ( {isHighlighted && ( {edge.label} )} ); })} {/* Nodes */} {nodes.map((node) => { const color = TYPE_COLORS[node.type] || "#AED6F1"; const isSelected = selectedNode === node.id; const isConnected = connectedEdges.some(e => e.source === node.id || e.target === node.id); const r = isSelected ? 26 : 20; const dimmed = selectedNode && !isSelected && !isConnected; return ( setSelectedNode(isSelected ? null : node.id)} opacity={dimmed ? 0.3 : 1} > {isSelected && ( <> )} {node.type === "QUERY" && ( ? )} {node.label} ); })}
{/* Sidebar */}
{/* Node Details */}
{selectedInfo ? "Node Details" : "Select a Node"}
{selectedInfo ? (
{selectedInfo.label}
{selectedInfo.type} {selectedInfo.description && (

{selectedInfo.description}

)}
{connectedEdges.length} Connection{connectedEdges.length !== 1 ? "s" : ""}
{connectedEdges.map((e, i) => { const other = e.source === selectedInfo.id ? e.target : e.source; const otherNode = nodeMap[other]; return (
setSelectedNode(other)} style={{ padding: "6px 10px", borderRadius: "8px", background: "rgba(255,255,255,0.04)" }}>
{e.label} {otherNode?.label}
); })}
) : (

Click any node on the graph to see its details, connections, and type information.

)}
{/* Graph Stats */}
Graph Statistics
{[ { label: "Nodes", value: nodes.length, color: "#FF6B00" }, { label: "Edges", value: edges.length, color: "#0072CE" }, { label: "Avg Degree", value: (edges.length * 2 / nodes.length).toFixed(1), color: "#5db8a6" }, { label: "Entity Types", value: new Set(nodes.map(n => n.type)).size, color: "#cc785c" }, { label: "Hops", value: hops, color: "#002B49" }, ].map((s, i) => (
{s.label} {s.value}
))}
{/* Legend */}
Entity Types
{Object.entries(TYPE_COLORS).map(([type, color]) => (
{type}
))}
{/* Reasoning Steps */}
🧠 Graph Reasoning Path
{reasoning.map((step, i) => (
Step {i + 1}

{step}

))}
); }