Refactor GUI rendering and align RTA axis
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
// Gemeinsame Erzeugung temporärer Canvas-Flächen für Views und Meter.
|
||||
export function createCanvasSurface(width, height) {
|
||||
const w = Math.max(1, Math.ceil(width));
|
||||
const h = Math.max(1, Math.ceil(height));
|
||||
if (typeof OffscreenCanvas === 'function') {
|
||||
const canvas = new OffscreenCanvas(w, h);
|
||||
const ctx = canvas.getContext('2d');
|
||||
if (ctx) return { canvas, ctx, width: w, height: h };
|
||||
}
|
||||
if (typeof document !== 'undefined') {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = w;
|
||||
canvas.height = h;
|
||||
const ctx = canvas.getContext('2d');
|
||||
if (ctx) return { canvas, ctx, width: w, height: h };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
+11
-17
@@ -1,5 +1,6 @@
|
||||
// core/registry.js — Lazy Loader + Safe Runner für Meter
|
||||
// Lädt Meter-Module on-demand (oder via registerMeter) und kapselt Fehler.
|
||||
import { createCanvasSurface } from './canvas_surface.js';
|
||||
|
||||
const cache = {
|
||||
meters: new Map(), // id -> module
|
||||
@@ -7,26 +8,12 @@ const cache = {
|
||||
|
||||
const meterRenderCache = new Map(); // key -> surface
|
||||
const METER_CACHE_MARGIN = 32;
|
||||
const METER_RENDER_CACHE_LIMIT = 48;
|
||||
let activeFrameStamp = 0;
|
||||
|
||||
const CAN_USE_OFFSCREEN = typeof OffscreenCanvas === 'function';
|
||||
|
||||
function createCacheSurface(width, height) {
|
||||
const w = Math.max(1, Math.ceil(width));
|
||||
const h = Math.max(1, Math.ceil(height));
|
||||
if (CAN_USE_OFFSCREEN) {
|
||||
const canvas = new OffscreenCanvas(w, h);
|
||||
const ctx = canvas.getContext('2d');
|
||||
if (ctx) return { canvas, ctx, width: w, height: h, stamp: -1 };
|
||||
}
|
||||
if (typeof document !== 'undefined') {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = w;
|
||||
canvas.height = h;
|
||||
const ctx = canvas.getContext('2d');
|
||||
if (ctx) return { canvas, ctx, width: w, height: h, stamp: -1 };
|
||||
}
|
||||
return null;
|
||||
const surface = createCanvasSurface(width, height);
|
||||
return surface ? { ...surface, stamp: -1 } : null;
|
||||
}
|
||||
|
||||
function cacheKeyForMeter(id, rect) {
|
||||
@@ -40,10 +27,17 @@ function cacheKeyForMeter(id, rect) {
|
||||
function ensureCacheSurface(id, rect) {
|
||||
const key = cacheKeyForMeter(id, rect);
|
||||
let surface = meterRenderCache.get(key);
|
||||
if (surface) {
|
||||
meterRenderCache.delete(key);
|
||||
meterRenderCache.set(key, surface);
|
||||
}
|
||||
if (!surface) {
|
||||
surface = createCacheSurface(rect.w + METER_CACHE_MARGIN * 2, rect.h + METER_CACHE_MARGIN * 2);
|
||||
if (!surface) return null;
|
||||
meterRenderCache.set(key, surface);
|
||||
while (meterRenderCache.size > METER_RENDER_CACHE_LIMIT) {
|
||||
meterRenderCache.delete(meterRenderCache.keys().next().value);
|
||||
}
|
||||
}
|
||||
if (!surface.canvas || !surface.ctx) return null;
|
||||
const w = Math.max(1, Math.ceil(rect.w + METER_CACHE_MARGIN * 2));
|
||||
|
||||
+19
-5
@@ -250,7 +250,9 @@ export function drawDbfsGridRect(ctx, x0, y0, w, h, CONFIG, nyq, opts = {}) {
|
||||
colorMinor = 'rgba(30,42,53,.55)',
|
||||
labelColor = '#8fd3d4',
|
||||
freqTicks = null,
|
||||
freqTickPositions = null,
|
||||
freqMin = 20,
|
||||
xLeftExtension = 0,
|
||||
refDb = null,
|
||||
refStyle = 'rgba(0,231,255,0.35)',
|
||||
refDash = [4, 3],
|
||||
@@ -261,6 +263,12 @@ export function drawDbfsGridRect(ctx, x0, y0, w, h, CONFIG, nyq, opts = {}) {
|
||||
|
||||
const _g = Number(CONFIG && CONFIG.AXIS_GUTTER_LEFT);
|
||||
const gutterL = Number.isFinite(_g) ? Math.max(8, _g) : 14;
|
||||
const requestedExtension = Number(xLeftExtension);
|
||||
const leftExtension = Number.isFinite(requestedExtension)
|
||||
? Math.max(0, Math.min(gutterL, requestedExtension))
|
||||
: 0;
|
||||
const contentX = x0 - leftExtension;
|
||||
const contentW = w + leftExtension;
|
||||
|
||||
ctx.save();
|
||||
ctx.strokeStyle = '#00e7ff'; ctx.lineWidth = 2; ctx.strokeRect(x0 - gutterL, y0, w + gutterL, h);
|
||||
@@ -272,7 +280,7 @@ export function drawDbfsGridRect(ctx, x0, y0, w, h, CONFIG, nyq, opts = {}) {
|
||||
const y = yFromDbfs(v, y0, y0 + h, CONFIG);
|
||||
const labelY = Math.min(y0 + h - 4, Math.max(y0 + 12, y + 4));
|
||||
ctx.strokeStyle = colorMajor; ctx.lineWidth = 1.2;
|
||||
ctx.beginPath(); ctx.moveTo(x0, y); ctx.lineTo(x0 + w, y); ctx.stroke();
|
||||
ctx.beginPath(); ctx.moveTo(contentX, y); ctx.lineTo(contentX + contentW, y); ctx.stroke();
|
||||
ctx.textAlign = 'right'; ctx.fillText(String(v), (x0 - gutterL) - 6, labelY);
|
||||
}
|
||||
|
||||
@@ -282,8 +290,8 @@ export function drawDbfsGridRect(ctx, x0, y0, w, h, CONFIG, nyq, opts = {}) {
|
||||
ctx.strokeStyle = refStyle;
|
||||
ctx.setLineDash(Array.isArray(refDash) ? refDash : [4, 3]);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x0, yRef);
|
||||
ctx.lineTo(x0 + w, yRef);
|
||||
ctx.moveTo(contentX, yRef);
|
||||
ctx.lineTo(contentX + contentW, yRef);
|
||||
ctx.stroke();
|
||||
ctx.setLineDash([]);
|
||||
}
|
||||
@@ -299,9 +307,15 @@ export function drawDbfsGridRect(ctx, x0, y0, w, h, CONFIG, nyq, opts = {}) {
|
||||
const logMin = Math.log10(minFreq);
|
||||
const logSpan = Math.max(1e-6, Math.log10(nyq) - logMin);
|
||||
for (const f of ticks) {
|
||||
const x = x0 + ((Math.log10(Math.max(f, minFreq)) - logMin) / logSpan) * w;
|
||||
const requestedPosition = freqTickPositions && typeof freqTickPositions === 'object'
|
||||
? Number(freqTickPositions[String(f)])
|
||||
: NaN;
|
||||
const fraction = Number.isFinite(requestedPosition)
|
||||
? Math.max(0, Math.min(1, requestedPosition))
|
||||
: ((Math.log10(Math.max(f, minFreq)) - logMin) / logSpan);
|
||||
const x = contentX + fraction * contentW;
|
||||
// Linken Rand nicht doppeln: keine Vertikal-Linie auf dem linken Plot-Rand
|
||||
if (x > x0 + 0.75) {
|
||||
if (x > contentX + 0.75) {
|
||||
ctx.strokeStyle = '#131b24';
|
||||
ctx.beginPath(); ctx.moveTo(x, y0); ctx.lineTo(x, y0 + h); ctx.stroke();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user