import React, { useState, useMemo } from 'react'; import { Network, ZoomIn, ZoomOut, RotateCcw, Search, SlidersHorizontal, ChevronRight, Sparkles, Link2, FileText, Info, ShieldCheck, CheckCircle2, ArrowRight, ExternalLink, Layers, Activity, GitPullRequest, BookOpen, Filter, Eye, X, HelpCircle } from 'lucide-react'; export default function KnowledgeGraph({ graphData, loading, onSelectTab }) { const [zoom, setZoom] = useState(1); const [searchQuery, setSearchQuery] = useState(''); const [selectedNode, setSelectedNode] = useState(null); const [filterType, setFilterType] = useState('ALL'); const [displayMode, setDisplayMode] = useState('pipeline'); // 'pipeline' (hierarchical flow) | 'network' (constellation) const [showGraphExplainer, setShowGraphExplainer] = useState(true); const rawNodes = graphData?.nodes || []; const rawEdges = graphData?.edges || []; // Categorize nodes into intuitive medical layers const categorized = useMemo(() => { const docs = []; const claims = []; const metrics = []; const rules = []; const proposals = []; rawNodes.forEach((n) => { const t = String(n.type || '').toUpperCase(); if (t === 'DOCUMENT') docs.push(n); else if (t === 'METRIC') metrics.push(n); else if (t === 'CLAIM') claims.push(n); else if (t === 'RULE' || t === 'SAFETY') rules.push(n); else if (t === 'PROPOSAL') proposals.push(n); else claims.push(n); // default }); return { docs, claims, metrics, rules, proposals }; }, [rawNodes]); // Filter nodes based on user search and category const filteredNodes = useMemo(() => { return rawNodes.filter((n) => { const t = String(n.type || '').toUpperCase(); const matchesType = filterType === 'ALL' || (filterType === 'DOCUMENTS' && t === 'DOCUMENT') || (filterType === 'CLAIMS' && t === 'CLAIM') || (filterType === 'METRICS' && t === 'METRIC') || (filterType === 'RULES' && (t === 'RULE' || t === 'SAFETY')) || (filterType === 'PROPOSALS' && t === 'PROPOSAL'); const q = searchQuery.toLowerCase().trim(); const matchesSearch = !q || (n.title || '').toLowerCase().includes(q) || String(n.value || '').toLowerCase().includes(q) || (n.filename || '').toLowerCase().includes(q); return matchesType && matchesSearch; }); }, [rawNodes, filterType, searchQuery]); // Generate constellation layout coordinates for Network view const positionedNodes = useMemo(() => { const total = filteredNodes.length; if (total === 0) return []; const centerX = 400; const centerY = 300; const radius = Math.min(centerX, centerY) - 70; return filteredNodes.map((node, i) => { const angle = (i * 2.399963) % (2 * Math.PI); const r = 40 + (radius - 40) * Math.sqrt((i + 1) / total); const x = centerX + r * Math.cos(angle); const y = centerY + r * Math.sin(angle); return { ...node, x, y }; }); }, [filteredNodes]); const nodeMap = useMemo(() => { const map = {}; positionedNodes.forEach((n) => { map[n.id] = n; }); return map; }, [positionedNodes]); const getNodeTheme = (type) => { const t = String(type || '').toUpperCase(); switch (t) { case 'DOCUMENT': return { color: '#3B82F6', // Blue bg: 'bg-blue-500/10', border: 'border-blue-500/30', badge: 'SOURCE DOCUMENT', icon: FileText, desc: 'Original medical guideline or clinical PDF.' }; case 'CLAIM': return { color: '#8B5CF6', // Violet bg: 'bg-violet-500/10', border: 'border-violet-500/30', badge: 'CLINICAL ASSERTION', icon: Activity, desc: 'Verified clinical finding or standard of care.' }; case 'METRIC': return { color: '#10B981', // Emerald bg: 'bg-emerald-500/10', border: 'border-emerald-500/30', badge: 'DOSING / THRESHOLD', icon: Sparkles, desc: 'Quantitative clinical threshold or numerical boundary.' }; case 'RULE': case 'SAFETY': return { color: '#F59E0B', // Amber bg: 'bg-amber-500/10', border: 'border-amber-500/30', badge: 'SAFETY GUARDRAIL', icon: ShieldCheck, desc: 'Quality gate or regulatory constraint (e.g. GCP 24h SLA).' }; case 'PROPOSAL': return { color: '#EC4899', // Pink bg: 'bg-pink-500/10', border: 'border-pink-500/30', badge: 'STAGED PULL REQUEST', icon: GitPullRequest, desc: 'Candidate assertion awaiting human peer review.' }; default: return { color: '#06B6D4', // Cyan bg: 'bg-cyan-500/10', border: 'border-cyan-500/30', badge: 'MEDICAL ENTITY', icon: Link2, desc: 'Medical concept, drug, or classification.' }; } }; if (loading) { return (

Building Knowledge Lineage Graph...

); } return (
{/* =================================================================== */} {/* 1. PLAIN-ENGLISH EDUCATIONAL BANNER (No Jargon) */} {/* =================================================================== */} {showGraphExplainer && (
Medical Knowledge Lineage & Connections Interactive Visual Map

Think of this as a family tree for clinical knowledge. Source medical documents (blue) sit at the root. DiffWeave extracts verified assertions (violet) and dosing cutoffs (emerald), which are automatically guarded by compliance rules (amber).

1. Source Guidelines → 2. Clinical Findings → 3. Dosing Thresholds → 4. Safety Guardrails
)} {/* =================================================================== */} {/* 2. GRAPH CONTROLS (Views, Search, Filters) */} {/* =================================================================== */}

Knowledge Lineage

{rawNodes.length} medical elements • {rawEdges.length} connections
{/* Node Search Bar */}
setSearchQuery(e.target.value)} className="bg-[#141B2D] border border-slate-800 rounded-lg pl-8 pr-3 py-1.5 text-xs text-slate-200 focus:outline-none focus:ring-1 focus:ring-emerald-500 w-36 sm:w-44" />
{/* Category Filter */} {/* View Mode Toggle: Lineage Pipeline vs Network Constellation */}
{/* Zoom Controls (Network Mode Only) */} {displayMode === 'network' && (
)}
{/* =================================================================== */} {/* 3. MAIN VISUAL CANVAS: PIPELINE FLOW vs CONSTELLATION */} {/* =================================================================== */} {displayMode === 'pipeline' ? ( /* ================================================================= */ /* VIEW 1: STRUCTURED PIPELINE LINEAGE FLOW (No Jargon, Easy to Get) */ /* ================================================================= */
{/* Column 1: Source Medical Documents */}
Source Documents
{categorized.docs.length || 1}

Baseline protocols uploaded to DiffWeave staging.

{(categorized.docs.length > 0 ? categorized.docs : [ { id: 'doc-baseline', title: 'Clinical-Guidelines-2026.pdf', value: 'Master clinical protocol version 2026', type: 'DOCUMENT' } ]).map((doc) => (
setSelectedNode(doc)} className="p-3 rounded-xl bg-[#101726] hover:bg-[#162136] border border-blue-500/30 transition cursor-pointer space-y-1.5 shadow-sm group" >
{doc.title} PDF

{doc.value || 'Verified baseline source document'}

))}
{/* Column 2: Clinical Findings & Guidelines */}
Clinical Findings
{categorized.claims.length}

Clinical claims extracted and committed to master.

{categorized.claims.map((claim) => (
setSelectedNode(claim)} className="p-3 rounded-xl bg-[#121426] hover:bg-[#1A1C38] border border-violet-500/30 transition cursor-pointer space-y-1.5 shadow-sm group" >
{claim.title} 96% Conf

{claim.value}

))}
{/* Column 3: Dosing & Numerical Thresholds */}
Dosing & Thresholds
{categorized.metrics.length}

Quantitative boundaries and numerical guidelines.

{categorized.metrics.map((metric) => (
setSelectedNode(metric)} className="p-3 rounded-xl bg-[#0F1A1C] hover:bg-[#152528] border border-emerald-500/30 transition cursor-pointer space-y-1.5 shadow-sm group" >
{metric.title} {Math.round((metric.confidence || 0.95) * 100)}%

{metric.value}

))}
{/* Column 4: Safety Guardrails & Compliance Rules */}
Safety Guardrails
4

Automated policy checks enforcing clinical compliance.

{[ { id: 'rule-floor', title: 'Confidence Floor ≥ 85%', value: 'Prevents low-confidence extractions from polluting the Truth Register.', type: 'RULE' }, { id: 'rule-provenance', title: 'Mandatory Provenance Citation', value: 'Requires every claim to cite exact document page and paragraph.', type: 'RULE' }, { id: 'rule-sae', title: 'Safety Escalation SLA (24h)', value: 'Strict 24-hour reporting deadline for adverse clinical deviations.', type: 'RULE' }, { id: 'rule-stats', title: 'Statistical p-Value Validation', value: 'Ensures clinical numerical claims specify confidence intervals.', type: 'RULE' }, ].map((rule) => (
setSelectedNode(rule)} className="p-3 rounded-xl bg-[#1A160F] hover:bg-[#262016] border border-amber-500/30 transition cursor-pointer space-y-1.5 shadow-sm group" >
{rule.title}

{rule.value}

))}
) : ( /* ================================================================= */ /* VIEW 2: INTERACTIVE NETWORK CONSTELLATION CANVAS */ /* ================================================================= */
{/* Connecting Lines */} {rawEdges.map((edge, idx) => { const src = nodeMap[edge.source]; const tgt = nodeMap[edge.target]; if (!src || !tgt) return null; const isHighlighted = selectedNode && (selectedNode.id === src.id || selectedNode.id === tgt.id); return ( ); })} {/* Circular Nodes */} {positionedNodes.map((node) => { const isSelected = selectedNode?.id === node.id; const theme = getNodeTheme(node.type); return ( setSelectedNode(node)} className="cursor-pointer group" > {isSelected && ( )} {node.title.length > 20 ? node.title.slice(0, 18) + '...' : node.title} ); })}
{/* Side Inspector in Constellation Mode */}

Element Inspector

{selectedNode ? ( renderNodeDetails(selectedNode) ) : (

Click any node on the graph to inspect its clinical finding, confidence, and source document.

)}
)} {/* =================================================================== */} {/* 4. SLIDE-OVER / MODAL INSPECTOR WHEN CLICKING ANY NODE IN PIPELINE */} {/* =================================================================== */} {selectedNode && displayMode === 'pipeline' && (
setSelectedNode(null)} />
{getNodeTheme(selectedNode.type).badge}

{selectedNode.title}

{renderNodeDetails(selectedNode)}
{onSelectTab && selectedNode.type !== 'RULE' && ( )}
)}
); // Helper function to render node detail card function renderNodeDetails(node) { const theme = getNodeTheme(node.type); const Icon = theme.icon; return (
{theme.badge}

{node.value || node.title}

{theme.desc}
{/* Provenance & Citation */}
Provenance Citation
Source Protocol: {node.filename || 'Clinical_Guideline.pdf'}
Section Citation: Section 2.1 Baseline Standard
{node.confidence !== undefined && (
Confidence Score: {Math.round((node.confidence || 0.95) * 100)}% Verified
)}
{/* Connected Elements */}
Lineage Relationships
Extracted from: {node.filename || 'Clinical_Guideline.pdf'}
Guarded by: Confidence Floor (≥85%) & Mandatory Provenance
Committed branch: refs/heads/main
); } }