Skip to content

Commit 16d55d2

Browse files
committed
UPDATE:
1. memory consumption chart based on no of qubits
1 parent 0bf7883 commit 16d55d2

File tree

1 file changed

+165
-67
lines changed

1 file changed

+165
-67
lines changed

qubitverse/visualizer/src/components/NQubitInput.jsx

Lines changed: 165 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,54 @@
11
import React, { useState, useRef, useEffect } from 'react';
2+
import { LineChart, Legend, Line, XAxis, YAxis, Tooltip, CartesianGrid, ResponsiveContainer } from "recharts";
23
import { Button } from './ui/button';
34

4-
function NQubitInput({ numQubits, setQubits }) {
5+
function NQubitInput({ setQubits }) {
56
const [tempQ, setTempQ] = useState('');
67
const [error, setError] = useState('');
8+
const [lineData, setLineData] = useState([]);
79
const inputRef = useRef(null);
810

911
useEffect(() => {
1012
inputRef.current?.focus();
1113
}, []);
1214

15+
const validate_input = (x) => {
16+
if (/^\d+$/.test(x.trim()) === false) {
17+
setError('Please enter a valid and positive number.');
18+
setQubits(null);
19+
inputRef.current.focus();
20+
return null;
21+
}
22+
const parsedValue = parseInt(x.trim(), 10);
23+
24+
if (isNaN(parsedValue) || parsedValue < 1 || !isFinite(parsedValue)) {
25+
setError('Please enter a number greater than or equal to 1.');
26+
setQubits(null);
27+
inputRef.current.focus();
28+
} else {
29+
setError('');
30+
}
31+
32+
return parsedValue;
33+
}
34+
1335
const handleChange = (e) => {
1436
setTempQ(e.target.value);
15-
setError('');
37+
const parsed = validate_input(e.target.value);
38+
39+
if (error == '' && parsed !== null) {
40+
const newData = [];
41+
for (let i = 1; i <= parsed; i++) {
42+
newData.push({
43+
name: `Qubit ${i}`,
44+
qubits: i,
45+
bytes: Math.pow(2, i) * 16
46+
});
47+
}
48+
setLineData(newData);
49+
}
50+
else
51+
setLineData([]);
1652
};
1753

1854
const handleConfirm = () => {
@@ -21,19 +57,10 @@ function NQubitInput({ numQubits, setQubits }) {
2157
return;
2258
}
2359

24-
const parsedValue = parseInt(tempQ.trim(), 10);
25-
26-
if (/^\d+$/.test(tempQ.trim()) === false) {
27-
setError('Please enter a valid and positive number.');
28-
setQubits(null);
29-
inputRef.current.focus();
30-
} else if (isNaN(parsedValue) || parsedValue < 1 || !isFinite(parsedValue)) {
31-
setError('Please enter a number greater than or equal to 1.');
32-
setQubits(null);
33-
inputRef.current.focus();
34-
} else {
35-
setError('');
36-
setQubits(parsedValue);
60+
const x = validate_input(tempQ);
61+
if (error == '' && x !== null) {
62+
setLineData([]);
63+
setQubits(x);
3764
}
3865
};
3966

@@ -44,60 +71,131 @@ function NQubitInput({ numQubits, setQubits }) {
4471
};
4572

4673
return (
47-
<div
48-
style={{
74+
<div style={{
75+
display: "flex"
76+
}}>
77+
<div style={{ height: "600px", width: "50%" }}>
78+
<textarea
79+
readOnly
80+
value={`A qubit (quantum bit) is the fundamental unit of quantum information.
81+
Unlike classical bits which are either 0 or 1, a qubit can be in a superposition ds
82+
of both 0 and 1 states at the same time. This allows quantum computers to
83+
perform complex calculations much faster than classical computers in some cases.`}
84+
style={{
85+
width: '100%',
86+
height: '50%',
87+
padding: '12px',
88+
fontSize: '14px',
89+
fontFamily: 'monospace, monospace',
90+
resize: 'none',
91+
backgroundColor: '#f0f0f0',
92+
color: '#333',
93+
borderRadius: '8px',
94+
border: '1px solid #ccc',
95+
marginBottom: '1rem',
96+
whiteSpace: 'pre-wrap'
97+
}}
98+
/>
99+
<div style={{ height: "480px", width: "100%", marginLeft: "20px" }}>
100+
{lineData.length > 0 ? (
101+
<ResponsiveContainer width="100%" height="100%">
102+
<LineChart data={lineData} margin={{ top: 10, right: 30, left: 0, bottom: 0 }}>
103+
<CartesianGrid strokeDasharray="3 3" />
104+
<XAxis dataKey="qubits" label={{ value: 'Qubits', position: 'insideBottom', offset: -5 }} />
105+
<YAxis
106+
label={{ value: "", angle: -90, position: 'insideLeft', offset: 50 }}
107+
tickFormatter={(val) => {
108+
if (val >= 1e15) return `${(val / 1e15).toFixed(1)} PB`;
109+
if (val >= 1e12) return `${(val / 1e12).toFixed(1)} TB`;
110+
if (val >= 1e9) return `${(val / 1e9).toFixed(1)} GB`;
111+
if (val >= 1e6) return `${(val / 1e6).toFixed(1)} MB`;
112+
if (val >= 1e3) return `${(val / 1e3).toFixed(1)} KB`;
113+
return `${val} B`;
114+
}}
115+
/>
116+
<Tooltip
117+
contentStyle={{ background: "#F8F1E7", fontWeight: "bold", borderRadius: "5px", padding: "10px", boxShadow: "0px 0px 10px rgba(0,0,0,0.2)" }}
118+
formatter={(val) =>
119+
[val >= 1e15 ? `Mem. Required: ${(val / 1e15).toFixed(1)} PB` :
120+
val >= 1e12 ? `Mem. Required: ${(val / 1e12).toFixed(1)} TB` :
121+
val >= 1e9 ? `Mem. Required: ${(val / 1e9).toFixed(1)} GB` :
122+
val >= 1e6 ? `Mem. Required: ${(val / 1e6).toFixed(1)} MB` :
123+
val >= 1e3 ? `Mem. Required: ${(val / 1e3).toFixed(1)} KB` :
124+
`${val} B`]
125+
}
126+
labelFormatter={(name) => [`Qubits: ${name}`]} />
127+
<Legend />
128+
<Line type="monotone" dataKey="bytes" stroke="#82ca9d" dot />
129+
</LineChart>
130+
</ResponsiveContainer>
131+
132+
) : (
133+
<div className="h-full flex items-center justify-center text-gray-500">
134+
Chart will appear here once you enter a number.
135+
</div>
136+
)}
137+
</div>
138+
</div>
139+
<div style={{
140+
width: "50%",
141+
height: "600px",
49142
display: "flex",
50-
flexDirection: "column",
51-
gap: "10px",
52-
userSelect: "none",
53-
width: "100%",
54-
maxWidth: "500px",
55143
alignItems: "center",
56-
justifyContent: "center",
57-
top: "50%",
58-
left: "50%",
59-
position: "absolute",
60-
transform: "translate(-50%, -50%)",
61-
border: "solid 3px",
62-
borderRadius: "8px",
63-
padding: "2rem",
64-
boxShadow: "0px 4px 12px rgba(0, 0, 0, 0.15)",
65-
backgroundColor: "#fff",
66-
}}
67-
>
68-
<h1 className="text-2xl font-bold mb-4 text-center">
69-
Enter Number of Qubits
70-
</h1>
71-
<input
72-
ref={inputRef}
73-
//type="number"
74-
value={tempQ}
75-
onChange={handleChange}
76-
onKeyDown={handleKeyDown}
77-
className="w-full p-2 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-blue-500"
78-
placeholder="Number of Qubits"
79-
min="1"
80-
/>
81-
<Button
82-
variant="outline"
83-
className="w-full py-2"
84-
onClick={handleConfirm}
85-
>
86-
Confirm
87-
</Button>
88-
<Button
89-
variant="ghost"
90-
className="w-full text-sm text-gray-500"
91-
onClick={() => {
92-
setTempQ('');
93-
setError('');
94-
setQubits(null);
95-
inputRef.current.focus();
96-
}}
97-
>
98-
Reset
99-
</Button>
100-
{error && <p className="text-red-500 text-sm mt-2" style={{ fontFamily: "monospace, monospace",}}>{error}</p>}
144+
justifyContent: "center"
145+
}}>
146+
<div
147+
style={{
148+
display: "flex",
149+
flexDirection: "column",
150+
gap: "10px",
151+
userSelect: "none",
152+
width: "100%",
153+
maxWidth: "500px",
154+
alignItems: "center",
155+
justifyContent: "center",
156+
border: "solid 3px",
157+
borderRadius: "8px",
158+
padding: "2rem",
159+
boxShadow: "0px 4px 12px rgba(0, 0, 0, 0.15)",
160+
backgroundColor: "#fff",
161+
}}
162+
163+
>
164+
<h1 className="text-2xl font-bold mb-4 text-center">
165+
Enter Number of Qubits
166+
</h1>
167+
<input
168+
ref={inputRef}
169+
type="number"
170+
value={tempQ}
171+
onChange={handleChange}
172+
onKeyDown={handleKeyDown}
173+
className="w-full p-2 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-blue-500"
174+
placeholder="Number of Qubits"
175+
min="1"
176+
/>
177+
<Button
178+
variant="outline"
179+
className="w-full py-2"
180+
onClick={handleConfirm}
181+
>
182+
Confirm
183+
</Button>
184+
<Button
185+
variant="ghost"
186+
className="w-full text-sm text-gray-500"
187+
onClick={() => {
188+
setTempQ('');
189+
setError('');
190+
setQubits(null);
191+
inputRef.current.focus();
192+
}}
193+
>
194+
Reset
195+
</Button>
196+
{error.length > 0 && <p className="text-red-500 text-sm mt-2" style={{ fontFamily: "monospace, monospace", }}>{error}</p>}
197+
</div>
198+
</div>
101199
</div>
102200
);
103201
}

0 commit comments

Comments
 (0)