import React, { useEffect, useRef, useState } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { BarChart3, Activity, Zap, Info, Maximize2 } from 'lucide-react'; import PropTypes from 'prop-types'; import FullscreenCircuitViewer from './FullscreenCircuitViewer'; const QuantumVisualization = ({ result, type = 'auto' }) => { const [activeVisualization, setActiveVisualization] = useState('circuit'); const [showFullscreen, setShowFullscreen] = useState(false); // Bloch Sphere Visualization const BlochSphere = ({ stateVector }) => { const canvasRef = useRef(null); useEffect(() => { if (!canvasRef.current || !stateVector) return; const canvas = canvasRef.current; const ctx = canvas.getContext('2d'); const centerX = canvas.width / 2; const centerY = canvas.height / 2; const radius = Math.min(centerX, centerY) - 20; // Clear canvas ctx.clearRect(0, 0, canvas.width, canvas.height); // Draw sphere outline ctx.beginPath(); ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI); ctx.strokeStyle = '#e5e7eb'; ctx.lineWidth = 2; ctx.stroke(); // Draw axes ctx.strokeStyle = '#9ca3af'; ctx.lineWidth = 1; // X axis ctx.beginPath(); ctx.moveTo(centerX - radius, centerY); ctx.lineTo(centerX + radius, centerY); ctx.stroke(); // Y axis (vertical) ctx.beginPath(); ctx.moveTo(centerX, centerY - radius); ctx.lineTo(centerX, centerY + radius); ctx.stroke(); // Calculate state vector position on Bloch sphere if (stateVector && stateVector.length >= 2) { const alpha = stateVector[0]; const beta = stateVector[1]; // Convert to Bloch sphere coordinates const theta = 2 * Math.acos(Math.abs(alpha)); const phi = Math.arg ? Math.arg(beta / alpha) : 0; const x = radius * Math.sin(theta) * Math.cos(phi); const z = radius * Math.cos(theta); // Project to 2D (simple projection) const projX = centerX + x; const projY = centerY - z; // Flip Y for canvas coordinates // Draw state vector ctx.beginPath(); ctx.moveTo(centerX, centerY); ctx.lineTo(projX, projY); ctx.strokeStyle = '#6366f1'; ctx.lineWidth = 3; ctx.stroke(); // Draw state point ctx.beginPath(); ctx.arc(projX, projY, 6, 0, 2 * Math.PI); ctx.fillStyle = '#6366f1'; ctx.fill(); } // Add labels ctx.fillStyle = '#374151'; ctx.font = '12px Inter'; ctx.textAlign = 'center'; ctx.fillText('|0⟩', centerX, centerY - radius - 10); ctx.fillText('|1⟩', centerX, centerY + radius + 20); ctx.textAlign = 'left'; ctx.fillText('|+⟩', centerX + radius + 10, centerY + 5); ctx.textAlign = 'right'; ctx.fillText('|-⟩', centerX - radius - 10, centerY + 5); }, [stateVector]); return ( ); }; // Probability Bar Chart const ProbabilityChart = ({ probabilities }) => { if (!probabilities || typeof probabilities !== 'object') return null; const entries = Object.entries(probabilities); const maxProb = Math.max(...entries.map(([, prob]) => prob)); return (
{entries.map(([state, probability]) => (
|{state}⟩
{(probability * 100).toFixed(1)}%
))}
); }; // Circuit SVG Display const CircuitDisplay = ({ circuitSvg }) => { const [zoom, setZoom] = useState(1); const [isDragging, setIsDragging] = useState(false); const [dragStart, setDragStart] = useState({ x: 0, y: 0 }); const [scrollPos, setScrollPos] = useState({ x: 0, y: 0 }); const containerRef = useRef(null); if (!circuitSvg) return null; const handleZoomIn = () => setZoom(prev => Math.min(prev + 0.2, 3)); const handleZoomOut = () => setZoom(prev => Math.max(prev - 0.2, 0.5)); const handleResetZoom = () => setZoom(1); const handleMouseDown = (e) => { setIsDragging(true); setDragStart({ x: e.clientX, y: e.clientY }); }; const handleMouseMove = (e) => { if (!isDragging || !containerRef.current) return; const deltaX = e.clientX - dragStart.x; const deltaY = e.clientY - dragStart.y; containerRef.current.scrollLeft = scrollPos.x - deltaX; containerRef.current.scrollTop = scrollPos.y - deltaY; }; const handleMouseUp = () => { if (containerRef.current) { setScrollPos({ x: containerRef.current.scrollLeft, y: containerRef.current.scrollTop }); } setIsDragging(false); }; return (

Quantum Circuit Diagram

Scroll or drag to navigate • Use zoom controls for better viewing

{/* Controls */}
{/* Zoom Controls */}
{Math.round(zoom * 100)}%
{/* Fullscreen Button */}
{ const touch = e.touches[0]; handleMouseDown({ clientX: touch.clientX, clientY: touch.clientY }); }} onTouchMove={(e) => { const touch = e.touches[0]; handleMouseMove({ clientX: touch.clientX, clientY: touch.clientY }); }} onTouchEnd={handleMouseUp} >
{/* Navigation hints */}
Drag to pan • Scroll to navigate Drag or swipe to navigate Use zoom controls for detail
); }; const visualizations = [ { id: 'circuit', label: 'Circuit', icon: , component: , available: !!result?.output?.circuit_svg, }, { id: 'probabilities', label: 'Probabilities', icon: , component: , available: !!result?.output?.probabilities, }, { id: 'bloch', label: 'Bloch Sphere', icon: , component: , available: !!result?.output?.state_vector, }, ]; const availableVisualizations = visualizations.filter(viz => viz.available); if (!result || availableVisualizations.length === 0) { return (

No visualization data available

Run a simulation to see results

); } return (
{availableVisualizations.length > 1 && (
{availableVisualizations.map((viz) => ( ))}
)} {availableVisualizations.map((viz) => ( viz.id === activeVisualization && ( {viz.component} ) ))} {/* Fullscreen Circuit Viewer */} setShowFullscreen(false)} />
); }; QuantumVisualization.propTypes = { result: PropTypes.object, type: PropTypes.string, }; export default QuantumVisualization;