diff options
| author | grothedev <grothedev@gmail.com> | 2025-10-02 23:35:14 -0400 |
|---|---|---|
| committer | grothedev <grothedev@gmail.com> | 2025-10-02 23:35:14 -0400 |
| commit | bcc93c8d058e6db05e32e262760d0903a721e402 (patch) | |
| tree | 6145b2ce2e3fd3a5ebb81a3409ecba858966286e /web-timeplot/src | |
| parent | ebcacda7c62454806740dd62260e46d6597692a7 (diff) | |
time scale
Diffstat (limited to 'web-timeplot/src')
| -rw-r--r-- | web-timeplot/src/main.js | 73 | ||||
| -rw-r--r-- | web-timeplot/src/waterfall.js | 35 |
2 files changed, 98 insertions, 10 deletions
diff --git a/web-timeplot/src/main.js b/web-timeplot/src/main.js index abcd72f..b0ba032 100644 --- a/web-timeplot/src/main.js +++ b/web-timeplot/src/main.js @@ -24,6 +24,13 @@ let app = null; // PixiJS Application let graphs = []; let metrics = null; let time = 0; +let frameCounter = 0; +let metricsUpdateInterval = 10; // Update metrics display every N frames + +// Vertical zoom dragging state +let isDraggingVerticalZoom = false; +let dragStartY = 0; +let dragStartZoom = 1.0; // ============================================================================ // APPLICATION ENTRY POINT @@ -64,6 +71,7 @@ async function initDOM() { dom.controls.exportBtn = document.getElementById('export-metrics'); dom.display.rendererType = document.getElementById('renderer-type'); dom.display.metrics = document.getElementById('metrics-display'); + dom.display.timeScale = document.getElementById('time-scale'); } async function initCfg() { @@ -90,8 +98,6 @@ async function initRenderer() { log('WebGPU not available, using WebGL'); preference = 'webgl'; } - console.log(navigator.gpu); - console.log(navigator); try { app = new Application(); @@ -172,6 +178,12 @@ function setupControls() { // Keyboard controls window.addEventListener('keydown', handleKeyboard); + // Mouse controls for time scaling + dom.container.addEventListener('mousedown', handleMouseDown); + window.addEventListener('mousemove', handleMouseMove); + window.addEventListener('mouseup', handleMouseUp); + dom.container.addEventListener('contextmenu', (e) => e.preventDefault()); // Prevent context menu + // Update button states updateControlButtons(); } @@ -205,6 +217,40 @@ function handleResize() { if (graphs[1]) graphs[1].resize(width / 2, 0, width / 2, height); } +function handleMouseDown(e) { + // Middle mouse button (button = 1) + if (e.button === 1) { + e.preventDefault(); + isDraggingVerticalZoom = true; + dragStartY = e.clientY; + dragStartZoom = graphs[0]?.getVerticalScale() || 1.0; + dom.container.style.cursor = 'ns-resize'; + } +} + +function handleMouseMove(e) { + if (!isDraggingVerticalZoom) return; + + const deltaY = dragStartY - e.clientY; // Inverted: drag up = zoom in + const sensitivity = 0.005; // Adjust sensitivity + const newZoom = dragStartZoom + (deltaY * sensitivity); + + // Apply to all graphs + graphs.forEach(graph => { + graph.setVerticalScale(newZoom); + }); + + // Update display + updateVerticalZoomDisplay(); +} + +function handleMouseUp(e) { + if (e.button === 1) { + isDraggingVerticalZoom = false; + dom.container.style.cursor = 'default'; + } +} + // ============================================================================ // MAIN UPDATE LOOP // ============================================================================ @@ -214,6 +260,7 @@ function update() { metrics.beginUpdate(); time += 0.016; // ~60fps increment + frameCounter++; // Update each graph graphs.forEach((graph, idx) => { @@ -232,12 +279,10 @@ function update() { metrics.endFrame(updateMs, renderMs, vertexCount, lineCount); - // Update UI - if (cfg.showMetrics) { + // Update UI less frequently to prevent flickering + if (cfg.showMetrics && frameCounter % metricsUpdateInterval === 0) { updateMetricsDisplay(); } - - console.log(metrics); } // ============================================================================ @@ -282,6 +327,22 @@ function updateControlButtons() { dom.controls.metricsBtn.classList.toggle('active', cfg.showMetrics); } +function updateVerticalZoomDisplay() { + if (dom.display.timeScale && graphs[0]) { + const zoom = graphs[0].getVerticalScale(); + dom.display.timeScale.textContent = `${zoom.toFixed(2)}x`; + + // Color code: zoomed out = blue, normal = white, zoomed in = orange + if (zoom < 0.8) { + dom.display.timeScale.style.color = '#6af'; // Zoomed out (see more history) + } else if (zoom > 1.2) { + dom.display.timeScale.style.color = '#fa6'; // Zoomed in (see less history) + } else { + dom.display.timeScale.style.color = '#fff'; + } + } +} + // ============================================================================ // UTILITIES // ============================================================================ diff --git a/web-timeplot/src/waterfall.js b/web-timeplot/src/waterfall.js index 78d8e40..bce0750 100644 --- a/web-timeplot/src/waterfall.js +++ b/web-timeplot/src/waterfall.js @@ -47,6 +47,11 @@ export class WaterfallGraph { this.showGrid = true; + // Time scaling and zoom + this.scrollSpeed = 1.0; // Speed multiplier for scrolling + this.baseScrollSpeed = 1.0; + this.verticalScale = 1.0; // Vertical zoom: >1 = zoomed in (see less history), <1 = zoomed out (see more) + this.draw(); } @@ -129,26 +134,48 @@ export class WaterfallGraph { } scrollLines() { - const scrollSpeed = 1.0; + const speed = this.baseScrollSpeed * this.scrollSpeed; this.lines.forEach(line => { - line.yOffset += scrollSpeed; + line.yOffset += speed; }); } + setScrollSpeed(speed) { + // Clamp between 0.1 (slow) and 5.0 (fast) + this.scrollSpeed = Math.max(0.1, Math.min(5.0, speed)); + } + + getScrollSpeed() { + return this.scrollSpeed; + } + + setVerticalScale(scale) { + // Clamp between 0.2 (zoomed out, see more history) and 3.0 (zoomed in, see less) + this.verticalScale = Math.max(0.2, Math.min(3.0, scale)); + } + + getVerticalScale() { + return this.verticalScale; + } + drawLines() { this.linesGraphics.clear(); for (const line of this.lines) { if (line.points.length < 2) continue; + // Apply vertical scale to y positions + // Current time is at top (y=0), older data has larger yOffset + const scaledYOffset = line.yOffset * this.verticalScale; + // Start path const firstPoint = line.points[0]; - this.linesGraphics.moveTo(firstPoint.x, firstPoint.y + line.yOffset); + this.linesGraphics.moveTo(firstPoint.x, firstPoint.y + scaledYOffset); // Draw line strip for (let i = 1; i < line.points.length; i++) { const point = line.points[i]; - this.linesGraphics.lineTo(point.x, point.y + line.yOffset); + this.linesGraphics.lineTo(point.x, point.y + scaledYOffset); } this.linesGraphics.stroke({ width: 2, color: line.color }); |
