@jigonzalez930209/scichart-engine 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scichart-engine.umd.js","sources":["../src/core/EventEmitter.ts","../src/core/Series.ts","../src/renderer/NativeWebGLRenderer.ts","../src/scales/index.ts","../src/theme/index.ts","../src/core/OverlayRenderer.ts","../src/core/InteractionManager.ts","../src/core/ChartControls.ts","../src/core/ChartLegend.ts","../src/core/Chart.ts","../src/renderer/RendererInterface.ts","../src/workers/downsample.ts","../src/analysis/utils.ts","../node_modules/.pnpm/react@19.2.3/node_modules/react/cjs/react-jsx-runtime.production.js","../node_modules/.pnpm/react@19.2.3/node_modules/react/cjs/react-jsx-runtime.development.js","../node_modules/.pnpm/react@19.2.3/node_modules/react/jsx-runtime.js","../src/react/useSciChart.ts","../src/react/SciChart.tsx"],"sourcesContent":["/**\n * Type-safe event emitter for chart events\n */\n\nexport class EventEmitter<EventMap extends object> {\n private listeners: Map<keyof EventMap, Set<(data: unknown) => void>> =\n new Map();\n\n /**\n * Subscribe to an event\n */\n on<K extends keyof EventMap>(\n event: K,\n handler: (data: EventMap[K]) => void\n ): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(handler as (data: unknown) => void);\n }\n\n /**\n * Unsubscribe from an event\n */\n off<K extends keyof EventMap>(\n event: K,\n handler: (data: EventMap[K]) => void\n ): void {\n const handlers = this.listeners.get(event);\n if (handlers) {\n handlers.delete(handler as (data: unknown) => void);\n }\n }\n\n /**\n * Emit an event with data\n */\n emit<K extends keyof EventMap>(event: K, data: EventMap[K]): void {\n const handlers = this.listeners.get(event);\n if (handlers) {\n handlers.forEach((handler) => {\n try {\n handler(data);\n } catch (error) {\n console.error(`[EventEmitter] Error in handler for \"${String(event)}\":`, error);\n }\n });\n }\n }\n\n /**\n * Subscribe to an event once\n */\n once<K extends keyof EventMap>(\n event: K,\n handler: (data: EventMap[K]) => void\n ): void {\n const wrappedHandler = (data: EventMap[K]) => {\n this.off(event, wrappedHandler);\n handler(data);\n };\n this.on(event, wrappedHandler);\n }\n\n /**\n * Remove all listeners\n */\n clear(): void {\n this.listeners.clear();\n }\n\n /**\n * Get listener count for an event\n */\n listenerCount(event: keyof EventMap): number {\n return this.listeners.get(event)?.size ?? 0;\n }\n}\n","/**\n * Series - Represents a single data series in the chart\n *\n * Manages data arrays, styling, and GPU buffer lifecycle.\n */\n\nimport type {\n SeriesOptions,\n SeriesData,\n SeriesStyle,\n SeriesUpdateData,\n Bounds,\n SeriesType,\n} from \"../types\";\n\nconst DEFAULT_STYLE: SeriesStyle = {\n color: \"#ff0055\",\n width: 1.5,\n opacity: 1,\n pointSize: 4,\n};\n\nfunction ensureTypedArray(\n data: Float32Array | Float64Array | number[] | undefined\n): Float32Array | Float64Array {\n if (!data) return new Float32Array(0);\n if (data instanceof Float32Array || data instanceof Float64Array) return data;\n return new Float32Array(data);\n}\n\nexport class Series {\n private id: string;\n private type: SeriesType;\n private data: SeriesData;\n private style: SeriesStyle;\n private visible: boolean;\n private cycle?: number;\n\n // Cached bounds for performance\n private cachedBounds: Bounds | null = null;\n private boundsNeedsUpdate = true;\n\n // Track if GPU buffer needs update\n private _needsBufferUpdate = true;\n\n // Smoothed data cache\n private smoothedData: SeriesData | null = null;\n private smoothingNeedsUpdate = true;\n\n constructor(options: SeriesOptions) {\n if (!options) throw new Error(\"[Series] Options are required\");\n this.id = options.id;\n this.type = options.type;\n\n this.data = {\n x: ensureTypedArray(options.data?.x),\n y: ensureTypedArray(options.data?.y),\n };\n\n // Support both style object and top-level style properties for convenience\n this.style = {\n ...DEFAULT_STYLE,\n ...options.style,\n };\n\n // Fallback for top-level style properties often used in examples\n if ((options as any).color) this.style.color = (options as any).color;\n if ((options as any).width) this.style.width = (options as any).width;\n if ((options as any).pointSize)\n this.style.pointSize = (options as any).pointSize;\n\n this.visible = options.visible ?? true;\n this.cycle = options.cycle;\n\n // Validate data\n if (this.data.x.length !== this.data.y.length) {\n console.warn(\n `[Series \"${this.id}\"] X and Y arrays have different lengths:`,\n this.data.x.length,\n \"vs\",\n this.data.y.length\n );\n }\n }\n\n // ----------------------------------------\n // Getters\n // ----------------------------------------\n\n getId(): string {\n return this.id;\n }\n\n getType(): SeriesType {\n return this.type;\n }\n\n getData(): SeriesData {\n if (this.style.smoothing && this.style.smoothing > 0) {\n return this.getSmoothedData();\n }\n return this.data;\n }\n\n private getSmoothedData(): SeriesData {\n if (this.smoothingNeedsUpdate || !this.smoothedData) {\n this.smoothedData = this.applySmoothing(this.data, 5); // Window size 5\n this.smoothingNeedsUpdate = false;\n }\n return this.smoothedData;\n }\n\n private applySmoothing(data: SeriesData, windowSize: number): SeriesData {\n const { x, y } = data;\n const len = x.length;\n if (len < windowSize) return { ...data };\n\n const smoothedY = new Float32Array(len);\n const halfWindow = Math.floor(windowSize / 2);\n\n for (let i = 0; i < len; i++) {\n let sum = 0;\n let count = 0;\n for (let j = i - halfWindow; j <= i + halfWindow; j++) {\n if (j >= 0 && j < len) {\n sum += y[j];\n count++;\n }\n }\n smoothedY[i] = sum / count;\n }\n\n return { x, y: smoothedY };\n }\n\n getStyle(): SeriesStyle {\n return this.style;\n }\n\n isVisible(): boolean {\n return this.visible;\n }\n\n getCycle(): number | undefined {\n return this.cycle;\n }\n\n getPointCount(): number {\n return this.data.x.length;\n }\n\n // ----------------------------------------\n // Bounds Calculation\n // ----------------------------------------\n\n getBounds(): Bounds | null {\n if (this.data.x.length === 0) {\n return null;\n }\n\n if (this.boundsNeedsUpdate || this.cachedBounds === null) {\n this.cachedBounds = this.calculateBounds();\n this.boundsNeedsUpdate = false;\n }\n\n return this.cachedBounds;\n }\n\n private calculateBounds(): Bounds {\n const { x, y } = this.data;\n\n let xMin = Infinity;\n let xMax = -Infinity;\n let yMin = Infinity;\n let yMax = -Infinity;\n\n // Single pass through data\n for (let i = 0; i < x.length; i++) {\n const xVal = x[i];\n const yVal = y[i];\n\n // Skip NaN/Infinity\n if (!isFinite(xVal) || !isFinite(yVal)) continue;\n\n if (xVal < xMin) xMin = xVal;\n if (xVal > xMax) xMax = xVal;\n if (yVal < yMin) yMin = yVal;\n if (yVal > yMax) yMax = yVal;\n }\n\n const bounds = { xMin, xMax, yMin, yMax };\n return bounds;\n }\n\n // ----------------------------------------\n // Data Updates\n // ----------------------------------------\n\n /**\n * Update series data\n *\n * For streaming data, use append=true to avoid recreating buffers.\n */\n updateData(update: SeriesUpdateData): void {\n if (!update) return;\n\n if (update.append) {\n const newX = ensureTypedArray(update.x);\n const newY = ensureTypedArray(update.y);\n\n if (newX.length > 0 && newY.length > 0) {\n this.data = {\n x: this.appendArray(this.data.x, newX),\n y: this.appendArray(this.data.y, newY),\n };\n }\n } else {\n // Replace mode\n if (update.x) this.data.x = ensureTypedArray(update.x);\n if (update.y) this.data.y = ensureTypedArray(update.y);\n }\n\n // Invalidate bounds cache\n this.boundsNeedsUpdate = true;\n this.smoothingNeedsUpdate = true;\n this._needsBufferUpdate = true;\n }\n\n private appendArray(\n existing: Float32Array | Float64Array,\n newData: Float32Array | Float64Array\n ): Float32Array | Float64Array {\n // Create new array with combined length\n const combined = new (existing.constructor as\n | Float32ArrayConstructor\n | Float64ArrayConstructor)(existing.length + newData.length);\n combined.set(existing, 0);\n combined.set(newData, existing.length);\n return combined;\n }\n\n /**\n * Replace all data at once\n */\n setData(\n x: Float32Array | Float64Array,\n y: Float32Array | Float64Array\n ): void {\n this.data = { x, y };\n this.boundsNeedsUpdate = true;\n this.smoothingNeedsUpdate = true;\n this._needsBufferUpdate = true;\n }\n\n // ----------------------------------------\n // Style Updates\n // ----------------------------------------\n\n setStyle(style: Partial<SeriesStyle>): void {\n const oldSmoothing = this.style.smoothing;\n this.style = { ...this.style, ...style };\n if (this.style.smoothing !== oldSmoothing) {\n this.smoothingNeedsUpdate = true;\n this._needsBufferUpdate = true;\n }\n }\n\n get needsBufferUpdate(): boolean {\n return this._needsBufferUpdate;\n }\n set needsBufferUpdate(val: boolean) {\n this._needsBufferUpdate = val;\n }\n\n setVisible(visible: boolean): void {\n this.visible = visible;\n }\n\n setType(type: SeriesType): void {\n this.type = type;\n }\n\n // ----------------------------------------\n // Cleanup\n // ----------------------------------------\n\n destroy(): void {\n // Clear data references\n this.data = {\n x: new Float32Array(0),\n y: new Float32Array(0),\n };\n this.cachedBounds = null;\n }\n}\n","/**\n * NativeWebGLRenderer - Zero-dependency WebGL renderer\n *\n * This renderer uses raw WebGL APIs without any external libraries.\n * Performance is identical (or slightly better) than regl since\n * we eliminate the abstraction layer overhead.\n *\n * Key optimizations:\n * - Pre-compiled shaders (compiled once, reused)\n * - Uniform updates via GPU (no buffer recreation for zoom/pan)\n * - Buffer pooling for dynamic data\n * - Minimal state changes per frame\n */\n\nimport type { Bounds, SeriesStyle } from \"../types\";\n\n// ============================================\n// Types\n// ============================================\n\nexport interface NativeSeriesRenderData {\n id: string;\n buffer: WebGLBuffer;\n count: number;\n style: SeriesStyle;\n visible: boolean;\n type: \"line\" | \"scatter\" | \"line+scatter\";\n}\n\nexport interface NativeRenderOptions {\n bounds: Bounds;\n backgroundColor?: [number, number, number, number];\n}\n\ninterface ShaderProgram {\n program: WebGLProgram;\n attributes: { position: number };\n uniforms: {\n uScale: WebGLUniformLocation;\n uTranslate: WebGLUniformLocation;\n uColor: WebGLUniformLocation;\n uPointSize?: WebGLUniformLocation;\n };\n}\n\n// ============================================\n// Shader Sources\n// ============================================\n\nconst LINE_VERT = `\nprecision highp float;\nattribute vec2 position;\nuniform vec2 uScale;\nuniform vec2 uTranslate;\n\nvoid main() {\n vec2 pos = position * uScale + uTranslate;\n gl_Position = vec4(pos, 0.0, 1.0);\n}\n`;\n\nconst LINE_FRAG = `\nprecision highp float;\nuniform vec4 uColor;\n\nvoid main() {\n gl_FragColor = uColor;\n}\n`;\n\nconst POINT_VERT = `\nprecision highp float;\nattribute vec2 position;\nuniform vec2 uScale;\nuniform vec2 uTranslate;\nuniform float uPointSize;\n\nvoid main() {\n vec2 pos = position * uScale + uTranslate;\n gl_Position = vec4(pos, 0.0, 1.0);\n gl_PointSize = uPointSize;\n}\n`;\n\nconst POINT_FRAG = `\nprecision highp float;\nuniform vec4 uColor;\n\nvoid main() {\n vec2 coord = gl_PointCoord - vec2(0.5);\n float dist = length(coord);\n if (dist > 0.5) discard;\n float alpha = 1.0 - smoothstep(0.4, 0.5, dist);\n gl_FragColor = vec4(uColor.rgb, uColor.a * alpha);\n}\n`;\n\n// ============================================\n// NativeWebGLRenderer Class\n// ============================================\n\nexport class NativeWebGLRenderer {\n private canvas: HTMLCanvasElement;\n private gl: WebGLRenderingContext;\n private dpr: number;\n\n // Compiled shader programs\n private lineProgram: ShaderProgram;\n private pointProgram: ShaderProgram;\n\n // Buffer cache\n private buffers: Map<string, WebGLBuffer> = new Map();\n private bufferSizes: Map<string, number> = new Map();\n\n // State\n private isInitialized = false;\n\n constructor(canvas: HTMLCanvasElement) {\n this.canvas = canvas;\n this.dpr = window.devicePixelRatio || 1;\n\n // Get WebGL context\n const gl = canvas.getContext(\"webgl\", {\n alpha: true,\n antialias: true,\n preserveDrawingBuffer: true, // Essential for on-demand rendering\n powerPreference: \"high-performance\",\n });\n\n if (!gl) {\n throw new Error(\"WebGL not supported\");\n }\n\n this.gl = gl;\n\n // Compile shaders\n this.lineProgram = this.createProgram(LINE_VERT, LINE_FRAG, false);\n this.pointProgram = this.createProgram(POINT_VERT, POINT_FRAG, true);\n\n // Enable blending for transparency\n gl.enable(gl.BLEND);\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n\n this.isInitialized = true;\n console.log(\"[NativeWebGL] Initialized successfully\");\n }\n\n // ----------------------------------------\n // Shader Compilation\n // ----------------------------------------\n\n private createShader(source: string, type: number): WebGLShader {\n const { gl } = this;\n const shader = gl.createShader(type);\n if (!shader) throw new Error(\"Failed to create shader\");\n\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const error = gl.getShaderInfoLog(shader);\n gl.deleteShader(shader);\n throw new Error(`Shader compilation error: ${error}`);\n }\n\n return shader;\n }\n\n private createProgram(\n vertSource: string,\n fragSource: string,\n hasPointSize: boolean\n ): ShaderProgram {\n const { gl } = this;\n\n const vertShader = this.createShader(vertSource, gl.VERTEX_SHADER);\n const fragShader = this.createShader(fragSource, gl.FRAGMENT_SHADER);\n\n const program = gl.createProgram();\n if (!program) throw new Error(\"Failed to create program\");\n\n gl.attachShader(program, vertShader);\n gl.attachShader(program, fragShader);\n gl.linkProgram(program);\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n const error = gl.getProgramInfoLog(program);\n throw new Error(`Program link error: ${error}`);\n }\n\n // Clean up shaders (they're now part of the program)\n gl.deleteShader(vertShader);\n gl.deleteShader(fragShader);\n\n // Get attribute and uniform locations\n const positionAttr = gl.getAttribLocation(program, \"position\");\n const scaleUniform = gl.getUniformLocation(program, \"uScale\");\n const translateUniform = gl.getUniformLocation(program, \"uTranslate\");\n const colorUniform = gl.getUniformLocation(program, \"uColor\");\n\n if (\n scaleUniform === null ||\n translateUniform === null ||\n colorUniform === null\n ) {\n throw new Error(\"Failed to get uniform locations\");\n }\n\n const result: ShaderProgram = {\n program,\n attributes: { position: positionAttr },\n uniforms: {\n uScale: scaleUniform,\n uTranslate: translateUniform,\n uColor: colorUniform,\n },\n };\n\n if (hasPointSize) {\n result.uniforms.uPointSize =\n gl.getUniformLocation(program, \"uPointSize\") ?? undefined;\n }\n\n return result;\n }\n\n // ----------------------------------------\n // Buffer Management\n // ----------------------------------------\n\n get available(): boolean {\n return this.isInitialized;\n }\n\n /**\n * Create or update a buffer with interleaved X,Y data\n */\n createBuffer(id: string, data: Float32Array): void {\n const { gl } = this;\n let buffer = this.buffers.get(id);\n const currentSize = this.bufferSizes.get(id) || 0;\n\n if (buffer && data.byteLength <= currentSize) {\n // Update existing buffer with subdata (faster)\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.bufferSubData(gl.ARRAY_BUFFER, 0, data);\n } else {\n // Create new buffer or recreate if size increased\n if (buffer) {\n gl.deleteBuffer(buffer);\n }\n buffer = gl.createBuffer();\n if (!buffer) throw new Error(\"Failed to create buffer\");\n\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ARRAY_BUFFER, data, gl.DYNAMIC_DRAW);\n\n this.buffers.set(id, buffer);\n this.bufferSizes.set(id, data.byteLength);\n }\n }\n\n /**\n * Get a buffer by ID\n */\n getBuffer(id: string): WebGLBuffer | undefined {\n return this.buffers.get(id);\n }\n\n /**\n * Delete a buffer\n */\n deleteBuffer(id: string): void {\n const buffer = this.buffers.get(id);\n if (buffer) {\n this.gl.deleteBuffer(buffer);\n this.buffers.delete(id);\n this.bufferSizes.delete(id);\n }\n }\n\n // ----------------------------------------\n // Rendering\n // ----------------------------------------\n\n /**\n * Calculate uniforms for the current viewport\n */\n private calculateUniforms(bounds: Bounds): {\n scale: [number, number];\n translate: [number, number];\n } {\n const dataWidth = bounds.xMax - bounds.xMin;\n const dataHeight = bounds.yMax - bounds.yMin;\n\n const scaleX = dataWidth > 0 ? 2 / dataWidth : 1;\n const scaleY = dataHeight > 0 ? 2 / dataHeight : 1;\n\n const translateX = -1 - bounds.xMin * scaleX;\n const translateY = -1 - bounds.yMin * scaleY;\n\n return {\n scale: [scaleX, scaleY],\n translate: [translateX, translateY],\n };\n }\n\n /**\n * Render a frame\n */\n render(series: NativeSeriesRenderData[], options: NativeRenderOptions): void {\n if (!this.isInitialized) return;\n\n const { gl } = this;\n const { bounds, backgroundColor = [0.1, 0.1, 0.18, 1] } = options;\n const uniforms = this.calculateUniforms(bounds);\n\n // Clear with background color\n gl.clearColor(\n backgroundColor[0],\n backgroundColor[1],\n backgroundColor[2],\n backgroundColor[3]\n );\n gl.clear(gl.COLOR_BUFFER_BIT);\n\n // Render each series\n for (const s of series) {\n if (!s.visible || s.count === 0) continue;\n\n const color = parseColor(s.style.color ?? \"#ff0055\");\n color[3] = s.style.opacity ?? 1;\n\n if (s.type === \"scatter\") {\n this.renderPoints(\n s.buffer,\n s.count,\n uniforms,\n color,\n (s.style.pointSize ?? 4) * this.dpr\n );\n } else if (s.type === \"line\") {\n this.renderLine(s.buffer, s.count, uniforms, color);\n } else if (s.type === \"line+scatter\") {\n this.renderLine(s.buffer, s.count, uniforms, color);\n this.renderPoints(\n s.buffer,\n s.count,\n uniforms,\n color,\n (s.style.pointSize ?? 4) * this.dpr\n );\n }\n }\n }\n\n private renderLine(\n buffer: WebGLBuffer,\n count: number,\n uniforms: { scale: [number, number]; translate: [number, number] },\n color: [number, number, number, number]\n ): void {\n const { gl } = this;\n const prog = this.lineProgram;\n\n gl.useProgram(prog.program);\n\n // Bind buffer\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.enableVertexAttribArray(prog.attributes.position);\n gl.vertexAttribPointer(prog.attributes.position, 2, gl.FLOAT, false, 0, 0);\n\n // Set uniforms\n gl.uniform2f(prog.uniforms.uScale, uniforms.scale[0], uniforms.scale[1]);\n gl.uniform2f(\n prog.uniforms.uTranslate,\n uniforms.translate[0],\n uniforms.translate[1]\n );\n gl.uniform4f(prog.uniforms.uColor, color[0], color[1], color[2], color[3]);\n\n // Draw\n gl.drawArrays(gl.LINE_STRIP, 0, count);\n\n gl.disableVertexAttribArray(prog.attributes.position);\n }\n\n private renderPoints(\n buffer: WebGLBuffer,\n count: number,\n uniforms: { scale: [number, number]; translate: [number, number] },\n color: [number, number, number, number],\n pointSize: number\n ): void {\n const { gl } = this;\n const prog = this.pointProgram;\n\n gl.useProgram(prog.program);\n\n // Bind buffer\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.enableVertexAttribArray(prog.attributes.position);\n gl.vertexAttribPointer(prog.attributes.position, 2, gl.FLOAT, false, 0, 0);\n\n // Set uniforms\n gl.uniform2f(prog.uniforms.uScale, uniforms.scale[0], uniforms.scale[1]);\n gl.uniform2f(\n prog.uniforms.uTranslate,\n uniforms.translate[0],\n uniforms.translate[1]\n );\n gl.uniform4f(prog.uniforms.uColor, color[0], color[1], color[2], color[3]);\n if (prog.uniforms.uPointSize) {\n gl.uniform1f(prog.uniforms.uPointSize, pointSize);\n }\n\n // Draw\n gl.drawArrays(gl.POINTS, 0, count);\n\n gl.disableVertexAttribArray(prog.attributes.position);\n }\n\n /**\n * Handle resize\n */\n resize(): void {\n const rect = this.canvas.getBoundingClientRect();\n const width = rect.width * this.dpr;\n const height = rect.height * this.dpr;\n\n if (this.canvas.width !== width || this.canvas.height !== height) {\n this.canvas.width = width;\n this.canvas.height = height;\n this.gl.viewport(0, 0, width, height);\n }\n }\n\n /**\n * Get WebGL limits (for debugging)\n */\n getLimits() {\n const { gl } = this;\n return {\n maxTextureSize: gl.getParameter(gl.MAX_TEXTURE_SIZE),\n maxViewportDims: gl.getParameter(gl.MAX_VIEWPORT_DIMS),\n renderer: gl.getParameter(gl.RENDERER),\n vendor: gl.getParameter(gl.VENDOR),\n };\n }\n\n /**\n * Destroy and cleanup\n */\n destroy(): void {\n const { gl } = this;\n\n // Destroy all buffers\n this.buffers.forEach((buffer) => gl.deleteBuffer(buffer));\n this.buffers.clear();\n this.bufferSizes.clear();\n\n // Destroy programs\n gl.deleteProgram(this.lineProgram.program);\n gl.deleteProgram(this.pointProgram.program);\n\n this.isInitialized = false;\n console.log(\"[NativeWebGL] Destroyed\");\n }\n}\n\n// ============================================\n// Utility: Parse Color\n// ============================================\n\nexport function parseColor(color: string): [number, number, number, number] {\n if (color.startsWith(\"#\")) {\n const hex = color.slice(1);\n if (hex.length === 3) {\n const r = parseInt(hex[0] + hex[0], 16) / 255;\n const g = parseInt(hex[1] + hex[1], 16) / 255;\n const b = parseInt(hex[2] + hex[2], 16) / 255;\n return [r, g, b, 1];\n } else if (hex.length === 6) {\n const r = parseInt(hex.slice(0, 2), 16) / 255;\n const g = parseInt(hex.slice(2, 4), 16) / 255;\n const b = parseInt(hex.slice(4, 6), 16) / 255;\n return [r, g, b, 1];\n } else if (hex.length === 8) {\n const r = parseInt(hex.slice(0, 2), 16) / 255;\n const g = parseInt(hex.slice(2, 4), 16) / 255;\n const b = parseInt(hex.slice(4, 6), 16) / 255;\n const a = parseInt(hex.slice(6, 8), 16) / 255;\n return [r, g, b, a];\n }\n }\n\n // Default: magenta for visibility\n return [1, 0, 1, 1];\n}\n\n// ============================================\n// Utility: Interleave Data\n// ============================================\n\nexport function interleaveData(\n x: Float32Array | Float64Array | number[],\n y: Float32Array | Float64Array | number[]\n): Float32Array {\n const length = Math.min(x.length, y.length);\n const result = new Float32Array(length * 2);\n\n for (let i = 0; i < length; i++) {\n result[i * 2] = x[i];\n result[i * 2 + 1] = y[i];\n }\n\n return result;\n}\n","/**\n * Scale interface and implementations\n *\n * Scales transform data values to pixel coordinates and vice versa.\n */\n\nexport interface Scale {\n /** Data domain [min, max] */\n domain: [number, number];\n /** Pixel range [min, max] */\n range: [number, number];\n /** Scale type identifier */\n type: \"linear\" | \"log\";\n\n /** Set the domain */\n setDomain(min: number, max: number): void;\n /** Set the range */\n setRange(min: number, max: number): void;\n\n /** Transform data value to pixel */\n transform(value: number): number;\n /** Transform pixel to data value */\n invert(pixel: number): number;\n\n /** Generate nice tick values */\n ticks(count?: number): number[];\n}\n\n/**\n * Linear scale - proportional mapping\n */\nexport class LinearScale implements Scale {\n public domain: [number, number] = [0, 1];\n public range: [number, number] = [0, 100];\n public readonly type = \"linear\" as const;\n\n setDomain(min: number, max: number): void {\n // Ensure we have a valid, non-zero range\n if (!isFinite(min) || !isFinite(max)) {\n this.domain = [0, 1];\n return;\n }\n if (min === max) {\n this.domain = [min - 0.5, max + 0.5];\n return;\n }\n this.domain = [min, max];\n }\n\n setRange(min: number, max: number): void {\n this.range = [min, max];\n }\n\n transform(value: number): number {\n const [d0, d1] = this.domain;\n const [r0, r1] = this.range;\n const normalized = (value - d0) / (d1 - d0);\n return r0 + normalized * (r1 - r0);\n }\n\n invert(pixel: number): number {\n const [d0, d1] = this.domain;\n const [r0, r1] = this.range;\n const normalized = (pixel - r0) / (r1 - r0);\n return d0 + normalized * (d1 - d0);\n }\n\n ticks(count = 10): number[] {\n const [min, max] = this.domain;\n if (!isFinite(min) || !isFinite(max) || min === max) return [];\n\n const step = niceStep(min, max, count);\n const start = Math.ceil(min / step) * step;\n const ticks: number[] = [];\n\n // Limit ticks to prevent infinite loops or performance issues\n const maxTicks = 100;\n let t = start;\n while (t <= max + step * 0.5 && ticks.length < maxTicks) {\n ticks.push(Math.round(t * 1e12) / 1e12); // Fix floating point\n t += step;\n }\n\n return ticks;\n }\n}\n\n/**\n * Logarithmic scale - for exponential data\n */\nexport class LogScale implements Scale {\n public domain: [number, number] = [1, 1000];\n public range: [number, number] = [0, 100];\n public readonly type = \"log\" as const;\n\n private base = 10;\n\n setDomain(min: number, max: number): void {\n // Log scale requires positive values and non-zero range\n const safeMin = Math.max(min, 1e-12);\n const safeMax = Math.max(max, 1e-12 * 10);\n\n if (safeMin === safeMax) {\n this.domain = [safeMin / 10, safeMax * 10];\n return;\n }\n this.domain = [safeMin, safeMax];\n }\n\n setRange(min: number, max: number): void {\n this.range = [min, max];\n }\n\n transform(value: number): number {\n const [d0, d1] = this.domain;\n const [r0, r1] = this.range;\n\n if (value <= 0) return r0; // Handle invalid values\n\n const logMin = Math.log(d0) / Math.log(this.base);\n const logMax = Math.log(d1) / Math.log(this.base);\n const logVal = Math.log(value) / Math.log(this.base);\n\n const normalized = (logVal - logMin) / (logMax - logMin);\n return r0 + normalized * (r1 - r0);\n }\n\n invert(pixel: number): number {\n const [d0, d1] = this.domain;\n const [r0, r1] = this.range;\n\n const logMin = Math.log(d0) / Math.log(this.base);\n const logMax = Math.log(d1) / Math.log(this.base);\n\n const normalized = (pixel - r0) / (r1 - r0);\n const logVal = logMin + normalized * (logMax - logMin);\n\n return Math.pow(this.base, logVal);\n }\n\n ticks(count = 10): number[] {\n const [min, max] = this.domain;\n const logMin = Math.floor(Math.log10(min));\n const logMax = Math.ceil(Math.log10(max));\n const ticks: number[] = [];\n\n for (let p = logMin; p <= logMax && ticks.length < count; p++) {\n const value = Math.pow(10, p);\n if (value >= min && value <= max) {\n ticks.push(value);\n }\n }\n\n return ticks;\n }\n}\n\n// ============================================\n// Helpers\n// ============================================\n\n/**\n * Calculate a \"nice\" step size for tick marks\n */\nfunction niceStep(min: number, max: number, count: number): number {\n const range = max - min;\n if (range <= 0 || !isFinite(range)) return 1;\n\n const rawStep = range / count;\n const magnitude = Math.pow(10, Math.floor(Math.log10(rawStep)));\n const normalized = rawStep / magnitude;\n\n let niceNormalized: number;\n if (normalized < 1.5) {\n niceNormalized = 1;\n } else if (normalized < 3) {\n niceNormalized = 2;\n } else if (normalized < 7) {\n niceNormalized = 5;\n } else {\n niceNormalized = 10;\n }\n\n return niceNormalized * magnitude;\n}\n\n/**\n * Factory function to create scale by type\n */\nexport function createScale(type: \"linear\" | \"log\"): Scale {\n return type === \"log\" ? new LogScale() : new LinearScale();\n}\n","/**\n * Theme - Visual styling configuration for SciChart\n *\n * Provides customizable themes for the chart including:\n * - Grid styling\n * - Axis styling\n * - Legend styling\n * - Cursor styling\n */\n\n// ============================================\n// Theme Types\n// ============================================\n\nexport interface GridTheme {\n /** Grid visibility */\n visible: boolean;\n /** Major grid line color */\n majorColor: string;\n /** Minor grid line color */\n minorColor: string;\n /** Major grid line width */\n majorWidth: number;\n /** Minor grid line width */\n minorWidth: number;\n /** Line dash pattern for major lines [dash, gap] */\n majorDash: number[];\n /** Line dash pattern for minor lines [dash, gap] */\n minorDash: number[];\n /** Show minor grid lines */\n showMinor: boolean;\n /** Number of minor divisions between major lines */\n minorDivisions: number;\n}\n\nexport interface AxisTheme {\n /** Axis line color */\n lineColor: string;\n /** Axis line width */\n lineWidth: number;\n /** Tick mark color */\n tickColor: string;\n /** Tick mark length */\n tickLength: number;\n /** Label color */\n labelColor: string;\n /** Label font size */\n labelSize: number;\n /** Axis title color */\n titleColor: string;\n /** Axis title font size */\n titleSize: number;\n /** Font family */\n fontFamily: string;\n}\n\nexport interface LegendTheme {\n /** Legend visibility */\n visible: boolean;\n /** Position */\n position: \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\";\n /** Background color */\n backgroundColor: string;\n /** Border color */\n borderColor: string;\n /** Border radius */\n borderRadius: number;\n /** Text color */\n textColor: string;\n /** Font size */\n fontSize: number;\n /** Font family */\n fontFamily: string;\n /** Padding inside legend */\n padding: number;\n /** Gap between items */\n itemGap: number;\n /** Color swatch size */\n swatchSize: number;\n}\n\nexport interface CursorTheme {\n /** Cursor line color */\n lineColor: string;\n /** Cursor line width */\n lineWidth: number;\n /** Cursor line dash pattern */\n lineDash: number[];\n /** Tooltip background color */\n tooltipBackground: string;\n /** Tooltip border color */\n tooltipBorder: string;\n /** Tooltip text color */\n tooltipColor: string;\n /** Tooltip font size */\n tooltipSize: number;\n}\n\nexport interface ChartTheme {\n /** Theme name */\n name: string;\n /** Background color */\n backgroundColor: string;\n /** Plot area border color */\n plotBorderColor: string;\n /** Grid theme */\n grid: GridTheme;\n /** X-axis theme */\n xAxis: AxisTheme;\n /** Y-axis theme */\n yAxis: AxisTheme;\n /** Legend theme */\n legend: LegendTheme;\n /** Cursor theme */\n cursor: CursorTheme;\n}\n\n// ============================================\n// Default Themes\n// ============================================\n\nconst DEFAULT_AXIS_THEME: AxisTheme = {\n lineColor: \"#666666\", // Brighter\n lineWidth: 1,\n tickColor: \"#888888\", // Brighter\n tickLength: 6,\n labelColor: \"#cccccc\", // Brighter\n labelSize: 12, // Larger\n titleColor: \"#ffffff\", // Brighter\n titleSize: 14, // Larger\n fontFamily: \"Inter, system-ui, sans-serif\",\n};\n\nconst DEFAULT_GRID_THEME: GridTheme = {\n visible: true,\n majorColor: \"rgba(255, 255, 255, 0.12)\", // Higher opacity\n minorColor: \"rgba(255, 255, 255, 0.05)\",\n majorWidth: 1,\n minorWidth: 0.5,\n majorDash: [4, 4],\n minorDash: [2, 4],\n showMinor: true, // Default to show minor\n minorDivisions: 5,\n};\n\nconst DEFAULT_LEGEND_THEME: LegendTheme = {\n visible: true,\n position: \"top-right\",\n backgroundColor: \"rgba(20, 20, 30, 0.9)\",\n borderColor: \"rgba(255, 255, 255, 0.15)\",\n borderRadius: 6,\n textColor: \"#ffffff\",\n fontSize: 11,\n fontFamily: \"Inter, system-ui, sans-serif\",\n padding: 10,\n itemGap: 6,\n swatchSize: 12,\n};\n\nconst DEFAULT_CURSOR_THEME: CursorTheme = {\n lineColor: \"rgba(255, 255, 255, 0.5)\",\n lineWidth: 1,\n lineDash: [5, 5],\n tooltipBackground: \"rgba(20, 20, 30, 0.95)\",\n tooltipBorder: \"rgba(255, 255, 255, 0.2)\",\n tooltipColor: \"#ffffff\",\n tooltipSize: 11,\n};\n\n// ============================================\n// Preset Themes\n// ============================================\n\nexport const DARK_THEME: ChartTheme = {\n name: \"dark\",\n backgroundColor: \"#0b0e14\",\n plotBorderColor: \"#444c56\",\n grid: {\n ...DEFAULT_GRID_THEME,\n majorColor: \"rgba(255, 255, 255, 0.12)\",\n minorColor: \"rgba(255, 255, 255, 0.04)\",\n },\n xAxis: {\n ...DEFAULT_AXIS_THEME,\n labelColor: \"#adbac7\",\n titleColor: \"#cdd9e5\",\n lineColor: \"#444c56\",\n tickColor: \"#444c56\",\n },\n yAxis: {\n ...DEFAULT_AXIS_THEME,\n labelColor: \"#adbac7\",\n titleColor: \"#cdd9e5\",\n lineColor: \"#444c56\",\n tickColor: \"#444c56\",\n },\n legend: DEFAULT_LEGEND_THEME,\n cursor: DEFAULT_CURSOR_THEME,\n};\n\nexport const MIDNIGHT_THEME: ChartTheme = {\n name: \"midnight\",\n backgroundColor: \"#05050a\",\n plotBorderColor: \"#3a3a5a\",\n grid: {\n ...DEFAULT_GRID_THEME,\n majorColor: \"rgba(150, 150, 255, 0.2)\",\n minorColor: \"rgba(150, 150, 255, 0.08)\",\n },\n xAxis: {\n ...DEFAULT_AXIS_THEME,\n lineColor: \"#5a5a8a\",\n labelColor: \"#b0b0e0\",\n titleColor: \"#d0d0f0\",\n tickColor: \"#5a5a8a\",\n },\n yAxis: {\n ...DEFAULT_AXIS_THEME,\n lineColor: \"#5a5a8a\",\n labelColor: \"#b0b0e0\",\n titleColor: \"#d0d0f0\",\n tickColor: \"#5a5a8a\",\n },\n legend: {\n ...DEFAULT_LEGEND_THEME,\n backgroundColor: \"rgba(15, 15, 30, 0.95)\",\n borderColor: \"rgba(100, 100, 255, 0.4)\",\n },\n cursor: {\n ...DEFAULT_CURSOR_THEME,\n lineColor: \"rgba(150, 150, 255, 0.7)\",\n },\n};\n\n/** Light theme - Clean white background */\nexport const LIGHT_THEME: ChartTheme = {\n name: \"light\",\n backgroundColor: \"#ffffff\",\n plotBorderColor: \"#cccccc\",\n grid: {\n ...DEFAULT_GRID_THEME,\n majorColor: \"rgba(0, 0, 0, 0.1)\",\n minorColor: \"rgba(0, 0, 0, 0.04)\",\n },\n xAxis: {\n ...DEFAULT_AXIS_THEME,\n lineColor: \"#888888\",\n tickColor: \"#888888\",\n labelColor: \"#444444\",\n titleColor: \"#222222\",\n },\n yAxis: {\n ...DEFAULT_AXIS_THEME,\n lineColor: \"#888888\",\n tickColor: \"#888888\",\n labelColor: \"#444444\",\n titleColor: \"#222222\",\n },\n legend: {\n ...DEFAULT_LEGEND_THEME,\n backgroundColor: \"rgba(255, 255, 255, 0.95)\",\n borderColor: \"rgba(0, 0, 0, 0.15)\",\n textColor: \"#222222\",\n },\n cursor: {\n ...DEFAULT_CURSOR_THEME,\n lineColor: \"rgba(0, 0, 0, 0.4)\",\n tooltipBackground: \"rgba(50, 50, 60, 0.95)\",\n },\n};\n\n/** Electrochemistry theme - Professional blue tones */\nexport const ELECTROCHEM_THEME: ChartTheme = {\n name: \"electrochemistry\",\n backgroundColor: \"#0a1628\",\n plotBorderColor: \"#1e3a5f\",\n grid: {\n ...DEFAULT_GRID_THEME,\n majorColor: \"rgba(30, 136, 229, 0.15)\",\n minorColor: \"rgba(30, 136, 229, 0.06)\",\n showMinor: true,\n minorDivisions: 2,\n },\n xAxis: {\n ...DEFAULT_AXIS_THEME,\n lineColor: \"#1e88e5\",\n tickColor: \"#42a5f5\",\n labelColor: \"#90caf9\",\n titleColor: \"#bbdefb\",\n },\n yAxis: {\n ...DEFAULT_AXIS_THEME,\n lineColor: \"#1e88e5\",\n tickColor: \"#42a5f5\",\n labelColor: \"#90caf9\",\n titleColor: \"#bbdefb\",\n },\n legend: {\n ...DEFAULT_LEGEND_THEME,\n backgroundColor: \"rgba(10, 22, 40, 0.95)\",\n borderColor: \"rgba(30, 136, 229, 0.3)\",\n },\n cursor: {\n ...DEFAULT_CURSOR_THEME,\n lineColor: \"rgba(100, 180, 255, 0.6)\",\n },\n};\n\n// ============================================\n// Theme Utilities\n// ============================================\n\n/**\n * Create a custom theme by merging with base theme\n */\nexport function createTheme(\n base: ChartTheme,\n overrides: Partial<ChartTheme>\n): ChartTheme {\n return {\n ...base,\n ...overrides,\n grid: { ...base.grid, ...overrides.grid },\n xAxis: { ...base.xAxis, ...overrides.xAxis },\n yAxis: { ...base.yAxis, ...overrides.yAxis },\n legend: { ...base.legend, ...overrides.legend },\n cursor: { ...base.cursor, ...overrides.cursor },\n };\n}\n\n/**\n * Get a theme by name\n */\nexport function getThemeByName(name: string): ChartTheme {\n switch (name) {\n case \"dark\":\n return DARK_THEME;\n case \"midnight\":\n return MIDNIGHT_THEME;\n case \"light\":\n return LIGHT_THEME;\n case \"electrochemistry\":\n case \"electrochem\":\n return ELECTROCHEM_THEME;\n default:\n console.warn(`[Theme] Unknown theme \"${name}\", using dark`);\n return DARK_THEME;\n }\n}\n\n/** Default theme export */\nexport const DEFAULT_THEME = DARK_THEME;\n","/**\n * OverlayRenderer - Canvas 2D rendering for axes, grid, legend, and cursor\n *\n * This module handles all 2D overlay rendering on top of the WebGL canvas.\n * It uses the theme system for consistent styling.\n */\n\nimport type { Scale } from \"../scales\";\nimport type { ChartTheme } from \"../theme\";\nimport type { Series } from \"./Series\";\n\n// ============================================\n// Types\n// ============================================\n\nexport interface PlotArea {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface AxisLabels {\n x?: string;\n y?: string;\n}\n\nexport interface CursorState {\n enabled: boolean;\n x: number;\n y: number;\n crosshair: boolean;\n tooltipText?: string;\n}\n\n// ============================================\n// Overlay Renderer Class\n// ============================================\n\nexport class OverlayRenderer {\n private ctx: CanvasRenderingContext2D;\n private theme: ChartTheme;\n\n constructor(ctx: CanvasRenderingContext2D, theme: ChartTheme) {\n this.ctx = ctx;\n this.theme = theme;\n }\n\n /**\n * Update the theme\n */\n setTheme(theme: ChartTheme): void {\n this.theme = theme;\n }\n\n /**\n * Clear the overlay\n */\n clear(width: number, height: number): void {\n this.ctx.clearRect(0, 0, width, height);\n }\n\n /**\n * Draw the grid\n */\n drawGrid(plotArea: PlotArea, xScale: Scale, yScale: Scale): void {\n if (!this.theme.grid.visible) return;\n\n const { ctx } = this;\n const grid = this.theme.grid;\n\n const xTicks = xScale.ticks(8);\n const yTicks = yScale.ticks(6);\n\n // Major grid lines\n ctx.strokeStyle = grid.majorColor;\n ctx.lineWidth = grid.majorWidth;\n ctx.setLineDash(grid.majorDash);\n\n // Vertical lines (X ticks)\n xTicks.forEach((tick) => {\n const x = xScale.transform(tick);\n if (x >= plotArea.x && x <= plotArea.x + plotArea.width) {\n ctx.beginPath();\n ctx.moveTo(x, plotArea.y);\n ctx.lineTo(x, plotArea.y + plotArea.height);\n ctx.stroke();\n }\n });\n\n // Horizontal lines (Y ticks)\n yTicks.forEach((tick) => {\n const y = yScale.transform(tick);\n if (y >= plotArea.y && y <= plotArea.y + plotArea.height) {\n ctx.beginPath();\n ctx.moveTo(plotArea.x, y);\n ctx.lineTo(plotArea.x + plotArea.width, y);\n ctx.stroke();\n }\n });\n\n // Minor grid lines (if enabled)\n if (grid.showMinor) {\n ctx.strokeStyle = grid.minorColor;\n ctx.lineWidth = grid.minorWidth;\n ctx.setLineDash(grid.minorDash);\n\n // Generate minor ticks between major ticks\n const minorXTicks = this.generateMinorTicks(xTicks, grid.minorDivisions);\n const minorYTicks = this.generateMinorTicks(yTicks, grid.minorDivisions);\n\n minorXTicks.forEach((tick) => {\n const x = xScale.transform(tick);\n if (x >= plotArea.x && x <= plotArea.x + plotArea.width) {\n ctx.beginPath();\n ctx.moveTo(x, plotArea.y);\n ctx.lineTo(x, plotArea.y + plotArea.height);\n ctx.stroke();\n }\n });\n\n minorYTicks.forEach((tick) => {\n const y = yScale.transform(tick);\n if (y >= plotArea.y && y <= plotArea.y + plotArea.height) {\n ctx.beginPath();\n ctx.moveTo(plotArea.x, y);\n ctx.lineTo(plotArea.x + plotArea.width, y);\n ctx.stroke();\n }\n });\n }\n\n ctx.setLineDash([]);\n }\n\n /**\n * Draw X axis with ticks and labels\n */\n drawXAxis(plotArea: PlotArea, xScale: Scale, label?: string): void {\n const { ctx } = this;\n const axis = this.theme.xAxis;\n const xTicks = xScale.ticks(8);\n const axisY = plotArea.y + plotArea.height;\n\n // Axis line\n ctx.strokeStyle = axis.lineColor;\n ctx.lineWidth = axis.lineWidth;\n ctx.beginPath();\n ctx.moveTo(plotArea.x, axisY);\n ctx.lineTo(plotArea.x + plotArea.width, axisY);\n ctx.stroke();\n\n // Ticks and labels\n ctx.fillStyle = axis.labelColor;\n ctx.font = `${axis.labelSize}px ${axis.fontFamily}`;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"top\";\n\n xTicks.forEach((tick) => {\n const x = xScale.transform(tick);\n\n if (x >= plotArea.x && x <= plotArea.x + plotArea.width) {\n // Tick mark\n ctx.strokeStyle = axis.tickColor;\n ctx.beginPath();\n ctx.moveTo(x, axisY);\n ctx.lineTo(x, axisY + axis.tickLength);\n ctx.stroke();\n\n // Label\n ctx.fillText(this.formatXTick(tick), x, axisY + axis.tickLength + 3);\n }\n });\n\n // Axis title\n if (label) {\n ctx.fillStyle = axis.titleColor;\n ctx.font = `${axis.titleSize}px ${axis.fontFamily}`;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"bottom\";\n ctx.fillText(\n label,\n plotArea.x + plotArea.width / 2,\n plotArea.y + plotArea.height + 45\n );\n }\n }\n\n /**\n * Draw Y axis with ticks and labels\n */\n drawYAxis(plotArea: PlotArea, yScale: Scale, label?: string): void {\n const { ctx } = this;\n const axis = this.theme.yAxis;\n const yTicks = yScale.ticks(6);\n const axisX = plotArea.x;\n\n // Axis line\n ctx.strokeStyle = axis.lineColor;\n ctx.lineWidth = axis.lineWidth;\n ctx.beginPath();\n ctx.moveTo(axisX, plotArea.y);\n ctx.lineTo(axisX, plotArea.y + plotArea.height);\n ctx.stroke();\n\n // Ticks and labels\n ctx.fillStyle = axis.labelColor;\n ctx.font = `${axis.labelSize}px ${axis.fontFamily}`;\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"middle\";\n\n yTicks.forEach((tick) => {\n const y = yScale.transform(tick);\n\n if (y >= plotArea.y && y <= plotArea.y + plotArea.height) {\n // Tick mark\n ctx.strokeStyle = axis.tickColor;\n ctx.beginPath();\n ctx.moveTo(axisX, y);\n ctx.lineTo(axisX - axis.tickLength, y);\n ctx.stroke();\n\n // Label\n ctx.fillText(this.formatYTick(tick), axisX - axis.tickLength - 3, y);\n }\n });\n\n // Axis title\n if (label) {\n ctx.save();\n ctx.fillStyle = axis.titleColor;\n ctx.font = `${axis.titleSize}px ${axis.fontFamily}`;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"top\";\n ctx.translate(15, plotArea.y + plotArea.height / 2);\n ctx.rotate(-Math.PI / 2);\n ctx.fillText(label, 0, 0);\n ctx.restore();\n }\n }\n\n /**\n * Draw plot area border\n */\n drawPlotBorder(plotArea: PlotArea): void {\n const { ctx } = this;\n ctx.strokeStyle = this.theme.plotBorderColor;\n ctx.lineWidth = 1;\n ctx.strokeRect(plotArea.x, plotArea.y, plotArea.width, plotArea.height);\n }\n\n /**\n * Draw legend\n */\n drawLegend(plotArea: PlotArea, series: Series[]): void {\n if (series.length === 0) return;\n\n const { ctx } = this;\n const legend = this.theme.legend;\n\n // Calculate legend dimensions\n ctx.font = `${legend.fontSize}px ${legend.fontFamily}`;\n let maxWidth = 0;\n const items = series.map((s) => {\n const label = s.getId();\n const width = ctx.measureText(label).width;\n maxWidth = Math.max(maxWidth, width);\n return { id: s.getId(), color: s.getStyle().color ?? \"#ff0055\", label };\n });\n\n const boxWidth = legend.swatchSize + 8 + maxWidth + legend.padding * 2;\n const boxHeight =\n items.length * (legend.swatchSize + legend.itemGap) -\n legend.itemGap +\n legend.padding * 2;\n\n // Calculate position\n let x: number, y: number;\n switch (legend.position) {\n case \"top-left\":\n x = plotArea.x + 10;\n y = plotArea.y + 10;\n break;\n case \"bottom-left\":\n x = plotArea.x + 10;\n y = plotArea.y + 10;\n break;\n case \"bottom-right\":\n x = plotArea.x + plotArea.width - boxWidth - 10;\n y = plotArea.y + plotArea.height - boxHeight - 10;\n break;\n case \"top-right\":\n default:\n x = plotArea.x + plotArea.width - boxWidth - 10;\n y = plotArea.y + 10;\n break;\n }\n\n // Draw background\n ctx.fillStyle = legend.backgroundColor;\n ctx.strokeStyle = legend.borderColor;\n ctx.lineWidth = 1;\n ctx.beginPath();\n const r = legend.borderRadius;\n ctx.moveTo(x + r, y);\n ctx.lineTo(x + boxWidth - r, y);\n ctx.arcTo(x + boxWidth, y, x + boxWidth, y + r, r);\n ctx.lineTo(x + boxWidth, y + boxHeight - r);\n ctx.arcTo(x + boxWidth, y + boxHeight, x + boxWidth - r, y + boxHeight, r);\n ctx.lineTo(x + r, y + boxHeight);\n ctx.arcTo(x, y + boxHeight, x, y + boxHeight - r, r);\n ctx.lineTo(x, y + r);\n ctx.arcTo(x, y, x + r, y, r);\n ctx.closePath();\n ctx.fill();\n ctx.stroke();\n\n // Draw items\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n\n items.forEach((item, i) => {\n const itemY =\n y + legend.padding + i * (legend.swatchSize + legend.itemGap);\n\n // Color swatch\n ctx.fillStyle = item.color;\n ctx.fillRect(\n x + legend.padding,\n itemY,\n legend.swatchSize,\n legend.swatchSize\n );\n\n // Label\n ctx.fillStyle = legend.textColor;\n ctx.fillText(\n item.label,\n x + legend.padding + legend.swatchSize + 8,\n itemY + legend.swatchSize / 2\n );\n });\n }\n\n /**\n * Draw cursor/crosshair\n */\n drawCursor(plotArea: PlotArea, cursor: CursorState): void {\n if (!cursor.enabled) return;\n\n const { ctx } = this;\n const cursorTheme = this.theme.cursor;\n\n // Check if cursor is in plot area\n if (\n cursor.x < plotArea.x ||\n cursor.x > plotArea.x + plotArea.width ||\n cursor.y < plotArea.y ||\n cursor.y > plotArea.y + plotArea.height\n ) {\n return;\n }\n\n ctx.save();\n\n // Clip to plot area\n ctx.beginPath();\n ctx.rect(plotArea.x, plotArea.y, plotArea.width, plotArea.height);\n ctx.clip();\n\n // Crosshair style\n ctx.strokeStyle = cursorTheme.lineColor;\n ctx.lineWidth = cursorTheme.lineWidth;\n ctx.setLineDash(cursorTheme.lineDash);\n\n if (cursor.crosshair) {\n // Vertical line\n ctx.beginPath();\n ctx.moveTo(cursor.x, plotArea.y);\n ctx.lineTo(cursor.x, plotArea.y + plotArea.height);\n ctx.stroke();\n\n // Horizontal line\n ctx.beginPath();\n ctx.moveTo(plotArea.x, cursor.y);\n ctx.lineTo(plotArea.x + plotArea.width, cursor.y);\n ctx.stroke();\n } else {\n // Just vertical line\n ctx.beginPath();\n ctx.moveTo(cursor.x, plotArea.y);\n ctx.lineTo(cursor.x, plotArea.y + plotArea.height);\n ctx.stroke();\n }\n\n ctx.restore();\n\n // Draw tooltip\n if (cursor.tooltipText) {\n this.drawTooltip(cursor.x, cursor.y, cursor.tooltipText, plotArea);\n }\n }\n\n /**\n * Draw tooltip\n */\n private drawTooltip(\n x: number,\n y: number,\n text: string,\n plotArea: PlotArea\n ): void {\n const { ctx } = this;\n const cursor = this.theme.cursor;\n const lines = text.split(\"\\n\");\n const lineHeight = cursor.tooltipSize + 5;\n const padding = 8;\n\n ctx.font = `${cursor.tooltipSize}px ${this.theme.xAxis.fontFamily}`;\n let maxWidth = 0;\n lines.forEach((line) => {\n maxWidth = Math.max(maxWidth, ctx.measureText(line).width);\n });\n\n const boxWidth = maxWidth + padding * 2;\n const boxHeight = lines.length * lineHeight + padding * 2 - 5;\n\n // Position tooltip\n let tooltipX = x + 15;\n let tooltipY = y - boxHeight - 10;\n\n if (tooltipX + boxWidth > plotArea.x + plotArea.width) {\n tooltipX = x - boxWidth - 15;\n }\n if (tooltipY < plotArea.y) {\n tooltipY = y + 15;\n }\n\n // Background\n ctx.fillStyle = cursor.tooltipBackground;\n ctx.strokeStyle = cursor.tooltipBorder;\n ctx.lineWidth = 1;\n ctx.beginPath();\n const r = 4;\n ctx.moveTo(tooltipX + r, tooltipY);\n ctx.lineTo(tooltipX + boxWidth - r, tooltipY);\n ctx.arcTo(tooltipX + boxWidth, tooltipY, tooltipX + boxWidth, tooltipY + r, r);\n ctx.lineTo(tooltipX + boxWidth, tooltipY + boxHeight - r);\n ctx.arcTo(tooltipX + boxWidth, tooltipY + boxHeight, tooltipX + boxWidth - r, tooltipY + boxHeight, r);\n ctx.lineTo(tooltipX + r, tooltipY + boxHeight);\n ctx.arcTo(tooltipX, tooltipY + boxHeight, tooltipX, tooltipY + boxHeight - r, r);\n ctx.lineTo(tooltipX, tooltipY + r);\n ctx.arcTo(tooltipX, tooltipY, tooltipX + r, tooltipY, r);\n ctx.closePath();\n ctx.fill();\n ctx.stroke();\n\n // Text\n ctx.fillStyle = cursor.tooltipColor;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n lines.forEach((line, i) => {\n ctx.fillText(\n line,\n tooltipX + padding,\n tooltipY + padding + i * lineHeight\n );\n });\n }\n\n /**\n * Draw selection rectangle (Box Zoom)\n */\n drawSelectionRect(rect: {\n x: number;\n y: number;\n width: number;\n height: number;\n }): void {\n const { ctx } = this;\n const isDark =\n this.theme.name.toLowerCase().includes(\"dark\") ||\n this.theme.name.toLowerCase().includes(\"midnight\");\n\n ctx.save();\n ctx.fillStyle = isDark\n ? \"rgba(0, 170, 255, 0.15)\"\n : \"rgba(0, 100, 255, 0.1)\";\n ctx.strokeStyle = \"#00aaff\";\n ctx.lineWidth = 1;\n ctx.setLineDash([5, 5]);\n\n ctx.beginPath();\n ctx.rect(rect.x, rect.y, rect.width, rect.height);\n ctx.fill();\n ctx.stroke();\n ctx.restore();\n }\n\n // ----------------------------------------\n // Helper Methods\n // ----------------------------------------\n\n private generateMinorTicks(\n majorTicks: number[],\n divisions: number\n ): number[] {\n if (majorTicks.length < 2) return [];\n\n const minor: number[] = [];\n for (let i = 0; i < majorTicks.length - 1; i++) {\n const step = (majorTicks[i + 1] - majorTicks[i]) / divisions;\n for (let j = 1; j < divisions; j++) {\n minor.push(majorTicks[i] + step * j);\n }\n }\n return minor;\n }\n\n private formatXTick(value: number): string {\n if (Math.abs(value) < 0.001 && value !== 0) {\n return this.toScientificUnicode(value, 1);\n }\n return value.toFixed(3).replace(/\\.?0+$/, \"\");\n }\n\n private formatYTick(value: number): string {\n if (value === 0) return \"0\";\n const absVal = Math.abs(value);\n if (absVal < 0.0001 || absVal >= 10000) {\n return this.toScientificUnicode(value, 1);\n }\n return value.toPrecision(3);\n }\n\n private toScientificUnicode(value: number, precision: number): string {\n const str = value.toExponential(precision);\n const [mantissa, exponent] = str.split(\"e\");\n\n // Convert exponent to unicode superscripts\n const superscriptMap: Record<string, string> = {\n \"0\": \"⁰\",\n \"1\": \"¹\",\n \"2\": \"²\",\n \"3\": \"³\",\n \"4\": \"⁴\",\n \"5\": \"⁵\",\n \"6\": \"⁶\",\n \"7\": \"⁷\",\n \"8\": \"⁸\",\n \"9\": \"⁹\",\n \"-\": \"⁻\",\n \"+\": \"⁺\",\n };\n\n const unicodeExp = exponent.replace(\n /[0-9\\-+]/g,\n (char) => superscriptMap[char] || char\n );\n\n // Return \"1.2 × 10⁻⁵\" format\n return `${mantissa} × 10${unicodeExp}`;\n }\n}\n","/**\n * InteractionManager - Handles mouse, touch, and keyboard interactions\n *\n * This module manages all user interactions with the chart including:\n * - Zoom (mouse wheel)\n * - Pan (mouse drag, touch drag)\n * - Cursor tracking\n */\n\nimport type { Bounds } from \"../types\";\n\n// ============================================\n// Types\n// ============================================\n\nexport interface InteractionCallbacks {\n onZoom: (bounds: Bounds) => void;\n onPan: (deltaX: number, deltaY: number) => void;\n onBoxZoom: (\n rect: { x: number; y: number; width: number; height: number } | null\n ) => void;\n onCursorMove: (x: number, y: number) => void;\n onCursorLeave: () => void;\n}\n\nexport interface PlotAreaGetter {\n (): { x: number; y: number; width: number; height: number };\n}\n\nexport interface BoundsGetter {\n (): Bounds;\n}\n\n// ============================================\n// Interaction Manager Class\n// ============================================\n\nexport class InteractionManager {\n private container: HTMLElement;\n private callbacks: InteractionCallbacks;\n private getPlotArea: PlotAreaGetter;\n private getBounds: BoundsGetter;\n\n private isDragging = false;\n private isBoxSelecting = false;\n private selectionStart = { x: 0, y: 0 };\n private lastMousePos = { x: 0, y: 0 };\n private isPanMode = true;\n\n // Bound handlers for cleanup\n private boundWheel: (e: WheelEvent) => void;\n private boundMouseDown: (e: MouseEvent) => void;\n private boundMouseMove: (e: MouseEvent) => void;\n private boundMouseUp: (e: MouseEvent) => void;\n private boundMouseLeave: (e: MouseEvent) => void;\n private boundTouchStart: (e: TouchEvent) => void;\n private boundTouchMove: (e: TouchEvent) => void;\n private boundTouchEnd: (e: TouchEvent) => void;\n\n constructor(\n container: HTMLElement,\n callbacks: InteractionCallbacks,\n getPlotArea: PlotAreaGetter,\n getBounds: BoundsGetter\n ) {\n this.container = container;\n this.callbacks = callbacks;\n this.getPlotArea = getPlotArea;\n this.getBounds = getBounds;\n\n // Bind handlers\n this.boundWheel = this.handleWheel.bind(this);\n this.boundMouseDown = this.handleMouseDown.bind(this);\n this.boundMouseMove = this.handleMouseMove.bind(this);\n this.boundMouseUp = this.handleMouseUp.bind(this);\n this.boundMouseLeave = this.handleMouseLeave.bind(this);\n this.boundTouchStart = this.handleTouchStart.bind(this);\n this.boundTouchMove = this.handleTouchMove.bind(this);\n this.boundTouchEnd = this.handleTouchEnd.bind(this);\n\n this.attachListeners();\n }\n\n private attachListeners(): void {\n this.container.addEventListener(\"wheel\", this.boundWheel, {\n passive: false,\n });\n this.container.addEventListener(\"mousedown\", this.boundMouseDown);\n this.container.addEventListener(\"mousemove\", this.boundMouseMove);\n this.container.addEventListener(\"mouseup\", this.boundMouseUp);\n this.container.addEventListener(\"mouseleave\", this.boundMouseLeave);\n this.container.addEventListener(\"touchstart\", this.boundTouchStart);\n this.container.addEventListener(\"touchmove\", this.boundTouchMove);\n this.container.addEventListener(\"touchend\", this.boundTouchEnd);\n }\n\n private detachListeners(): void {\n this.container.removeEventListener(\"wheel\", this.boundWheel);\n this.container.removeEventListener(\"mousedown\", this.boundMouseDown);\n this.container.removeEventListener(\"mousemove\", this.boundMouseMove);\n this.container.removeEventListener(\"mouseup\", this.boundMouseUp);\n this.container.removeEventListener(\"mouseleave\", this.boundMouseLeave);\n this.container.removeEventListener(\"touchstart\", this.boundTouchStart);\n this.container.removeEventListener(\"touchmove\", this.boundTouchMove);\n this.container.removeEventListener(\"touchend\", this.boundTouchEnd);\n }\n\n public setPanMode(enabled: boolean): void {\n this.isPanMode = enabled;\n }\n\n // ----------------------------------------\n // Mouse Handlers\n // ----------------------------------------\n\n private handleWheel(e: WheelEvent): void {\n const plotArea = this.getPlotArea();\n if (plotArea.width <= 1 || plotArea.height <= 1) return;\n\n e.preventDefault();\n const rect = this.container.getBoundingClientRect();\n const mouseX = e.clientX - rect.left;\n const mouseY = e.clientY - rect.top;\n\n const bounds = this.getBounds();\n\n // Determine zoom targets\n let zoomX = false;\n let zoomY = false;\n\n // Y Axis area (left)\n if (\n mouseX < plotArea.x &&\n mouseY >= plotArea.y &&\n mouseY <= plotArea.y + plotArea.height\n ) {\n zoomY = true;\n }\n // X Axis area (bottom)\n else if (\n mouseY > plotArea.y + plotArea.height &&\n mouseX >= plotArea.x &&\n mouseX <= plotArea.x + plotArea.width\n ) {\n zoomX = true;\n }\n // Plot area (both)\n else if (\n mouseX >= plotArea.x &&\n mouseX <= plotArea.x + plotArea.width &&\n mouseY >= plotArea.y &&\n mouseY <= plotArea.y + plotArea.height\n ) {\n zoomX = true;\n zoomY = true;\n } else {\n return; // Outside interactive areas\n }\n\n const zoomFactor = e.deltaY > 0 ? 1.1 : 0.9;\n\n // Calculate zoom center in data coordinates\n const normalizedX = (mouseX - plotArea.x) / plotArea.width;\n const normalizedY = 1 - (mouseY - plotArea.y) / plotArea.height;\n\n const dataX = bounds.xMin + normalizedX * (bounds.xMax - bounds.xMin);\n const dataY = bounds.yMin + normalizedY * (bounds.yMax - bounds.yMin);\n\n // Safeguard: Prevent zooming out too far or in too deep\n // Limits\n const MIN_RANGE = 1e-12;\n const MAX_RANGE = 1e15;\n\n let nextXMin = zoomX\n ? dataX - (dataX - bounds.xMin) * zoomFactor\n : bounds.xMin;\n let nextXMax = zoomX\n ? dataX + (bounds.xMax - dataX) * zoomFactor\n : bounds.xMax;\n let nextYMin = zoomY\n ? dataY - (dataY - bounds.yMin) * zoomFactor\n : bounds.yMin;\n let nextYMax = zoomY\n ? dataY + (bounds.yMax - dataY) * zoomFactor\n : bounds.yMax;\n\n const nextXRange = nextXMax - nextXMin;\n const nextYRange = nextYMax - nextYMin;\n\n if (nextXRange < MIN_RANGE || nextXRange > MAX_RANGE) {\n nextXMin = bounds.xMin;\n nextXMax = bounds.xMax;\n }\n if (nextYRange < MIN_RANGE || nextYRange > MAX_RANGE) {\n nextYMin = bounds.yMin;\n nextYMax = bounds.yMax;\n }\n\n const newBounds: Bounds = {\n xMin: nextXMin,\n xMax: nextXMax,\n yMin: nextYMin,\n yMax: nextYMax,\n };\n\n this.callbacks.onZoom(newBounds);\n }\n\n private handleMouseDown(e: MouseEvent): void {\n const plotArea = this.getPlotArea();\n if (plotArea.width <= 1 || plotArea.height <= 1) return;\n\n const rect = this.container.getBoundingClientRect();\n const mouseX = e.clientX - rect.left;\n const mouseY = e.clientY - rect.top;\n\n // Check if mouse is in plot area\n if (\n mouseX >= plotArea.x &&\n mouseX <= plotArea.x + plotArea.width &&\n mouseY >= plotArea.y &&\n mouseY <= plotArea.y + plotArea.height\n ) {\n if (this.isPanMode) {\n this.isDragging = true;\n this.lastMousePos = { x: e.clientX, y: e.clientY };\n this.container.style.cursor = \"grabbing\";\n } else {\n this.isBoxSelecting = true;\n this.selectionStart = { x: mouseX, y: mouseY };\n this.container.style.cursor = \"crosshair\";\n }\n }\n }\n\n private handleMouseMove(e: MouseEvent): void {\n const rect = this.container.getBoundingClientRect();\n const mouseX = e.clientX - rect.left;\n const mouseY = e.clientY - rect.top;\n\n // Update cursor position\n this.callbacks.onCursorMove(mouseX, mouseY);\n\n if (this.isDragging) {\n const deltaX = e.clientX - this.lastMousePos.x;\n const deltaY = e.clientY - this.lastMousePos.y;\n this.callbacks.onPan(deltaX, deltaY);\n this.lastMousePos = { x: e.clientX, y: e.clientY };\n } else if (this.isBoxSelecting) {\n const x = Math.min(this.selectionStart.x, mouseX);\n const y = Math.min(this.selectionStart.y, mouseY);\n const width = Math.abs(mouseX - this.selectionStart.x);\n const height = Math.abs(mouseY - this.selectionStart.y);\n this.callbacks.onBoxZoom({ x, y, width, height });\n }\n }\n\n private handleMouseUp(): void {\n if (this.isBoxSelecting) {\n this.callbacks.onBoxZoom(null); // Signal to apply\n }\n this.isDragging = false;\n this.isBoxSelecting = false;\n this.container.style.cursor = \"\";\n }\n\n private handleMouseLeave(): void {\n this.isDragging = false;\n this.container.style.cursor = \"\";\n this.callbacks.onCursorLeave();\n }\n\n // ----------------------------------------\n // Touch Handlers\n // ----------------------------------------\n\n private handleTouchStart(e: TouchEvent): void {\n if (e.touches.length === 1) {\n const touch = e.touches[0];\n this.isDragging = true;\n this.lastMousePos = { x: touch.clientX, y: touch.clientY };\n }\n }\n\n private handleTouchMove(e: TouchEvent): void {\n if (!this.isDragging || e.touches.length !== 1) return;\n\n e.preventDefault();\n\n const touch = e.touches[0];\n const deltaX = touch.clientX - this.lastMousePos.x;\n const deltaY = touch.clientY - this.lastMousePos.y;\n\n this.callbacks.onPan(deltaX, deltaY);\n\n this.lastMousePos = { x: touch.clientX, y: touch.clientY };\n }\n\n private handleTouchEnd(): void {\n this.isDragging = false;\n }\n\n // ----------------------------------------\n // Cleanup\n // ----------------------------------------\n\n destroy(): void {\n this.detachListeners();\n }\n}\n","/**\n * ChartControls - In-chart control buttons (Plotly-style)\n *\n * Provides a floating glassmorphism toolbar for chart controls:\n * - Pan/Zoom mode toggle\n * - Reset Zoom\n * - Display Mode (Line, Scatter, Both)\n * - Smoothing toggle\n */\n\nimport { ChartTheme } from \"../theme\";\n\nexport interface ChartControlsCallbacks {\n onResetZoom: () => void;\n onSetType: (type: \"line\" | \"scatter\" | \"line+scatter\") => void;\n onToggleSmoothing: () => void;\n onTogglePan: (active: boolean) => void;\n onExport: () => void;\n onAutoScale: () => void;\n}\n\n// ============================================\n// SVG Icons (Plotly-inspired)\n// ============================================\n\nconst ICONS = {\n PAN: `<svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M18 11V6a2 2 0 0 0-2-2v0a2 2 0 0 0-2 2v0\"></path><path d=\"M14 10V4a2 2 0 0 0-2-2v0a2 2 0 0 0-2 2v0\"></path><path d=\"M10 10.5V6a2 2 0 0 0-2-2v0a2 2 0 0 0-2 2v0\"></path><path d=\"M18 8a2 2 0 1 1 4 0v6a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15\"></path></svg>`,\n RESET: `<svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"23 4 23 10 17 10\"></polyline><polyline points=\"1 20 1 14 7 14\"></polyline><path d=\"M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15\"></path></svg>`,\n LINE: `<svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 3v18h18\"></path><path d=\"M18.7 8l-5.1 5.2-2.8-2.7L7 14.3\"></path></svg>`,\n SCATTER: `<svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" fill=\"currentColor\"><circle cx=\"7\" cy=\"14\" r=\"2\"></circle><circle cx=\"11\" cy=\"10\" r=\"2\"></circle><circle cx=\"15\" cy=\"13\" r=\"2\"></circle><circle cx=\"19\" cy=\"8\" r=\"2\"></circle><path d=\"M3 3v18h18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path></svg>`,\n BOTH: `<svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 3v18h18\"></path><path d=\"M18.7 8l-5.1 5.2-2.8-2.7L7 14.3\"></path><circle cx=\"7\" cy=\"14.3\" r=\"1\" fill=\"currentColor\"></circle><circle cx=\"10.8\" cy=\"10.5\" r=\"1\" fill=\"currentColor\"></circle><circle cx=\"13.6\" cy=\"13.2\" r=\"1\" fill=\"currentColor\"></circle><circle cx=\"18.7\" cy=\"8\" r=\"1\" fill=\"currentColor\"></circle></svg>`,\n SMOOTH: `<svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M2 12c.5 0 .9-.3 1.2-.7l1.6-2.6c.3-.4.7-.7 1.2-.7h2c.5 0 .9.3 1.2.7l1.6 2.6c.3.4.7.7 1.2.7h2c.5 0 .9-.3 1.2-.7l1.6-2.6c.3-.4.7-.7 1.2-.7h2\"></path></svg>`,\n AUTOSCALE: `<svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"15 3 21 3 21 9\"></polyline><polyline points=\"9 21 3 21 3 15\"></polyline><line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\"></line><line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\"></line></svg>`,\n EXPORT: `<svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"></path><polyline points=\"7 10 12 15 17 10\"></polyline><line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\"></line></svg>`,\n};\n\nexport class ChartControls {\n private container: HTMLDivElement;\n private toolbar: HTMLDivElement;\n private callbacks: ChartControlsCallbacks;\n private theme: ChartTheme;\n\n private isSmoothing = false;\n private isPanMode = true;\n private currentType: \"line\" | \"scatter\" | \"line+scatter\" = \"line\";\n\n constructor(\n parent: HTMLElement,\n theme: ChartTheme,\n callbacks: ChartControlsCallbacks\n ) {\n this.callbacks = callbacks;\n this.theme = theme;\n\n this.container = document.createElement(\"div\");\n this.container.style.cssText = `\n position: absolute;\n top: 8px;\n right: 8px;\n z-index: 100;\n pointer-events: auto;\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 8px;\n `;\n\n this.toolbar = document.createElement(\"div\");\n this.toolbar.className = \"scichart-modebar\";\n this.updateToolbarStyle();\n\n this.createButtons();\n this.container.appendChild(this.toolbar);\n parent.appendChild(this.container);\n }\n\n private isDarkTheme(): boolean {\n const name = this.theme.name.toLowerCase();\n return (\n name.includes(\"dark\") ||\n name.includes(\"midnight\") ||\n name.includes(\"electro\")\n );\n }\n\n private updateToolbarStyle(): void {\n const isDark = this.isDarkTheme();\n\n const bg = isDark ? \"rgba(15, 23, 42, 0.85)\" : \"rgba(255, 255, 255, 0.95)\";\n const borderColor = isDark\n ? \"rgba(255, 255, 255, 0.2)\"\n : \"rgba(0, 0, 0, 0.15)\";\n const shadow = isDark\n ? \"0 4px 12px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.1)\"\n : \"0 4px 12px rgba(0, 0, 0, 0.15)\";\n\n this.toolbar.style.cssText = `\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 4px;\n background: ${bg};\n backdrop-filter: blur(12px) saturate(180%);\n -webkit-backdrop-filter: blur(12px) saturate(180%);\n border: 1px solid ${borderColor};\n border-radius: 8px;\n box-shadow: ${shadow};\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n `;\n }\n\n private createButtons(): void {\n // Pan Mode\n this.createButton(\n ICONS.PAN,\n \"Pan Mode\",\n () => {\n this.isPanMode = !this.isPanMode;\n this.updateButtonStates();\n this.callbacks.onTogglePan(this.isPanMode);\n },\n \"pan\"\n );\n\n // Reset Zoom\n this.createButton(\n ICONS.RESET,\n \"Reset Zoom\",\n () => this.callbacks.onResetZoom(),\n \"reset\"\n );\n\n // Auto Scale\n this.createButton(\n ICONS.AUTOSCALE,\n \"Auto Scale\",\n () => this.callbacks.onAutoScale(),\n \"autoscale\"\n );\n\n // Separator\n const sep = document.createElement(\"div\");\n const isDark = this.isDarkTheme();\n sep.style.cssText = `width: 1px; height: 20px; background: ${\n isDark ? \"rgba(255,255,255,0.25)\" : \"rgba(0,0,0,0.2)\"\n }; margin: 0 6px;`;\n this.toolbar.appendChild(sep);\n\n // Type Switcher\n this.createButton(\n ICONS.LINE,\n \"Toggle Line/Scatter/Both\",\n () => {\n const types: (\"line\" | \"scatter\" | \"line+scatter\")[] = [\n \"line\",\n \"scatter\",\n \"line+scatter\",\n ];\n const nextIdx = (types.indexOf(this.currentType) + 1) % types.length;\n this.currentType = types[nextIdx];\n this.callbacks.onSetType(this.currentType);\n this.updateButtonStates();\n },\n \"type\"\n );\n\n // Smoothing\n this.createButton(\n ICONS.SMOOTH,\n \"Automated Smoothing\",\n () => {\n this.isSmoothing = !this.isSmoothing;\n this.updateButtonStates();\n this.callbacks.onToggleSmoothing();\n },\n \"smooth\"\n );\n\n // Separator\n const sep2 = document.createElement(\"div\");\n sep2.style.cssText = `width: 1px; height: 20px; background: ${\n isDark ? \"rgba(255,255,255,0.25)\" : \"rgba(0,0,0,0.2)\"\n }; margin: 0 6px;`;\n this.toolbar.appendChild(sep2);\n\n // Export Image\n this.createButton(\n ICONS.EXPORT,\n \"Export as PNG\",\n () => this.callbacks.onExport(),\n \"export\"\n );\n\n this.updateButtonStates();\n }\n\n private enforceSVGVisibility(btn: HTMLButtonElement): void {\n // Force SVG visibility and make sure currentColor is applied even under aggressive page CSS\n const icon = btn.querySelector<HTMLElement>(\".scichart-control-icon\");\n if (icon) {\n icon.style.display = \"flex\";\n icon.style.alignItems = \"center\";\n icon.style.justifyContent = \"center\";\n icon.style.width = \"100%\";\n icon.style.height = \"100%\";\n icon.style.pointerEvents = \"none\";\n }\n\n const svgEl = btn.querySelector<SVGElement>(\"svg\");\n if (svgEl) {\n svgEl.setAttribute(\"width\", \"14\");\n svgEl.setAttribute(\"height\", \"14\");\n (svgEl as any).style.display = \"block\";\n (svgEl as any).style.overflow = \"visible\";\n (svgEl as any).style.color = \"inherit\";\n (svgEl as any).style.stroke = \"currentColor\";\n if (!svgEl.getAttribute(\"fill\")) {\n (svgEl as any).style.fill = \"none\";\n }\n }\n }\n\n private createButton(\n svg: string,\n title: string,\n onClick: () => void,\n id: string\n ): HTMLButtonElement {\n const btn = document.createElement(\"button\");\n btn.innerHTML = `<span class=\"scichart-control-icon\">${svg}</span>`;\n btn.title = title;\n btn.dataset.id = id;\n\n const isDark = this.isDarkTheme();\n const color = isDark ? \"#ffffff\" : \"#1e293b\";\n\n btn.style.cssText = `\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: ${color};\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n opacity: 0.9;\n `;\n\n btn.onmouseenter = () => {\n btn.style.opacity = \"1\";\n btn.style.background = isDark\n ? \"rgba(255, 255, 255, 0.15)\"\n : \"rgba(0, 0, 0, 0.1)\";\n btn.style.transform = \"translateY(-1px)\";\n btn.style.boxShadow = isDark\n ? \"0 2px 4px rgba(0,0,0,0.4)\"\n : \"0 2px 4px rgba(0,0,0,0.1)\";\n };\n btn.onmouseleave = () => {\n btn.style.transform = \"none\";\n btn.style.boxShadow = \"none\";\n this.updateButtonStates();\n };\n btn.onclick = onClick;\n\n // Force SVG visibility\n this.enforceSVGVisibility(btn);\n\n this.toolbar.appendChild(btn);\n return btn;\n }\n\n private updateButtonStates(): void {\n const buttons = this.toolbar.querySelectorAll(\"button\");\n const isDark = this.isDarkTheme();\n\n const activeColor = \"#38bdf8\"; // Brighter blue\n const smoothActiveColor = \"#fb7185\"; // Brighter pink\n const normalColor = isDark ? \"#f1f5f9\" : \"#334155\"; // High contrast\n\n buttons.forEach((btn: HTMLButtonElement) => {\n const id = btn.dataset.id;\n const isHover = btn.matches(\":hover\");\n\n if (id === \"pan\") {\n btn.style.color = this.isPanMode ? activeColor : normalColor;\n btn.style.opacity = isHover || this.isPanMode ? \"1\" : \"0.8\";\n if (this.isPanMode) {\n btn.style.background = isDark\n ? \"rgba(56, 189, 248, 0.15)\"\n : \"rgba(56, 189, 248, 0.1)\";\n }\n } else if (id === \"smooth\") {\n btn.style.color = this.isSmoothing ? smoothActiveColor : normalColor;\n btn.style.opacity = isHover || this.isSmoothing ? \"1\" : \"0.8\";\n if (this.isSmoothing) {\n btn.style.background = isDark\n ? \"rgba(251, 113, 133, 0.15)\"\n : \"rgba(251, 113, 133, 0.1)\";\n }\n } else if (id === \"type\") {\n btn.innerHTML =\n this.currentType === \"line\"\n ? ICONS.LINE\n : this.currentType === \"scatter\"\n ? ICONS.SCATTER\n : ICONS.BOTH;\n // Reapply SVG visibility styles after changing innerHTML\n this.enforceSVGVisibility(btn);\n btn.style.color = normalColor;\n btn.style.opacity = isHover ? \"1\" : \"0.8\";\n } else if (id === \"reset\" || id === \"autoscale\" || id === \"export\") {\n btn.style.color = normalColor;\n btn.style.opacity = isHover ? \"1\" : \"0.8\";\n }\n\n if (\n !isHover &&\n !(\n (id === \"pan\" && this.isPanMode) ||\n (id === \"smooth\" && this.isSmoothing)\n )\n ) {\n btn.style.background = \"transparent\";\n }\n });\n }\n\n public updateTheme(theme: ChartTheme): void {\n this.theme = theme;\n this.updateToolbarStyle();\n this.updateButtonStates();\n }\n\n public destroy(): void {\n this.container.remove();\n }\n}\n","/**\n * ChartLegend - In-chart draggable legend component\n */\n\nimport { ChartTheme } from \"../theme\";\nimport { Series } from \"./Series\";\n\nexport interface ChartLegendCallbacks {\n onMove: (x: number, y: number) => void;\n}\n\nexport class ChartLegend {\n private container: HTMLDivElement;\n private header: HTMLDivElement;\n private content: HTMLDivElement;\n private theme: ChartTheme;\n private series: Series[] = [];\n private callbacks: ChartLegendCallbacks;\n\n private isDragging = false;\n private startX = 0;\n private startY = 0;\n private initialX = 0;\n private initialY = 0;\n\n constructor(\n parent: HTMLElement,\n theme: ChartTheme,\n options: { x?: number; y?: number },\n callbacks: ChartLegendCallbacks\n ) {\n this.theme = theme;\n this.callbacks = callbacks;\n\n this.container = document.createElement(\"div\");\n this.container.className = \"scichart-legend\";\n\n // Default position (top-right, below controls toolbar)\n // Controls toolbar height is ~32px (24px buttons + 4px padding*2 + borders) + 8px top margin = ~40px\n // Add extra margin to ensure no overlap\n const x = options.x ?? parent.clientWidth - 150;\n const y = options.y ?? 55;\n\n this.container.style.cssText = `\n position: absolute;\n left: ${x}px;\n top: ${y}px;\n z-index: 90;\n pointer-events: auto;\n min-width: 120px;\n border-radius: ${theme.legend.borderRadius}px;\n overflow: hidden;\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n user-select: none;\n transition: box-shadow 0.2s ease;\n `;\n\n this.updateStyle();\n\n // Draggable header\n this.header = document.createElement(\"div\");\n this.header.style.cssText = `\n height: 8px;\n cursor: move;\n background: rgba(255,255,255,0.05);\n border-bottom: 1px solid rgba(255,255,255,0.05);\n `;\n\n this.content = document.createElement(\"div\");\n this.content.style.padding = `${theme.legend.padding}px`;\n\n this.container.appendChild(this.header);\n this.container.appendChild(this.content);\n parent.appendChild(this.container);\n\n this.initDragging();\n }\n\n private updateStyle(): void {\n const isDark =\n this.theme.name.toLowerCase().includes(\"dark\") ||\n this.theme.name.toLowerCase().includes(\"midnight\") ||\n this.theme.name.toLowerCase().includes(\"electro\");\n\n const bg = isDark ? \"rgba(15, 23, 42, 0.85)\" : \"rgba(255, 255, 255, 0.95)\";\n const borderColor = isDark\n ? \"rgba(255, 255, 255, 0.15)\"\n : \"rgba(0, 0, 0, 0.1)\";\n const shadow = isDark\n ? \"0 4px 12px rgba(0, 0, 0, 0.6)\"\n : \"0 4px 12px rgba(0, 0, 0, 0.15)\";\n\n this.container.style.background = bg;\n this.container.style.backdropFilter = \"blur(12px) saturate(180%)\";\n (this.container.style as any).webkitBackdropFilter =\n \"blur(12px) saturate(180%)\";\n this.container.style.border = `1px solid ${borderColor}`;\n this.container.style.boxShadow = shadow;\n }\n\n private initDragging(): void {\n let rafId: number | null = null;\n\n const onMouseDown = (e: MouseEvent) => {\n // Only handle left click\n if (e.button !== 0) return;\n\n e.stopPropagation();\n e.preventDefault();\n\n this.isDragging = true;\n this.startX = e.clientX;\n this.startY = e.clientY;\n this.initialX = this.container.offsetLeft;\n this.initialY = this.container.offsetTop;\n\n this.container.style.transition = \"none\";\n this.container.style.willChange = \"transform\";\n this.container.style.boxShadow = \"0 8px 24px rgba(0,0,0,0.3)\";\n this.container.style.cursor = \"grabbing\";\n\n document.addEventListener(\"mousemove\", onMouseMove);\n document.addEventListener(\"mouseup\", onMouseUp);\n };\n\n const updatePosition = (clientX: number, clientY: number) => {\n const dx = clientX - this.startX;\n const dy = clientY - this.startY;\n\n let newX = this.initialX + dx;\n let newY = this.initialY + dy;\n\n const parent = this.container.parentElement;\n if (parent) {\n newX = Math.max(\n 0,\n Math.min(newX, parent.clientWidth - this.container.clientWidth)\n );\n newY = Math.max(\n 0,\n Math.min(newY, parent.clientHeight - this.container.clientHeight)\n );\n }\n\n // Use transform for better performance (no layout recalc)\n const tx = newX - this.initialX;\n const ty = newY - this.initialY;\n this.container.style.transform = `translate3d(${tx}px, ${ty}px, 0)`;\n };\n\n const onMouseMove = (e: MouseEvent) => {\n if (!this.isDragging) return;\n if (rafId) cancelAnimationFrame(rafId);\n rafId = requestAnimationFrame(() => updatePosition(e.clientX, e.clientY));\n };\n\n const onMouseUp = () => {\n if (this.isDragging) {\n this.isDragging = false;\n if (rafId) cancelAnimationFrame(rafId);\n\n // Finalize position and commit to left/top (to keep it there)\n const rect = this.container.getBoundingClientRect();\n const parentRect =\n this.container.parentElement?.getBoundingClientRect();\n if (parentRect) {\n const finalX = rect.left - parentRect.left;\n const finalY = rect.top - parentRect.top;\n\n this.container.style.transform = \"none\";\n this.container.style.left = `${finalX}px`;\n this.container.style.top = `${finalY}px`;\n\n this.callbacks.onMove(finalX, finalY);\n }\n\n this.container.style.willChange = \"auto\";\n this.container.style.transition = \"box-shadow 0.2s ease\";\n this.container.style.boxShadow = \"0 4px 12px rgba(0,0,0,0.15)\";\n this.container.style.cursor = \"auto\";\n }\n document.removeEventListener(\"mousemove\", onMouseMove);\n document.removeEventListener(\"mouseup\", onMouseUp);\n };\n\n this.container.addEventListener(\"mousedown\", onMouseDown);\n\n // Block events from reaching the chart while over the legend\n this.container.addEventListener(\"wheel\", (e) => e.stopPropagation());\n this.container.addEventListener(\"click\", (e) => e.stopPropagation());\n this.container.addEventListener(\"dblclick\", (e) => e.stopPropagation());\n // Note: mousemove/mouseup on container MUST bubble to document during drag\n }\n\n public update(series: Series[]): void {\n this.series = series;\n this.render();\n }\n\n private render(): void {\n this.content.innerHTML = \"\";\n const legend = this.theme.legend;\n\n this.series.forEach((s) => {\n const item = document.createElement(\"div\");\n item.style.cssText = `\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: ${legend.itemGap}px;\n font-family: ${legend.fontFamily};\n font-size: ${legend.fontSize}px;\n color: ${legend.textColor};\n `;\n\n const swatch = document.createElement(\"div\");\n swatch.style.cssText = `\n width: ${legend.swatchSize}px;\n height: ${legend.swatchSize}px;\n background: ${s.getStyle().color || \"#ff0055\"};\n border-radius: 2px;\n `;\n\n const label = document.createElement(\"span\");\n label.textContent = s.getId();\n\n item.appendChild(swatch);\n item.appendChild(label);\n this.content.appendChild(item);\n });\n }\n\n public draw(ctx: CanvasRenderingContext2D, dpr: number): void {\n if (this.series.length === 0) return;\n\n const legend = this.theme.legend;\n const padding = legend.padding * dpr;\n const itemGap = legend.itemGap * dpr;\n const swatchSize = legend.swatchSize * dpr;\n const headerHeight = 8 * dpr; // Matching the 8px header in constructor\n\n // Get current position in pixels\n const x = this.container.offsetLeft * dpr;\n const y = this.container.offsetTop * dpr;\n const width = this.container.clientWidth * dpr;\n const height = this.container.clientHeight * dpr;\n\n ctx.save();\n\n // 1. Draw background\n const isDark =\n this.theme.name.toLowerCase().includes(\"dark\") ||\n this.theme.name.toLowerCase().includes(\"midnight\");\n ctx.fillStyle = isDark\n ? legend.backgroundColor\n : \"rgba(255, 255, 255, 0.85)\";\n ctx.strokeStyle = legend.borderColor;\n ctx.lineWidth = 1 * dpr;\n\n const r = legend.borderRadius * dpr;\n ctx.beginPath();\n ctx.moveTo(x + r, y);\n ctx.lineTo(x + width - r, y);\n ctx.arcTo(x + width, y, x + width, y + r, r);\n ctx.lineTo(x + width, y + height - r);\n ctx.arcTo(x + width, y + height, x + width - r, y + height, r);\n ctx.lineTo(x + r, y + height);\n ctx.arcTo(x, y + height, x, y + height - r, r);\n ctx.lineTo(x, y + r);\n ctx.arcTo(x, y, x + r, y, r);\n ctx.closePath();\n ctx.fill();\n ctx.stroke();\n\n // 2. Draw Items\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n ctx.font = `${legend.fontSize * dpr}px ${legend.fontFamily}`;\n\n this.series.forEach((s, i) => {\n // Offset by headerHeight and padding\n const itemY =\n y +\n headerHeight +\n padding +\n i * (swatchSize + itemGap) +\n swatchSize / 2;\n\n // Swatch\n ctx.fillStyle = s.getStyle().color || \"#ff0055\";\n ctx.fillRect(x + padding, itemY - swatchSize / 2, swatchSize, swatchSize);\n\n // Label\n ctx.fillStyle = legend.textColor;\n ctx.fillText(s.getId(), x + padding + swatchSize + 8 * dpr, itemY);\n });\n\n ctx.restore();\n }\n\n public updateTheme(theme: ChartTheme): void {\n this.theme = theme;\n this.updateStyle();\n this.render();\n }\n\n public destroy(): void {\n this.container.remove();\n }\n}\n","/**\n * Chart - Main SciChart Engine orchestrator\n *\n * Coordinates WebGL rendering, overlay, interactions, and data management.\n * This is the public API for creating and controlling charts.\n */\n\nimport type {\n ChartOptions,\n AxisOptions,\n SeriesOptions,\n SeriesUpdateData,\n ZoomOptions,\n CursorOptions,\n ChartEventMap,\n Bounds,\n} from \"../types\";\nimport { EventEmitter } from \"./EventEmitter\";\nimport { Series } from \"./Series\";\nimport {\n NativeWebGLRenderer,\n interleaveData,\n parseColor,\n type NativeSeriesRenderData as SeriesRenderData,\n} from \"../renderer/NativeWebGLRenderer\";\nimport { LinearScale, LogScale, type Scale } from \"../scales\";\nimport { DEFAULT_THEME, getThemeByName, type ChartTheme } from \"../theme\";\nimport { OverlayRenderer, type CursorState } from \"./OverlayRenderer\";\nimport { InteractionManager } from \"./InteractionManager\";\nimport { ChartControls } from \"./ChartControls\";\nimport { ChartLegend } from \"./ChartLegend\";\n\n// ============================================\n// Layout Constants\n// ============================================\n\nconst MARGINS = { top: 20, right: 30, bottom: 55, left: 75 };\n\n// ============================================\n// Chart Interface\n// ============================================\n\nexport interface Chart {\n addSeries(options: SeriesOptions): void;\n removeSeries(id: string): void;\n updateSeries(id: string, data: SeriesUpdateData): void;\n getSeries(id: string): Series | undefined;\n getAllSeries(): Series[];\n zoom(options: ZoomOptions): void;\n pan(deltaX: number, deltaY: number): void;\n resetZoom(): void;\n getViewBounds(): Bounds;\n enableCursor(options: CursorOptions): void;\n disableCursor(): void;\n resize(width?: number, height?: number): void;\n render(): void;\n on<K extends keyof ChartEventMap>(\n event: K,\n handler: (data: ChartEventMap[K]) => void\n ): void;\n off<K extends keyof ChartEventMap>(\n event: K,\n handler: (data: ChartEventMap[K]) => void\n ): void;\n destroy(): void;\n exportImage(type?: \"png\" | \"jpeg\"): string;\n autoScale(): void;\n setTheme(theme: string | object): void;\n}\n\n// ============================================\n// Chart Implementation\n// ============================================\n\nclass ChartImpl implements Chart {\n private container: HTMLDivElement;\n private webglCanvas: HTMLCanvasElement;\n private overlayCanvas: HTMLCanvasElement;\n private overlayCtx: CanvasRenderingContext2D;\n\n private series: Map<string, Series> = new Map();\n private events = new EventEmitter<ChartEventMap>();\n private viewBounds: Bounds = {\n xMin: -0.5,\n xMax: 0.5,\n yMin: -1e-5,\n yMax: 1e-5,\n };\n\n private xAxisOptions: AxisOptions;\n private yAxisOptions: AxisOptions;\n private dpr: number;\n private backgroundColor: [number, number, number, number];\n\n private renderer: NativeWebGLRenderer;\n private overlay: OverlayRenderer;\n private interaction: InteractionManager;\n private xScale: Scale;\n private yScale: Scale;\n private theme: ChartTheme;\n\n private cursorOptions: CursorOptions | null = null;\n private cursorPosition: { x: number; y: number } | null = null;\n private showLegend: boolean;\n private legend: ChartLegend | null = null;\n private showControls: boolean;\n private controls: ChartControls | null = null;\n private animationFrameId: number | null = null;\n private needsRender = false;\n private isDestroyed = false;\n private selectionRect: {\n x: number;\n y: number;\n width: number;\n height: number;\n } | null = null;\n\n constructor(options: ChartOptions) {\n const container = options.container;\n if (!container) throw new Error(\"[SciChart] Container element is required\");\n this.container = container;\n\n this.dpr = options.devicePixelRatio ?? window.devicePixelRatio;\n\n // Initialize theme\n this.theme =\n typeof options.theme === \"string\"\n ? getThemeByName(options.theme)\n : (options.theme as ChartTheme) ?? DEFAULT_THEME;\n\n const bgColor = parseColor(\n options.background ?? this.theme.backgroundColor\n );\n this.backgroundColor = [bgColor[0], bgColor[1], bgColor[2], bgColor[3]];\n this.showLegend = options.showLegend ?? this.theme.legend.visible;\n this.showControls = options.showControls ?? false;\n\n this.xAxisOptions = { scale: \"linear\", auto: true, ...options.xAxis };\n this.yAxisOptions = { scale: \"linear\", auto: true, ...options.yAxis };\n this.xScale =\n this.xAxisOptions.scale === \"log\" ? new LogScale() : new LinearScale();\n this.yScale =\n this.yAxisOptions.scale === \"log\" ? new LogScale() : new LinearScale();\n\n // Create DOM structure\n this.container.style.position = \"relative\";\n this.container.style.overflow = \"hidden\";\n this.container.style.backgroundColor =\n options.background ?? this.theme.backgroundColor;\n\n this.webglCanvas = this.createCanvas(\"webgl\");\n this.overlayCanvas = this.createCanvas(\"overlay\");\n\n // Clear container before adding our canvases (especially for React)\n while (this.container.firstChild) {\n this.container.removeChild(this.container.firstChild);\n }\n\n this.container.appendChild(this.webglCanvas);\n this.container.appendChild(this.overlayCanvas);\n\n const ctx = this.overlayCanvas.getContext(\"2d\");\n if (!ctx) throw new Error(\"Failed to get 2D context\");\n this.overlayCtx = ctx;\n\n // Initialize subsystems\n this.renderer = new NativeWebGLRenderer(this.webglCanvas);\n this.overlay = new OverlayRenderer(this.overlayCtx, this.theme);\n this.interaction = new InteractionManager(\n this.container,\n {\n onZoom: (b) => this.zoom({ x: [b.xMin, b.xMax], y: [b.yMin, b.yMax] }),\n onPan: (dx, dy) => this.pan(dx, dy),\n onBoxZoom: (rect) => this.handleBoxZoom(rect),\n onCursorMove: (x, y) => {\n this.cursorPosition = { x, y };\n this.requestRender();\n },\n onCursorLeave: () => {\n this.cursorPosition = null;\n this.requestRender();\n },\n },\n () => this.getPlotArea(),\n () => this.viewBounds\n );\n\n // Setup resize observer\n new ResizeObserver(() => !this.isDestroyed && this.resize()).observe(\n this.container\n );\n\n // Initialize controls if enabled\n if (this.showControls) {\n this.controls = new ChartControls(this.container, this.theme, {\n onResetZoom: () => this.resetZoom(),\n onSetType: (type) => {\n this.series.forEach((s) => s.setType(type));\n this.requestRender();\n },\n onToggleSmoothing: () => {\n this.series.forEach((s) => {\n const style = s.getStyle();\n s.setStyle({ smoothing: (style.smoothing || 0) === 0 ? 0.5 : 0 });\n });\n this.requestRender();\n },\n onTogglePan: (active: boolean) => {\n this.interaction.setPanMode(active);\n },\n onExport: () => {\n const dataUrl = this.exportImage();\n const link = document.createElement(\"a\");\n link.download = `scichart-export-${Date.now()}.png`;\n link.href = dataUrl;\n link.click();\n },\n onAutoScale: () => {\n this.autoScale();\n this.requestRender();\n this.events.emit(\"autoScale\", undefined);\n },\n });\n }\n\n // Initialize legend if enabled\n if (this.showLegend) {\n this.legend = new ChartLegend(\n this.container,\n this.theme,\n options.legendPosition || {},\n {\n onMove: (x, y) => this.events.emit(\"legendMove\", { x, y }),\n }\n );\n this.legend.update(this.getAllSeries());\n }\n\n this.resize();\n this.startRenderLoop();\n\n // Safety resize after a short delay to handle cases where the container\n // might not have been fully sized during construction (e.g. in some frameworks)\n setTimeout(() => !this.isDestroyed && this.resize(), 100);\n\n console.log(\"[SciChart] Initialized\", {\n dpr: this.dpr,\n theme: this.theme.name,\n });\n }\n\n public setTheme(theme: string | ChartTheme): void {\n if (this.isDestroyed) return;\n\n this.theme =\n typeof theme === \"string\"\n ? getThemeByName(theme)\n : (theme as ChartTheme) ?? DEFAULT_THEME;\n\n const bgColor = parseColor(this.theme.backgroundColor);\n this.backgroundColor = [bgColor[0], bgColor[1], bgColor[2], bgColor[3]];\n this.container.style.backgroundColor = this.theme.backgroundColor;\n\n this.overlay.setTheme(this.theme);\n\n if (this.controls) {\n this.controls.updateTheme(this.theme);\n }\n\n if (this.legend) {\n this.legend.updateTheme(this.theme);\n }\n\n // Explicitly update WebGL renderer state if needed\n // The background color is passed during each render() call, so it's already covered.\n\n this.resize();\n this.requestRender();\n\n // Safety second render to ensure everything is flushed\n setTimeout(() => {\n if (!this.isDestroyed) {\n this.resize();\n this.render();\n }\n }, 50);\n }\n\n // ----------------------------------------\n // DOM Setup\n // ----------------------------------------\n\n private createCanvas(type: \"webgl\" | \"overlay\"): HTMLCanvasElement {\n const c = document.createElement(\"canvas\");\n c.style.cssText =\n type === \"webgl\"\n ? `position:absolute;top:${MARGINS.top}px;left:${\n MARGINS.left\n }px;width:calc(100% - ${\n MARGINS.left + MARGINS.right\n }px);height:calc(100% - ${MARGINS.top + MARGINS.bottom}px)`\n : `position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none`;\n return c;\n }\n\n private getPlotArea() {\n const rect = this.container.getBoundingClientRect();\n const width = Math.max(10, rect.width - MARGINS.left - MARGINS.right);\n const height = Math.max(10, rect.height - MARGINS.top - MARGINS.bottom);\n return {\n x: MARGINS.left,\n y: MARGINS.top,\n width,\n height,\n };\n }\n\n exportImage(type: \"png\" | \"jpeg\" = \"png\"): string {\n const finalCanvas = document.createElement(\"canvas\");\n finalCanvas.width = this.overlayCanvas.width;\n finalCanvas.height = this.overlayCanvas.height;\n const ctx = finalCanvas.getContext(\"2d\");\n if (!ctx) return \"\";\n\n // 1. Fill background\n const bg = this.backgroundColor;\n ctx.fillStyle = `rgba(${Math.round(bg[0] * 255)}, ${Math.round(\n bg[1] * 255\n )}, ${Math.round(bg[2] * 255)}, ${bg[3]})`;\n ctx.fillRect(0, 0, finalCanvas.width, finalCanvas.height);\n\n // 2. Draw WebGL plot area\n const plotX = MARGINS.left * this.dpr;\n const plotY = MARGINS.top * this.dpr;\n ctx.drawImage(this.webglCanvas, plotX, plotY);\n\n // 3. Draw Overlay (Axes, Grid, Labels)\n ctx.drawImage(this.overlayCanvas, 0, 0);\n\n // 4. Draw Legend (if exists and visible)\n if (this.legend && this.showLegend) {\n this.legend.draw(ctx, this.dpr);\n }\n\n return finalCanvas.toDataURL(`image/${type}`);\n }\n\n // ----------------------------------------\n // Series Management\n // ----------------------------------------\n\n addSeries(options: SeriesOptions): void {\n if (this.series.has(options.id)) this.removeSeries(options.id);\n const s = new Series(options);\n this.series.set(options.id, s);\n this.updateSeriesBuffer(s);\n if (this.xAxisOptions.auto || this.yAxisOptions.auto) this.autoScale();\n if (this.legend) this.legend.update(this.getAllSeries());\n this.requestRender();\n }\n\n removeSeries(id: string): void {\n const s = this.series.get(id);\n if (s) {\n this.renderer.deleteBuffer(id);\n s.destroy();\n this.series.delete(id);\n if (this.legend) this.legend.update(this.getAllSeries());\n this.requestRender();\n }\n }\n\n updateSeries(id: string, data: SeriesUpdateData): void {\n const s = this.series.get(id);\n if (!s) return;\n s.updateData(data);\n this.updateSeriesBuffer(s);\n if (this.xAxisOptions.auto || this.yAxisOptions.auto) {\n this.autoScale();\n }\n this.requestRender();\n }\n\n private updateSeriesBuffer(s: Series): void {\n const d = s.getData();\n if (!d || d.x.length === 0) return;\n this.renderer.createBuffer(s.getId(), interleaveData(d.x, d.y));\n }\n\n getSeries(id: string): Series | undefined {\n return this.series.get(id);\n }\n getAllSeries(): Series[] {\n return Array.from(this.series.values());\n }\n\n // ----------------------------------------\n // View Management\n // ----------------------------------------\n\n zoom(options: ZoomOptions): void {\n if (options.x) {\n this.viewBounds.xMin = options.x[0];\n this.viewBounds.xMax = options.x[1];\n }\n if (options.y) {\n this.viewBounds.yMin = options.y[0];\n this.viewBounds.yMax = options.y[1];\n }\n this.events.emit(\"zoom\", {\n x: [this.viewBounds.xMin, this.viewBounds.xMax],\n y: [this.viewBounds.yMin, this.viewBounds.yMax],\n });\n this.requestRender();\n }\n\n pan(deltaX: number, deltaY: number): void {\n const pa = this.getPlotArea();\n const dx =\n (deltaX / pa.width) * (this.viewBounds.xMax - this.viewBounds.xMin);\n const dy =\n (deltaY / pa.height) * (this.viewBounds.yMax - this.viewBounds.yMin);\n this.viewBounds.xMin -= dx;\n this.viewBounds.xMax -= dx;\n this.viewBounds.yMin += dy;\n this.viewBounds.yMax += dy;\n this.events.emit(\"pan\", { deltaX: dx, deltaY: dy });\n this.requestRender();\n }\n\n resetZoom(): void {\n this.autoScale();\n this.events.emit(\"zoom\", {\n x: [this.viewBounds.xMin, this.viewBounds.xMax],\n y: [this.viewBounds.yMin, this.viewBounds.yMax],\n });\n this.requestRender();\n }\n\n getViewBounds(): Bounds {\n return { ...this.viewBounds };\n }\n\n public autoScale(): void {\n if (this.series.size === 0) return;\n\n let xMin = Infinity,\n xMax = -Infinity,\n yMin = Infinity,\n yMax = -Infinity;\n let hasValidData = false;\n\n this.series.forEach((s) => {\n const b = s.getBounds();\n if (\n b &&\n isFinite(b.xMin) &&\n isFinite(b.xMax) &&\n isFinite(b.yMin) &&\n isFinite(b.yMax)\n ) {\n xMin = Math.min(xMin, b.xMin);\n xMax = Math.max(xMax, b.xMax);\n yMin = Math.min(yMin, b.yMin);\n yMax = Math.max(yMax, b.yMax);\n hasValidData = true;\n }\n });\n\n if (!hasValidData) {\n console.warn(\"[SciChart] No valid data bounds found for autoScale\");\n return;\n }\n\n // Add 5% padding\n let xRange = xMax - xMin;\n let yRange = yMax - yMin;\n\n // Fallback for zero range (single point or identical points)\n if (xRange <= 0 || !isFinite(xRange)) xRange = Math.abs(xMin) * 0.1 || 1;\n if (yRange <= 0 || !isFinite(yRange)) yRange = Math.abs(yMin) * 0.1 || 1;\n\n // Ensure we don't have extreme values that could break rendering\n const MAX_VALUE = 1e15;\n const MIN_VALUE = -1e15;\n\n xMin = Math.max(MIN_VALUE, Math.min(MAX_VALUE, xMin));\n xMax = Math.max(MIN_VALUE, Math.min(MAX_VALUE, xMax));\n yMin = Math.max(MIN_VALUE, Math.min(MAX_VALUE, yMin));\n yMax = Math.max(MIN_VALUE, Math.min(MAX_VALUE, yMax));\n\n const xPad = Math.min(xRange * 0.05, 1e10);\n const yPad = Math.min(yRange * 0.05, 1e10);\n\n const newBounds = {\n xMin: Math.max(MIN_VALUE, xMin - xPad),\n xMax: Math.min(MAX_VALUE, xMax + xPad),\n yMin: Math.max(MIN_VALUE, yMin - yPad),\n yMax: Math.min(MAX_VALUE, yMax + yPad),\n };\n\n if (this.xAxisOptions.auto) {\n this.viewBounds.xMin = newBounds.xMin;\n this.viewBounds.xMax = newBounds.xMax;\n }\n if (this.yAxisOptions.auto) {\n this.viewBounds.yMin = newBounds.yMin;\n this.viewBounds.yMax = newBounds.yMax;\n }\n\n this.requestRender();\n }\n\n // ----------------------------------------\n // Cursor\n // ----------------------------------------\n\n enableCursor(options: CursorOptions): void {\n this.cursorOptions = { enabled: true, ...options };\n }\n disableCursor(): void {\n this.cursorOptions = null;\n this.cursorPosition = null;\n }\n\n // ----------------------------------------\n // Rendering\n // ----------------------------------------\n\n resize(): void {\n const rect = this.container.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) return;\n\n this.overlayCanvas.width = rect.width * this.dpr;\n this.overlayCanvas.height = rect.height * this.dpr;\n\n // Reset transform before scaling to avoid cumulative effects\n this.overlayCtx.setTransform(1, 0, 0, 1, 0, 0);\n this.overlayCtx.scale(this.dpr, this.dpr);\n\n this.renderer.resize();\n this.events.emit(\"resize\", { width: rect.width, height: rect.height });\n this.requestRender();\n }\n\n private requestRender(): void {\n this.needsRender = true;\n }\n\n render(): void {\n if (this.isDestroyed) return;\n const start = performance.now();\n\n this.xScale.setDomain(this.viewBounds.xMin, this.viewBounds.xMax);\n this.yScale.setDomain(this.viewBounds.yMin, this.viewBounds.yMax);\n\n // WebGL render\n const seriesData: SeriesRenderData[] = [];\n const plotArea = this.getPlotArea();\n\n if (this.webglCanvas.width === 0 || this.webglCanvas.height === 0) {\n console.warn(\"[SciChart] Canvas has zero size, skipping render\");\n return;\n }\n\n // Update scales with current range\n this.xScale.setRange(plotArea.x, plotArea.x + plotArea.width);\n this.yScale.setRange(plotArea.y + plotArea.height, plotArea.y); // Y is inverted in pixels\n\n this.series.forEach((s) => {\n if (s.needsBufferUpdate) {\n this.updateSeriesBuffer(s);\n s.needsBufferUpdate = false;\n }\n\n const buf = this.renderer.getBuffer(s.getId());\n if (buf)\n seriesData.push({\n id: s.getId(),\n buffer: buf,\n count: s.getPointCount(),\n style: s.getStyle(),\n visible: s.isVisible(),\n type: s.getType(),\n });\n });\n\n if (seriesData.length === 0 && this.series.size > 0) {\n console.warn(\n \"[SciChart] No series data to render despite having series\",\n {\n count: this.series.size,\n rendererAvailable: this.renderer.available,\n }\n );\n }\n\n this.renderer.render(seriesData, {\n bounds: this.viewBounds,\n backgroundColor: this.backgroundColor,\n });\n\n // Overlay render\n const rect = this.container.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) {\n console.warn(\n \"[SciChart] Container has zero size in render, skipping overlay\"\n );\n return;\n }\n\n this.overlay.clear(rect.width, rect.height);\n this.overlay.drawGrid(plotArea, this.xScale, this.yScale);\n this.overlay.drawXAxis(plotArea, this.xScale, this.xAxisOptions.label);\n this.overlay.drawYAxis(plotArea, this.yScale, this.yAxisOptions.label);\n this.overlay.drawPlotBorder(plotArea);\n\n // Draw Selection Box\n if (this.selectionRect) {\n this.overlay.drawSelectionRect(this.selectionRect);\n }\n\n // Legend is now handled by ChartLegend component (HTML)\n\n if (this.cursorOptions?.enabled && this.cursorPosition) {\n const cursor: CursorState = {\n enabled: true,\n x: this.cursorPosition.x,\n y: this.cursorPosition.y,\n crosshair: this.cursorOptions.crosshair ?? false,\n tooltipText: this.cursorOptions.formatter\n ? this.cursorOptions.formatter(\n this.pixelToDataX(this.cursorPosition.x),\n this.pixelToDataY(this.cursorPosition.y),\n \"\"\n )\n : `X: ${this.pixelToDataX(this.cursorPosition.x).toFixed(\n 3\n )}\\nY: ${this.pixelToDataY(this.cursorPosition.y).toExponential(\n 2\n )}`,\n };\n this.overlay.drawCursor(plotArea, cursor);\n }\n\n const frameTime = performance.now() - start;\n this.events.emit(\"render\", {\n fps: frameTime > 0 ? 1000 / frameTime : 999,\n frameTime,\n });\n }\n\n private pixelToDataX(px: number): number {\n const pa = this.getPlotArea();\n return (\n this.viewBounds.xMin +\n ((px - pa.x) / pa.width) * (this.viewBounds.xMax - this.viewBounds.xMin)\n );\n }\n\n private pixelToDataY(py: number): number {\n const pa = this.getPlotArea();\n return (\n this.viewBounds.yMin +\n (1 - (py - pa.y) / pa.height) *\n (this.viewBounds.yMax - this.viewBounds.yMin)\n );\n }\n\n private startRenderLoop(): void {\n const loop = () => {\n if (this.isDestroyed) return;\n if (this.needsRender) {\n this.render();\n this.needsRender = false;\n }\n this.animationFrameId = requestAnimationFrame(loop);\n };\n this.animationFrameId = requestAnimationFrame(loop);\n }\n\n // ----------------------------------------\n // Events & Cleanup\n // ----------------------------------------\n\n on<K extends keyof ChartEventMap>(\n e: K,\n h: (d: ChartEventMap[K]) => void\n ): void {\n this.events.on(e, h);\n }\n off<K extends keyof ChartEventMap>(\n e: K,\n h: (d: ChartEventMap[K]) => void\n ): void {\n this.events.off(e, h);\n }\n\n destroy(): void {\n this.isDestroyed = true;\n if (this.animationFrameId) cancelAnimationFrame(this.animationFrameId);\n this.interaction.destroy();\n this.series.forEach((s) => {\n this.renderer.deleteBuffer(s.getId());\n s.destroy();\n });\n this.series.clear();\n this.renderer.destroy();\n if (this.controls) this.controls.destroy();\n if (this.legend) this.legend.destroy();\n\n // Remove our canvases and UI elements, but NOT the container itself\n // as it belongs to the caller (e.g. React/Vue ref)\n while (this.container.firstChild) {\n this.container.removeChild(this.container.firstChild);\n }\n\n console.log(\"[SciChart] Destroyed\");\n }\n\n private handleBoxZoom(\n rect: { x: number; y: number; width: number; height: number } | null\n ): void {\n if (rect === null) {\n if (\n this.selectionRect &&\n this.selectionRect.width > 5 &&\n this.selectionRect.height > 5\n ) {\n const plotArea = this.getPlotArea();\n const bounds = this.viewBounds;\n\n const xMinNorm = (this.selectionRect.x - plotArea.x) / plotArea.width;\n const xMaxNorm =\n (this.selectionRect.x + this.selectionRect.width - plotArea.x) /\n plotArea.width;\n const yMaxNorm =\n 1 - (this.selectionRect.y - plotArea.y) / plotArea.height;\n const yMinNorm =\n 1 -\n (this.selectionRect.y + this.selectionRect.height - plotArea.y) /\n plotArea.height;\n\n const newXMin = bounds.xMin + xMinNorm * (bounds.xMax - bounds.xMin);\n const newXMax = bounds.xMin + xMaxNorm * (bounds.xMax - bounds.xMin);\n const newYMin = bounds.yMin + yMinNorm * (bounds.yMax - bounds.yMin);\n const newYMax = bounds.yMin + yMaxNorm * (bounds.yMax - bounds.yMin);\n\n this.zoom({\n x: [newXMin, newXMax],\n y: [newYMin, newYMax],\n });\n }\n this.selectionRect = null;\n } else {\n this.selectionRect = rect;\n }\n this.requestRender();\n }\n}\n\n// ============================================\n// Factory\n// ============================================\n\nexport function createChart(options: ChartOptions): Chart {\n return new ChartImpl(options);\n}\nexport { ChartOptions };\n","/**\n * WebGL Renderer Interface & Factory\n *\n * This module provides a common interface for WebGL rendering.\n * Currently optimized for NativeWebGLRenderer (zero dependencies).\n */\n\nimport type { Bounds, SeriesStyle } from '../types';\nimport { NativeWebGLRenderer } from './NativeWebGLRenderer';\n\n// ============================================\n// Common Types\n// ============================================\n\nexport interface SeriesRenderData {\n id: string;\n buffer: WebGLBuffer;\n count: number;\n style: SeriesStyle;\n visible: boolean;\n type: 'line' | 'scatter';\n}\n\nexport interface RenderOptions {\n bounds: Bounds;\n backgroundColor?: [number, number, number, number];\n}\n\n// ============================================\n// Renderer Interface\n// ============================================\n\n/**\n * Common interface for all WebGL renderer implementations\n */\nexport interface IWebGLRenderer {\n /** Check if WebGL is available and initialized */\n readonly available: boolean;\n\n /**\n * Create or update a GPU buffer with interleaved X,Y data\n * @param id - Unique buffer identifier\n * @param data - Interleaved Float32Array [x0, y0, x1, y1, ...]\n */\n createBuffer(id: string, data: Float32Array): void;\n\n /**\n * Get a buffer by ID\n */\n getBuffer(id: string): WebGLBuffer | undefined;\n\n /**\n * Delete a buffer and free GPU memory\n */\n deleteBuffer(id: string): void;\n\n /**\n * Render a frame with all visible series\n */\n render(series: SeriesRenderData[], options: RenderOptions): void;\n\n /**\n * Handle canvas resize\n */\n resize(): void;\n\n /**\n * Get WebGL capabilities/limits\n */\n getLimits(): Record<string, unknown>;\n\n /**\n * Cleanup and destroy all GPU resources\n */\n destroy(): void;\n}\n\n// ============================================\n// Factory Functions\n// ============================================\n\n/**\n * Create a WebGL renderer (Native WebGL)\n *\n * @param canvas - Target canvas element\n */\nexport function createRenderer(canvas: HTMLCanvasElement): IWebGLRenderer {\n return new NativeWebGLRenderer(canvas);\n}\n\n/**\n * Create a renderer synchronously (native only)\n */\nexport { NativeWebGLRenderer as createNativeRenderer } from './NativeWebGLRenderer';\n","/**\n * LTTB (Largest-Triangle-Three-Buckets) Downsampling Algorithm\n *\n * This algorithm downsamples time-series data while preserving visual features.\n * It's much better than naive sampling for preserving peaks and valleys.\n *\n * Reference: https://skemman.is/bitstream/1946/15343/3/SS_MSthesis.pdf\n */\n\nexport interface DownsampleResult {\n x: Float32Array;\n y: Float32Array;\n /** Original indices of selected points */\n indices: Uint32Array;\n}\n\n/**\n * Downsample data using LTTB algorithm\n *\n * @param x - X values (e.g., potential)\n * @param y - Y values (e.g., current)\n * @param targetPoints - Number of output points\n * @returns Downsampled data\n */\nexport function lttbDownsample(\n x: Float32Array | Float64Array,\n y: Float32Array | Float64Array,\n targetPoints: number\n): DownsampleResult {\n const length = x.length;\n\n // No need to downsample\n if (targetPoints >= length || targetPoints <= 2) {\n return {\n x: new Float32Array(x),\n y: new Float32Array(y),\n indices: new Uint32Array(Array.from({ length }, (_, i) => i)),\n };\n }\n\n const outX = new Float32Array(targetPoints);\n const outY = new Float32Array(targetPoints);\n const outIndices = new Uint32Array(targetPoints);\n\n // Always include first point\n outX[0] = x[0];\n outY[0] = y[0];\n outIndices[0] = 0;\n\n // Bucket size\n const bucketSize = (length - 2) / (targetPoints - 2);\n\n let a = 0; // Previous selected point index\n let outIdx = 1;\n\n for (let i = 0; i < targetPoints - 2; i++) {\n // Calculate bucket boundaries\n const bucketStart = Math.floor((i + 1) * bucketSize) + 1;\n const bucketEnd = Math.floor((i + 2) * bucketSize) + 1;\n\n // Calculate average point of next bucket\n const nextBucketStart = Math.min(bucketEnd, length - 1);\n const nextBucketEnd = Math.min(\n Math.floor((i + 3) * bucketSize) + 1,\n length\n );\n\n let avgX = 0;\n let avgY = 0;\n let avgCount = 0;\n\n for (let j = nextBucketStart; j < nextBucketEnd; j++) {\n avgX += x[j];\n avgY += y[j];\n avgCount++;\n }\n\n if (avgCount > 0) {\n avgX /= avgCount;\n avgY /= avgCount;\n }\n\n // Find point in current bucket with largest triangle area\n let maxArea = -1;\n let maxIndex = bucketStart;\n\n const aX = x[a];\n const aY = y[a];\n\n for (let j = bucketStart; j < bucketEnd && j < length; j++) {\n // Calculate triangle area (simplified: |x1(y2-y3) + x2(y3-y1) + x3(y1-y2)| / 2)\n const area = Math.abs(\n (aX - avgX) * (y[j] - aY) - (aX - x[j]) * (avgY - aY)\n );\n\n if (area > maxArea) {\n maxArea = area;\n maxIndex = j;\n }\n }\n\n // Store selected point\n outX[outIdx] = x[maxIndex];\n outY[outIdx] = y[maxIndex];\n outIndices[outIdx] = maxIndex;\n\n a = maxIndex;\n outIdx++;\n }\n\n // Always include last point\n outX[targetPoints - 1] = x[length - 1];\n outY[targetPoints - 1] = y[length - 1];\n outIndices[targetPoints - 1] = length - 1;\n\n return { x: outX, y: outY, indices: outIndices };\n}\n\n/**\n * Min-Max per bucket downsampling\n *\n * Simpler alternative to LTTB that preserves extremes in each bucket.\n * Uses 2 points per bucket (min and max), so output is ~2x target.\n */\nexport function minMaxDownsample(\n x: Float32Array | Float64Array,\n y: Float32Array | Float64Array,\n bucketCount: number\n): DownsampleResult {\n const length = x.length;\n\n if (bucketCount >= length / 2) {\n return {\n x: new Float32Array(x),\n y: new Float32Array(y),\n indices: new Uint32Array(Array.from({ length }, (_, i) => i)),\n };\n }\n\n const bucketSize = length / bucketCount;\n const outX: number[] = [];\n const outY: number[] = [];\n const outIndices: number[] = [];\n\n for (let b = 0; b < bucketCount; b++) {\n const start = Math.floor(b * bucketSize);\n const end = Math.floor((b + 1) * bucketSize);\n\n let minY = Infinity;\n let maxY = -Infinity;\n let minIdx = start;\n let maxIdx = start;\n\n for (let i = start; i < end && i < length; i++) {\n if (y[i] < minY) {\n minY = y[i];\n minIdx = i;\n }\n if (y[i] > maxY) {\n maxY = y[i];\n maxIdx = i;\n }\n }\n\n // Add points in order (min first if it comes before max)\n if (minIdx <= maxIdx) {\n outX.push(x[minIdx], x[maxIdx]);\n outY.push(y[minIdx], y[maxIdx]);\n outIndices.push(minIdx, maxIdx);\n } else {\n outX.push(x[maxIdx], x[minIdx]);\n outY.push(y[maxIdx], y[minIdx]);\n outIndices.push(maxIdx, minIdx);\n }\n }\n\n return {\n x: new Float32Array(outX),\n y: new Float32Array(outY),\n indices: new Uint32Array(outIndices),\n };\n}\n\n/**\n * Calculate optimal target points based on canvas width\n */\nexport function calculateTargetPoints(\n dataLength: number,\n canvasWidth: number,\n pointsPerPixel = 2\n): number {\n // Never draw more than pointsPerPixel per pixel\n const maxPoints = canvasWidth * pointsPerPixel;\n return Math.min(dataLength, maxPoints);\n}\n","/**\n * Data Analysis Utilities\n *\n * General-purpose utilities for scientific data formatting,\n * cycle detection, peak detection, and data validation.\n */\n\n// ============================================\n// Unit Prefixes\n// ============================================\n\ntype SIPrefix = 'p' | 'n' | 'µ' | 'm' | '' | 'k' | 'M' | 'G';\n\nexport interface PrefixInfo {\n symbol: SIPrefix;\n factor: number;\n}\n\nconst SI_PREFIXES: PrefixInfo[] = [\n { symbol: 'p', factor: 1e-12 },\n { symbol: 'n', factor: 1e-9 },\n { symbol: 'µ', factor: 1e-6 },\n { symbol: 'm', factor: 1e-3 },\n { symbol: '', factor: 1 },\n { symbol: 'k', factor: 1e3 },\n { symbol: 'M', factor: 1e6 },\n { symbol: 'G', factor: 1e9 },\n];\n\n/**\n * Find the best SI prefix for a value\n */\nexport function getBestPrefix(value: number): PrefixInfo {\n const absValue = Math.abs(value);\n\n if (absValue === 0) {\n return { symbol: '', factor: 1 };\n }\n\n // Find prefix where value becomes 1-999\n for (let i = SI_PREFIXES.length - 1; i >= 0; i--) {\n const prefix = SI_PREFIXES[i];\n const scaled = absValue / prefix.factor;\n if (scaled >= 1 && scaled < 1000) {\n return prefix;\n }\n }\n\n // Default to base unit\n return { symbol: '', factor: 1 };\n}\n\n/**\n * Format a value with automatic SI prefix\n *\n * @example\n * formatWithPrefix(0.000001, 'A') // \"1.00 µA\"\n * formatWithPrefix(0.5, 'V') // \"500 mV\"\n * formatWithPrefix(1500, 'm') // \"1.50 km\"\n */\nexport function formatWithPrefix(\n value: number,\n unit: string,\n decimals = 2\n): string {\n const prefix = getBestPrefix(value);\n const scaled = value / prefix.factor;\n return `${scaled.toFixed(decimals)} ${prefix.symbol}${unit}`;\n}\n\n/**\n * Format a numeric value with specified decimals\n * Automatically switches to scientific notation for very large/small values\n */\nexport function formatValue(value: number, decimals = 3): string {\n if (Math.abs(value) < 0.001 || Math.abs(value) >= 1e6) {\n return value.toExponential(decimals);\n }\n return value.toFixed(decimals);\n}\n\n/**\n * Format value in scientific notation\n */\nexport function formatScientific(value: number, decimals = 2): string {\n return value.toExponential(decimals);\n}\n\n// ============================================\n// Cycle Detection\n// ============================================\n\nexport interface CycleInfo {\n /** Cycle number (1-indexed) */\n number: number;\n /** Start index in data array */\n startIndex: number;\n /** End index in data array */\n endIndex: number;\n /** Direction at start: 1 = forward, -1 = reverse */\n direction: 1 | -1;\n}\n\n/**\n * Detect cycles in oscillating data\n *\n * A cycle is complete when the signal returns to its starting value\n * after going through both sweep directions. Useful for:\n * - Cyclic voltammetry data\n * - Periodic signals\n * - Oscillation analysis\n *\n * @param signal - The signal data (e.g., potential, position, etc.)\n * @param tolerance - How close to starting value to consider a cycle complete\n */\nexport function detectCycles(\n signal: Float32Array | Float64Array | number[],\n tolerance = 0.001\n): CycleInfo[] {\n const data = signal instanceof Array ? new Float32Array(signal) : signal;\n \n if (data.length < 3) return [];\n\n const cycles: CycleInfo[] = [];\n let cycleStart = 0;\n let cycleNumber = 1;\n\n // Determine initial direction\n let prevDirection = Math.sign(data[1] - data[0]);\n let directionChanges = 0;\n\n for (let i = 2; i < data.length; i++) {\n const direction = Math.sign(data[i] - data[i - 1]);\n\n // Skip if no movement\n if (direction === 0) continue;\n\n // Direction change detected\n if (direction !== prevDirection) {\n directionChanges++;\n\n // After 2 direction changes, check if we're back at start\n if (directionChanges >= 2) {\n const startValue = data[cycleStart];\n const currentValue = data[i];\n\n if (Math.abs(currentValue - startValue) < tolerance) {\n cycles.push({\n number: cycleNumber,\n startIndex: cycleStart,\n endIndex: i,\n direction: data[cycleStart + 1] > data[cycleStart] ? 1 : -1,\n });\n\n cycleNumber++;\n cycleStart = i;\n directionChanges = 0;\n }\n }\n\n prevDirection = direction;\n }\n }\n\n // Handle last incomplete cycle\n if (cycleStart < data.length - 1) {\n cycles.push({\n number: cycleNumber,\n startIndex: cycleStart,\n endIndex: data.length - 1,\n direction: data[cycleStart + 1] > data[cycleStart] ? 1 : -1,\n });\n }\n\n return cycles;\n}\n\n/**\n * Generate distinct colors for cycles/series\n *\n * Uses HSL color space to generate evenly distributed hues\n */\nexport function generateCycleColors(count: number): string[] {\n const colors: string[] = [];\n const hueStep = 360 / Math.max(count, 1);\n\n for (let i = 0; i < count; i++) {\n const hue = (i * hueStep) % 360;\n colors.push(`hsl(${hue}, 70%, 55%)`);\n }\n\n return colors;\n}\n\n// ============================================\n// Peak Detection\n// ============================================\n\nexport interface Peak {\n /** Index in data array */\n index: number;\n /** X value at peak */\n x: number;\n /** Y value at peak */\n y: number;\n /** Peak type */\n type: 'max' | 'min';\n /** Prominence of the peak */\n prominence: number;\n}\n\n/**\n * Detect peaks (local maxima and minima) in data\n *\n * Uses simple local extrema detection with optional prominence filtering.\n * Useful for:\n * - Signal peak detection\n * - Finding local maxima/minima\n * - Feature extraction\n *\n * @param x - X values (independent variable)\n * @param y - Y values (dependent variable)\n * @param options - Detection options\n */\nexport function detectPeaks(\n x: Float32Array | Float64Array | number[],\n y: Float32Array | Float64Array | number[],\n options: {\n /** Minimum prominence to be considered a peak */\n minProminence?: number;\n /** Only return 'max' or 'min' peaks */\n type?: 'max' | 'min' | 'both';\n } = {}\n): Peak[] {\n const { minProminence = 0, type = 'both' } = options;\n const peaks: Peak[] = [];\n\n const xData = x instanceof Array ? new Float32Array(x) : x;\n const yData = y instanceof Array ? new Float32Array(y) : y;\n\n for (let i = 1; i < yData.length - 1; i++) {\n const prev = yData[i - 1];\n const curr = yData[i];\n const next = yData[i + 1];\n\n // Local maximum\n if (curr > prev && curr > next) {\n const prominence = Math.min(curr - prev, curr - next);\n if (prominence >= minProminence && (type === 'both' || type === 'max')) {\n peaks.push({ index: i, x: xData[i], y: curr, type: 'max', prominence });\n }\n }\n\n // Local minimum\n if (curr < prev && curr < next) {\n const prominence = Math.min(prev - curr, next - curr);\n if (prominence >= minProminence && (type === 'both' || type === 'min')) {\n peaks.push({ index: i, x: xData[i], y: curr, type: 'min', prominence });\n }\n }\n }\n\n return peaks;\n}\n\n// ============================================\n// Data Validation\n// ============================================\n\nexport interface ValidationResult {\n /** Whether all data is valid */\n valid: boolean;\n /** Number of invalid values (NaN, Infinity, etc.) */\n invalidCount: number;\n /** Index of first invalid value (-1 if all valid) */\n firstInvalidIndex: number;\n}\n\n/**\n * Validate that data contains only finite numbers\n *\n * Checks for NaN, Infinity, and -Infinity values.\n * Useful for data quality checks before rendering.\n */\nexport function validateData(\n data: Float32Array | Float64Array | number[]\n): ValidationResult {\n let invalidCount = 0;\n let firstInvalidIndex = -1;\n\n const arr = data instanceof Array ? data : Array.from(data);\n\n for (let i = 0; i < arr.length; i++) {\n if (!isFinite(arr[i])) {\n invalidCount++;\n if (firstInvalidIndex === -1) {\n firstInvalidIndex = i;\n }\n }\n }\n\n return {\n valid: invalidCount === 0,\n invalidCount,\n firstInvalidIndex,\n };\n}\n\n// ============================================\n// Data Statistics\n// ============================================\n\nexport interface DataStats {\n min: number;\n max: number;\n mean: number;\n stdDev: number;\n count: number;\n}\n\n/**\n * Calculate basic statistics for a dataset\n */\nexport function calculateStats(\n data: Float32Array | Float64Array | number[]\n): DataStats {\n const arr = data instanceof Array ? data : Array.from(data);\n const count = arr.length;\n\n if (count === 0) {\n return { min: 0, max: 0, mean: 0, stdDev: 0, count: 0 };\n }\n\n let min = arr[0];\n let max = arr[0];\n let sum = 0;\n\n for (let i = 0; i < count; i++) {\n const val = arr[i];\n if (val < min) min = val;\n if (val > max) max = val;\n sum += val;\n }\n\n const mean = sum / count;\n\n // Calculate standard deviation\n let sumSquaredDiff = 0;\n for (let i = 0; i < count; i++) {\n const diff = arr[i] - mean;\n sumSquaredDiff += diff * diff;\n }\n const stdDev = Math.sqrt(sumSquaredDiff / count);\n\n return { min, max, mean, stdDev, count };\n}\n\n// ============================================\n// Data Smoothing\n// ============================================\n\n/**\n * Apply moving average smoothing to data\n *\n * @param data - Input data array\n * @param windowSize - Number of points to average (must be odd)\n */\nexport function movingAverage(\n data: Float32Array | Float64Array | number[],\n windowSize: number\n): Float32Array {\n const arr = data instanceof Array ? new Float32Array(data) : data;\n const result = new Float32Array(arr.length);\n const halfWindow = Math.floor(windowSize / 2);\n\n for (let i = 0; i < arr.length; i++) {\n let sum = 0;\n let count = 0;\n\n for (let j = Math.max(0, i - halfWindow); j <= Math.min(arr.length - 1, i + halfWindow); j++) {\n sum += arr[j];\n count++;\n }\n\n result[i] = sum / count;\n }\n\n return result;\n}\n\n/**\n * Downsample data using LTTB (Largest Triangle Three Buckets) algorithm\n *\n * Preserves visual characteristics while reducing point count.\n * Ideal for rendering large datasets efficiently.\n *\n * @param x - X values\n * @param y - Y values\n * @param targetPoints - Desired number of output points\n */\nexport function downsampleLTTB(\n x: Float32Array | Float64Array,\n y: Float32Array | Float64Array,\n targetPoints: number\n): { x: Float32Array; y: Float32Array } {\n const dataLength = x.length;\n\n if (targetPoints >= dataLength || targetPoints < 3) {\n return { x: new Float32Array(x), y: new Float32Array(y) };\n }\n\n const sampledX = new Float32Array(targetPoints);\n const sampledY = new Float32Array(targetPoints);\n\n // Always include first point\n sampledX[0] = x[0];\n sampledY[0] = y[0];\n\n const bucketSize = (dataLength - 2) / (targetPoints - 2);\n\n let a = 0; // Previous selected point index\n let sampledIndex = 1;\n\n for (let i = 0; i < targetPoints - 2; i++) {\n // Calculate bucket range\n const bucketStart = Math.floor((i + 1) * bucketSize) + 1;\n const bucketEnd = Math.floor((i + 2) * bucketSize) + 1;\n const nextBucketEnd = Math.min(Math.floor((i + 3) * bucketSize) + 1, dataLength);\n\n // Calculate average of next bucket for comparison\n let avgX = 0;\n let avgY = 0;\n let avgCount = 0;\n\n for (let j = bucketEnd; j < nextBucketEnd; j++) {\n avgX += x[j];\n avgY += y[j];\n avgCount++;\n }\n\n if (avgCount > 0) {\n avgX /= avgCount;\n avgY /= avgCount;\n }\n\n // Find point in current bucket with largest triangle area\n let maxArea = -1;\n let maxAreaIndex = bucketStart;\n\n for (let j = bucketStart; j < bucketEnd && j < dataLength; j++) {\n // Triangle area calculation\n const area = Math.abs(\n (x[a] - avgX) * (y[j] - y[a]) - (x[a] - x[j]) * (avgY - y[a])\n );\n\n if (area > maxArea) {\n maxArea = area;\n maxAreaIndex = j;\n }\n }\n\n sampledX[sampledIndex] = x[maxAreaIndex];\n sampledY[sampledIndex] = y[maxAreaIndex];\n sampledIndex++;\n a = maxAreaIndex;\n }\n\n // Always include last point\n sampledX[targetPoints - 1] = x[dataLength - 1];\n sampledY[targetPoints - 1] = y[dataLength - 1];\n\n return { x: sampledX, y: sampledY };\n}\n","/**\n * @license React\n * react-jsx-runtime.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nvar REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\");\nfunction jsxProd(type, config, maybeKey) {\n var key = null;\n void 0 !== maybeKey && (key = \"\" + maybeKey);\n void 0 !== config.key && (key = \"\" + config.key);\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n config = maybeKey.ref;\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n ref: void 0 !== config ? config : null,\n props: maybeKey\n };\n}\nexports.Fragment = REACT_FRAGMENT_TYPE;\nexports.jsx = jsxProd;\nexports.jsxs = jsxProd;\n","/**\n * @license React\n * react-jsx-runtime.development.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\n\"production\" !== process.env.NODE_ENV &&\n (function () {\n function getComponentNameFromType(type) {\n if (null == type) return null;\n if (\"function\" === typeof type)\n return type.$$typeof === REACT_CLIENT_REFERENCE\n ? null\n : type.displayName || type.name || null;\n if (\"string\" === typeof type) return type;\n switch (type) {\n case REACT_FRAGMENT_TYPE:\n return \"Fragment\";\n case REACT_PROFILER_TYPE:\n return \"Profiler\";\n case REACT_STRICT_MODE_TYPE:\n return \"StrictMode\";\n case REACT_SUSPENSE_TYPE:\n return \"Suspense\";\n case REACT_SUSPENSE_LIST_TYPE:\n return \"SuspenseList\";\n case REACT_ACTIVITY_TYPE:\n return \"Activity\";\n }\n if (\"object\" === typeof type)\n switch (\n (\"number\" === typeof type.tag &&\n console.error(\n \"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.\"\n ),\n type.$$typeof)\n ) {\n case REACT_PORTAL_TYPE:\n return \"Portal\";\n case REACT_CONTEXT_TYPE:\n return type.displayName || \"Context\";\n case REACT_CONSUMER_TYPE:\n return (type._context.displayName || \"Context\") + \".Consumer\";\n case REACT_FORWARD_REF_TYPE:\n var innerType = type.render;\n type = type.displayName;\n type ||\n ((type = innerType.displayName || innerType.name || \"\"),\n (type = \"\" !== type ? \"ForwardRef(\" + type + \")\" : \"ForwardRef\"));\n return type;\n case REACT_MEMO_TYPE:\n return (\n (innerType = type.displayName || null),\n null !== innerType\n ? innerType\n : getComponentNameFromType(type.type) || \"Memo\"\n );\n case REACT_LAZY_TYPE:\n innerType = type._payload;\n type = type._init;\n try {\n return getComponentNameFromType(type(innerType));\n } catch (x) {}\n }\n return null;\n }\n function testStringCoercion(value) {\n return \"\" + value;\n }\n function checkKeyStringCoercion(value) {\n try {\n testStringCoercion(value);\n var JSCompiler_inline_result = !1;\n } catch (e) {\n JSCompiler_inline_result = !0;\n }\n if (JSCompiler_inline_result) {\n JSCompiler_inline_result = console;\n var JSCompiler_temp_const = JSCompiler_inline_result.error;\n var JSCompiler_inline_result$jscomp$0 =\n (\"function\" === typeof Symbol &&\n Symbol.toStringTag &&\n value[Symbol.toStringTag]) ||\n value.constructor.name ||\n \"Object\";\n JSCompiler_temp_const.call(\n JSCompiler_inline_result,\n \"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.\",\n JSCompiler_inline_result$jscomp$0\n );\n return testStringCoercion(value);\n }\n }\n function getTaskName(type) {\n if (type === REACT_FRAGMENT_TYPE) return \"<>\";\n if (\n \"object\" === typeof type &&\n null !== type &&\n type.$$typeof === REACT_LAZY_TYPE\n )\n return \"<...>\";\n try {\n var name = getComponentNameFromType(type);\n return name ? \"<\" + name + \">\" : \"<...>\";\n } catch (x) {\n return \"<...>\";\n }\n }\n function getOwner() {\n var dispatcher = ReactSharedInternals.A;\n return null === dispatcher ? null : dispatcher.getOwner();\n }\n function UnknownOwner() {\n return Error(\"react-stack-top-frame\");\n }\n function hasValidKey(config) {\n if (hasOwnProperty.call(config, \"key\")) {\n var getter = Object.getOwnPropertyDescriptor(config, \"key\").get;\n if (getter && getter.isReactWarning) return !1;\n }\n return void 0 !== config.key;\n }\n function defineKeyPropWarningGetter(props, displayName) {\n function warnAboutAccessingKey() {\n specialPropKeyWarningShown ||\n ((specialPropKeyWarningShown = !0),\n console.error(\n \"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)\",\n displayName\n ));\n }\n warnAboutAccessingKey.isReactWarning = !0;\n Object.defineProperty(props, \"key\", {\n get: warnAboutAccessingKey,\n configurable: !0\n });\n }\n function elementRefGetterWithDeprecationWarning() {\n var componentName = getComponentNameFromType(this.type);\n didWarnAboutElementRef[componentName] ||\n ((didWarnAboutElementRef[componentName] = !0),\n console.error(\n \"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.\"\n ));\n componentName = this.props.ref;\n return void 0 !== componentName ? componentName : null;\n }\n function ReactElement(type, key, props, owner, debugStack, debugTask) {\n var refProp = props.ref;\n type = {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n props: props,\n _owner: owner\n };\n null !== (void 0 !== refProp ? refProp : null)\n ? Object.defineProperty(type, \"ref\", {\n enumerable: !1,\n get: elementRefGetterWithDeprecationWarning\n })\n : Object.defineProperty(type, \"ref\", { enumerable: !1, value: null });\n type._store = {};\n Object.defineProperty(type._store, \"validated\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: 0\n });\n Object.defineProperty(type, \"_debugInfo\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: null\n });\n Object.defineProperty(type, \"_debugStack\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugStack\n });\n Object.defineProperty(type, \"_debugTask\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugTask\n });\n Object.freeze && (Object.freeze(type.props), Object.freeze(type));\n return type;\n }\n function jsxDEVImpl(\n type,\n config,\n maybeKey,\n isStaticChildren,\n debugStack,\n debugTask\n ) {\n var children = config.children;\n if (void 0 !== children)\n if (isStaticChildren)\n if (isArrayImpl(children)) {\n for (\n isStaticChildren = 0;\n isStaticChildren < children.length;\n isStaticChildren++\n )\n validateChildKeys(children[isStaticChildren]);\n Object.freeze && Object.freeze(children);\n } else\n console.error(\n \"React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.\"\n );\n else validateChildKeys(children);\n if (hasOwnProperty.call(config, \"key\")) {\n children = getComponentNameFromType(type);\n var keys = Object.keys(config).filter(function (k) {\n return \"key\" !== k;\n });\n isStaticChildren =\n 0 < keys.length\n ? \"{key: someKey, \" + keys.join(\": ..., \") + \": ...}\"\n : \"{key: someKey}\";\n didWarnAboutKeySpread[children + isStaticChildren] ||\n ((keys =\n 0 < keys.length ? \"{\" + keys.join(\": ..., \") + \": ...}\" : \"{}\"),\n console.error(\n 'A props object containing a \"key\" prop is being spread into JSX:\\n let props = %s;\\n <%s {...props} />\\nReact keys must be passed directly to JSX without using spread:\\n let props = %s;\\n <%s key={someKey} {...props} />',\n isStaticChildren,\n children,\n keys,\n children\n ),\n (didWarnAboutKeySpread[children + isStaticChildren] = !0));\n }\n children = null;\n void 0 !== maybeKey &&\n (checkKeyStringCoercion(maybeKey), (children = \"\" + maybeKey));\n hasValidKey(config) &&\n (checkKeyStringCoercion(config.key), (children = \"\" + config.key));\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n children &&\n defineKeyPropWarningGetter(\n maybeKey,\n \"function\" === typeof type\n ? type.displayName || type.name || \"Unknown\"\n : type\n );\n return ReactElement(\n type,\n children,\n maybeKey,\n getOwner(),\n debugStack,\n debugTask\n );\n }\n function validateChildKeys(node) {\n isValidElement(node)\n ? node._store && (node._store.validated = 1)\n : \"object\" === typeof node &&\n null !== node &&\n node.$$typeof === REACT_LAZY_TYPE &&\n (\"fulfilled\" === node._payload.status\n ? isValidElement(node._payload.value) &&\n node._payload.value._store &&\n (node._payload.value._store.validated = 1)\n : node._store && (node._store.validated = 1));\n }\n function isValidElement(object) {\n return (\n \"object\" === typeof object &&\n null !== object &&\n object.$$typeof === REACT_ELEMENT_TYPE\n );\n }\n var React = require(\"react\"),\n REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_PORTAL_TYPE = Symbol.for(\"react.portal\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\"),\n REACT_STRICT_MODE_TYPE = Symbol.for(\"react.strict_mode\"),\n REACT_PROFILER_TYPE = Symbol.for(\"react.profiler\"),\n REACT_CONSUMER_TYPE = Symbol.for(\"react.consumer\"),\n REACT_CONTEXT_TYPE = Symbol.for(\"react.context\"),\n REACT_FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\"),\n REACT_SUSPENSE_TYPE = Symbol.for(\"react.suspense\"),\n REACT_SUSPENSE_LIST_TYPE = Symbol.for(\"react.suspense_list\"),\n REACT_MEMO_TYPE = Symbol.for(\"react.memo\"),\n REACT_LAZY_TYPE = Symbol.for(\"react.lazy\"),\n REACT_ACTIVITY_TYPE = Symbol.for(\"react.activity\"),\n REACT_CLIENT_REFERENCE = Symbol.for(\"react.client.reference\"),\n ReactSharedInternals =\n React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,\n hasOwnProperty = Object.prototype.hasOwnProperty,\n isArrayImpl = Array.isArray,\n createTask = console.createTask\n ? console.createTask\n : function () {\n return null;\n };\n React = {\n react_stack_bottom_frame: function (callStackForError) {\n return callStackForError();\n }\n };\n var specialPropKeyWarningShown;\n var didWarnAboutElementRef = {};\n var unknownOwnerDebugStack = React.react_stack_bottom_frame.bind(\n React,\n UnknownOwner\n )();\n var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));\n var didWarnAboutKeySpread = {};\n exports.Fragment = REACT_FRAGMENT_TYPE;\n exports.jsx = function (type, config, maybeKey) {\n var trackActualOwner =\n 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;\n return jsxDEVImpl(\n type,\n config,\n maybeKey,\n !1,\n trackActualOwner\n ? Error(\"react-stack-top-frame\")\n : unknownOwnerDebugStack,\n trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask\n );\n };\n exports.jsxs = function (type, config, maybeKey) {\n var trackActualOwner =\n 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;\n return jsxDEVImpl(\n type,\n config,\n maybeKey,\n !0,\n trackActualOwner\n ? Error(\"react-stack-top-frame\")\n : unknownOwnerDebugStack,\n trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask\n );\n };\n })();\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-jsx-runtime.production.js');\n} else {\n module.exports = require('./cjs/react-jsx-runtime.development.js');\n}\n","/**\n * useSciChart - React hook for SciChart Engine\n *\n * Manages chart lifecycle and provides a clean React API.\n */\n\nimport {\n useEffect,\n useRef,\n useState,\n useCallback,\n type RefObject,\n} from \"react\";\nimport { createChart, type Chart, type ChartOptions } from \"../core/Chart\";\nimport type {\n SeriesOptions,\n SeriesUpdateData,\n ZoomOptions,\n Bounds,\n} from \"../types\";\n\nexport interface UseSciChartOptions extends Omit<ChartOptions, \"container\"> {\n /** Auto-resize on container changes */\n autoResize?: boolean;\n}\n\nexport interface UseSciChartReturn {\n /** Chart instance (null until initialized) */\n chart: Chart | null;\n /** Whether the chart is ready */\n isReady: boolean;\n /** Error during initialization */\n error: Error | null;\n /** Current view bounds */\n bounds: Bounds | null;\n /** Add a series */\n addSeries: (options: SeriesOptions) => void;\n /** Update series data */\n updateSeries: (id: string, data: SeriesUpdateData) => void;\n /** Remove a series */\n removeSeries: (id: string) => void;\n /** Set zoom range */\n zoom: (options: ZoomOptions) => void;\n /** Reset zoom to show all data */\n resetZoom: () => void;\n}\n\n/**\n * React hook for using SciChart Engine\n *\n * @example\n * ```tsx\n * function MyChart() {\n * const canvasRef = useRef<HTMLCanvasElement>(null);\n * const { chart, isReady, addSeries, zoom } = useSciChart(canvasRef, {\n * xAxis: { label: 'E / V' },\n * yAxis: { label: 'I / A' }\n * });\n *\n * useEffect(() => {\n * if (isReady) {\n * addSeries({\n * id: 'cv-1',\n * type: 'line',\n * data: { x: xData, y: yData },\n * style: { color: '#ff0055' }\n * });\n * }\n * }, [isReady]);\n *\n * return <canvas ref={canvasRef} />;\n * }\n * ```\n */\nexport function useSciChart(\n containerRef: RefObject<HTMLDivElement>,\n options: UseSciChartOptions = {}\n): UseSciChartReturn {\n const [chart, setChart] = useState<Chart | null>(null);\n const [isReady, setIsReady] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [bounds, setBounds] = useState<Bounds | null>(null);\n\n // Store options in ref to avoid re-creating chart on every render\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n // Initialize chart\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n try {\n const chartInstance = createChart({\n ...optionsRef.current,\n container,\n });\n\n // Listen to zoom events to update bounds\n chartInstance.on(\"zoom\", () => {\n setBounds(chartInstance.getViewBounds());\n });\n\n setChart(chartInstance);\n setIsReady(true);\n setBounds(chartInstance.getViewBounds());\n setError(null);\n\n console.log(\"[useSciChart] Chart initialized\");\n } catch (err) {\n console.error(\"[useSciChart] Failed to initialize chart:\", err);\n setError(err instanceof Error ? err : new Error(String(err)));\n setIsReady(false);\n }\n\n return () => {\n if (chart) {\n chart.destroy();\n setChart(null);\n setIsReady(false);\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [containerRef]);\n\n // Memoized methods\n const addSeries = useCallback(\n (seriesOptions: SeriesOptions) => {\n if (chart) {\n chart.addSeries(seriesOptions);\n setBounds(chart.getViewBounds());\n }\n },\n [chart]\n );\n\n const updateSeries = useCallback(\n (id: string, data: SeriesUpdateData) => {\n if (chart) {\n chart.updateSeries(id, data);\n }\n },\n [chart]\n );\n\n const removeSeries = useCallback(\n (id: string) => {\n if (chart) {\n chart.removeSeries(id);\n }\n },\n [chart]\n );\n\n const zoom = useCallback(\n (zoomOptions: ZoomOptions) => {\n if (chart) {\n chart.zoom(zoomOptions);\n }\n },\n [chart]\n );\n\n const resetZoom = useCallback(() => {\n if (chart) {\n chart.resetZoom();\n setBounds(chart.getViewBounds());\n }\n }, [chart]);\n\n return {\n chart,\n isReady,\n error,\n bounds,\n addSeries,\n updateSeries,\n removeSeries,\n zoom,\n resetZoom,\n };\n}\n","/**\n * SciChart - React Component for Scientific Charts\n *\n * A declarative React component that wraps the SciChart Engine.\n */\n\nimport {\n useRef,\n useEffect,\n useImperativeHandle,\n forwardRef,\n useMemo,\n type CSSProperties,\n} from \"react\";\nimport { useSciChart, type UseSciChartOptions } from \"./useSciChart\";\nimport type {\n SeriesOptions,\n ZoomOptions,\n CursorOptions,\n Bounds,\n} from \"../types\";\nimport type { Chart } from \"../core/Chart\";\n\n// ============================================\n// Types\n// ============================================\n\nexport interface SciChartSeries {\n id: string;\n x: Float32Array | Float64Array;\n y: Float32Array | Float64Array;\n color?: string;\n width?: number;\n visible?: boolean;\n}\n\nexport interface SciChartProps extends UseSciChartOptions {\n /** Series data to display */\n series?: SciChartSeries[];\n /** Zoom state (controlled) */\n zoom?: ZoomOptions;\n /** Callback when zoom changes */\n onZoomChange?: (bounds: Bounds) => void;\n /** Cursor configuration */\n cursor?: CursorOptions;\n /** Container width */\n width?: number | string;\n /** Container height */\n height?: number | string;\n /** Additional class name */\n className?: string;\n /** Additional styles */\n style?: CSSProperties;\n /** Debug mode - shows FPS counter */\n debug?: boolean;\n}\n\nexport interface SciChartRef {\n /** Get the chart instance */\n getChart: () => Chart | null;\n /** Reset zoom to show all data */\n resetZoom: () => void;\n /** Get current bounds */\n getBounds: () => Bounds | null;\n}\n\n// ============================================\n// Component\n// ============================================\n\n/**\n * SciChart React Component\n *\n * @example\n * ```tsx\n * <SciChart\n * series={[\n * { id: 'cv-1', x: potentialData, y: currentData, color: '#ff0055' }\n * ]}\n * xAxis={{ label: 'E / V' }}\n * yAxis={{ label: 'I / A' }}\n * height={400}\n * cursor={{ enabled: true, snap: true }}\n * onZoomChange={(bounds) => console.log('Zoom:', bounds)}\n * />\n * ```\n */\nexport const SciChart = forwardRef<SciChartRef, SciChartProps>(\n function SciChart(\n {\n series = [],\n zoom: zoomProp,\n onZoomChange,\n cursor,\n width = \"100%\",\n height = 400,\n className = \"\",\n style = {},\n debug = false,\n ...chartOptions\n },\n ref\n ) {\n const containerRef = useRef<HTMLDivElement>(null);\n const previousSeriesRef = useRef<Map<string, SciChartSeries>>(new Map());\n\n const {\n chart,\n isReady,\n bounds,\n addSeries,\n updateSeries,\n removeSeries,\n resetZoom,\n } = useSciChart(containerRef, chartOptions);\n\n // Expose methods via ref\n useImperativeHandle(\n ref,\n () => ({\n getChart: () => chart,\n resetZoom,\n getBounds: () => bounds,\n }),\n [chart, resetZoom, bounds]\n );\n\n // Handle series changes\n useEffect(() => {\n if (!isReady || !chart) return;\n\n const currentSeriesMap = new Map(series.map((s) => [s.id, s]));\n const previousSeriesMap = previousSeriesRef.current;\n\n // Remove series that no longer exist\n previousSeriesMap.forEach((_, id) => {\n if (!currentSeriesMap.has(id)) {\n removeSeries(id);\n }\n });\n\n // Add or update series\n currentSeriesMap.forEach((seriesData, id) => {\n const prevSeries = previousSeriesMap.get(id);\n\n if (!prevSeries) {\n // New series - add it\n const options: SeriesOptions = {\n id: seriesData.id,\n type: \"line\",\n data: { x: seriesData.x, y: seriesData.y },\n style: {\n color: seriesData.color ?? \"#ff0055\",\n width: seriesData.width ?? 1.5,\n },\n visible: seriesData.visible ?? true,\n };\n addSeries(options);\n // Force an initial autoscale if it's the first series\n if (currentSeriesMap.size === 1) {\n chart.autoScale();\n }\n } else if (\n prevSeries.x !== seriesData.x ||\n prevSeries.y !== seriesData.y\n ) {\n // Data changed - update\n updateSeries(id, {\n x: seriesData.x,\n y: seriesData.y,\n });\n }\n });\n\n previousSeriesRef.current = currentSeriesMap;\n }, [series, isReady, chart, addSeries, updateSeries, removeSeries]);\n\n // Handle controlled zoom\n useEffect(() => {\n if (!isReady || !chart || !zoomProp) return;\n chart.zoom(zoomProp);\n }, [isReady, chart, zoomProp]);\n\n // Handle zoom change callback\n useEffect(() => {\n if (!isReady || !chart || !onZoomChange) return;\n\n chart.on(\"zoom\", (event) => {\n onZoomChange({\n xMin: event.x[0],\n xMax: event.x[1],\n yMin: event.y[0],\n yMax: event.y[1],\n });\n });\n }, [isReady, chart, onZoomChange]);\n\n // Handle cursor\n useEffect(() => {\n if (!isReady || !chart) return;\n\n if (cursor?.enabled) {\n chart.enableCursor(cursor);\n } else {\n chart.disableCursor();\n }\n }, [isReady, chart, cursor]);\n\n // Container styles\n const containerStyle = useMemo<CSSProperties>(\n () => ({\n position: \"relative\",\n width: typeof width === \"number\" ? `${width}px` : width,\n height: typeof height === \"number\" ? `${height}px` : height,\n ...style,\n }),\n [width, height, style]\n );\n\n return (\n <div\n ref={containerRef}\n className={`scichart-container ${className}`}\n style={containerStyle}\n >\n {/* Debug overlay */}\n {debug && bounds && (\n <div\n style={{\n position: \"absolute\",\n top: 8,\n right: 8,\n background: \"rgba(0,0,0,0.7)\",\n color: \"#0f0\",\n padding: \"4px 8px\",\n borderRadius: 4,\n fontSize: 11,\n fontFamily: \"monospace\",\n }}\n >\n <div>\n X: [{bounds.xMin.toFixed(3)}, {bounds.xMax.toFixed(3)}]\n </div>\n <div>\n Y: [{bounds.yMin.toExponential(2)}, {bounds.yMax.toExponential(2)}\n ]\n </div>\n <div>Series: {series.length}</div>\n </div>\n )}\n </div>\n );\n }\n);\n\nexport default SciChart;\n"],"names":["EventEmitter","__publicField","event","handler","handlers","data","error","wrappedHandler","_a","DEFAULT_STYLE","ensureTypedArray","Series","options","_b","windowSize","x","y","len","smoothedY","halfWindow","i","sum","count","j","xMin","xMax","yMin","yMax","xVal","yVal","update","newX","newY","existing","newData","combined","style","oldSmoothing","val","visible","type","LINE_VERT","LINE_FRAG","POINT_VERT","POINT_FRAG","NativeWebGLRenderer","canvas","gl","source","shader","vertSource","fragSource","hasPointSize","vertShader","fragShader","program","positionAttr","scaleUniform","translateUniform","colorUniform","result","id","buffer","currentSize","bounds","dataWidth","dataHeight","scaleX","scaleY","translateX","translateY","series","backgroundColor","uniforms","s","color","parseColor","prog","pointSize","rect","width","height","hex","r","g","b","a","interleaveData","length","LinearScale","min","max","value","d0","d1","r0","r1","normalized","pixel","step","niceStep","start","ticks","maxTicks","t","LogScale","safeMin","safeMax","logMin","logMax","logVal","p","range","rawStep","magnitude","niceNormalized","createScale","DEFAULT_AXIS_THEME","DEFAULT_GRID_THEME","DEFAULT_LEGEND_THEME","DEFAULT_CURSOR_THEME","DARK_THEME","MIDNIGHT_THEME","LIGHT_THEME","ELECTROCHEM_THEME","createTheme","base","overrides","getThemeByName","name","DEFAULT_THEME","OverlayRenderer","ctx","theme","plotArea","xScale","yScale","grid","xTicks","yTicks","tick","minorXTicks","minorYTicks","label","axis","axisY","axisX","legend","maxWidth","items","boxWidth","boxHeight","item","itemY","cursor","cursorTheme","text","lines","lineHeight","padding","line","tooltipX","tooltipY","isDark","majorTicks","divisions","minor","absVal","precision","str","mantissa","exponent","superscriptMap","unicodeExp","char","InteractionManager","container","callbacks","getPlotArea","getBounds","enabled","mouseX","mouseY","zoomX","zoomY","zoomFactor","normalizedX","normalizedY","dataX","dataY","MIN_RANGE","MAX_RANGE","nextXMin","nextXMax","nextYMin","nextYMax","nextXRange","nextYRange","newBounds","deltaX","deltaY","touch","ICONS","ChartControls","parent","bg","borderColor","shadow","sep","types","nextIdx","sep2","btn","icon","svgEl","svg","title","onClick","buttons","activeColor","smoothActiveColor","normalColor","isHover","ChartLegend","rafId","onMouseDown","e","onMouseMove","onMouseUp","updatePosition","clientX","clientY","dx","dy","tx","ty","parentRect","finalX","finalY","swatch","dpr","itemGap","swatchSize","headerHeight","MARGINS","ChartImpl","bgColor","active","dataUrl","link","c","finalCanvas","plotX","plotY","d","pa","hasValidData","xRange","yRange","MAX_VALUE","MIN_VALUE","xPad","yPad","seriesData","buf","frameTime","px","py","loop","h","xMinNorm","xMaxNorm","yMaxNorm","yMinNorm","newXMin","newXMax","newYMin","newYMax","createChart","createRenderer","lttbDownsample","targetPoints","_","outX","outY","outIndices","bucketSize","outIdx","bucketStart","bucketEnd","nextBucketStart","nextBucketEnd","avgX","avgY","avgCount","maxArea","maxIndex","aX","aY","area","minMaxDownsample","bucketCount","end","minY","maxY","minIdx","maxIdx","calculateTargetPoints","dataLength","canvasWidth","pointsPerPixel","maxPoints","SI_PREFIXES","getBestPrefix","absValue","prefix","scaled","formatWithPrefix","unit","decimals","formatValue","formatScientific","detectCycles","signal","tolerance","cycles","cycleStart","cycleNumber","prevDirection","directionChanges","direction","startValue","currentValue","generateCycleColors","colors","hueStep","hue","detectPeaks","minProminence","peaks","xData","yData","prev","curr","next","prominence","validateData","invalidCount","firstInvalidIndex","arr","calculateStats","mean","sumSquaredDiff","diff","stdDev","movingAverage","downsampleLTTB","sampledX","sampledY","sampledIndex","maxAreaIndex","REACT_ELEMENT_TYPE","REACT_FRAGMENT_TYPE","jsxProd","config","maybeKey","key","propName","reactJsxRuntime_production","getComponentNameFromType","REACT_CLIENT_REFERENCE","REACT_PROFILER_TYPE","REACT_STRICT_MODE_TYPE","REACT_SUSPENSE_TYPE","REACT_SUSPENSE_LIST_TYPE","REACT_ACTIVITY_TYPE","REACT_PORTAL_TYPE","REACT_CONTEXT_TYPE","REACT_CONSUMER_TYPE","REACT_FORWARD_REF_TYPE","innerType","REACT_MEMO_TYPE","REACT_LAZY_TYPE","testStringCoercion","checkKeyStringCoercion","JSCompiler_inline_result","JSCompiler_temp_const","JSCompiler_inline_result$jscomp$0","getTaskName","getOwner","dispatcher","ReactSharedInternals","UnknownOwner","hasValidKey","hasOwnProperty","getter","defineKeyPropWarningGetter","props","displayName","warnAboutAccessingKey","specialPropKeyWarningShown","elementRefGetterWithDeprecationWarning","componentName","didWarnAboutElementRef","ReactElement","owner","debugStack","debugTask","refProp","jsxDEVImpl","isStaticChildren","children","isArrayImpl","validateChildKeys","keys","k","didWarnAboutKeySpread","node","isValidElement","object","React","require$$0","createTask","callStackForError","unknownOwnerDebugStack","unknownOwnerDebugTask","reactJsxRuntime_development","trackActualOwner","jsxRuntimeModule","require$$1","useSciChart","containerRef","chart","setChart","useState","isReady","setIsReady","setError","setBounds","optionsRef","useRef","useEffect","chartInstance","err","addSeries","useCallback","seriesOptions","updateSeries","removeSeries","zoom","zoomOptions","resetZoom","SciChart","forwardRef","zoomProp","onZoomChange","className","debug","chartOptions","ref","previousSeriesRef","useImperativeHandle","currentSeriesMap","previousSeriesMap","prevSeries","containerStyle","useMemo","jsx","jsxs"],"mappings":"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","x_google_ignoreList":[13,14,15]}