Skip to content

Commit 13cfcae

Browse files
author
Ritika Mishra
committed
updated code for full page view of beta candle
1 parent 566ac0e commit 13cfcae

File tree

2 files changed

+100
-46
lines changed

2 files changed

+100
-46
lines changed

src/components/CandleLit.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,19 +80,18 @@ const BrightCandleView: React.FC<BrightCandleViewProps> = ({ fftData = [], betaP
8080
border border-gray-300 dark:border-white/20
8181
backdrop-blur-md shadow-xl
8282
transition-transform duration-300
83-
group-hover:scale-105
8483
before:absolute before:inset-0 before:bg-white/10 before:opacity-40 before:rounded-b-xl before:rounded-t-md
85-
after:absolute after:bottom-0 after:left-0 after:right-0 after:h-2 after:bg-gradient-to-b after:from-transparent after:to-gray-300/30"
84+
"
8685
>
8786

88-
<div className="absolute inset-0 overflow-hidden rounded-b-xl rounded-t-md bg-gradient-to-b from-cyan-300 via-blue-400 to-blue-600
87+
<div className="absolute inset-0 overflow-hidden rounded-b-xl rounded-t-md bg-gradient-to-b from-cyan-300 via-blue-400 to-blue-400
8988
">
9089

9190
<div className="absolute top-2 left-2 right-2 h-0.5 bg-gray-300/30"></div>
9291

9392
<div className="absolute top-2 left-1/2 transform -translate-x-1/2 text-center">
94-
<div className="text-sm font-semibold text-gray-700 px-2 py-1 rounded-md ">
95-
Beta: {betaPower.toFixed(1)}%
93+
<div className="text-sm font-semibold text-gray-500 px-2 py-1 rounded-md ">
94+
{String(Math.floor(betaPower)).padStart(2, '0')}
9695
</div>
9796
</div>
9897
</div>

src/components/FFT.tsx

Lines changed: 96 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import React, {
77
useMemo,
88
useCallback,
99
} from "react";
10+
import { Expand, Shrink } from "lucide-react";
1011
import { useTheme } from "next-themes";
1112
import BandPowerGraph from "./BandPowerGraph";
1213
import { WebglPlot, ColorRGBA, WebglLine } from "webgl-plot";
@@ -31,7 +32,9 @@ const FFT = forwardRef(
3132
ref
3233
) => {
3334
const fftBufferRef = useRef<number[][]>(Array.from({ length: 16 }, () => []));
34-
const [fftData, setFftData] = useState<number[][]>(Array.from({ length: 16 }, () => []));
35+
const [fftData, setFftData] = useState<number[][]>(
36+
Array.from({ length: 16 }, () => [])
37+
);
3538
const fftSize = 256;
3639
const sampleupdateref = useRef<number>(50);
3740
sampleupdateref.current = currentSamplingRate / 10;
@@ -41,20 +44,28 @@ const FFT = forwardRef(
4144
const maxFreq = 60;
4245
const [betaPower, setBetaPower] = useState<number>(0);
4346
const betaPowerRef = useRef<number>(0);
44-
const channelColors = useMemo(() => ["red", "green", "blue", "purple", "orange", "yellow"], []);
47+
const channelColors = useMemo(
48+
() => ["red", "green", "blue", "purple", "orange", "yellow"],
49+
[]
50+
);
4551
const canvasContainerRef = useRef<HTMLDivElement>(null);
4652
const dataPointCountRef = useRef<number>(1000);
4753
const wglPlotsref = useRef<WebglPlot[]>([]);
4854
const linesRef = useRef<WebglLine[]>([]);
49-
const sweepPositions = useRef<number[]>(new Array(6).fill(0)); // Array for sweep positions
50-
const [activeBandPowerView, setActiveBandPowerView] = useState<'bandpower' | 'brightcandle' | 'moveup'>('bandpower');
55+
const sweepPositions = useRef<number[]>(new Array(6).fill(0));
56+
57+
// Extend views to include 'fullcandle'
58+
const [activeBandPowerView, setActiveBandPowerView] = useState<
59+
'bandpower' | 'brightcandle' | 'fullcandle'
60+
>('bandpower');
5161

5262
const buttonStyles = (view: string) => `
53-
px-4 py-2 text-sm font-medium transition-all duration-300 rounded-md
54-
${activeBandPowerView === view
63+
px-4 py-2 text-sm font-medium transition-all duration-300 rounded-md
64+
${activeBandPowerView === view
5565
? 'bg-primary text-primary-foreground border rounded-xl '
56-
: 'border rounded-xl bg-gray-600 text-primary-foreground'}
57-
`;
66+
: 'border rounded-xl bg-gray-600 text-primary-foreground'
67+
}
68+
`;
5869

5970
let samplesReceived = 0;
6071
class SmoothingFilter {
@@ -64,15 +75,15 @@ const FFT = forwardRef(
6475
private dataIndex: number = 0;
6576

6677
constructor(bufferSize: number = 5, initialLength: number = 0) {
67-
this.bufferSize = bufferSize;
78+
this.bufferSize = Math.max(1, Math.floor(bufferSize)); // Prevent negative or NaN
6879
this.circularBuffers = Array.from({ length: initialLength }, () =>
69-
new Array(bufferSize).fill(0)
80+
Array(this.bufferSize).fill(0)
7081
);
7182
this.sums = new Array(initialLength).fill(0);
7283
}
7384

85+
7486
getSmoothedValues(newValues: number[]): number[] {
75-
// Initialize buffers if first run or size changed
7687
if (this.circularBuffers.length !== newValues.length) {
7788
this.circularBuffers = Array.from({ length: newValues.length }, () =>
7889
new Array(this.bufferSize).fill(0)
@@ -94,57 +105,69 @@ const FFT = forwardRef(
94105
}
95106
}
96107

97-
// Add this useEffect to calculate initial beta power
98108
useEffect(() => {
99109
if (fftData.length > 0 && fftData[0].length > 0) {
100110
const channelData = fftData[0];
101-
const betaPower = calculateBandPower(channelData, [13, 32]); // Beta range
102-
const totalPower = calculateBandPower(channelData, [0.5, 100]); // Full range
103-
const normalizedBeta = (betaPower / totalPower) * 100;
111+
const beta = calculateBandPower(channelData, [13, 32]);
112+
const total = calculateBandPower(channelData, [0.5, 100]);
113+
const normalizedBeta = (beta / total) * 100;
104114
setBetaPower(normalizedBeta);
105115
betaPowerRef.current = normalizedBeta;
106116
}
107117
}, [fftData]);
108118

109-
// Add this calculateBandPower function to FFT.tsx
110-
const calculateBandPower = useCallback((magnitudes: number[], range: [number, number]) => {
111-
const [startFreq, endFreq] = range;
112-
const freqStep = currentSamplingRate / fftSize;
113-
const startIndex = Math.max(1, Math.floor(startFreq / freqStep));
114-
const endIndex = Math.min(Math.floor(endFreq / freqStep), magnitudes.length - 1);
115-
let power = 0;
116-
for (let i = startIndex; i <= endIndex; i++) {
117-
power += magnitudes[i] * magnitudes[i];
118-
}
119-
return power;
120-
}, [currentSamplingRate, fftSize]);
119+
const calculateBandPower = useCallback(
120+
(magnitudes: number[], range: [number, number]) => {
121+
const [startFreq, endFreq] = range;
122+
const freqStep = currentSamplingRate / fftSize;
123+
const startIndex = Math.max(1, Math.floor(startFreq / freqStep));
124+
const endIndex = Math.min(
125+
Math.floor(endFreq / freqStep),
126+
magnitudes.length - 1
127+
);
128+
let power = 0;
129+
for (let i = startIndex; i <= endIndex; i++) {
130+
power += magnitudes[i] * magnitudes[i];
131+
}
132+
return power;
133+
},
134+
[currentSamplingRate, fftSize]
135+
);
121136

122137
const renderBandPowerView = () => {
123138
switch (activeBandPowerView) {
124139
case 'bandpower':
125140
return (
126141
<BandPowerGraph
127142
fftData={fftData}
128-
// Update both state and ref
129143
onBetaUpdate={(beta) => {
130144
betaPowerRef.current = beta;
131145
setBetaPower(beta);
132146
}}
133-
134147
samplingRate={currentSamplingRate}
135148
/>
136149
);
137150
case 'brightcandle':
138151
return (
139152
<BrightCandleView
140-
betaPower={betaPower} // Use state value instead of ref
153+
betaPower={betaPower}
141154
fftData={fftData}
142155
/>
143156
);
144-
case 'moveup':
157+
case 'fullcandle':
145158
return (
146-
<div className="w-full h-full flex items-center justify-center text-gray-400">
147-
Move Up View
159+
<div className="fixed inset-0 bg-gradient-to-b from-gray-900 to-black z-50 flex flex-col items-center justify-center p-4">
160+
<button
161+
onClick={() => setActiveBandPowerView('brightcandle')}
162+
className="absolute top-4 right-4 p-2 bg-transparent text-white hover:text-gray-300 transition-all duration-300"
163+
>
164+
<Shrink />
165+
</button>
166+
<div className="w-full max-w-4xl h-full flex items-center justify-center">
167+
<div className="transform scale-150 filter drop-shadow-2xl">
168+
<BrightCandleView betaPower={betaPower} fftData={fftData} />
169+
</div>
170+
</div>
148171
</div>
149172
);
150173
default:
@@ -155,13 +178,15 @@ const FFT = forwardRef(
155178
betaPowerRef.current = beta;
156179
setBetaPower(beta);
157180
}}
158-
159181
samplingRate={currentSamplingRate}
160182
/>
161183
);
162184
}
163185
};
164-
const filter = new SmoothingFilter((currentSamplingRate / sampleupdateref.current) * 2, 1);
186+
const rawBufferSize = (currentSamplingRate / sampleupdateref.current) * 2;
187+
const safeBufferSize = Math.max(1, Math.floor(rawBufferSize) || 1);
188+
const filter = new SmoothingFilter(safeBufferSize, 1);
189+
165190

166191
useImperativeHandle(
167192
ref,
@@ -177,8 +202,7 @@ const FFT = forwardRef(
177202
}
178203
samplesReceived++;
179204

180-
// Trigger FFT computation more frequently
181-
if (samplesReceived % sampleupdateref.current === 0) { // Changed from 25 to 5
205+
if (samplesReceived % sampleupdateref.current === 0) {
182206
const processedBuffer = fftBufferRef.current[i].slice(0, fftSize);
183207
const floatInput = new Float32Array(processedBuffer);
184208
const fftMags = fftProcessor.computeMagnitudes(floatInput);
@@ -454,7 +478,8 @@ const FFT = forwardRef(
454478
<main
455479
ref={canvasContainerRef}
456480
className="flex-1 bg-highlight rounded-2xl m-2 overflow-hidden min-h-0 "
457-
>
481+
>
482+
458483
</main>
459484
<div className="flex-1 m-2 flex flex-col md:flex-row justify-center overflow-hidden min-h-0 "
460485
>
@@ -467,17 +492,47 @@ const FFT = forwardRef(
467492
className="w-full h-full"
468493
/>
469494
</div>
470-
<div className="flex-1 flex flex-col overflow-hidden min-h-0 min-w-0 ml-4 bg-highlight rounded-2xl">
495+
<div
496+
className="
497+
relative /* ← make this container the positioning context */
498+
flex-1 flex flex-col
499+
overflow-hidden min-h-0 min-w-0
500+
ml-4 bg-highlight rounded-2xl
501+
"
502+
>
503+
{/* only show when we’re on the Beta Candle view */}
504+
{activeBandPowerView === 'brightcandle' && (
505+
<button
506+
onClick={() => setActiveBandPowerView('fullcandle')}
507+
className="
508+
absolute top-2 right-2
509+
p-2 bg-transparent
510+
text-gray-500 hover:text-gray-700
511+
transition-all duration-300
512+
"
513+
>
514+
<Expand />
515+
</button>
516+
)}
517+
471518
<div className="flex justify-center space-x-2 pt-2 rounded-t-xl">
472-
<button onClick={() => setActiveBandPowerView('bandpower')} className={buttonStyles('bandpower')}>
519+
<button
520+
onClick={() => setActiveBandPowerView('bandpower')}
521+
className={buttonStyles('bandpower')}
522+
>
473523
Band Power
474524
</button>
475-
<button onClick={() => setActiveBandPowerView('brightcandle')} className={buttonStyles('brightcandle')}>
525+
<button
526+
onClick={() => setActiveBandPowerView('brightcandle')}
527+
className={buttonStyles('brightcandle')}
528+
>
476529
Beta Candle
477530
</button>
478531
</div>
532+
479533
{renderBandPowerView()}
480534
</div>
535+
481536
</div>
482537
</div>
483538
);

0 commit comments

Comments
 (0)