diff --git a/src/app/globals.css b/src/app/globals.css index c8617d6..1d670c3 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -7,6 +7,11 @@ --background: 0 0% 100%; --foreground: 222.2 84% 4.9%; + /* background color for canvas page */ + --highlight: 0 0% 100%; /* Light mode: white color */ + --gray-light: 0 0% 95%; /* Light mode: gray-100 */ + + --card: 0 0% 100%; --card-foreground: 222.2 84% 4.9%; @@ -38,6 +43,9 @@ .dark { --background: 222.2 84% 4.9%; --foreground: 210 40% 98%; + + --highlight: 222.2 84% 4.9%; /* Dark mode: light gray */ + --gray-light: 222.2 84% 7%; /* Dark mode: dark gray */ --card: 222.2 84% 4.9%; --card-foreground: 210 40% 98%; @@ -81,6 +89,15 @@ -webkit-background-clip: text; -webkit-text-fill-color: transparent; } + .bg-highlight { + background-color: hsl(var(--highlight)); + } + .bg-g { + background-color: hsl(var(--gray-light)); + } + .border-g { + border-color: hsl(var(--gray-light)); + } } .loader { diff --git a/src/components/Canvas.tsx b/src/components/Canvas.tsx index 588df70..06afc1e 100644 --- a/src/components/Canvas.tsx +++ b/src/components/Canvas.tsx @@ -42,7 +42,8 @@ const Canvas = forwardRef( const [lines, setLines] = useState([]); const linesRef = useRef([]); const samplingRate = 500; // Set the sampling rate in Hz - + const sweepPositions = useRef(new Array(6).fill(0)); // Array for sweep positions + const currentSweepPos = useRef(new Array(6).fill(0)); // Array for sweep positions let numX: number; const getpoints = useCallback((bits: BitSelection): number => { @@ -64,6 +65,11 @@ const Canvas = forwardRef( ref, () => ({ updateData(data: number[]) { + // Reset the sweep positions if the number of channels has changed + if (currentSweepPos.current.length !== numChannels) { + currentSweepPos.current = new Array(numChannels).fill(0); + sweepPositions.current = new Array(numChannels).fill(0); + } updatePlots(data, Zoom); if (previousCounter !== null) { // If there was a previous counter value @@ -78,9 +84,34 @@ const Canvas = forwardRef( previousCounter = data[6]; // Update the previous counter with the current counter }, }), - [Zoom] + [Zoom, numChannels] ); + + // // + // updateGrid(); + + // function addGridLine(coords: Float32Array) { + // const color = new ColorRGBA(0.5, 0.5, 0.5, 1); + // const line = new WebglLine(color, 2); + // line.xy = coords; + // wglp.addLine(line); + // } + // function updateGrid(): void { + // wglp.removeAllLines(); + // wglp.addLine(lineMain); + // const ngX = 5; + // const ngY = 5; + // for (let i = 0; i < ngX; i++) { + // const divPoint = (2 * i) / (ngX - 1) - 1; + // addGridLine(new Float32Array([divPoint, -1, divPoint, 1])); + // } + // for (let i = 0; i < ngY; i++) { + // const divPoint = (2 * i) / (ngY - 1) - 1; + // addGridLine(new Float32Array([-1, divPoint, 1, divPoint])); + // } + // } + const createCanvases = () => { if (!canvasContainerRef.current) return; @@ -105,30 +136,26 @@ const Canvas = forwardRef( const newCanvases = []; const newWglPlots = []; const newLines = []; - for (let i = 0; i < numChannels; i++) { + for (let i = 0; i < numChannels; i++) { const canvasWrapper = document.createElement("div"); - canvasWrapper.className = "canvas-container border-b border-gray-300 flex-[1_1_0%] min-h-0"; - + canvasWrapper.className = "canvas-container flex-[1_1_0%] ";//border-b border-gray-300 + const canvas = document.createElement("canvas"); canvas.id = `canvas${i + 1}`; - - - canvas.width = canvasContainerRef.current.clientWidth; - - const canvasHeight = canvasContainerRef.current.clientHeight / numChannels; - console.log(canvasHeight); - canvas.height = canvasHeight; - - canvas.className = "w-full h-full block"; - + canvas.width = canvasContainerRef.current.clientWidth*2; + + const canvasHeight = (canvasContainerRef.current.clientHeight / numChannels)*2; + canvas.height = canvasHeight; + canvas.className = "w-full h-full block rounded-2xl"; + // Create a badge for the channel number const badge = document.createElement("div"); badge.className = - "absolute top-240 left-1 text-gray-500 text-sm rounded-full p-1"; // Set absolute positioning and styles + "absolute text-gray-500 text-sm rounded-full p-2 m-2"; // Set absolute positioning and styles badge.innerText = `CH${i + 1}`; // Append the canvas and badge to the container - + canvasWrapper.appendChild(badge); canvasWrapper.appendChild(canvas); canvasContainerRef.current.appendChild(canvasWrapper); @@ -136,11 +163,29 @@ const Canvas = forwardRef( const wglp = new WebglPlot(canvas); newWglPlots.push(wglp); wglp.gScaleY = Zoom; - const line = new WebglLine(getRandomColor(i,theme), numX); + const line = new WebglLine(getRandomColor(i, theme), numX); wglp.gOffsetY = 0; line.offsetY = 0; line.lineSpaceX(-1, 2 / numX); - + //grid + // const ngX = 5; + // const ngY = 5; + // for (let i = 0; i < ngX; i++) { + // const divPoint = (2 * i) / (ngX - 1) - 1; + // const color = new ColorRGBA(0.5, 0.5, 0.5, 1); + // const line = new WebglLine(color, 2); + // const coords = new Float32Array([divPoint, -1, divPoint, 1]) + // line.xy = coords; + // wglp.addLine(line);; + // } + // for (let i = 0; i < ngY; i++) { + // const divPoint = (2 * i) / (ngY - 1) - 1; + // const color = new ColorRGBA(0.5, 0.5, 0.5, 1); + // const line = new WebglLine(color, 2); + // const coords = new Float32Array([divPoint, -1, divPoint, 1]) + // line.xy = coords; + // wglp.addLine(line); + // } wglp.addLine(line); newLines.push(line); } @@ -151,7 +196,7 @@ const Canvas = forwardRef( setLines(newLines); }; - const getRandomColor = (i: number,theme:string| undefined): ColorRGBA => { + const getRandomColor = (i: number, theme: string | undefined): ColorRGBA => { // Define bright colors const colorsDark: ColorRGBA[] = [ new ColorRGBA(1, 0.286, 0.529, 1), // Bright Pink @@ -168,22 +213,23 @@ const Canvas = forwardRef( new ColorRGBA(0.404, 0.255, 0.533, 1), // #674188 - Bright Purple new ColorRGBA(0.902, 0.361, 0.098, 1), // #E65C19 - Bright Orange new ColorRGBA(0.180, 0.027, 0.247, 1), // #2E073F - Dark Purple - ]; - + ]; + // Return color based on the index, cycling through if necessary // return colors[i % colors.length]; // Ensure to always return a valid ColorRGBA return theme === "dark" - ? colorsDark[i % colorsDark.length] - : colorsLight[i % colorsLight.length]; + ? colorsDark[i % colorsDark.length] + : colorsLight[i % colorsLight.length]; }; const updatePlots = useCallback( (data: number[], Zoom: number) => { + wglPlots.forEach((wglp, index) => { if (wglp) { try { - wglp.gScaleY = Zoom; // Adjust this value as needed + wglp.gScaleY = Zoom; // Adjust the zoom value } catch (error) { console.error( `Error setting gScaleY for WebglPlot instance at index ${index}:`, @@ -194,24 +240,31 @@ const Canvas = forwardRef( console.warn(`WebglPlot instance at index ${index} is undefined.`); } }); + linesRef.current.forEach((line, i) => { - // Shift the data points efficiently using a single operation - const bitsPoints = Math.pow(2, getValue(selectedBits)); // Adjust this according to your ADC resolution + const bitsPoints = Math.pow(2, getValue(selectedBits)); // Adjust according to your ADC resolution const yScale = 2 / bitsPoints; const chData = (data[i] - bitsPoints / 2) * yScale; - for (let j = 1; j < line.numPoints; j++) { - line.setY(j - 1, line.getY(j)); - } - line.setY(line.numPoints - 1, chData); + // Use a separate sweep position for each line + currentSweepPos.current[i] = sweepPositions.current[i]; + // Plot the new data at the current sweep position + line.setY(currentSweepPos.current[i] % line.numPoints, chData); + + // Clear the next point to create a gap (optional, for visual effect) + const clearPosition = (currentSweepPos.current[i] + (numX/100)) % line.numPoints; + line.setY(clearPosition, NaN); + + // Increment the sweep position for the current line + sweepPositions.current[i] = (currentSweepPos.current[i] + 1) % line.numPoints; }); }, - [lines, wglPlots] - ); // Add dependencies here + [lines, wglPlots, numChannels, theme] + ); useEffect(() => { createCanvases(); - }, [numChannels,theme]); + }, [numChannels, theme]); const getValue = useCallback((bits: BitSelection): number => { switch (bits) { @@ -252,8 +305,8 @@ const Canvas = forwardRef( }, [createCanvases]); return ( -
); diff --git a/src/components/Connection.tsx b/src/components/Connection.tsx index c262cfc..cfe3a5c 100644 --- a/src/components/Connection.tsx +++ b/src/components/Connection.tsx @@ -736,14 +736,15 @@ const Connection: React.FC = ({ }; // bg-gray-100 text-white p-2 flex-none flex items-center justify-center return ( -
+
{/* Left-aligned section */} -
+
{isRecordingRef.current && (
-
+
+
= ({ >