chartgpu 0.2.2 → 0.2.4
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.
- package/README.md +38 -11
- package/dist/ChartGPU.d.ts +23 -6
- package/dist/ChartGPU.d.ts.map +1 -1
- package/dist/config/OptionResolver.d.ts.map +1 -1
- package/dist/config/types.d.ts +26 -1
- package/dist/config/types.d.ts.map +1 -1
- package/dist/core/GPUContext.d.ts +2 -2
- package/dist/core/GPUContext.d.ts.map +1 -1
- package/dist/core/createRenderCoordinator.d.ts +3 -2
- package/dist/core/createRenderCoordinator.d.ts.map +1 -1
- package/dist/core/renderCoordinator/animation/animationHelpers.d.ts +183 -0
- package/dist/core/renderCoordinator/animation/animationHelpers.d.ts.map +1 -0
- package/dist/core/renderCoordinator/annotations/processAnnotations.d.ts +88 -0
- package/dist/core/renderCoordinator/annotations/processAnnotations.d.ts.map +1 -0
- package/dist/core/renderCoordinator/axis/axisLabelHelpers.d.ts +91 -0
- package/dist/core/renderCoordinator/axis/axisLabelHelpers.d.ts.map +1 -0
- package/dist/core/renderCoordinator/axis/computeAxisTicks.d.ts +53 -0
- package/dist/core/renderCoordinator/axis/computeAxisTicks.d.ts.map +1 -0
- package/dist/core/renderCoordinator/data/computeVisibleSlice.d.ts +66 -0
- package/dist/core/renderCoordinator/data/computeVisibleSlice.d.ts.map +1 -0
- package/dist/core/renderCoordinator/gpu/textureManager.d.ts +69 -0
- package/dist/core/renderCoordinator/gpu/textureManager.d.ts.map +1 -0
- package/dist/core/renderCoordinator/interaction/interactionHelpers.d.ts +160 -0
- package/dist/core/renderCoordinator/interaction/interactionHelpers.d.ts.map +1 -0
- package/dist/core/renderCoordinator/render/renderAnnotationLabels.d.ts +36 -0
- package/dist/core/renderCoordinator/render/renderAnnotationLabels.d.ts.map +1 -0
- package/dist/core/renderCoordinator/render/renderAxisLabels.d.ts +40 -0
- package/dist/core/renderCoordinator/render/renderAxisLabels.d.ts.map +1 -0
- package/dist/core/renderCoordinator/render/renderOverlays.d.ts +70 -0
- package/dist/core/renderCoordinator/render/renderOverlays.d.ts.map +1 -0
- package/dist/core/renderCoordinator/render/renderSeries.d.ts +146 -0
- package/dist/core/renderCoordinator/render/renderSeries.d.ts.map +1 -0
- package/dist/core/renderCoordinator/renderers/rendererPool.d.ts +112 -0
- package/dist/core/renderCoordinator/renderers/rendererPool.d.ts.map +1 -0
- package/dist/core/renderCoordinator/types.d.ts +19 -0
- package/dist/core/renderCoordinator/types.d.ts.map +1 -0
- package/dist/core/renderCoordinator/ui/tooltipLegendHelpers.d.ts +104 -0
- package/dist/core/renderCoordinator/ui/tooltipLegendHelpers.d.ts.map +1 -0
- package/dist/core/renderCoordinator/utils/axisUtils.d.ts +122 -0
- package/dist/core/renderCoordinator/utils/axisUtils.d.ts.map +1 -0
- package/dist/core/renderCoordinator/utils/boundsComputation.d.ts +69 -0
- package/dist/core/renderCoordinator/utils/boundsComputation.d.ts.map +1 -0
- package/dist/core/renderCoordinator/utils/canvasUtils.d.ts +52 -0
- package/dist/core/renderCoordinator/utils/canvasUtils.d.ts.map +1 -0
- package/dist/core/renderCoordinator/utils/dataPointUtils.d.ts +71 -0
- package/dist/core/renderCoordinator/utils/dataPointUtils.d.ts.map +1 -0
- package/dist/core/renderCoordinator/utils/index.d.ts +12 -0
- package/dist/core/renderCoordinator/utils/index.d.ts.map +1 -0
- package/dist/core/renderCoordinator/utils/timeAxisUtils.d.ts +149 -0
- package/dist/core/renderCoordinator/utils/timeAxisUtils.d.ts.map +1 -0
- package/dist/core/renderCoordinator/zoom/zoomHelpers.d.ts +129 -0
- package/dist/core/renderCoordinator/zoom/zoomHelpers.d.ts.map +1 -0
- package/dist/data/cartesianData.d.ts +67 -0
- package/dist/data/cartesianData.d.ts.map +1 -0
- package/dist/data/createDataStore.d.ts +4 -12
- package/dist/data/createDataStore.d.ts.map +1 -1
- package/dist/data/sampleSeries.d.ts +19 -2
- package/dist/data/sampleSeries.d.ts.map +1 -1
- package/dist/index.cjs +1270 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6068 -5643
- package/dist/index.js.map +1 -1
- package/dist/interaction/createAnnotationAuthoring.d.ts.map +1 -1
- package/dist/interaction/createAnnotationDragHandler.d.ts.map +1 -1
- package/dist/interaction/createAnnotationHitTester.d.ts.map +1 -1
- package/dist/interaction/createChartSync.d.ts +17 -2
- package/dist/interaction/createChartSync.d.ts.map +1 -1
- package/dist/interaction/findNearestPoint.d.ts.map +1 -1
- package/dist/interaction/findPointsAtX.d.ts.map +1 -1
- package/dist/renderers/createAreaRenderer.d.ts +2 -1
- package/dist/renderers/createAreaRenderer.d.ts.map +1 -1
- package/dist/renderers/createBarRenderer.d.ts.map +1 -1
- package/dist/renderers/createHighlightRenderer.d.ts +1 -1
- package/dist/renderers/createHighlightRenderer.d.ts.map +1 -1
- package/dist/renderers/createLineRenderer.d.ts.map +1 -1
- package/dist/renderers/createScatterRenderer.d.ts +2 -1
- package/dist/renderers/createScatterRenderer.d.ts.map +1 -1
- package/package.json +5 -3
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,1270 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function Ea(e){return typeof HTMLCanvasElement<"u"&&e instanceof HTMLCanvasElement}function Da(e){const t=e.clientWidth||e.width||0,n=e.clientHeight||e.height||0;if(!Number.isFinite(t)||!Number.isFinite(n))throw new Error(`GPUContext: Invalid canvas dimensions detected: width=${e.clientWidth||e.width}, height=${e.clientHeight||e.height}. Canvas must have finite dimensions. Ensure canvas is properly sized before initialization.`);return{width:t,height:n}}function eo(e,t){const n=(t==null?void 0:t.devicePixelRatio)??(typeof window<"u"?window.devicePixelRatio:1),i=Number.isFinite(n)&&n>0?n:1,r=(t==null?void 0:t.alphaMode)??"opaque",o=(t==null?void 0:t.powerPreference)??"high-performance";return{adapter:null,device:null,initialized:!1,canvas:e||null,canvasContext:null,preferredFormat:null,devicePixelRatio:i,alphaMode:r,powerPreference:o}}async function to(e){var i,r;if(e.initialized)throw new Error("GPUContext is already initialized. Call destroyGPUContext() before reinitializing.");const t=Number.isFinite(e.devicePixelRatio)&&e.devicePixelRatio>0?e.devicePixelRatio:1;if(!navigator.gpu)throw new Error("WebGPU is not available in this browser. Please use a browser that supports WebGPU (Chrome 113+, Edge 113+, or Safari 18+). Ensure WebGPU is enabled in browser flags if needed.");let n=null;try{const o=await navigator.gpu.requestAdapter({powerPreference:e.powerPreference});if(!o)throw new Error("Failed to request WebGPU adapter. No compatible adapter found. This may occur if no GPU is available or WebGPU is disabled.");if(n=await o.requestDevice(),!n)throw new Error("Failed to request WebGPU device from adapter.");n.addEventListener("uncapturederror",c=>{console.error("WebGPU uncaptured error:",c.error)});let s=null,a=null;if(e.canvas){const c=e.canvas.getContext("webgpu");if(!c){try{n.destroy()}catch(S){console.warn("Error destroying device during canvas setup failure:",S)}throw new Error("Failed to get WebGPU context from canvas.")}const{width:u,height:p}=Da(e.canvas),h=t,l=Math.floor(u*h),m=Math.floor(p*h),C=n.limits.maxTextureDimension2D,F=Math.max(1,Math.min(l,C)),R=Math.max(1,Math.min(m,C));e.canvas.width=F,e.canvas.height=R,a=((r=(i=navigator.gpu).getPreferredCanvasFormat)==null?void 0:r.call(i))||"bgra8unorm",c.configure({device:n,format:a,alphaMode:e.alphaMode}),s=c}return{adapter:o,device:n,initialized:!0,canvas:e.canvas,canvasContext:s,preferredFormat:a,devicePixelRatio:t,alphaMode:e.alphaMode,powerPreference:e.powerPreference}}catch(o){if(n)try{n.destroy()}catch(s){console.warn("Error destroying device during initialization failure:",s)}throw o instanceof Error?o:new Error(`Failed to initialize GPUContext: ${String(o)}`)}}function no(e){if(!e.canvas)throw new Error("Canvas is not configured. Provide a canvas element when creating the context.");if(!e.initialized||!e.canvasContext)throw new Error("GPUContext is not initialized. Call initializeGPUContext() first.");return e.canvasContext.getCurrentTexture()}function qs(e,t,n,i,r){if(t<0||t>1||n<0||n>1||i<0||i>1||r<0||r>1)throw new Error("Color components must be in the range [0.0, 1.0]");if(!e.canvas)throw new Error("Canvas is not configured. Provide a canvas element when creating the context.");if(!e.initialized||!e.device||!e.canvasContext)throw new Error("GPUContext is not initialized. Call initializeGPUContext() first.");const o=no(e),s=e.device.createCommandEncoder();s.beginRenderPass({colorAttachments:[{view:o.createView(),clearValue:{r:t,g:n,b:i,a:r},loadOp:"clear",storeOp:"store"}]}).end(),e.device.queue.submit([s.finish()])}function Zs(e){if(e.device)try{e.device.destroy()}catch(t){console.warn("Error destroying GPU device:",t)}return{adapter:null,device:null,initialized:!1,canvas:e.canvas,canvasContext:null,preferredFormat:null,devicePixelRatio:e.devicePixelRatio,alphaMode:e.alphaMode,powerPreference:e.powerPreference}}async function Ba(e,t){const n=eo(e,t);return to(n)}class nr{get adapter(){return this._state.adapter}get device(){return this._state.device}get initialized(){return this._state.initialized}get canvas(){return this._state.canvas}get canvasContext(){return this._state.canvasContext}get preferredFormat(){return this._state.preferredFormat}get devicePixelRatio(){return this._state.devicePixelRatio}get alphaMode(){return this._state.alphaMode}get powerPreference(){return this._state.powerPreference}constructor(t,n){this._state=eo(t,n)}async initialize(){this._state=await to(this._state)}static async create(t,n){const i=new nr(t,n);return await i.initialize(),i}getCanvasTexture(){return no(this._state)}clearScreen(t,n,i,r){qs(this._state,t,n,i,r)}destroy(){this._state=Zs(this._state)}}function Po(e){return Array.isArray(e)}function hr(e){if(!e)throw new TypeError("packDataPoints: points parameter is required");if(!Array.isArray(e))throw new TypeError("packDataPoints: points must be an array");if(e.length===0)return new Float32Array(0);const t=268435456;if(e.length>t)throw new RangeError(`packDataPoints: points array too large (${e.length} points). Maximum supported: ${t.toLocaleString()} points (2GB buffer limit)`);const n=new ArrayBuffer(e.length*2*4),i=new Float32Array(n);for(let r=0;r<e.length;r++){const o=e[r];if(o==null)throw new TypeError(`packDataPoints: Invalid point at index ${r}. Expected DataPoint (tuple or object), got ${o}`);const s=Po(o)?o[0]:o.x,a=Po(o)?o[1]:o.y;if(typeof s!="number"||typeof a!="number")throw new TypeError(`packDataPoints: Invalid coordinate values at index ${r}. Expected numbers, got x=${typeof s}, y=${typeof a}`);i[r*2+0]=s,i[r*2+1]=a}return i}const Yi=4;function $r(e){return e+3&-4}function La(e){if(!Number.isFinite(e)||e<=0)return 1;const t=Math.ceil(e);return 2**Math.ceil(Math.log2(t))}function Ao(e,t){const n=Math.max(Yi,$r(t)),i=Math.max(Yi,La(n));return Math.max(e,i)}function js(e,t){let n=e>>>0;for(let i=0;i<t.length;i++)n^=t[i],n=Math.imul(n,16777619)>>>0;return n>>>0}function Ro(e){const t=new Uint32Array(e.buffer,e.byteOffset,e.byteLength/4);return js(2166136261,t)}function ka(e){const t=new Map;let n=!1;const i=C=>Array.isArray(C),r=(C,F)=>{if(!C||C.length===0)return new Float32Array(0);const R=new ArrayBuffer(C.length*2*4),S=new Float32Array(R);for(let y=0;y<C.length;y++){const b=C[y],w=i(b)?b[0]:b.x,d=i(b)?b[1]:b.y;S[y*2+0]=w-F,S[y*2+1]=d}return S},o=()=>{if(n)throw new Error("DataStore is disposed.")},s=C=>{o();const F=t.get(C);if(!F)throw new Error(`Series ${C} has no data. Call setSeries(${C}, data) first.`);return F};return{setSeries:(C,F,R)=>{o();const S=(R==null?void 0:R.xOffset)??0,y=S===0?hr(F):r(F,S),b=F.length,w=Ro(y),d=$r(y.byteLength),g=Math.max(Yi,d),v=t.get(C);if(v&&v.pointCount===b&&v.hash32===w)return;let I=(v==null?void 0:v.buffer)??null,T=(v==null?void 0:v.capacityBytes)??0;if(!I||g>T){const E=e.limits.maxBufferSize;if(g>E)throw new Error(`DataStore.setSeries(${C}): required buffer size ${g} exceeds device.limits.maxBufferSize (${E}).`);if(I)try{I.destroy()}catch{}const f=Ao(T,g);f>E?T=g:T=f,I=e.createBuffer({size:T,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST})}y.byteLength>0&&e.queue.writeBuffer(I,0,y.buffer),t.set(C,{buffer:I,capacityBytes:T,pointCount:b,hash32:w,xOffset:S,data:F.length===0?[]:F.slice()})},appendSeries:(C,F)=>{if(o(),!F||F.length===0)return;const R=s(C),S=R.pointCount,y=S+F.length,b=R.xOffset===0?hr(F):r(F,R.xOffset),w=b.byteLength,d=$r(y*2*4),g=Math.max(Yi,d);let v=R.buffer,M=R.capacityBytes;const I=R.data;I.push(...F);const T=e.limits.maxBufferSize;if(g>M){if(g>T)throw new Error(`DataStore.appendSeries(${C}): required buffer size ${g} exceeds device.limits.maxBufferSize (${T}).`);try{v.destroy()}catch{}const x=Ao(M,g);M=x>T?g:x,v=e.createBuffer({size:M,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST});const N=R.xOffset===0?hr(I):r(I,R.xOffset);N.byteLength>0&&e.queue.writeBuffer(v,0,N.buffer),t.set(C,{buffer:v,capacityBytes:M,pointCount:y,hash32:Ro(N),xOffset:R.xOffset,data:I});return}if(w>0){const x=S*2*4;e.queue.writeBuffer(v,x,b.buffer)}const E=new Uint32Array(b.buffer,b.byteOffset,b.byteLength/4),f=js(R.hash32,E);t.set(C,{buffer:v,capacityBytes:M,pointCount:y,hash32:f,xOffset:R.xOffset,data:I})},removeSeries:C=>{o();const F=t.get(C);if(F){try{F.buffer.destroy()}catch{}t.delete(C)}},getSeriesBuffer:C=>s(C).buffer,getSeriesPointCount:C=>s(C).pointCount,getSeriesData:C=>s(C).data,dispose:()=>{if(!n){n=!0;for(const C of t.values())try{C.buffer.destroy()}catch{}t.clear()}}}}function fn(e){return Array.isArray(e)}function Ua(e,t){const n=e.length>>>1,i=n-1;if(t<=0||n===0)return new Int32Array(0);if(t===1)return new Int32Array([0]);if(t===2)return n>=2?new Int32Array([0,i]):new Int32Array([0]);if(n<=t){const p=new Int32Array(n);for(let h=0;h<n;h++)p[h]=h;return p}const r=new Int32Array(t);r[0]=0,r[t-1]=i;const o=(n-2)/(t-2);let s=0,a=1;const c=e[i*2+0],u=e[i*2+1];for(let p=0;p<t-2;p++){let h=Math.floor(o*p)+1,l=Math.min(Math.floor(o*(p+1))+1,i);h>=l&&(h=Math.min(h,i-1),l=Math.min(h+1,i));const m=Math.floor(o*(p+1))+1,C=Math.min(Math.floor(o*(p+2))+1,i);let F=c,R=u;if(m<C){let d=0,g=0,v=0;for(let M=m;M<C;M++)d+=e[M*2+0],g+=e[M*2+1],v++;v>0&&(F=d/v,R=g/v)}const S=e[s*2+0],y=e[s*2+1];let b=-1,w=h;for(let d=h;d<l;d++){const g=e[d*2+0],v=e[d*2+1],M=(S-F)*(v-y)-(S-g)*(R-y),I=M<0?-M:M;I>b&&(b=I,w=d)}r[a++]=w,s=w}return r}function _a(e,t){const n=e.length,i=n-1;if(t<=0||n===0)return new Int32Array(0);if(t===1)return new Int32Array([0]);if(t===2)return n>=2?new Int32Array([0,i]):new Int32Array([0]);if(n<=t){const h=new Int32Array(n);for(let l=0;l<n;l++)h[l]=l;return h}const r=new Int32Array(t);r[0]=0,r[t-1]=i;const o=(n-2)/(t-2);let s=0,a=1;const c=e[i],u=fn(c)?c[0]:c.x,p=fn(c)?c[1]:c.y;for(let h=0;h<t-2;h++){let l=Math.floor(o*h)+1,m=Math.min(Math.floor(o*(h+1))+1,i);l>=m&&(l=Math.min(l,i-1),m=Math.min(l+1,i));const C=Math.floor(o*(h+1))+1,F=Math.min(Math.floor(o*(h+2))+1,i);let R=u,S=p;if(C<F){let v=0,M=0,I=0;for(let T=C;T<F;T++){const E=e[T],f=fn(E)?E[0]:E.x,x=fn(E)?E[1]:E.y;v+=f,M+=x,I++}I>0&&(R=v/I,S=M/I)}const y=e[s],b=fn(y)?y[0]:y.x,w=fn(y)?y[1]:y.y;let d=-1,g=l;for(let v=l;v<m;v++){const M=e[v],I=fn(M)?M[0]:M.x,T=fn(M)?M[1]:M.y,E=(b-R)*(T-w)-(b-I)*(S-w),f=E<0?-E:E;f>d&&(d=f,g=v)}r[a++]=g,s=g}return r}function hi(e,t){const n=Math.floor(t);if(e instanceof Float32Array){const s=e.length>>>1;if(n<=0||s===0)return new Float32Array(0);if(s<=n)return e;const a=Ua(e,n),c=new Float32Array(a.length*2);for(let u=0;u<a.length;u++){const p=a[u];c[u*2+0]=e[p*2+0],c[u*2+1]=e[p*2+1]}return c}const i=e.length;if(n<=0||i===0)return[];if(i<=n)return e;const r=_a(e,n),o=new Array(r.length);for(let s=0;s<r.length;s++)o[s]=e[r[s]];return o}function ir(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)&&"x"in e&&"y"in e&&typeof e.x=="object"&&typeof e.y=="object"&&"length"in e.x&&"length"in e.y}function rr(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)&&ArrayBuffer.isView(e)}function io(e){return Array.isArray(e)}function Xe(e){if(ir(e))return Math.min(e.x.length,e.y.length);if(rr(e)){if(e instanceof DataView)throw new Error("DataView is not supported for InterleavedXYData. Use typed arrays (Float32Array, Float64Array, etc.).");return Math.floor(e.length/2)}return e.length}function Ee(e,t){if(ir(e))return e.x[t];if(rr(e)){if(e instanceof DataView)throw new Error("DataView is not supported for InterleavedXYData. Use typed arrays (Float32Array, Float64Array, etc.).");return e[t*2]}const n=e[t];return io(n)?n[0]:n.x}function We(e,t){if(ir(e))return e.y[t];if(rr(e)){if(e instanceof DataView)throw new Error("DataView is not supported for InterleavedXYData. Use typed arrays (Float32Array, Float64Array, etc.).");return e[t*2+1]}const n=e[t];return io(n)?n[1]:n.y}function mt(e,t){var i;if(ir(e))return(i=e.size)==null?void 0:i[t];if(rr(e))return;const n=e[t];return io(n)?n[2]:n.size}function sn(e){let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;const o=Xe(e);for(let s=0;s<o;s++){const a=Ee(e,s),c=We(e,s);!Number.isFinite(a)||!Number.isFinite(c)||(a<t&&(t=a),a>n&&(n=a),c<i&&(i=c),c>r&&(r=c))}return!Number.isFinite(t)||!Number.isFinite(n)||!Number.isFinite(i)||!Number.isFinite(r)?null:(t===n&&(n=t+1),i===r&&(r=i+1),{xMin:t,xMax:n,yMin:i,yMax:r})}function Ks(e){const t=Math.floor(e);return Number.isFinite(t)?t:0}function Ga(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)&&"x"in e&&"y"in e&&typeof e.x=="object"&&typeof e.y=="object"&&"length"in e.x&&"length"in e.y}function za(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)&&ArrayBuffer.isView(e)}function Eo(e){const t=Xe(e),n=new Float32Array(t*2);for(let i=0;i<t;i++)n[i*2]=Ee(e,i),n[i*2+1]=We(e,i);return n}function yr(e,t,n){const i=Xe(e),r=Ks(t);if(r<=0||i===0)return[];if(r===1){const c=Ee(e,0),u=We(e,0),p=mt(e,0);return p!==void 0?[[c,u,p]]:[[c,u]]}if(r===2)if(i>=2){const c=Ee(e,0),u=We(e,0),p=mt(e,0),h=Ee(e,i-1),l=We(e,i-1),m=mt(e,i-1);return[p!==void 0?[c,u,p]:[c,u],m!==void 0?[h,l,m]:[h,l]]}else{const c=Ee(e,0),u=We(e,0),p=mt(e,0);return p!==void 0?[[c,u,p]]:[[c,u]]}const o=i-1,s=new Array(r);{const c=Ee(e,0),u=We(e,0),p=mt(e,0);s[0]=p!==void 0?[c,u,p]:[c,u];const h=Ee(e,o),l=We(e,o),m=mt(e,o);s[r-1]=m!==void 0?[h,l,m]:[h,l]}const a=(i-2)/(r-2);for(let c=0;c<r-2;c++){let u=Math.floor(a*c)+1,p=Math.min(Math.floor(a*(c+1))+1,o);u>=p&&(u=Math.min(u,o-1),p=Math.min(u+1,o));let h=null;if(n==="average"){let l=0,m=0,C=0,F=0,R=0;for(let S=u;S<p;S++){const y=Ee(e,S),b=We(e,S);if(!Number.isFinite(y)||!Number.isFinite(b))continue;l+=y,m+=b,F++;const w=mt(e,S);typeof w=="number"&&Number.isFinite(w)&&(C+=w,R++)}if(F>0){const S=l/F,y=m/F;R>0?h=[S,y,C/R]:h=[S,y]}}else{let l=n==="max"?Number.NEGATIVE_INFINITY:Number.POSITIVE_INFINITY,m=u;for(let S=u;S<p;S++){const y=We(e,S);Number.isFinite(y)&&(n==="max"?y>l&&(l=y,m=S):y<l&&(l=y,m=S))}const C=Ee(e,m),F=We(e,m),R=mt(e,m);h=R!==void 0?[C,F,R]:[C,F]}if(h===null){const l=Ee(e,u),m=We(e,u),C=mt(e,u);h=C!==void 0?[l,m,C]:[l,m]}s[c+1]=h}return s}function _n(e,t,n){const i=Ks(n),r=Xe(e);if(t==="none"||!(i>0)||r<=i)return e;switch(t){case"lttb":{if(e instanceof Float32Array)return hi(e,i);if(za(e)){const o=Eo(e);return hi(o,i)}if(Ga(e)){const o=Eo(e);return hi(o,i)}return hi(e,i)}case"average":return yr(e,i,"average");case"max":return yr(e,i,"max");case"min":return yr(e,i,"min");default:return e}}function Va(e){return Array.isArray(e)}function Wr(e,t){const n=Math.floor(t),i=e.length;if(n<2||i<=n)return e;const r=new Array(n);if(r[0]=e[0],r[n-1]=e[i-1],n===2)return r;const o=Va(e[0]),s=(i-2)/(n-2);if(o){const a=e;for(let c=0;c<n-2;c++){let u=Math.floor(s*c)+1,p=Math.min(Math.floor(s*(c+1))+1,i-1);u>=p&&(u=Math.min(u,i-2),p=Math.min(u+1,i-1));const h=a[u],l=a[p-1],m=h[0],C=h[1],F=l[2];let R=-1/0,S=1/0;for(let y=u;y<p;y++){const b=a[y],w=b[3],d=b[4];d>R&&(R=d),w<S&&(S=w)}r[c+1]=[m,C,F,S,R]}}else{const a=e;for(let c=0;c<n-2;c++){let u=Math.floor(s*c)+1,p=Math.min(Math.floor(s*(c+1))+1,i-1);u>=p&&(u=Math.min(u,i-2),p=Math.min(u+1,i-1));const h=a[u],l=a[p-1],m=h.timestamp,C=h.open,F=l.close;let R=-1/0,S=1/0;for(let y=u;y<p;y++){const b=a[y],w=b.high,d=b.low;w>R&&(R=w),d<S&&(S=d)}r[c+1]={timestamp:m,open:C,close:F,low:S,high:R}}}return r}function Oa(e){return e?e.clientWidth:0}function $a(e){return e?e.clientHeight:0}function pn(e,t,n){return Math.min(n,Math.max(t,e|0))}function Hi(e){return Array.isArray(e)}const yi=new WeakMap,gi=new WeakMap;function ro(e){const t=typeof e=="object"&&e!==null?e:null;if(t){const r=yi.get(t);if(r!==void 0)return r}let n=Number.NEGATIVE_INFINITY;const i=Xe(e);for(let r=0;r<i;r++){const o=Ee(e,r);if(!Number.isFinite(o)||o<n)return t&&yi.set(t,!1),!1;n=o}return t&&yi.set(t,!0),!0}function Wa(e){const t=gi.get(e);if(t!==void 0)return t;let n=Number.NEGATIVE_INFINITY;for(let i=0;i<e.length;i++){const r=e[i],o=Hi(r)?r[0]:r.timestamp;if(!Number.isFinite(o)||o<n)return gi.set(e,!1),!1;n=o}return gi.set(e,!0),!0}function Js(e,t){let n=0,i=Xe(e);for(;n<i;){const r=n+i>>>1;Ee(e,r)<t?n=r+1:i=r}return n}function Qs(e,t){let n=0,i=Xe(e);for(;n<i;){const r=n+i>>>1;Ee(e,r)<=t?n=r+1:i=r}return n}function Xa(e,t){let n=0,i=e.length;for(;n<i;){const r=n+i>>>1;e[r][0]<t?n=r+1:i=r}return n}function Ya(e,t){let n=0,i=e.length;for(;n<i;){const r=n+i>>>1;e[r][0]<=t?n=r+1:i=r}return n}function Ha(e,t){let n=0,i=e.length;for(;n<i;){const r=n+i>>>1;e[r].timestamp<t?n=r+1:i=r}return n}function qa(e,t){let n=0,i=e.length;for(;n<i;){const r=n+i>>>1;e[r].timestamp<=t?n=r+1:i=r}return n}function Do(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)&&"x"in e&&"y"in e&&typeof e.x=="object"&&typeof e.y=="object"&&"length"in e.x&&"length"in e.y}function Bo(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)&&ArrayBuffer.isView(e)}function Za(e,t,n){const i=Xe(e),r=Math.max(0,Math.min(t,i)),o=Math.max(r,Math.min(n,i));if(r===0&&o===i)return e;if(o<=r){if(Do(e))return{x:[],y:[],...e.size?{size:[]}:{}};if(Bo(e)){if(e instanceof DataView)throw new Error("DataView is not supported for InterleavedXYData");const s=e.constructor;return new s(0)}return[]}if(Do(e)){const s=Array.isArray(e.x)?e.x.slice(r,o):"subarray"in e.x?e.x.subarray(r,o):Array.from(e.x).slice(r,o),a=Array.isArray(e.y)?e.y.slice(r,o):"subarray"in e.y?e.y.subarray(r,o):Array.from(e.y).slice(r,o),c={x:s,y:a};if(e.size){const u=Array.isArray(e.size)?e.size.slice(r,o):"subarray"in e.size?e.size.subarray(r,o):Array.from(e.size).slice(r,o);c.size=u}return c}if(Bo(e)){if(e instanceof DataView)throw new Error("DataView is not supported for InterleavedXYData");return e.subarray(r*2,o*2)}return e.slice(r,o)}function xi(e,t,n){const i=Xe(e);if(i===0||!Number.isFinite(t)||!Number.isFinite(n))return e;if(ro(e)){const s=Js(e,t),a=Qs(e,n);return s<=0&&a>=i?e:Za(e,s,a)}const o=[];for(let s=0;s<i;s++){const a=Ee(e,s);if(Number.isFinite(a)&&a>=t&&a<=n){const c=We(e,s);o.push([a,c])}}return o}function ja(e,t,n){const i=Xe(e);if(i===0)return{start:0,end:0};if(!Number.isFinite(t)||!Number.isFinite(n))return{start:0,end:i};if(!ro(e))return{start:0,end:i};const o=Js(e,t),s=Qs(e,n),a=pn(o,0,i),c=pn(s,0,i);return c<=a?{start:a,end:a}:{start:a,end:c}}function bi(e,t,n){const i=e.length;if(i===0||!Number.isFinite(t)||!Number.isFinite(n))return e;const r=Wa(e),o=i>0&&Hi(e[0]);if(r){const a=o?Xa(e,t):Ha(e,t),c=o?Ya(e,n):qa(e,n);return a<=0&&c>=i?e:c<=a?[]:e.slice(a,c)}const s=[];for(let a=0;a<i;a++){const c=e[a],u=Hi(c)?c[0]:c.timestamp;Number.isFinite(u)&&u>=t&&u<=n&&s.push(c)}return s}const Lo=e=>Math.min(1,Math.max(0,e)),ko=e=>Math.min(255,Math.max(0,e)),Mn=e=>{const t=Number.parseInt(e,16);return Number.isFinite(t)?t:0},Fn=e=>{const t=Number.parseInt(e,16);return Number.isFinite(t)?t:0},Ka=e=>{const t=e.trim();if(!t.startsWith("#"))return null;const n=t.slice(1);if(n.length===3){const i=Mn(n[0]),r=Mn(n[1]),o=Mn(n[2]);return[i*17/255,r*17/255,o*17/255,1]}if(n.length===4){const i=Mn(n[0]),r=Mn(n[1]),o=Mn(n[2]),s=Mn(n[3]);return[i*17/255,r*17/255,o*17/255,s*17/255]}if(n.length===6){const i=Fn(n.slice(0,2)),r=Fn(n.slice(2,4)),o=Fn(n.slice(4,6));return[i/255,r/255,o/255,1]}if(n.length===8){const i=Fn(n.slice(0,2)),r=Fn(n.slice(2,4)),o=Fn(n.slice(4,6)),s=Fn(n.slice(6,8));return[i/255,r/255,o/255,s/255]}return null},En=e=>{const t=e.trim();if(t.length===0)return null;if(t.endsWith("%")){const i=Number.parseFloat(t.slice(0,-1));return Number.isFinite(i)?ko(i/100*255):null}const n=Number.parseFloat(t);return Number.isFinite(n)?ko(n):null},Ja=e=>{const t=e.trim();if(t.length===0)return null;if(t.endsWith("%")){const i=Number.parseFloat(t.slice(0,-1));return Number.isFinite(i)?Lo(i/100):null}const n=Number.parseFloat(t);return Number.isFinite(n)?Lo(n):null},Qa=e=>{const t=e.trim(),n=/^(rgba?|RGBA?)\(\s*([^\)]*)\s*\)$/.exec(t);if(!n)return null;const i=n[1].toLowerCase(),o=n[2].split(",").map(s=>s.trim());if(i==="rgb"){if(o.length!==3)return null;const s=En(o[0]),a=En(o[1]),c=En(o[2]);return s==null||a==null||c==null?null:[s/255,a/255,c/255,1]}if(i==="rgba"){if(o.length!==4)return null;const s=En(o[0]),a=En(o[1]),c=En(o[2]),u=Ja(o[3]);return s==null||a==null||c==null||u==null?null:[s/255,a/255,c/255,u]}return null},pt=e=>{if(typeof e!="string")return null;const t=e.trim();if(t.length===0)return null;const n=Ka(t);if(n)return n;const i=Qa(t);return i||null},ec=(e,t={r:0,g:0,b:0,a:1})=>{const n=pt(e);if(!n)return t;const[i,r,o,s]=n;return{r:i,g:r,b:o,a:s}},vi=e=>typeof e=="number"&&Number.isFinite(e)?e:void 0,Xr=e=>{throw new Error(`RenderCoordinator: unreachable value: ${String(e)}`)},ea=e=>Array.isArray(e),tc=e=>ea(e)?{x:e[0],y:e[1]}:{x:e.x,y:e.y},Mt=e=>Math.min(1,Math.max(0,e)),nc=e=>{const{canvasWidth:t,canvasHeight:n,devicePixelRatio:i}=e,r=e.left*i,o=t-e.right*i,s=e.top*i,a=n-e.bottom*i,c=pn(Math.floor(r),0,Math.max(0,t)),u=pn(Math.floor(s),0,Math.max(0,n)),p=pn(Math.ceil(o),0,Math.max(0,t)),h=pn(Math.ceil(a),0,Math.max(0,n)),l=Math.max(0,p-c),m=Math.max(0,h-u);return{x:c,y:u,w:l,h:m}},Qn=(e,t)=>(e+1)/2*t,ei=(e,t)=>(1-e)/2*t,qi=24*60*60*1e3,ic=30*qi,rc=365*qi,oc=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],gr=(e,t)=>{if(typeof e=="number")return Number.isFinite(e)?e:null;if(typeof e!="string")return null;const n=e.trim();if(n.length===0)return null;if(n.endsWith("%")){const r=Number.parseFloat(n.slice(0,-1));return Number.isFinite(r)?r/100*t:null}const i=Number.parseFloat(n);return Number.isFinite(i)?i:null},sc=e=>Array.isArray(e),ac=(e,t)=>{if(e==null)return{inner:0,outer:t*.7};if(sc(e)){const r=gr(e[0],t),o=gr(e[1],t),s=Math.max(0,Number.isFinite(r)?r:0),a=Math.max(s,Number.isFinite(o)?o:t*.7);return{inner:s,outer:Math.min(t,a)}}const n=gr(e,t),i=Math.max(0,Number.isFinite(n)?n:t*.7);return{inner:0,outer:Math.min(t,i)}},_t=e=>String(Math.trunc(e)).padStart(2,"0"),cc=(e,t)=>{if(!Number.isFinite(e))return null;(!Number.isFinite(t)||t<0)&&(t=0);const n=new Date(e);if(!Number.isFinite(n.getTime()))return null;const i=n.getFullYear(),r=n.getMonth()+1,o=n.getDate(),s=n.getHours(),a=n.getMinutes();return t<qi?`${_t(s)}:${_t(a)}`:t<=7*qi?`${_t(r)}/${_t(o)} ${_t(s)}:${_t(a)}`:t<3*ic?`${_t(r)}/${_t(o)}`:t<=rc?`${oc[n.getMonth()]??_t(r)} ${_t(o)}`:`${i}/${_t(r)}`},lc=8;function uc(e,t=lc){const n=Math.abs(e);if(!Number.isFinite(n)||n===0)return 0;for(let i=0;i<=t;i++){const r=n*10**i,o=Math.round(r),s=Math.abs(r-o),a=1e-9*Math.max(1,Math.abs(r));if(s<=a)return i}return Math.max(0,Math.min(t,1-Math.floor(Math.log10(n))+1))}function Uo(e){const t=uc(e);return new Intl.NumberFormat(void 0,{maximumFractionDigits:t})}function _o(e,t){if(!Number.isFinite(t))return null;const n=Math.abs(t)<1e-12?0:t,i=e.format(n);return i==="NaN"?null:i}function fc(e){return Math.max(e+1,Math.round(e*1.15))}const Go=6,xr=4,dc=5;function br(e,t){return(e+1)/2*t}function vr(e,t){return(1-e)/2*t}function wi(e,t,n){e.style.fontFamily=n.fontFamily,e.style.fontWeight=t?"500":"400",e.style.userSelect="none",e.style.pointerEvents="none"}function mc(e,t,n){var V,_,re;const{gpuContext:i,currentOptions:r,xScale:o,yScale:s,xTickValues:a,plotClipRect:c,visibleXRangeMs:u}=n;if(!r.series.some(Y=>Y.type!=="pie")||!e||!t)return;const h=i.canvas;if(!h)return;const l=Oa(h),m=$a(h);if(l<=0||m<=0)return;const C=h.offsetLeft||0,F=h.offsetTop||0,R=br(c.left,l),S=br(c.right,l),y=vr(c.top,m),b=vr(c.bottom,m);e.clear();const w=r.xAxis.tickLength??Go,d=b+w+xr+r.theme.fontSize*.5,g=r.xAxis.type==="time",v=(()=>{if(g)return null;const Y=vi(r.xAxis.min)??o.invert(c.left),W=vi(r.xAxis.max)??o.invert(c.right),Z=a.length,oe=Z===1?0:(W-Y)/(Z-1);return Uo(oe)})();for(let Y=0;Y<a.length;Y++){const W=a[Y],Z=o.scale(W),oe=br(Z,l),ee=a.length===1?"middle":Y===0?"start":Y===a.length-1?"end":"middle",q=g?cc(W,u):_o(v,W);if(q==null)continue;const de=e.addLabel(q,C+oe,F+d,{fontSize:r.theme.fontSize,color:r.theme.textColor,anchor:ee});wi(de,!1,r.theme)}const M=dc,I=r.yAxis.tickLength??Go,T=vi(r.yAxis.min)??s.invert(c.bottom),E=vi(r.yAxis.max)??s.invert(c.top),f=(E-T)/(M-1),x=Uo(f),N=R-I-xr,A=[];for(let Y=0;Y<M;Y++){const W=Y/(M-1),Z=T+W*(E-T),oe=s.scale(Z),ee=vr(oe,m),q=_o(x,Z);if(q==null)continue;const de=e.addLabel(q,C+N,F+ee,{fontSize:r.theme.fontSize,color:r.theme.textColor,anchor:"end"});wi(de,!1,r.theme),A.push(de)}const P=fc(r.theme.fontSize),L=((V=r.xAxis.name)==null?void 0:V.trim())??"";if(L.length>0){const Y=(R+S)/2,W=d+r.theme.fontSize*.5,ee=((_=r.dataZoom)==null?void 0:_.some(G=>(G==null?void 0:G.type)==="slider"))??!1?m-32:m,q=(W+ee)/2,de=e.addLabel(L,C+Y,F+q,{fontSize:P,color:r.theme.textColor,anchor:"middle"});wi(de,!0,r.theme)}const B=((re=r.yAxis.name)==null?void 0:re.trim())??"";if(B.length>0){const Y=A.length===0?0:A.reduce((q,de)=>Math.max(q,de.getBoundingClientRect().width),0),W=(y+b)/2,oe=N-Y-xr-P*.5,ee=e.addLabel(B,C+oe,F+W,{fontSize:P,color:r.theme.textColor,anchor:"middle",rotation:-90});wi(ee,!0,r.theme)}}function zo(e){return"offsetLeft"in e}function wr(e,t){return(e+1)/2*t}function Cr(e,t){return(1-e)/2*t}function pc(e,t){const n=pt(e)??[0,0,0,1],i=Mt(n[3]*Mt(t)),r=Math.round(Mt(n[0])*255),o=Math.round(Mt(n[1])*255),s=Math.round(Mt(n[2])*255);return`rgba(${r}, ${o}, ${s}, ${i})`}function hc(e,t){if(!Number.isFinite(e))return"";if(t==null)return String(e);const n=Math.min(20,Math.max(0,Math.floor(t)));return e.toFixed(n)}const Vo=/\{(x|y|value|name)\}/g;function Oo(e,t,n){return Vo.lastIndex=0,e.replace(Vo,(i,r)=>{if(r==="name")return t.name??"";const o=t[r];return o==null?"":hc(o,n)})}function yc(e){switch(e){case"center":return"middle";case"end":return"end";case"start":default:return"start"}}function gc(e,t,n){var S,y,b;const{currentOptions:i,xScale:r,yScale:o,canvasCssWidthForAnnotations:s,canvasCssHeightForAnnotations:a,plotLeftCss:c,plotTopCss:u,plotWidthCss:p,plotHeightCss:h,canvas:l}=n;if(!i.series.some(w=>w.type!=="pie")||!e||!t)return;if(!l||s<=0||a<=0||p<=0||h<=0){e.clear();return}const C=zo(l)?l.offsetLeft:0,F=zo(l)?l.offsetTop:0;e.clear();const R=i.annotations??[];if(R.length!==0)for(let w=0;w<R.length;w++){const d=R[w],g=d.label;if(!(g!=null||d.type==="text"))continue;let M=null,I=null,T={name:d.id??""};switch(d.type){case"lineX":{const ee=r.scale(d.x);M=wr(ee,s),I=u,T={...T,x:d.x,value:d.x};break}case"lineY":{const ee=o.scale(d.y),q=Cr(ee,a);M=c,I=q-8,T={...T,y:d.y,value:d.y};break}case"point":{const ee=r.scale(d.x),q=o.scale(d.y),de=wr(ee,s),G=Cr(q,a);M=de,I=G,T={...T,x:d.x,y:d.y,value:d.y};break}case"text":{if(d.position.space==="data"){const ee=r.scale(d.position.x),q=o.scale(d.position.y),de=wr(ee,s),G=Cr(q,a);M=de,I=G,T={...T,x:d.position.x,y:d.position.y,value:d.position.y}}else{const ee=c+d.position.x*p,q=u+d.position.y*h;M=ee,I=q,T={...T,x:d.position.x,y:d.position.y,value:d.position.y}}break}default:Xr(d)}if(M==null||I==null||!Number.isFinite(M)||!Number.isFinite(I))continue;const E=((S=g==null?void 0:g.offset)==null?void 0:S[0])??0,f=((y=g==null?void 0:g.offset)==null?void 0:y[1])??0,x=M+E,N=I+f,A=(g==null?void 0:g.text)??(g!=null&&g.template?Oo(g.template,T,g.decimals):g?(()=>{const ee=d.type==="lineX"?"x={x}":d.type==="lineY"?"y={y}":d.type==="point"?"({x}, {y})":d.type==="text"?d.text:"";return ee.includes("{")?Oo(ee,T,g.decimals):ee})():d.type==="text"?d.text:""),P=typeof A=="string"?A.trim():"";if(P.length===0)continue;const L=yc(g==null?void 0:g.anchor),B=((b=d.style)==null?void 0:b.color)??i.theme.textColor,V=i.theme.fontSize,_=g==null?void 0:g.background,re=(_==null?void 0:_.color)!=null?pc(_.color,_.opacity??1):void 0,Y=(()=>{const ee=_==null?void 0:_.padding;return typeof ee=="number"&&Number.isFinite(ee)?[ee,ee,ee,ee]:Array.isArray(ee)&&ee.length===4&&ee.every(q=>typeof q=="number"&&Number.isFinite(q))?[ee[0],ee[1],ee[2],ee[3]]:_?[2,4,2,4]:void 0})(),W=typeof(_==null?void 0:_.borderRadius)=="number"&&Number.isFinite(_.borderRadius)?_.borderRadius:void 0,Z={x:C+x,y:F+N,...re?{background:{backgroundColor:re,...Y?{padding:Y}:{},...W!=null?{borderRadius:W}:{}}}:{}},oe=e.addLabel(P,Z.x,Z.y,{fontSize:V,color:B,anchor:L});if(Z.background){if(oe.style.backgroundColor=Z.background.backgroundColor,oe.style.display="inline-block",oe.style.boxSizing="border-box",Z.background.padding){const[ee,q,de,G]=Z.background.padding;oe.style.padding=`${ee}px ${q}px ${de}px ${G}px`}Z.background.borderRadius!=null&&(oe.style.borderRadius=`${Z.background.borderRadius}px`)}}}const $o=20,xc=.01,bc=.2,Mr=4;function vc(e,t){let n=0,i=Xe(e);for(;n<i;){const r=n+i>>>1;Ee(e,r)<t?n=r+1:i=r}return n}function wc(e,t,n){return e>=n.left&&e<=n.right&&t>=n.top&&t<=n.bottom}const Fr=e=>Math.min(1,Math.max(0,e)),Cc=e=>{const t=e.trim().match(/^(\d+(?:\.\d+)?)%$/);if(!t)return null;const n=Number(t[1])/100;return Number.isFinite(n)?n:null},Mc=e=>{if(typeof e!="string")return"";const t=e.trim();return t.length>0?t:""},ta=e=>Array.isArray(e),Fc=e=>{if(ta(e)){const n=e[2];return typeof n=="number"&&Number.isFinite(n)?n:null}const t=e.size;return typeof t=="number"&&Number.isFinite(t)?t:null},Sc=e=>ta(e)?e:[e.x,e.y,e.size],Nc=(e,t)=>{try{const n=e(t);return typeof n=="number"&&Number.isFinite(n)?n:null}catch{return null}},Sr=(e,t)=>{const n=Fc(t);if(n!=null)return Math.max(0,n);const i=e.symbolSize;if(typeof i=="number")return Number.isFinite(i)?Math.max(0,i):Mr;if(typeof i=="function"){const r=Nc(i,Sc(t));return r==null?Mr:Math.max(0,r)}return Mr};function Tc(e){const t=new Map,n=new Array(e.length),i=new Array(e.length);let r=0;for(let o=0;o<e.length;o++){const s=Mc(e[o].stack);if(i[o]=s,s!==""){const a=t.get(s);if(a!==void 0)n[o]=a;else{const c=r++;t.set(s,c),n[o]=c}}else n[o]=r++}return{clusterIndexBySeries:n,clusterCount:Math.max(1,r),stackIdBySeries:i}}function Ic(e){const t=[];for(let i=0;i<e.length;i++){const r=e[i].data,o=Xe(r);for(let s=0;s<o;s++){const a=Ee(r,s);Number.isFinite(a)&&t.push(a)}}if(t.length<2)return 1;t.sort((i,r)=>i-r);let n=Number.POSITIVE_INFINITY;for(let i=1;i<t.length;i++){const r=t[i]-t[i-1];r>0&&r<n&&(n=r)}return Number.isFinite(n)&&n>0?n:1}function Pc(e,t,n){if(Number.isFinite(n)&&n>0){const s=t.scale(0),a=t.scale(0+n),c=Math.abs(a-s);if(Number.isFinite(c)&&c>0)return c}const i=[];for(let o=0;o<e.length;o++){const s=e[o].data,a=Xe(s);for(let c=0;c<a;c++){const u=Ee(s,c);if(!Number.isFinite(u))continue;const p=t.scale(u);Number.isFinite(p)&&i.push(p)}}if(i.length<2)return 0;i.sort((o,s)=>o-s);let r=Number.POSITIVE_INFINITY;for(let o=1;o<i.length;o++){const s=i[o]-i[o-1];s>0&&s<r&&(r=s)}return Number.isFinite(r)&&r>0?r:0}const Ac=e=>{let t,n,i;for(let r=0;r<e.length;r++){const o=e[r];t===void 0&&o.barWidth!==void 0&&(t=o.barWidth),n===void 0&&o.barGap!==void 0&&(n=o.barGap),i===void 0&&o.barCategoryGap!==void 0&&(i=o.barCategoryGap)}return{barWidth:t,barGap:n,barCategoryGap:i}};function na(e,t){const n=Tc(e),i=n.clusterCount,r=Ic(e),o=Pc(e,t,r),s=Ac(e),a=Fr(s.barGap??xc),c=Fr(s.barCategoryGap??bc),u=Math.max(0,o*(1-c)),p=i+Math.max(0,i-1)*a,h=p>0?u/p:0;let l=0;const m=s.barWidth;if(typeof m=="number")l=Math.max(0,m),l=Math.min(l,h);else if(typeof m=="string"){const R=Cc(m);l=R==null?0:h*Fr(R)}l>0||(l=h);const C=l*a,F=i*l+Math.max(0,i-1)*C;return{categoryStep:r,categoryWidthPx:o,barWidthPx:l,gapPx:C,clusterWidthPx:F,clusterSlots:n}}const Nr=e=>{let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY;for(let i=0;i<e.length;i++){const r=e[i].data,o=Xe(r);for(let s=0;s<o;s++){const a=We(r,s);Number.isFinite(a)&&(a<t&&(t=a),a>n&&(n=a))}}return!Number.isFinite(t)||!Number.isFinite(n)||t<=0&&0<=n?0:Math.abs(t)<Math.abs(n)?t:n};function Rc(e,t){let n=0;for(let i=0;i<e.length;i++){const r=e[i].data,o=Xe(r);for(let s=0;s<o;s++){const a=We(r,s);if(!Number.isFinite(a))continue;const c=t.scale(a);Number.isFinite(c)&&c>n&&(n=c)}}return Math.max(0,n)}function Ec(e,t,n){const i=t.invert(n),r=t.invert(0),o=Math.min(i,r),s=Math.max(i,r);let a;!Number.isFinite(o)||!Number.isFinite(s)?a=Nr(e):o<=0&&0<=s?a=0:o>0?a=o:s<0?a=s:a=Nr(e);let c=t.scale(a);return Number.isFinite(c)||(a=Nr(e),c=t.scale(a)),Number.isFinite(c)||(a=0,c=t.scale(0)),{baselineDomain:a,baselinePx:c}}function Dc(e,t,n,i){return Number.isFinite(t)&&t>0&&Number.isFinite(e)?Math.round(e/t):Number.isFinite(i)&&i>0&&Number.isFinite(n)?Math.round(n/i):Math.round(n*1e6)}function Zi(e,t,n,i,r,o=$o){var S;if(!Number.isFinite(t)||!Number.isFinite(n))return null;const s=Number.isFinite(o)?Math.max(0,o):$o,a=s*s,c=i.invert(t);if(!Number.isFinite(c))return null;let u=-1,p=-1,h=null,l=Number.POSITIVE_INFINITY;const m=[],C=[];for(let y=0;y<e.length;y++){const b=e[y];(b==null?void 0:b.type)==="bar"&&b.visible!==!1&&(m.push(b),C.push(y))}if(m.length>0){const y=na(m,i);if(y.barWidthPx>0&&y.clusterWidthPx>=0){const b=Rc(m,r),{baselineDomain:w,baselinePx:d}=Ec(m,r,b),{clusterSlots:g,barWidthPx:v,gapPx:M,clusterWidthPx:I,categoryWidthPx:T,categoryStep:E}=y,f=new Map;let x=null;for(let N=0;N<m.length;N++){const A=m[N],P=C[N]??-1;if(P<0)continue;const L=A.data,B=Xe(L),V=g.clusterIndexBySeries[N]??0,_=g.stackIdBySeries[N]??"";for(let re=0;re<B;re++){const Y=Ee(L,re),W=We(L,re);if(!Number.isFinite(Y)||!Number.isFinite(W))continue;const Z=i.scale(Y);if(!Number.isFinite(Z))continue;const oe=Z-I/2+V*(v+M),ee=oe+v;let q=w,de=W;if(_!==""){let ne=f.get(_);ne||(ne=new Map,f.set(_,ne));const H=Dc(Z,T,Y,E);let O=ne.get(H);O||(O={posSum:w,negSum:w},ne.set(H,O)),W>=0?(q=O.posSum,de=q+W,O.posSum=de):(q=O.negSum,de=q+W,O.negSum=de)}else q=w,de=W;const G=_!==""?r.scale(q):d,te=r.scale(de);if(!Number.isFinite(G)||!Number.isFinite(te))continue;const X={left:oe,right:ee,top:Math.min(G,te),bottom:Math.max(G,te)};if(!wc(t,n,X))continue;(x===null||X.top<x.top||X.top===x.top&&P>x.seriesIndex)&&(x={seriesIndex:P,dataIndex:re,top:X.top})}}if(x){const N=(S=e[x.seriesIndex])==null?void 0:S.data;if(N){const A=Ee(N,x.dataIndex),P=We(N,x.dataIndex),L=mt(N,x.dataIndex),B=L!==void 0?[A,P,L]:[A,P];return{seriesIndex:x.seriesIndex,dataIndex:x.dataIndex,point:B,distance:0}}}}}const F=[],R=[];for(let y=0;y<e.length;y++){const b=e[y];b.type==="pie"||b.type==="candlestick"||b.visible!==!1&&(F.push(b),R.push(y))}for(let y=0;y<F.length;y++){const b=F[y],w=R[y]??-1;if(w<0)continue;const d=b.data,g=Xe(d);if(g===0)continue;const M=b.type==="scatter"?b:null;if(ro(d)){const T=vc(d,c);for(let E=T;E<g;E++){const f=Ee(d,E),x=We(d,E);if(!Number.isFinite(f)||!Number.isFinite(x))continue;const N=i.scale(f),A=r.scale(x);if(!Number.isFinite(N)||!Number.isFinite(A))continue;const P=N-t,L=A-n,B=P*P+L*L;if(P*P>l)break;let _=a;if(M){const Y=mt(d,E),Z=Sr(M,Y!==void 0?[f,x,Y]:[f,x]),oe=s+Z;_=oe*oe}if(B>_)continue;if(B<l||B===l&&(h===null||w<u||w===u&&E<p)){l=B,u=w,p=E;const Y=mt(d,E);h=Y!==void 0?[f,x,Y]:[f,x]}}for(let E=T-1;E>=0;E--){const f=Ee(d,E),x=We(d,E);if(!Number.isFinite(f)||!Number.isFinite(x))continue;const N=i.scale(f),A=r.scale(x);if(!Number.isFinite(N)||!Number.isFinite(A))continue;const P=N-t,L=A-n,B=P*P+L*L;if(P*P>l)break;let _=a;if(M){const Y=mt(d,E),Z=Sr(M,Y!==void 0?[f,x,Y]:[f,x]),oe=s+Z;_=oe*oe}if(B>_)continue;if(B<l||B===l&&(h===null||w<u||w===u&&E<p)){l=B,u=w,p=E;const Y=mt(d,E);h=Y!==void 0?[f,x,Y]:[f,x]}}}else for(let T=0;T<g;T++){const E=Ee(d,T),f=We(d,T);if(!Number.isFinite(E)||!Number.isFinite(f))continue;const x=i.scale(E),N=r.scale(f);if(!Number.isFinite(x)||!Number.isFinite(N))continue;const A=x-t,P=N-n,L=A*A+P*P;let B=a;if(M){const _=mt(d,T),Y=Sr(M,_!==void 0?[E,f,_]:[E,f]),W=s+Y;B=W*W}if(L>B)continue;if(L<l||L===l&&(h===null||w<u||w===u&&T<p)){l=L,u=w,p=T;const _=mt(d,T);h=_!==void 0?[E,f,_]:[E,f]}}}return h===null||!Number.isFinite(l)?null:{seriesIndex:u,dataIndex:p,point:h,distance:Math.sqrt(l)}}const Bc=5,Lc=1,kc=4;function Uc(e,t){var l;const{currentOptions:n,xScale:i,yScale:r,gridArea:o,xTickCount:s,hasCartesianSeries:a,effectivePointer:c,interactionScales:u,seriesForRender:p,withAlpha:h}=t;if(e.gridRenderer.prepare(o,{color:n.theme.gridLineColor}),a&&(e.xAxisRenderer.prepare(n.xAxis,i,"x",o,n.theme.axisLineColor,n.theme.axisTickColor,s),e.yAxisRenderer.prepare(n.yAxis,r,"y",o,n.theme.axisLineColor,n.theme.axisTickColor,Bc)),c.hasPointer&&c.isInGrid){const m={showX:!0,showY:c.source!=="sync",color:h(n.theme.axisLineColor,.6),lineWidth:Lc};e.crosshairRenderer.prepare(c.x,c.y,o,m),e.crosshairRenderer.setVisible(!0)}else e.crosshairRenderer.setVisible(!1);if(c.source==="mouse"&&c.hasPointer&&c.isInGrid)if(u){const m=Zi(p,c.gridX,c.gridY,u.xScale,u.yScale);if(m){const{x:C,y:F}=tc(m.point),R=u.xScale.scale(C),S=u.yScale.scale(F);if(Number.isFinite(R)&&Number.isFinite(S)){const y=o.left+R,b=o.top+S,w=nc(o),d={centerDeviceX:y*o.devicePixelRatio,centerDeviceY:b*o.devicePixelRatio,devicePixelRatio:o.devicePixelRatio,canvasWidth:o.canvasWidth,canvasHeight:o.canvasHeight,scissor:w},g=((l=n.series[m.seriesIndex])==null?void 0:l.color)??"#888";e.highlightRenderer.prepare(d,g,kc),e.highlightRenderer.setVisible(!0)}else e.highlightRenderer.setVisible(!1)}else e.highlightRenderer.setVisible(!1)}else e.highlightRenderer.setVisible(!1);else e.highlightRenderer.setVisible(!1)}function Wo(e,t,n){const i=pt(e??n)??pt(n)??[1,1,1,1],r=t==null?1:Mt(t);return[Mt(i[0]),Mt(i[1]),Mt(i[2]),Mt(i[3]*r)]}function _c(e,t){const n=pt(e)??[0,0,0,1],i=Mt(n[3]*Mt(t)),r=Math.round(Mt(n[0])*255),o=Math.round(Mt(n[1])*255),s=Math.round(Mt(n[2])*255);return`rgba(${r}, ${o}, ${s}, ${i})`}function Gc(e,t){if(!Number.isFinite(e))return"";if(t==null)return String(e);const n=Math.min(20,Math.max(0,Math.floor(t)));return e.toFixed(n)}function Xo(e,t,n){const i=/\{(x|y|value|name)\}/g;return e.replace(i,(r,o)=>{if(o==="name")return t.name??"";const s=t[o];return s==null?"":Gc(s,n)})}function zc(e){switch(e){case"center":return"middle";case"end":return"end";case"start":default:return"start"}}function Vc(e){var b,w,d,g,v,M,I,T,E,f,x,N,A,P;const{annotations:t,xScale:n,yScale:i,plotBounds:r,canvasCssWidth:o,canvasCssHeight:s,theme:a,offsetX:c=0,offsetY:u=0}=e,{leftCss:p,topCss:h,widthCss:l,heightCss:m}=r,C=[],F=[],R=[],S=[],y=[];if(t.length===0||o<=0||s<=0||l<=0||m<=0)return{linesBelow:C,linesAbove:F,markersBelow:R,markersAbove:S,labels:y};for(let L=0;L<t.length;L++){const B=t[L],V=B.layer??"aboveSeries",_=V==="belowSeries"?C:F,re=V==="belowSeries"?R:S,Y=(b=B.style)==null?void 0:b.color,W=(w=B.style)==null?void 0:w.opacity,Z=typeof((d=B.style)==null?void 0:d.lineWidth)=="number"&&Number.isFinite(B.style.lineWidth)?Math.max(0,B.style.lineWidth):1,oe=(g=B.style)==null?void 0:g.lineDash,ee=Wo(Y,W,a.textColor);switch(B.type){case"lineX":{const he=n.scale(B.x),be=Qn(he,o);if(!Number.isFinite(be))break;_.push({axis:"vertical",positionCssPx:be,lineWidth:Z,lineDash:oe,rgba:ee});break}case"lineY":{const he=i.scale(B.y),be=ei(he,s);if(!Number.isFinite(be))break;_.push({axis:"horizontal",positionCssPx:be,lineWidth:Z,lineDash:oe,rgba:ee});break}case"point":{const he=n.scale(B.x),be=i.scale(B.y),Ge=Qn(he,o),ze=ei(be,s);if(!Number.isFinite(Ge)||!Number.isFinite(ze))break;const rt=typeof((v=B.marker)==null?void 0:v.size)=="number"&&Number.isFinite(B.marker.size)?Math.max(1,B.marker.size):6,Ze=((I=(M=B.marker)==null?void 0:M.style)==null?void 0:I.color)??((T=B.style)==null?void 0:T.color),ht=((f=(E=B.marker)==null?void 0:E.style)==null?void 0:f.opacity)??((x=B.style)==null?void 0:x.opacity),gt=Wo(Ze,ht,a.textColor);re.push({xCssPx:Ge,yCssPx:ze,sizeCssPx:rt,fillRgba:gt});break}case"text":break;default:Xr(B)}const q=B.label;if(!(q!=null||B.type==="text"))continue;let G=null,te=null,X={name:B.id??""};switch(B.type){case"lineX":{const he=n.scale(B.x);G=Qn(he,o),te=h,X={...X,x:B.x,value:B.x};break}case"lineY":{const he=i.scale(B.y),be=ei(he,s);G=p,te=be-8,X={...X,y:B.y,value:B.y};break}case"point":{const he=n.scale(B.x),be=i.scale(B.y),Ge=Qn(he,o),ze=ei(be,s);G=Ge,te=ze,X={...X,x:B.x,y:B.y,value:B.y};break}case"text":{if(B.position.space==="data"){const he=n.scale(B.position.x),be=i.scale(B.position.y),Ge=Qn(he,o),ze=ei(be,s);G=Ge,te=ze,X={...X,x:B.position.x,y:B.position.y,value:B.position.y}}else{const he=p+B.position.x*l,be=h+B.position.y*m;G=he,te=be,X={...X,x:B.position.x,y:B.position.y,value:B.position.y}}break}default:Xr(B)}if(G==null||te==null||!Number.isFinite(G)||!Number.isFinite(te))continue;const Q=((N=q==null?void 0:q.offset)==null?void 0:N[0])??0,ne=((A=q==null?void 0:q.offset)==null?void 0:A[1])??0,H=G+Q,O=te+ne,se=(q==null?void 0:q.text)??(q!=null&&q.template?Xo(q.template,X,q.decimals):q?(()=>{const he=B.type==="lineX"?"x={x}":B.type==="lineY"?"y={y}":B.type==="point"?"({x}, {y})":B.type==="text"?B.text:"";return he.includes("{")?Xo(he,X,q.decimals):he})():B.type==="text"?B.text:""),ce=typeof se=="string"?se.trim():"";if(ce.length===0)continue;const le=zc(q==null?void 0:q.anchor),me=((P=B.style)==null?void 0:P.color)??a.textColor,ge=a.fontSize,we=q==null?void 0:q.background,it=(we==null?void 0:we.color)!=null?_c(we.color,we.opacity??1):void 0,Ke=(()=>{const he=we==null?void 0:we.padding;return typeof he=="number"&&Number.isFinite(he)?[he,he,he,he]:Array.isArray(he)&&he.length===4&&he.every(be=>typeof be=="number"&&Number.isFinite(be))?[he[0],he[1],he[2],he[3]]:we?[2,4,2,4]:void 0})(),et=typeof(we==null?void 0:we.borderRadius)=="number"&&Number.isFinite(we.borderRadius)?we.borderRadius:void 0,ke={text:ce,x:c+H,y:u+O,anchor:le,color:me,fontSize:ge,...it?{background:{backgroundColor:it,...Ke?{padding:Ke}:{},...et!=null?{borderRadius:et}:{}}}:{}};y.push(ke)}return{linesBelow:C,linesAbove:F,markersBelow:R,markersAbove:S,labels:y}}function ia(e){return Math.max(0,Math.min(1,e))}function Oc(e){return e.type==="area"||e.type==="line"&&!!e.areaStyle}function $c(e,t){const{currentOptions:n,seriesForRender:i,xScale:r,yScale:o,gridArea:s,dataStore:a,appendedGpuThisFrame:c,gpuSeriesKindByIndex:u,zoomState:p,visibleXDomain:h,introPhase:l,introProgress01:m,withAlpha:C,maxRadiusCss:F}=t,R=n.yAxis.min??n.yAxis.min??0,S=[],y=l==="running"?ia(m):1;for(let d=0;d<i.length;d++){const g=i[d];switch(g.type){case"area":{const v=g.baseline??R;e.areaRenderers[d].prepare(g,g.data,r,o,v);break}case"line":{const v=(()=>{if(n.xAxis.type!=="time")return 0;const E=g.data;for(let f=0;f<E.length;f++){const x=E[f],N=ea(x)?x[0]:x.x;if(Number.isFinite(N))return N}return 0})();c.has(d)||a.setSeries(d,g.data,{xOffset:v});const M=a.getSeriesBuffer(d);e.lineRenderers[d].prepare(g,M,r,o,v);const I=(p==null?void 0:p.getRange())??null;if((I==null||Number.isFinite(I.start)&&Number.isFinite(I.end)&&I.start<=0&&I.end>=100)&&g.sampling==="none"?u[d]="fullRawLine":u[d]="other",g.areaStyle){const E={type:"area",name:g.name,rawData:g.data,data:g.data,color:g.areaStyle.color,areaStyle:g.areaStyle,sampling:g.sampling,samplingThreshold:g.samplingThreshold};e.areaRenderers[d].prepare(E,E.data,r,o,R)}break}case"bar":{S.push(g);break}case"scatter":{if(g.mode==="density"){const v=g.rawData??g.data,M=ja(v,h.min,h.max);c.has(d)||a.setSeries(d,v);const I=a.getSeriesBuffer(d),T=a.getSeriesPointCount(d);e.scatterDensityRenderers[d].prepare(g,I,T,M.start,M.end,r,o,s,g.rawBounds),u[d]="other"}else{const v=y<1?{...g,color:C(g.color,y)}:g;e.scatterRenderers[d].prepare(v,g.data,r,o,s)}break}case"pie":{if(y<1&&F>0){const v=ac(g.radius,F),M=Math.max(0,v.inner)*y,I=Math.max(M,v.outer)*y,T={...g,radius:[M,I]};e.pieRenderers[d].prepare(T,s);break}e.pieRenderers[d].prepare(g,s);break}case"candlestick":{e.candlestickRenderers[d].prepare(g,g.data,r,o,s,n.theme.backgroundColor);break}default:{const v=g;throw new Error(`Unhandled series type: ${v.type}`)}}}const b=i.map((d,g)=>({series:d,originalIndex:g})).filter(({series:d})=>d.visible!==!1),w=S.filter(d=>d.visible!==!1);return{visibleSeriesForRender:b,barSeriesConfigs:S,visibleBarSeriesConfigs:w}}function Wc(e,t,n){for(let i=0;i<t.length;i++){const r=t[i];r.visible!==!1&&r.type==="scatter"&&r.mode==="density"&&e.scatterDensityRenderers[i].encodeCompute(n)}}function Xc(e,t,n,i){const{hasCartesianSeries:r,gridArea:o,mainPass:s,plotScissor:a,introPhase:c,introProgress01:u,referenceLineBelowCount:p,markerBelowCount:h}=n,{visibleSeriesForRender:l}=i,m=c==="running"?ia(u):1;for(let C=0;C<l.length;C++){const{series:F,originalIndex:R}=l[C];F.type==="pie"&&e.pieRenderers[R].render(s)}r&&a.w>0&&a.h>0&&(p>0||h>0)&&(s.setScissorRect(a.x,a.y,a.w,a.h),p>0&&t.referenceLineRenderer.render(s,0,p),h>0&&t.annotationMarkerRenderer.render(s,0,h),s.setScissorRect(0,0,o.canvasWidth,o.canvasHeight));for(let C=0;C<l.length;C++){const{series:F,originalIndex:R}=l[C];if(Oc(F))if(m<1){const S=pn(Math.floor(a.w*m),0,a.w);S>0&&a.h>0&&(s.setScissorRect(a.x,a.y,S,a.h),e.areaRenderers[R].render(s),s.setScissorRect(0,0,o.canvasWidth,o.canvasHeight))}else s.setScissorRect(a.x,a.y,a.w,a.h),e.areaRenderers[R].render(s),s.setScissorRect(0,0,o.canvasWidth,o.canvasHeight)}a.w>0&&a.h>0&&(s.setScissorRect(a.x,a.y,a.w,a.h),e.barRenderer.render(s),s.setScissorRect(0,0,o.canvasWidth,o.canvasHeight));for(let C=0;C<l.length;C++){const{series:F,originalIndex:R}=l[C];F.type==="candlestick"&&e.candlestickRenderers[R].render(s)}for(let C=0;C<l.length;C++){const{series:F,originalIndex:R}=l[C];F.type==="scatter"&&(F.mode==="density"?e.scatterDensityRenderers[R].render(s):e.scatterRenderers[R].render(s))}for(let C=0;C<l.length;C++){const{series:F,originalIndex:R}=l[C];if(F.type==="line")if(m<1){const S=pn(Math.floor(a.w*m),0,a.w);S>0&&a.h>0&&(s.setScissorRect(a.x,a.y,S,a.h),e.lineRenderers[R].render(s),s.setScissorRect(0,0,o.canvasWidth,o.canvasHeight))}else s.setScissorRect(a.x,a.y,a.w,a.h),e.lineRenderers[R].render(s),s.setScissorRect(0,0,o.canvasWidth,o.canvasHeight)}}function Yc(e,t){const{hasCartesianSeries:n,gridArea:i,overlayPass:r,plotScissor:o,referenceLineBelowCount:s,referenceLineAboveCount:a,markerBelowCount:c,markerAboveCount:u}=t;if(n&&o.w>0&&o.h>0&&(a>0||u>0)){const h=s,l=c;r.setScissorRect(o.x,o.y,o.w,o.h),a>0&&e.referenceLineRendererMsaa.render(r,h,a),u>0&&e.annotationMarkerRendererMsaa.render(r,l,u),r.setScissorRect(0,0,i.canvasWidth,i.canvasHeight)}}const ji=`// grid.wgsl
|
|
2
|
+
// Minimal grid line shader:
|
|
3
|
+
// - Vertex input: vec2<f32> position in clip-space coordinates
|
|
4
|
+
// - Uniforms: identity transform + solid RGBA color
|
|
5
|
+
|
|
6
|
+
struct VSUniforms {
|
|
7
|
+
transform: mat4x4<f32>,
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
@group(0) @binding(0) var<uniform> vsUniforms: VSUniforms;
|
|
11
|
+
|
|
12
|
+
struct FSUniforms {
|
|
13
|
+
color: vec4<f32>,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
@group(0) @binding(1) var<uniform> fsUniforms: FSUniforms;
|
|
17
|
+
|
|
18
|
+
struct VSIn {
|
|
19
|
+
@location(0) position: vec2<f32>,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
struct VSOut {
|
|
23
|
+
@builtin(position) clipPosition: vec4<f32>,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
@vertex
|
|
27
|
+
fn vsMain(in: VSIn) -> VSOut {
|
|
28
|
+
var out: VSOut;
|
|
29
|
+
out.clipPosition = vsUniforms.transform * vec4<f32>(in.position, 0.0, 1.0);
|
|
30
|
+
return out;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@fragment
|
|
34
|
+
fn fsMain() -> @location(0) vec4<f32> {
|
|
35
|
+
return fsUniforms.color;
|
|
36
|
+
}
|
|
37
|
+
`,Hc="vsMain",qc="fsMain",Zc=e=>Number.isInteger(e)&&e>0&&(e&e-1)===0,jc=(e,t)=>{if(!Number.isFinite(e)||e<0)throw new Error(`alignTo(value): value must be a finite non-negative number. Received: ${String(e)}`);if(!Zc(t))throw new Error(`alignTo(alignment): alignment must be a positive power of two. Received: ${String(t)}`);return Math.floor(e)+t-1&~(t-1)},Yo=(e,t)=>"module"in t?{module:t.module,entryPoint:t.entryPoint||"",constants:t.constants}:{module:ra(e,t.code,t.label),entryPoint:t.entryPoint||"",constants:t.constants};function ra(e,t,n){if(typeof t!="string"||t.length===0)throw new Error("createShaderModule(code): WGSL code must be a non-empty string.");return e.createShaderModule({code:t,label:n})}function Tt(e,t){const n=t.layout??(t.bindGroupLayouts?e.createPipelineLayout({bindGroupLayouts:[...t.bindGroupLayouts]}):"auto"),i=Yo(e,t.vertex),r=i.entryPoint||Hc;let o;if(t.fragment){const c=Yo(e,t.fragment),u=c.entryPoint||qc;let p=t.fragment.targets;if(!p){const h=t.fragment.formats;if(!h)throw new Error("createRenderPipeline(fragment): provide either `fragment.targets` or `fragment.formats` when a fragment stage is present.");p=(Array.isArray(h)?h:[h]).map(m=>({format:m,blend:t.fragment.blend,writeMask:t.fragment.writeMask}))}o={module:c.module,entryPoint:u,targets:[...p],constants:c.constants}}const s=t.primitive??{topology:"triangle-list"},a=t.multisample??{count:1};return e.createRenderPipeline({label:t.label,layout:n,vertex:{module:i.module,entryPoint:r,buffers:t.vertex.buffers?[...t.vertex.buffers]:[],constants:i.constants},fragment:o,primitive:s,depthStencil:t.depthStencil,multisample:a})}function nt(e,t,n){if(!Number.isFinite(t)||t<=0)throw new Error(`createUniformBuffer(size): size must be a positive number. Received: ${String(t)}`);const i=(n==null?void 0:n.alignment)??16,r=jc(t,Math.max(4,i)),o=e.limits.maxUniformBufferBindingSize;if(r>o)throw new Error(`createUniformBuffer(size): requested size ${r} exceeds device.limits.maxUniformBufferBindingSize (${o}).`);return e.createBuffer({label:n==null?void 0:n.label,size:r,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST})}function Qe(e,t,n){const i=n instanceof ArrayBuffer?{arrayBuffer:n,offset:0,size:n.byteLength}:{arrayBuffer:n.buffer,offset:n.byteOffset,size:n.byteLength};if(i.size!==0){if(i.offset&3||i.size&3)throw new Error(`writeUniformBuffer(data): data byteOffset (${i.offset}) and byteLength (${i.size}) must be multiples of 4 for queue.writeBuffer().`);if(i.size>t.size)throw new Error(`writeUniformBuffer(data): data byteLength (${i.size}) exceeds buffer.size (${t.size}).`);e.queue.writeBuffer(t,0,i.arrayBuffer,i.offset,i.size)}}const Kc="bgra8unorm",Jc=5,Qc=6,el=[1,1,1,.8],tl=()=>{const e=new ArrayBuffer(64);return new Float32Array(e).set([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),e},nl=e=>Number.isFinite(e.left)&&Number.isFinite(e.right)&&Number.isFinite(e.top)&&Number.isFinite(e.bottom)&&Number.isFinite(e.canvasWidth)&&Number.isFinite(e.canvasHeight),Ho=e=>typeof e=="number"&&Number.isFinite(e)?e:void 0,il=(e,t)=>{let n=e,i=t;if((!Number.isFinite(n)||!Number.isFinite(i))&&(n=0,i=1),n===i)i=n+1;else if(n>i){const r=n;n=i,i=r}return{min:n,max:i}},rl=(e,t,n,i,r)=>{const{left:o,right:s,top:a,bottom:c,canvasWidth:u,canvasHeight:p}=i,h=Number.isFinite(i.devicePixelRatio)&&i.devicePixelRatio>0?i.devicePixelRatio:1;if(!nl(i))throw new Error("AxisRenderer.prepare: gridArea dimensions must be finite numbers.");if(u<=0||p<=0)throw new Error("AxisRenderer.prepare: canvas dimensions must be positive.");if(o<0||s<0||a<0||c<0)throw new Error("AxisRenderer.prepare: gridArea margins must be non-negative.");const l=o*h,m=u-s*h,C=a*h,F=p-c*h,R=l/u*2-1,S=m/u*2-1,y=1-C/p*2,b=1-F/p*2,w=e.tickLength??Qc;if(!Number.isFinite(w)||w<0)throw new Error("AxisRenderer.prepare: tickLength must be a finite non-negative number.");const d=r??Jc,g=Math.max(1,Math.floor(d));if(!Number.isFinite(d)||g<1)throw new Error("AxisRenderer.prepare: tickCount must be a finite number >= 1.");const v=w*h,M=v/u*2,I=v/p*2,T=Ho(e.min)??(n==="x"?t.invert(R):t.invert(b)),E=Ho(e.max)??(n==="x"?t.invert(S):t.invert(y)),f=il(T,E),x=f.min,N=f.max,A=1+g,P=new Float32Array(A*2*2);let L=0;if(n==="x"){P[L++]=R,P[L++]=b,P[L++]=S,P[L++]=b;const B=b,V=B-I;for(let _=0;_<g;_++){const re=g===1?.5:_/(g-1),Y=x+re*(N-x),W=t.scale(Y);P[L++]=W,P[L++]=B,P[L++]=W,P[L++]=V}}else{P[L++]=R,P[L++]=b,P[L++]=R,P[L++]=y;const B=R,V=B-M;for(let _=0;_<g;_++){const re=g===1?.5:_/(g-1),Y=x+re*(N-x),W=t.scale(Y);P[L++]=B,P[L++]=W,P[L++]=V,P[L++]=W}}return P};function qo(e,t){let n=!1;const i=(t==null?void 0:t.targetFormat)??Kc,r=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),o=nt(e,64,{label:"axisRenderer/vsUniforms"}),s=nt(e,16,{label:"axisRenderer/fsUniformsLine"}),a=nt(e,16,{label:"axisRenderer/fsUniformsTick"}),c=e.createBindGroup({layout:r,entries:[{binding:0,resource:{buffer:o}},{binding:1,resource:{buffer:s}}]}),u=e.createBindGroup({layout:r,entries:[{binding:0,resource:{buffer:o}},{binding:1,resource:{buffer:a}}]}),p=Tt(e,{label:"axisRenderer/pipeline",bindGroupLayouts:[r],vertex:{code:ji,label:"grid.wgsl",buffers:[{arrayStride:8,stepMode:"vertex",attributes:[{shaderLocation:0,format:"float32x2",offset:0}]}]},fragment:{code:ji,label:"grid.wgsl",formats:i,blend:{color:{operation:"add",srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{operation:"add",srcFactor:"one",dstFactor:"one-minus-src-alpha"}}},primitive:{topology:"line-list",cullMode:"none"},multisample:{count:1}});let h=null,l=0;const m=()=>{if(n)throw new Error("AxisRenderer is disposed.")};return{prepare:(S,y,b,w,d,g,v)=>{if(m(),b!=="x"&&b!=="y")throw new Error("AxisRenderer.prepare: orientation must be 'x' or 'y'.");const M=rl(S,y,b,w,v),I=M.byteLength,T=Math.max(4,I);if(!h||h.size<T){if(h)try{h.destroy()}catch{}h=e.createBuffer({label:"axisRenderer/vertexBuffer",size:T,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST})}e.queue.writeBuffer(h,0,M.buffer,0,M.byteLength),l=M.length/2,Qe(e,o,tl());const E=d??"rgba(255,255,255,0.8)",f=g??E,x=pt(E)??el,N=pt(f)??x,A=new ArrayBuffer(4*4);new Float32Array(A).set([x[0],x[1],x[2],x[3]]),Qe(e,s,A);const P=new ArrayBuffer(4*4);new Float32Array(P).set([N[0],N[1],N[2],N[3]]),Qe(e,a,P)},render:S=>{m(),!(l===0||!h)&&(S.setPipeline(p),S.setVertexBuffer(0,h),S.setBindGroup(0,c),S.draw(Math.min(2,l)),l>2&&(S.setBindGroup(0,u),S.draw(l-2,1,2,0)))},dispose:()=>{if(!n){n=!0;try{o.destroy()}catch{}try{s.destroy()}catch{}try{a.destroy()}catch{}if(h)try{h.destroy()}catch{}h=null,l=0}}}}const ol="bgra8unorm",sl=5,al=6,cl="rgba(255,255,255,0.15)",ll=[1,1,1,.15],ul=()=>{const e=new ArrayBuffer(64);return new Float32Array(e).set([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),e},fl=(e,t,n)=>{const{left:i,right:r,top:o,bottom:s,canvasWidth:a,canvasHeight:c}=e,u=Number.isFinite(e.devicePixelRatio)&&e.devicePixelRatio>0?e.devicePixelRatio:1,p=i*u,h=a-r*u,l=o*u,m=c-s*u,C=h-p,F=m-l,R=t+n,S=new Float32Array(R*2*2);let y=0;for(let b=0;b<t;b++){const w=t===1?.5:b/(t-1),d=l+w*F,g=p/a*2-1,v=h/a*2-1,M=1-d/c*2;S[y++]=g,S[y++]=M,S[y++]=v,S[y++]=M}for(let b=0;b<n;b++){const w=n===1?.5:b/(n-1),g=(p+w*C)/a*2-1,v=1-l/c*2,M=1-m/c*2;S[y++]=g,S[y++]=v,S[y++]=g,S[y++]=M}return S};function dl(e,t){let n=!1;const i=(t==null?void 0:t.targetFormat)??ol,r=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),o=nt(e,64,{label:"gridRenderer/vsUniforms"}),s=nt(e,16,{label:"gridRenderer/fsUniforms"}),a=e.createBindGroup({layout:r,entries:[{binding:0,resource:{buffer:o}},{binding:1,resource:{buffer:s}}]}),c=Tt(e,{label:"gridRenderer/pipeline",bindGroupLayouts:[r],vertex:{code:ji,label:"grid.wgsl",buffers:[{arrayStride:8,stepMode:"vertex",attributes:[{shaderLocation:0,format:"float32x2",offset:0}]}]},fragment:{code:ji,label:"grid.wgsl",formats:i,blend:{color:{operation:"add",srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{operation:"add",srcFactor:"one",dstFactor:"one-minus-src-alpha"}}},primitive:{topology:"line-list",cullMode:"none"},multisample:{count:1}});let u=null,p=0;const h=()=>{if(n)throw new Error("GridRenderer is disposed.")};return{prepare:(F,R)=>{h();const S=R!=null&&typeof R=="object"&&("lineCount"in R||"color"in R),y=S?R:void 0,b=S?y==null?void 0:y.lineCount:R,w=(b==null?void 0:b.horizontal)??sl,d=(b==null?void 0:b.vertical)??al,g=(y==null?void 0:y.color)??cl;if(w<0||d<0)throw new Error("GridRenderer.prepare: line counts must be non-negative.");if(!Number.isFinite(F.left)||!Number.isFinite(F.right)||!Number.isFinite(F.top)||!Number.isFinite(F.bottom)||!Number.isFinite(F.canvasWidth)||!Number.isFinite(F.canvasHeight))throw new Error("GridRenderer.prepare: gridArea dimensions must be finite numbers.");if(F.canvasWidth<=0||F.canvasHeight<=0)throw new Error("GridRenderer.prepare: canvas dimensions must be positive.");if(w===0&&d===0){p=0;return}const v=fl(F,w,d),M=v.byteLength,I=Math.max(4,M);if(!u||u.size<I){if(u)try{u.destroy()}catch{}u=e.createBuffer({label:"gridRenderer/vertexBuffer",size:I,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST})}e.queue.writeBuffer(u,0,v.buffer,0,v.byteLength),p=(w+d)*2;const T=ul();Qe(e,o,T);const E=pt(g)??ll,f=new ArrayBuffer(4*4);new Float32Array(f).set([E[0],E[1],E[2],E[3]]),Qe(e,s,f)},render:F=>{h(),!(p===0||!u)&&(F.setPipeline(c),F.setBindGroup(0,a),F.setVertexBuffer(0,u),F.draw(p))},dispose:()=>{if(!n){n=!0;try{o.destroy()}catch{}try{s.destroy()}catch{}if(u)try{u.destroy()}catch{}u=null,p=0}}}}const Zo=`// area.wgsl
|
|
38
|
+
// Minimal area-fill shader (triangle-strip):
|
|
39
|
+
// - Vertex input: vec2<f32> position in data coords
|
|
40
|
+
// - Uniforms: clip-space transform + baseline value + solid RGBA color
|
|
41
|
+
// - Topology: triangle-strip
|
|
42
|
+
// - CPU duplicates vertices as p0,p0,p1,p1,... and we use vertex_index parity:
|
|
43
|
+
// even index -> "top" vertex (original y)
|
|
44
|
+
// odd index -> "baseline" vertex (uniform baseline)
|
|
45
|
+
|
|
46
|
+
struct VSUniforms {
|
|
47
|
+
transform: mat4x4<f32>,
|
|
48
|
+
baseline: f32,
|
|
49
|
+
// Pad to 16-byte multiple (uniform buffer layout requirements).
|
|
50
|
+
_pad0: vec3<f32>,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
@group(0) @binding(0) var<uniform> vsUniforms: VSUniforms;
|
|
54
|
+
|
|
55
|
+
struct FSUniforms {
|
|
56
|
+
color: vec4<f32>,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
@group(0) @binding(1) var<uniform> fsUniforms: FSUniforms;
|
|
60
|
+
|
|
61
|
+
struct VSIn {
|
|
62
|
+
@location(0) position: vec2<f32>,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
struct VSOut {
|
|
66
|
+
@builtin(position) clipPosition: vec4<f32>,
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
@vertex
|
|
70
|
+
fn vsMain(in: VSIn, @builtin(vertex_index) vertexIndex: u32) -> VSOut {
|
|
71
|
+
var out: VSOut;
|
|
72
|
+
let useBaseline = (vertexIndex & 1u) == 1u;
|
|
73
|
+
let y = select(in.position.y, vsUniforms.baseline, useBaseline);
|
|
74
|
+
let pos = vec2<f32>(in.position.x, y);
|
|
75
|
+
out.clipPosition = vsUniforms.transform * vec4<f32>(pos, 0.0, 1.0);
|
|
76
|
+
return out;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@fragment
|
|
80
|
+
fn fsMain() -> @location(0) vec4<f32> {
|
|
81
|
+
return fsUniforms.color;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
`,ml="bgra8unorm",jo=e=>Math.min(1,Math.max(0,e)),pl=e=>pt(e)??[0,0,0,1],hl=e=>Array.isArray(e),oa=e=>hl(e)?{x:e[0],y:e[1]}:{x:e.x,y:e.y},yl=e=>{let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;for(let o=0;o<e.length;o++){const{x:s,y:a}=oa(e[o]);!Number.isFinite(s)||!Number.isFinite(a)||(s<t&&(t=s),s>n&&(n=s),a<i&&(i=a),a>r&&(r=a))}return!Number.isFinite(t)||!Number.isFinite(n)||!Number.isFinite(i)||!Number.isFinite(r)?{xMin:0,xMax:1,yMin:0,yMax:1}:(t===n&&(n=t+1),i===r&&(r=i+1),{xMin:t,xMax:n,yMin:i,yMax:r})},Ko=(e,t,n)=>{const i=e.scale(t),r=e.scale(n);if(!Number.isFinite(t)||!Number.isFinite(n)||t===n||!Number.isFinite(i)||!Number.isFinite(r))return{a:0,b:Number.isFinite(i)?i:0};const o=(r-i)/(n-t),s=i-o*t;return{a:Number.isFinite(o)?o:0,b:Number.isFinite(s)?s:0}},gl=(e,t,n,i,r)=>{e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=i,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=n,e[13]=r,e[14]=0,e[15]=1},xl=e=>{const t=e.length,n=new Float32Array(t*2*2);let i=0;for(let r=0;r<t;r++){const{x:o,y:s}=oa(e[r]);n[i++]=o,n[i++]=s,n[i++]=o,n[i++]=s}return n};function bl(e,t){let n=!1;const i=(t==null?void 0:t.targetFormat)??ml,r=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),o=nt(e,96,{label:"areaRenderer/vsUniforms"}),s=nt(e,16,{label:"areaRenderer/fsUniforms"}),a=new ArrayBuffer(96),c=new Float32Array(a),u=new Float32Array(4),p=e.createBindGroup({layout:r,entries:[{binding:0,resource:{buffer:o}},{binding:1,resource:{buffer:s}}]}),h=Tt(e,{label:"areaRenderer/pipeline",bindGroupLayouts:[r],vertex:{code:Zo,label:"area.wgsl",buffers:[{arrayStride:8,stepMode:"vertex",attributes:[{shaderLocation:0,format:"float32x2",offset:0}]}]},fragment:{code:Zo,label:"area.wgsl",formats:i,blend:{color:{operation:"add",srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{operation:"add",srcFactor:"one",dstFactor:"one-minus-src-alpha"}}},primitive:{topology:"triangle-strip",cullMode:"none"},multisample:{count:1}});let l=null,m=0;const C=()=>{if(n)throw new Error("AreaRenderer is disposed.")},F=(b,w,d,g,v)=>{gl(c,b,w,d,g),c[16]=v,c[17]=0,c[18]=0,c[19]=0,c[20]=0,c[21]=0,c[22]=0,c[23]=0,Qe(e,o,a)};return{prepare:(b,w,d,g,v)=>{C();const M=xl(w),I=M.byteLength,T=Math.max(4,I);if(!l||l.size<T){if(l)try{l.destroy()}catch{}l=e.createBuffer({label:"areaRenderer/vertexBuffer",size:T,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST})}M.byteLength>0&&e.queue.writeBuffer(l,0,M.buffer,0,M.byteLength),m=M.length/2;const{xMin:E,xMax:f,yMin:x,yMax:N}=yl(w),{a:A,b:P}=Ko(d,E,f),{a:L,b:B}=Ko(g,x,N),V=Number.isFinite(v??Number.NaN)?v:Number.isFinite(x)?x:0;F(A,P,L,B,V);const[_,re,Y,W]=pl(b.areaStyle.color),Z=jo(b.areaStyle.opacity);u[0]=_,u[1]=re,u[2]=Y,u[3]=jo(W*Z),Qe(e,s,u)},render:b=>{C(),!(!l||m<4)&&(b.setPipeline(h),b.setBindGroup(0,p),b.setVertexBuffer(0,l),b.draw(m))},dispose:()=>{if(!n){if(n=!0,l)try{l.destroy()}catch{}l=null,m=0;try{o.destroy()}catch{}try{s.destroy()}catch{}}}}}const Jo=`// line.wgsl
|
|
85
|
+
// Minimal line-strip shader:
|
|
86
|
+
// - Vertex input: vec2<f32> position in data coords
|
|
87
|
+
// - Uniforms: clip-space transform + solid RGBA color
|
|
88
|
+
|
|
89
|
+
struct VSUniforms {
|
|
90
|
+
transform: mat4x4<f32>,
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
@group(0) @binding(0) var<uniform> vsUniforms: VSUniforms;
|
|
94
|
+
|
|
95
|
+
struct FSUniforms {
|
|
96
|
+
color: vec4<f32>,
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
@group(0) @binding(1) var<uniform> fsUniforms: FSUniforms;
|
|
100
|
+
|
|
101
|
+
struct VSIn {
|
|
102
|
+
@location(0) position: vec2<f32>,
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
struct VSOut {
|
|
106
|
+
@builtin(position) clipPosition: vec4<f32>,
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
@vertex
|
|
110
|
+
fn vsMain(in: VSIn) -> VSOut {
|
|
111
|
+
var out: VSOut;
|
|
112
|
+
out.clipPosition = vsUniforms.transform * vec4<f32>(in.position, 0.0, 1.0);
|
|
113
|
+
return out;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
@fragment
|
|
117
|
+
fn fsMain() -> @location(0) vec4<f32> {
|
|
118
|
+
return fsUniforms.color;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
`,vl="bgra8unorm",Qo=e=>Math.min(1,Math.max(0,e)),wl=e=>pt(e)??[0,0,0,1],Cl=e=>Array.isArray(e),Ml=e=>Cl(e)?{x:e[0],y:e[1]}:{x:e.x,y:e.y},Fl=e=>{let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;for(let o=0;o<e.length;o++){const{x:s,y:a}=Ml(e[o]);!Number.isFinite(s)||!Number.isFinite(a)||(s<t&&(t=s),s>n&&(n=s),a<i&&(i=a),a>r&&(r=a))}return!Number.isFinite(t)||!Number.isFinite(n)||!Number.isFinite(i)||!Number.isFinite(r)?{xMin:0,xMax:1,yMin:0,yMax:1}:(t===n&&(n=t+1),i===r&&(r=i+1),{xMin:t,xMax:n,yMin:i,yMax:r})},es=(e,t,n)=>{const i=e.scale(t),r=e.scale(n);if(!Number.isFinite(t)||!Number.isFinite(n)||t===n||!Number.isFinite(i)||!Number.isFinite(r))return{a:0,b:Number.isFinite(i)?i:0};const o=(r-i)/(n-t),s=i-o*t;return{a:Number.isFinite(o)?o:0,b:Number.isFinite(s)?s:0}},Sl=(e,t,n,i,r)=>{e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=i,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=n,e[13]=r,e[14]=0,e[15]=1};function Nl(e,t){let n=!1;const i=(t==null?void 0:t.targetFormat)??vl,r=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),o=nt(e,64,{label:"lineRenderer/vsUniforms"}),s=nt(e,16,{label:"lineRenderer/fsUniforms"}),a=new ArrayBuffer(64),c=new Float32Array(a),u=new Float32Array(4),p=e.createBindGroup({layout:r,entries:[{binding:0,resource:{buffer:o}},{binding:1,resource:{buffer:s}}]}),h=Tt(e,{label:"lineRenderer/pipeline",bindGroupLayouts:[r],vertex:{code:Jo,label:"line.wgsl",buffers:[{arrayStride:8,stepMode:"vertex",attributes:[{shaderLocation:0,format:"float32x2",offset:0}]}]},fragment:{code:Jo,label:"line.wgsl",formats:i,blend:{color:{operation:"add",srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{operation:"add",srcFactor:"one",dstFactor:"one-minus-src-alpha"}}},primitive:{topology:"line-strip",cullMode:"none"},multisample:{count:1}});let l=null,m=0;const C=()=>{if(n)throw new Error("LineRenderer is disposed.")};return{prepare:(y,b,w,d,g=0)=>{C(),l=b;const v=y.data;m=v.length;const{xMin:M,xMax:I,yMin:T,yMax:E}=Fl(v),{a:f,b:x}=es(w,M,I),{a:N,b:A}=es(d,T,E),P=x+f*g;Sl(c,f,P,N,A),Qe(e,o,a);const[L,B,V,_]=wl(y.color),re=Qo(y.lineStyle.opacity);u[0]=L,u[1]=B,u[2]=V,u[3]=Qo(_*re),Qe(e,s,u)},render:y=>{C(),!(!l||m<2)&&(y.setPipeline(h),y.setBindGroup(0,p),y.setVertexBuffer(0,l),y.draw(m))},dispose:()=>{if(!n){n=!0,l=null,m=0;try{o.destroy()}catch{}try{s.destroy()}catch{}}}}}const ts=`// bar.wgsl
|
|
122
|
+
// Instanced bar/rect shader:
|
|
123
|
+
// - Per-instance vertex input:
|
|
124
|
+
// - rect = vec4<f32>(x, y, width, height) in CLIP space
|
|
125
|
+
// - color = vec4<f32>(r, g, b, a) in [0..1]
|
|
126
|
+
// - Draw call: draw(6, instanceCount) using triangle-list expansion in VS
|
|
127
|
+
// - Uniforms:
|
|
128
|
+
// - @group(0) @binding(0): VSUniforms { transform }
|
|
129
|
+
|
|
130
|
+
struct VSUniforms {
|
|
131
|
+
transform: mat4x4<f32>,
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
@group(0) @binding(0) var<uniform> vsUniforms: VSUniforms;
|
|
135
|
+
|
|
136
|
+
struct VSIn {
|
|
137
|
+
// rect.xy = origin, rect.zw = size (width, height)
|
|
138
|
+
@location(0) rect: vec4<f32>,
|
|
139
|
+
@location(1) color: vec4<f32>,
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
struct VSOut {
|
|
143
|
+
@builtin(position) clipPosition: vec4<f32>,
|
|
144
|
+
@location(0) color: vec4<f32>,
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
@vertex
|
|
148
|
+
fn vsMain(in: VSIn, @builtin(vertex_index) vertexIndex: u32) -> VSOut {
|
|
149
|
+
// Fixed local corners for 2 triangles (triangle-list).
|
|
150
|
+
let corners = array<vec2<f32>, 6>(
|
|
151
|
+
vec2<f32>(0.0, 0.0),
|
|
152
|
+
vec2<f32>(1.0, 0.0),
|
|
153
|
+
vec2<f32>(0.0, 1.0),
|
|
154
|
+
vec2<f32>(0.0, 1.0),
|
|
155
|
+
vec2<f32>(1.0, 0.0),
|
|
156
|
+
vec2<f32>(1.0, 1.0)
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
// Normalize negative width/height by computing min/max extents.
|
|
160
|
+
let p0 = in.rect.xy;
|
|
161
|
+
let p1 = in.rect.xy + in.rect.zw;
|
|
162
|
+
let rectMin = min(p0, p1);
|
|
163
|
+
let rectMax = max(p0, p1);
|
|
164
|
+
let rectSize = rectMax - rectMin;
|
|
165
|
+
|
|
166
|
+
let corner = corners[vertexIndex];
|
|
167
|
+
let pos = rectMin + corner * rectSize;
|
|
168
|
+
|
|
169
|
+
var out: VSOut;
|
|
170
|
+
out.clipPosition = vsUniforms.transform * vec4<f32>(pos, 0.0, 1.0);
|
|
171
|
+
out.color = in.color;
|
|
172
|
+
return out;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
@fragment
|
|
176
|
+
fn fsMain(in: VSOut) -> @location(0) vec4<f32> {
|
|
177
|
+
return in.color;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
`,Tl="bgra8unorm",Il=.01,Pl=.2,Ui=32,Tr=Ui/4,Ir=e=>Math.min(1,Math.max(0,e)),Al=e=>pt(e)??[0,0,0,1],ns=e=>{if(!Number.isFinite(e)||e<=0)return 1;const t=Math.ceil(e);return 2**Math.ceil(Math.log2(t))},Rl=()=>{const e=new ArrayBuffer(64);return new Float32Array(e).set([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),e},El=e=>{const t=e.trim().match(/^(\d+(?:\.\d+)?)%$/);if(!t)return null;const n=Number(t[1])/100;return Number.isFinite(n)?n:null},is=e=>{if(typeof e!="string")return"";const t=e.trim();return t.length>0?t:""},Dl=e=>Array.isArray(e),Pr=e=>Dl(e)?{x:e[0],y:e[1]}:{x:e.x,y:e.y},Bl=e=>{const t=e.devicePixelRatio;if(!(t>0))return null;const n=e.canvasWidth/t,i=e.canvasHeight/t,r=n-e.left-e.right,o=i-e.top-e.bottom;return!(r>0)||!(o>0)?null:{plotWidthCss:r,plotHeightCss:o}},Ll=e=>{const{left:t,right:n,top:i,bottom:r,canvasWidth:o,canvasHeight:s,devicePixelRatio:a}=e,c=t*a,u=o-n*a,p=i*a,h=s-r*a,l=c/o*2-1,m=u/o*2-1,C=1-p/s*2,F=1-h/s*2;return{left:l,right:m,top:C,bottom:F}},kl=(e,t,n,i)=>{if(Number.isFinite(t)&&t>0){const a=e.scale(0),c=e.scale(0+t),u=Math.abs(c-a);if(Number.isFinite(u)&&u>0)return u}const r=Math.abs(n.right-n.left);if(!(r>0))return 0;const o=Math.max(1,Math.floor(i));return r/o};function Ul(e,t){let n=!1;const i=(t==null?void 0:t.targetFormat)??Tl,r=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}}]}),o=nt(e,64,{label:"barRenderer/vsUniforms"});Qe(e,o,Rl());const s=e.createBindGroup({layout:r,entries:[{binding:0,resource:{buffer:o}}]}),a=Tt(e,{label:"barRenderer/pipeline",bindGroupLayouts:[r],vertex:{code:ts,label:"bar.wgsl",buffers:[{arrayStride:Ui,stepMode:"instance",attributes:[{shaderLocation:0,format:"float32x4",offset:0},{shaderLocation:1,format:"float32x4",offset:16}]}]},fragment:{code:ts,label:"bar.wgsl",formats:i,blend:{color:{operation:"add",srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{operation:"add",srcFactor:"one",dstFactor:"one-minus-src-alpha"}}},primitive:{topology:"triangle-list",cullMode:"none"},multisample:{count:1}});let c=null,u=0,p=new ArrayBuffer(0),h=new Float32Array(p);const l=[],m=()=>{if(n)throw new Error("BarRenderer is disposed.")},C=g=>{if(g<=h.length)return;const v=Math.max(8,ns(g));p=new ArrayBuffer(v*4),h=new Float32Array(p)},F=g=>{l.length=0;for(let M=0;M<g.length;M++){const I=g[M].data;for(let T=0;T<I.length;T++){const{x:E}=Pr(I[T]);Number.isFinite(E)&&l.push(E)}}if(l.length<2)return 1;l.sort((M,I)=>M-I);let v=Number.POSITIVE_INFINITY;for(let M=1;M<l.length;M++){const I=l[M]-l[M-1];I>0&&I<v&&(v=I)}return Number.isFinite(v)&&v>0?v:1},R=g=>{let v,M,I;for(let T=0;T<g.length;T++){const E=g[T];v===void 0&&E.barWidth!==void 0&&(v=E.barWidth),M===void 0&&E.barGap!==void 0&&(M=E.barGap),I===void 0&&E.barCategoryGap!==void 0&&(I=E.barCategoryGap)}return{barWidth:v,barGap:M,barCategoryGap:I}},S=g=>{let v=Number.POSITIVE_INFINITY,M=Number.NEGATIVE_INFINITY;for(let I=0;I<g.length;I++){const T=g[I].data;for(let E=0;E<T.length;E++){const{y:f}=Pr(T[E]);Number.isFinite(f)&&(f<v&&(v=f),f>M&&(M=f))}}return!Number.isFinite(v)||!Number.isFinite(M)||v<=0&&0<=M?0:Math.abs(v)<Math.abs(M)?v:M},y=(g,v,M)=>{const I=v.invert(M.bottom),T=v.invert(M.top),E=Math.min(I,T),f=Math.max(I,T);return!Number.isFinite(E)||!Number.isFinite(f)?S(g):E<=0&&0<=f?0:E>0?E:f<0?f:S(g)};return{prepare:(g,v,M,I,T)=>{if(m(),g.length===0){u=0;return}const E=Bl(T);if(!E){u=0;return}const f=Ll(T),x=f.right-f.left,N=E.plotWidthCss>0?x/E.plotWidthCss:0,A=new Map,P=new Array(g.length);let L=0;for(let le=0;le<g.length;le++){const me=is(g[le].stack);if(me!==""){const ge=A.get(me);if(ge!==void 0)P[le]=ge;else{const we=L++;A.set(me,we),P[le]=we}}else P[le]=L++}L=Math.max(1,L);const B=F(g),V=R(g),_=Ir(V.barGap??Il),re=Ir(V.barCategoryGap??Pl);let Y=1;for(let le=0;le<g.length;le++){const me=g[le].data.length;Y=Math.max(Y,Math.floor(me))}const W=kl(M,B,f,Y),Z=Math.max(0,W*(1-re)),oe=L+Math.max(0,L-1)*_,ee=oe>0?Z/oe:0;let q=0;const de=V.barWidth;if(typeof de=="number")q=Math.max(0,de)*N,q=Math.min(q,ee);else if(typeof de=="string"){const le=El(de);q=le==null?0:ee*Ir(le)}q>0||(q=ee);const G=q*_,te=L*q+Math.max(0,L-1)*G;let X=y(g,I,f),Q=I.scale(X);if(!Number.isFinite(Q)){const le=S(g);if(X=le,Q=I.scale(le),Number.isFinite(Q)||(X=0,Q=I.scale(0)),!Number.isFinite(Q)){u=0;return}}let ne=0;for(let le=0;le<g.length;le++)ne+=Math.max(0,g[le].data.length);C(ne*Tr);const H=h;let O=0;const se=new Map;for(let le=0;le<g.length;le++){const me=g[le],ge=me.data,[we,it,Ke,et]=Al(me.color),ke=is(me.stack),he=P[le]??0;for(let be=0;be<ge.length;be++){const{x:Ge,y:ze}=Pr(ge[be]),rt=M.scale(Ge);if(!Number.isFinite(rt)||!Number.isFinite(ze))continue;const Ze=rt-te/2+he*(q+G);let ht=Q,gt=0;if(ke!==""){let ot=se.get(ke);ot||(ot=new Map,se.set(ke,ot));let Ft;Number.isFinite(W)&&W>0&&Number.isFinite(rt)?Ft=Math.round((rt-f.left)/W):Number.isFinite(B)&&B>0?Ft=Math.round(Ge/B):Ft=Math.round(Ge*1e6);let It=ot.get(Ft);It||(It={posSum:X,negSum:X},ot.set(Ft,It));let Bt,Lt;ze>=0?(Bt=It.posSum,Lt=Bt+ze,It.posSum=Lt):(Bt=It.negSum,Lt=Bt+ze,It.negSum=Lt);const k=I.scale(Bt),j=I.scale(Lt);if(!Number.isFinite(k)||!Number.isFinite(j))continue;ht=k,gt=j-k}else{const ot=I.scale(ze);if(!Number.isFinite(ot))continue;gt=ot-Q}H[O+0]=Ze,H[O+1]=ht,H[O+2]=q,H[O+3]=gt,H[O+4]=we,H[O+5]=it,H[O+6]=Ke,H[O+7]=et,O+=Tr}}u=O/Tr;const ce=Math.max(4,u*Ui);if(!c||c.size<ce){const le=Math.max(Math.max(4,ns(ce)),c?c.size:0);if(c)try{c.destroy()}catch{}c=e.createBuffer({label:"barRenderer/instanceBuffer",size:le,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST})}u>0&&e.queue.writeBuffer(c,0,p,0,u*Ui)},render:g=>{m(),!(!c||u===0)&&(g.setPipeline(a),g.setBindGroup(0,s),g.setVertexBuffer(0,c),g.draw(6,u))},dispose:()=>{if(!n){if(n=!0,c)try{c.destroy()}catch{}c=null,u=0;try{o.destroy()}catch{}}}}}const rs=`// scatter.wgsl
|
|
181
|
+
// Instanced anti-aliased circle shader (SDF):
|
|
182
|
+
// - Per-instance vertex input:
|
|
183
|
+
// - center = vec2<f32> point center (transformed by VSUniforms.transform)
|
|
184
|
+
// - radiusPx = f32 circle radius in pixels
|
|
185
|
+
// - Draw call: draw(6, instanceCount) using triangle-list expansion in VS
|
|
186
|
+
// - Uniforms:
|
|
187
|
+
// - @group(0) @binding(0): VSUniforms { transform, viewportPx }
|
|
188
|
+
// - @group(0) @binding(1): FSUniforms { color }
|
|
189
|
+
//
|
|
190
|
+
// Notes:
|
|
191
|
+
// - \`viewportPx\` is the current render target size in pixels (width, height).
|
|
192
|
+
// - The quad is expanded in clip space using \`radiusPx\` and \`viewportPx\`.
|
|
193
|
+
|
|
194
|
+
struct VSUniforms {
|
|
195
|
+
transform: mat4x4<f32>,
|
|
196
|
+
viewportPx: vec2<f32>,
|
|
197
|
+
// Pad to 16-byte alignment (mat4x4 is 64B; vec2 adds 8B; pad to 80B).
|
|
198
|
+
_pad0: vec2<f32>,
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
@group(0) @binding(0) var<uniform> vsUniforms: VSUniforms;
|
|
202
|
+
|
|
203
|
+
struct FSUniforms {
|
|
204
|
+
color: vec4<f32>,
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
@group(0) @binding(1) var<uniform> fsUniforms: FSUniforms;
|
|
208
|
+
|
|
209
|
+
struct VSIn {
|
|
210
|
+
@location(0) center: vec2<f32>,
|
|
211
|
+
@location(1) radiusPx: f32,
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
struct VSOut {
|
|
215
|
+
@builtin(position) clipPosition: vec4<f32>,
|
|
216
|
+
@location(0) localPx: vec2<f32>,
|
|
217
|
+
@location(1) radiusPx: f32,
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
@vertex
|
|
221
|
+
fn vsMain(in: VSIn, @builtin(vertex_index) vertexIndex: u32) -> VSOut {
|
|
222
|
+
// Fixed local corners for 2 triangles (triangle-list).
|
|
223
|
+
// \`localNdc\` is a quad in [-1, 1]^2; we convert it to pixel offsets via radiusPx.
|
|
224
|
+
let localNdc = array<vec2<f32>, 6>(
|
|
225
|
+
vec2<f32>(-1.0, -1.0),
|
|
226
|
+
vec2<f32>( 1.0, -1.0),
|
|
227
|
+
vec2<f32>(-1.0, 1.0),
|
|
228
|
+
vec2<f32>(-1.0, 1.0),
|
|
229
|
+
vec2<f32>( 1.0, -1.0),
|
|
230
|
+
vec2<f32>( 1.0, 1.0)
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
let corner = localNdc[vertexIndex];
|
|
234
|
+
let localPx = corner * in.radiusPx;
|
|
235
|
+
|
|
236
|
+
// Convert pixel offset to clip-space offset.
|
|
237
|
+
// Clip space spans [-1, 1] across the viewport, so px -> clip is (2 / viewportPx).
|
|
238
|
+
let localClip = localPx * (2.0 / vsUniforms.viewportPx);
|
|
239
|
+
|
|
240
|
+
let centerClip = (vsUniforms.transform * vec4<f32>(in.center, 0.0, 1.0)).xy;
|
|
241
|
+
|
|
242
|
+
var out: VSOut;
|
|
243
|
+
out.clipPosition = vec4<f32>(centerClip + localClip, 0.0, 1.0);
|
|
244
|
+
out.localPx = localPx;
|
|
245
|
+
out.radiusPx = in.radiusPx;
|
|
246
|
+
return out;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
@fragment
|
|
250
|
+
fn fsMain(in: VSOut) -> @location(0) vec4<f32> {
|
|
251
|
+
// Signed distance to the circle boundary (negative inside).
|
|
252
|
+
let dist = length(in.localPx) - in.radiusPx;
|
|
253
|
+
|
|
254
|
+
// Analytic-ish AA: smooth edge based on derivative of dist in screen space.
|
|
255
|
+
let w = fwidth(dist);
|
|
256
|
+
let a = 1.0 - smoothstep(0.0, w, dist);
|
|
257
|
+
|
|
258
|
+
// Discard fully outside to avoid unnecessary blending work.
|
|
259
|
+
if (a <= 0.0) {
|
|
260
|
+
discard;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return vec4<f32>(fsUniforms.color.rgb, fsUniforms.color.a * a);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
`,_l="bgra8unorm",Ar=4,_i=16,Rr=_i/4,Gl=e=>Math.min(1,Math.max(0,e)),Ci=(e,t,n)=>Math.min(n,Math.max(t,e|0)),zl=e=>pt(e)??[0,0,0,1],os=e=>{if(!Number.isFinite(e)||e<=0)return 1;const t=Math.ceil(e);return 2**Math.ceil(Math.log2(t))},oo=e=>Array.isArray(e),sa=e=>oo(e)?{x:e[0],y:e[1]}:{x:e.x,y:e.y},Vl=e=>{if(oo(e)){const n=e[2];return typeof n=="number"&&Number.isFinite(n)?n:null}const t=e.size;return typeof t=="number"&&Number.isFinite(t)?t:null},Ol=e=>oo(e)?e:[e.x,e.y,e.size],$l=e=>{let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;for(let o=0;o<e.length;o++){const{x:s,y:a}=sa(e[o]);!Number.isFinite(s)||!Number.isFinite(a)||(s<t&&(t=s),s>n&&(n=s),a<i&&(i=a),a>r&&(r=a))}return!Number.isFinite(t)||!Number.isFinite(n)||!Number.isFinite(i)||!Number.isFinite(r)?{xMin:0,xMax:1,yMin:0,yMax:1}:(t===n&&(n=t+1),i===r&&(r=i+1),{xMin:t,xMax:n,yMin:i,yMax:r})},ss=(e,t,n)=>{const i=e.scale(t),r=e.scale(n);if(!Number.isFinite(t)||!Number.isFinite(n)||t===n||!Number.isFinite(i)||!Number.isFinite(r))return{a:0,b:Number.isFinite(i)?i:0};const o=(r-i)/(n-t),s=i-o*t;return{a:Number.isFinite(o)?o:0,b:Number.isFinite(s)?s:0}},Wl=(e,t,n,i,r)=>{e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=i,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=n,e[13]=r,e[14]=0,e[15]=1},Xl=e=>{const{canvasWidth:t,canvasHeight:n,devicePixelRatio:i}=e,r=e.left*i,o=t-e.right*i,s=e.top*i,a=n-e.bottom*i,c=Ci(Math.floor(r),0,Math.max(0,t)),u=Ci(Math.floor(s),0,Math.max(0,n)),p=Ci(Math.ceil(o),0,Math.max(0,t)),h=Ci(Math.ceil(a),0,Math.max(0,n)),l=Math.max(0,p-c),m=Math.max(0,h-u);return{x:c,y:u,w:l,h:m}};function Yl(e,t){let n=!1;const i=(t==null?void 0:t.targetFormat)??_l,r=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),o=nt(e,80,{label:"scatterRenderer/vsUniforms"}),s=nt(e,16,{label:"scatterRenderer/fsUniforms"}),a=new ArrayBuffer(80),c=new Float32Array(a),u=new Float32Array(4),p=e.createBindGroup({layout:r,entries:[{binding:0,resource:{buffer:o}},{binding:1,resource:{buffer:s}}]}),h=Tt(e,{label:"scatterRenderer/pipeline",bindGroupLayouts:[r],vertex:{code:rs,label:"scatter.wgsl",buffers:[{arrayStride:_i,stepMode:"instance",attributes:[{shaderLocation:0,format:"float32x2",offset:0},{shaderLocation:1,format:"float32",offset:8}]}]},fragment:{code:rs,label:"scatter.wgsl",formats:i,blend:{color:{operation:"add",srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{operation:"add",srcFactor:"one",dstFactor:"one-minus-src-alpha"}}},primitive:{topology:"triangle-list",cullMode:"none"},multisample:{count:1}});let l=null,m=0,C=new ArrayBuffer(0),F=new Float32Array(C),R=0,S=0,y=[1,1],b=null;const w=()=>{if(n)throw new Error("ScatterRenderer is disposed.")},d=T=>{if(T<=F.length)return;const E=Math.max(8,os(T));C=new ArrayBuffer(E*4),F=new Float32Array(C)},g=(T,E,f,x,N,A)=>{const P=Number.isFinite(N)&&N>0?N:1,L=Number.isFinite(A)&&A>0?A:1;Wl(c,T,E,f,x),c[16]=P,c[17]=L,c[18]=0,c[19]=0,Qe(e,o,a),y=[P,L]};return{prepare:(T,E,f,x,N)=>{w();const{xMin:A,xMax:P,yMin:L,yMax:B}=$l(E),{a:V,b:_}=ss(f,A,P),{a:re,b:Y}=ss(x,L,B);N?(R=N.canvasWidth,S=N.canvasHeight,g(V,_,re,Y,N.canvasWidth,N.canvasHeight),b=Xl(N)):(g(V,_,re,Y,y[0],y[1]),b=null);const[W,Z,oe,ee]=zl(T.color);u[0]=W,u[1]=Z,u[2]=oe,u[3]=Gl(ee),Qe(e,s,u);const q=(N==null?void 0:N.devicePixelRatio)??1,de=q>0&&Number.isFinite(q),G=T.symbolSize,te=typeof G=="function"?H=>{const O=G(Ol(H));return typeof O=="number"&&Number.isFinite(O)?O:Ar}:typeof G=="number"&&Number.isFinite(G)?()=>G:()=>Ar;d(E.length*Rr);const X=F;let Q=0;for(let H=0;H<E.length;H++){const O=E[H],{x:se,y:ce}=sa(O);if(!Number.isFinite(se)||!Number.isFinite(ce))continue;const le=Vl(O)??te(O),me=Number.isFinite(le)?Math.max(0,le):Ar,ge=de?me*q:me;ge>0&&(X[Q+0]=se,X[Q+1]=ce,X[Q+2]=ge,X[Q+3]=0,Q+=Rr)}m=Q/Rr;const ne=Math.max(4,m*_i);if(!l||l.size<ne){const H=Math.max(Math.max(4,os(ne)),l?l.size:0);if(l)try{l.destroy()}catch{}l=e.createBuffer({label:"scatterRenderer/instanceBuffer",size:H,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST})}l&&m>0&&e.queue.writeBuffer(l,0,C,0,m*_i)},render:T=>{w(),!(!l||m===0)&&(b&&R>0&&S>0&&T.setScissorRect(b.x,b.y,b.w,b.h),T.setPipeline(h),T.setBindGroup(0,p),T.setVertexBuffer(0,l),T.draw(6,m),b&&R>0&&S>0&&T.setScissorRect(0,0,R,S))},dispose:()=>{if(!n){if(n=!0,l)try{l.destroy()}catch{}l=null,m=0;try{o.destroy()}catch{}try{s.destroy()}catch{}R=0,S=0,y=[1,1],b=null}}}}const Hl=`struct ComputeUniforms {
|
|
267
|
+
transform: mat4x4<f32>,
|
|
268
|
+
viewportPx: vec2f,
|
|
269
|
+
_pad0: vec2f,
|
|
270
|
+
plotOriginPx: vec2<u32>,
|
|
271
|
+
plotSizePx: vec2<u32>,
|
|
272
|
+
binSizePx: u32,
|
|
273
|
+
binCountX: u32,
|
|
274
|
+
binCountY: u32,
|
|
275
|
+
visibleStart: u32,
|
|
276
|
+
visibleEnd: u32,
|
|
277
|
+
normalization: u32,
|
|
278
|
+
_pad1: vec2<u32>,
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
@group(0) @binding(0) var<uniform> u: ComputeUniforms;
|
|
282
|
+
@group(0) @binding(1) var<storage, read> points: array<vec2f>;
|
|
283
|
+
@group(0) @binding(2) var<storage, read_write> bins: array<atomic<u32>>;
|
|
284
|
+
|
|
285
|
+
struct MaxBuffer {
|
|
286
|
+
value: atomic<u32>,
|
|
287
|
+
};
|
|
288
|
+
@group(0) @binding(3) var<storage, read_write> maxBuf: MaxBuffer;
|
|
289
|
+
|
|
290
|
+
fn clipToDevicePx(clip: vec2f) -> vec2f {
|
|
291
|
+
// clip in [-1,1] -> device pixel in [0, viewport]
|
|
292
|
+
return vec2f(
|
|
293
|
+
(clip.x * 0.5 + 0.5) * u.viewportPx.x,
|
|
294
|
+
(-clip.y * 0.5 + 0.5) * u.viewportPx.y
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
@compute @workgroup_size(256)
|
|
299
|
+
fn binPoints(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
300
|
+
let idx = u.visibleStart + gid.x;
|
|
301
|
+
if (idx >= u.visibleEnd) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
let p = points[idx];
|
|
306
|
+
let clip4 = u.transform * vec4f(p.x, p.y, 0.0, 1.0);
|
|
307
|
+
let clip = clip4.xy / max(1e-9, clip4.w);
|
|
308
|
+
let px = clipToDevicePx(clip);
|
|
309
|
+
|
|
310
|
+
// Scissor bounds in device px
|
|
311
|
+
let left = f32(u.plotOriginPx.x);
|
|
312
|
+
let top = f32(u.plotOriginPx.y);
|
|
313
|
+
let right = left + f32(u.plotSizePx.x);
|
|
314
|
+
let bottom = top + f32(u.plotSizePx.y);
|
|
315
|
+
|
|
316
|
+
if (px.x < left || px.x >= right || px.y < top || px.y >= bottom) {
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
let localX = u32((px.x - left) / f32(u.binSizePx));
|
|
321
|
+
let localY = u32((px.y - top) / f32(u.binSizePx));
|
|
322
|
+
if (localX >= u.binCountX || localY >= u.binCountY) {
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
let binIndex = localY * u.binCountX + localX;
|
|
327
|
+
atomicAdd(&bins[binIndex], 1u);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
@compute @workgroup_size(256)
|
|
331
|
+
fn reduceMax(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
332
|
+
let binTotal = u.binCountX * u.binCountY;
|
|
333
|
+
let i = gid.x;
|
|
334
|
+
if (i >= binTotal) {
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
let v = atomicLoad(&bins[i]);
|
|
339
|
+
atomicMax(&maxBuf.value, v);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
`,as=`struct RenderUniforms {
|
|
343
|
+
plotOriginPx: vec2<u32>,
|
|
344
|
+
plotSizePx: vec2<u32>,
|
|
345
|
+
binSizePx: u32,
|
|
346
|
+
binCountX: u32,
|
|
347
|
+
binCountY: u32,
|
|
348
|
+
normalization: u32,
|
|
349
|
+
_pad: vec2<u32>,
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
@group(0) @binding(0) var<uniform> u: RenderUniforms;
|
|
353
|
+
@group(0) @binding(1) var<storage, read> bins: array<u32>;
|
|
354
|
+
@group(0) @binding(2) var<storage, read> maxBuf: array<u32>;
|
|
355
|
+
@group(0) @binding(3) var lutTex: texture_2d<f32>;
|
|
356
|
+
|
|
357
|
+
struct VsOut {
|
|
358
|
+
@builtin(position) position: vec4f,
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
@vertex
|
|
362
|
+
fn vsMain(@builtin(vertex_index) vid: u32) -> VsOut {
|
|
363
|
+
// Fullscreen triangle (covers clip space).
|
|
364
|
+
// (0,0)->(-1,-1), (2,0)->(3,-1), (0,2)->(-1,3)
|
|
365
|
+
var pos = array<vec2f, 3>(
|
|
366
|
+
vec2f(-1.0, -1.0),
|
|
367
|
+
vec2f(3.0, -1.0),
|
|
368
|
+
vec2f(-1.0, 3.0)
|
|
369
|
+
);
|
|
370
|
+
var out: VsOut;
|
|
371
|
+
out.position = vec4f(pos[vid], 0.0, 1.0);
|
|
372
|
+
return out;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
fn applyNormalization(count: f32, maxCount: f32, mode: u32) -> f32 {
|
|
376
|
+
if (maxCount <= 0.0) {
|
|
377
|
+
return 0.0;
|
|
378
|
+
}
|
|
379
|
+
let t = clamp(count / maxCount, 0.0, 1.0);
|
|
380
|
+
if (mode == 1u) { // sqrt
|
|
381
|
+
return sqrt(t);
|
|
382
|
+
}
|
|
383
|
+
if (mode == 2u) { // log
|
|
384
|
+
// log1p(count) / log1p(max)
|
|
385
|
+
return clamp(log(1.0 + count) / max(1e-9, log(1.0 + maxCount)), 0.0, 1.0);
|
|
386
|
+
}
|
|
387
|
+
return t; // linear
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
@fragment
|
|
391
|
+
fn fsMain(@builtin(position) pos: vec4f) -> @location(0) vec4f {
|
|
392
|
+
// pos.xy is framebuffer pixel coords (device px) with origin top-left.
|
|
393
|
+
let x = pos.x;
|
|
394
|
+
let y = pos.y;
|
|
395
|
+
|
|
396
|
+
let left = f32(u.plotOriginPx.x);
|
|
397
|
+
let top = f32(u.plotOriginPx.y);
|
|
398
|
+
// plot scissor also applied on CPU; keep a guard anyway.
|
|
399
|
+
if (x < left || y < top) {
|
|
400
|
+
return vec4f(0.0);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
let localX = u32((x - left) / f32(u.binSizePx));
|
|
404
|
+
let localY = u32((y - top) / f32(u.binSizePx));
|
|
405
|
+
if (localX >= u.binCountX || localY >= u.binCountY) {
|
|
406
|
+
return vec4f(0.0);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
let idx = localY * u.binCountX + localX;
|
|
410
|
+
let c = f32(bins[idx]);
|
|
411
|
+
let maxC = f32(maxBuf[0]);
|
|
412
|
+
|
|
413
|
+
let t = applyNormalization(c, maxC, u.normalization);
|
|
414
|
+
let lutX = i32(round(t * 255.0));
|
|
415
|
+
let lut = textureLoad(lutTex, vec2<i32>(lutX, 0), 0);
|
|
416
|
+
return vec4f(lut.rgb, 1.0);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
`,ql="bgra8unorm",Mi=e=>Math.min(1,Math.max(0,e)),hn=(e,t,n)=>Math.min(n,Math.max(t,e|0)),Zl=e=>{if(!Number.isFinite(e)||e<=0)return 1;const t=Math.ceil(e);return 2**Math.ceil(Math.log2(t))},cs=(e,t,n)=>{const i=e.scale(t),r=e.scale(n);if(!Number.isFinite(t)||!Number.isFinite(n)||t===n||!Number.isFinite(i)||!Number.isFinite(r))return{a:0,b:Number.isFinite(i)?i:0};const o=(r-i)/(n-t),s=i-o*t;return{a:Number.isFinite(o)?o:0,b:Number.isFinite(s)?s:0}},jl=(e,t,n,i,r)=>{e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=i,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=n,e[13]=r,e[14]=0,e[15]=1},Kl=e=>{const{canvasWidth:t,canvasHeight:n,devicePixelRatio:i}=e,r=e.left*i,o=t-e.right*i,s=e.top*i,a=n-e.bottom*i,c=hn(Math.floor(r),0,Math.max(0,t)),u=hn(Math.floor(s),0,Math.max(0,n)),p=hn(Math.ceil(o),0,Math.max(0,t)),h=hn(Math.ceil(a),0,Math.max(0,n)),l=Math.max(0,p-c),m=Math.max(0,h-u);return{x:c,y:u,w:l,h:m}},Fi=(e,t,n)=>e+(t-e)*n,Jl=(e,t,n)=>[Fi(e[0],t[0],n),Fi(e[1],t[1],n),Fi(e[2],t[2],n),Fi(e[3],t[3],n)],Ql=e=>pt(e)??[0,0,0,1],ls=e=>e==="plasma"?["#0d0887","#6a00a8","#b12a90","#e16462","#fca636","#f0f921"]:e==="inferno"?["#000004","#420a68","#932667","#dd513a","#fca50a","#fcffa4"]:["#440154","#3b528b","#21918c","#5ec962","#fde725"],eu=e=>{const n=(typeof e=="string"?ls(e):Array.isArray(e)&&e.length>0?e:ls("viridis")).map(Ql),i=Math.max(2,n.length),r=new Uint8Array(new ArrayBuffer(256*4));for(let o=0;o<256;o++){const a=o/255*(i-1),c=Math.min(i-2,Math.max(0,Math.floor(a))),u=a-c,p=Jl(n[c],n[c+1],u);r[o*4+0]=hn(Math.round(Mi(p[0])*255),0,255),r[o*4+1]=hn(Math.round(Mi(p[1])*255),0,255),r[o*4+2]=hn(Math.round(Mi(p[2])*255),0,255),r[o*4+3]=hn(Math.round(Mi(p[3])*255),0,255)}return r},tu=e=>{if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return"custom"}},nu=e=>e==="sqrt"?1:e==="log"?2:0;function iu(e,t){let n=!1;const i=(t==null?void 0:t.targetFormat)??ql,r=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:2,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:3,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}}]}),o=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:3,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"unfilterable-float"}}]}),s=nt(e,128,{label:"scatterDensity/computeUniforms"}),a=new ArrayBuffer(128),c=new Float32Array(a,0,20),u=new Uint32Array(a),p=nt(e,48,{label:"scatterDensity/renderUniforms"}),h=new ArrayBuffer(48),l=new Uint32Array(h),m=ra(e,Hl,"scatterDensityBinning.wgsl"),C=e.createComputePipeline({label:"scatterDensity/binPointsPipeline",layout:e.createPipelineLayout({bindGroupLayouts:[r]}),compute:{module:m,entryPoint:"binPoints"}}),F=e.createComputePipeline({label:"scatterDensity/reduceMaxPipeline",layout:e.createPipelineLayout({bindGroupLayouts:[r]}),compute:{module:m,entryPoint:"reduceMax"}}),R=Tt(e,{label:"scatterDensity/renderPipeline",bindGroupLayouts:[o],vertex:{code:as,label:"scatterDensityColormap.wgsl"},fragment:{code:as,label:"scatterDensityColormap.wgsl",formats:i,blend:void 0},primitive:{topology:"triangle-list",cullMode:"none"},multisample:{count:1}});let S=null,y=null,b=0,w=null,d=null,g="",v=null,M=null,I=null,T=-1,E=0,f=0,x=0,N=0,A=0,P=null,L=0,B=0,V=2,_=!0,re=!1,Y=new Uint32Array(0);const W=()=>{if(n)throw new Error("ScatterDensityRenderer is disposed.")},Z=X=>{const Q=tu(X.densityColormap);if(w||(w=e.createTexture({label:"scatterDensity/lutTexture",size:{width:256,height:1,depthOrArrayLayers:1},format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST}),d=w.createView(),g=""),Q===g)return;const ne=eu(X.densityColormap);e.queue.writeTexture({texture:w},ne,{bytesPerRow:256*4,rowsPerImage:1},{width:256,height:1,depthOrArrayLayers:1}),g=Q},oe=(X,Q)=>{const ne=Math.max(1,X|0)*Math.max(1,Q|0);if(S&&y&&ne<=b)return;const H=Math.max(1,ne);if(b=Math.max(256,Zl(H)),S){try{S.destroy()}catch{}S=null}if(y){try{y.destroy()}catch{}y=null}S=e.createBuffer({label:"scatterDensity/binsBuffer",size:b*4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),y=e.createBuffer({label:"scatterDensity/maxBuffer",size:4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),Y=new Uint32Array(b),v=null,M=null,_=!0},ee=()=>{!S||!y||!d||!I||(v||(v=e.createBindGroup({label:"scatterDensity/computeBindGroup",layout:r,entries:[{binding:0,resource:{buffer:s}},{binding:1,resource:{buffer:I}},{binding:2,resource:{buffer:S}},{binding:3,resource:{buffer:y}}]})),M||(M=e.createBindGroup({label:"scatterDensity/renderBindGroup",layout:o,entries:[{binding:0,resource:{buffer:p}},{binding:1,resource:{buffer:S}},{binding:2,resource:{buffer:y}},{binding:3,resource:d}]})))};return{prepare:(X,Q,ne,H,O,se,ce,le,me)=>{W(),re=!0;const ge=Kl(le),we=le.devicePixelRatio,it=Number.isFinite(X.binSize)?Math.max(1e-6,X.binSize):2,Ke=Math.max(1,Math.round(it*(Number.isFinite(we)&&we>0?we:1))),et=Math.max(1,Math.ceil(ge.w/Ke)),ke=Math.max(1,Math.ceil(ge.h/Ke));oe(et,ke),Z(X);const he=nu(X.densityNormalization);I!==Q&&(I=Q,v=null,M=null,_=!0),T!==ne&&(T=ne,_=!0),(E!==H||f!==O)&&(E=H,f=O,_=!0),(x!==Ke||N!==et||A!==ke)&&(x=Ke,N=et,A=ke,_=!0),(!P||P.x!==ge.x||P.y!==ge.y||P.w!==ge.w||P.h!==ge.h)&&(P=ge,_=!0),(L!==le.canvasWidth||B!==le.canvasHeight)&&(L=le.canvasWidth,B=le.canvasHeight,_=!0),V!==he&&(V=he,_=!0);const be=me,Ge=(be==null?void 0:be.xMin)??0,ze=(be==null?void 0:be.xMax)??1,rt=(be==null?void 0:be.yMin)??0,Ze=(be==null?void 0:be.yMax)??1,{a:ht,b:gt}=cs(se,Ge,ze),{a:ot,b:Ft}=cs(ce,rt,Ze);jl(c,ht,gt,ot,Ft),c[16]=le.canvasWidth>0?le.canvasWidth:1,c[17]=le.canvasHeight>0?le.canvasHeight:1,c[18]=0,c[19]=0,u[20]=ge.x>>>0,u[21]=ge.y>>>0,u[22]=ge.w>>>0,u[23]=ge.h>>>0,u[24]=Ke>>>0,u[25]=et>>>0,u[26]=ke>>>0,u[27]=(Math.max(0,H)|0)>>>0,u[28]=(Math.max(0,O)|0)>>>0,u[29]=he>>>0,Qe(e,s,a),l[0]=ge.x>>>0,l[1]=ge.y>>>0,l[2]=ge.w>>>0,l[3]=ge.h>>>0,l[4]=Ke>>>0,l[5]=et>>>0,l[6]=ke>>>0,l[7]=he>>>0,Qe(e,p,h),ee()},encodeCompute:X=>{if(W(),!re||!_)return;if(!S||!y||!v||T<=0){_=!1;return}if(!P||P.w<=0||P.h<=0){_=!1;return}e.queue.writeBuffer(S,0,Y.buffer,0,b*4),e.queue.writeBuffer(y,0,new Uint32Array([0]).buffer);const Q=N*A|0,ne=Math.max(0,f-E|0),H=X.beginComputePass({label:"scatterDensity/computePass"});H.setBindGroup(0,v),H.setPipeline(C);const O=256,se=Math.ceil(ne/O);se>0&&H.dispatchWorkgroups(se),H.setPipeline(F);const ce=Math.ceil(Q/O);ce>0&&H.dispatchWorkgroups(ce),H.end(),_=!1},render:X=>{W(),re&&(!M||!P||!d||P.w<=0||P.h<=0||(X.setScissorRect(P.x,P.y,P.w,P.h),X.setPipeline(R),X.setBindGroup(0,M),X.draw(3),L>0&&B>0&&X.setScissorRect(0,0,L,B)))},dispose:()=>{if(!n){n=!0;try{s.destroy()}catch{}try{p.destroy()}catch{}if(S)try{S.destroy()}catch{}if(y)try{y.destroy()}catch{}if(S=null,y=null,b=0,w)try{w.destroy()}catch{}w=null,d=null,v=null,M=null,I=null}}}}const us=`// pie.wgsl
|
|
420
|
+
// Instanced anti-aliased pie-slice shader (instanced quad + SDF mask).
|
|
421
|
+
//
|
|
422
|
+
// - Per-instance vertex input:
|
|
423
|
+
// - center = vec2<f32> slice center (transformed by VSUniforms.transform)
|
|
424
|
+
// - startAngleRad = f32 start angle in radians
|
|
425
|
+
// - endAngleRad = f32 end angle in radians
|
|
426
|
+
// - radiiPx = vec2<f32>(innerRadiusPx, outerRadiusPx) in *device pixels*
|
|
427
|
+
// - color = vec4<f32> RGBA color in [0..1]
|
|
428
|
+
//
|
|
429
|
+
// - Draw call: draw(6, instanceCount) using triangle-list expansion in VS
|
|
430
|
+
//
|
|
431
|
+
// - Uniforms:
|
|
432
|
+
// - @group(0) @binding(0): VSUniforms { transform, viewportPx }
|
|
433
|
+
//
|
|
434
|
+
// Notes:
|
|
435
|
+
// - The quad is expanded in clip space using \`radiusPx\` and \`viewportPx\`.
|
|
436
|
+
// - Fragment uses an SDF mask for the circle boundary + an angular wedge mask.
|
|
437
|
+
// - Fully outside fragments are discarded to avoid unnecessary blending work.
|
|
438
|
+
//
|
|
439
|
+
// Conventions: matches other shaders in this repo (vsMain/fsMain, group 0 bindings,
|
|
440
|
+
// and explicit uniform padding/alignment where needed).
|
|
441
|
+
|
|
442
|
+
const PI: f32 = 3.141592653589793;
|
|
443
|
+
const TAU: f32 = 6.283185307179586; // 2*pi
|
|
444
|
+
|
|
445
|
+
struct VSUniforms {
|
|
446
|
+
transform: mat4x4<f32>,
|
|
447
|
+
viewportPx: vec2<f32>,
|
|
448
|
+
// Pad to 16-byte alignment (mat4x4 is 64B; vec2 adds 8B; pad to 80B).
|
|
449
|
+
_pad0: vec2<f32>,
|
|
450
|
+
};
|
|
451
|
+
|
|
452
|
+
@group(0) @binding(0) var<uniform> vsUniforms: VSUniforms;
|
|
453
|
+
|
|
454
|
+
struct VSIn {
|
|
455
|
+
@location(0) center: vec2<f32>,
|
|
456
|
+
@location(1) startAngleRad: f32,
|
|
457
|
+
@location(2) endAngleRad: f32,
|
|
458
|
+
@location(3) radiiPx: vec2<f32>, // (innerPx, outerPx)
|
|
459
|
+
@location(4) color: vec4<f32>,
|
|
460
|
+
};
|
|
461
|
+
|
|
462
|
+
struct VSOut {
|
|
463
|
+
@builtin(position) clipPosition: vec4<f32>,
|
|
464
|
+
@location(0) localPx: vec2<f32>,
|
|
465
|
+
@location(1) startAngleRad: f32,
|
|
466
|
+
@location(2) endAngleRad: f32,
|
|
467
|
+
@location(3) radiiPx: vec2<f32>,
|
|
468
|
+
@location(4) color: vec4<f32>,
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
@vertex
|
|
472
|
+
fn vsMain(in: VSIn, @builtin(vertex_index) vertexIndex: u32) -> VSOut {
|
|
473
|
+
// Fixed local corners for 2 triangles (triangle-list).
|
|
474
|
+
// \`localNdc\` is a quad in [-1, 1]^2; we convert it to pixel offsets via radiusPx.
|
|
475
|
+
let localNdc = array<vec2<f32>, 6>(
|
|
476
|
+
vec2<f32>(-1.0, -1.0),
|
|
477
|
+
vec2<f32>( 1.0, -1.0),
|
|
478
|
+
vec2<f32>(-1.0, 1.0),
|
|
479
|
+
vec2<f32>(-1.0, 1.0),
|
|
480
|
+
vec2<f32>( 1.0, -1.0),
|
|
481
|
+
vec2<f32>( 1.0, 1.0)
|
|
482
|
+
);
|
|
483
|
+
|
|
484
|
+
let corner = localNdc[vertexIndex];
|
|
485
|
+
let outerPx = in.radiiPx.y;
|
|
486
|
+
let localPx = corner * outerPx;
|
|
487
|
+
|
|
488
|
+
// Convert pixel offset to clip-space offset.
|
|
489
|
+
// Clip space spans [-1, 1] across the viewport, so px -> clip is (2 / viewportPx).
|
|
490
|
+
let localClip = localPx * (2.0 / vsUniforms.viewportPx);
|
|
491
|
+
|
|
492
|
+
let centerClip = (vsUniforms.transform * vec4<f32>(in.center, 0.0, 1.0)).xy;
|
|
493
|
+
|
|
494
|
+
var out: VSOut;
|
|
495
|
+
out.clipPosition = vec4<f32>(centerClip + localClip, 0.0, 1.0);
|
|
496
|
+
out.localPx = localPx;
|
|
497
|
+
out.startAngleRad = in.startAngleRad;
|
|
498
|
+
out.endAngleRad = in.endAngleRad;
|
|
499
|
+
out.radiiPx = in.radiiPx;
|
|
500
|
+
out.color = in.color;
|
|
501
|
+
return out;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
fn wrapToTau(theta: f32) -> f32 {
|
|
505
|
+
// Maps theta to [0, TAU). (Input often comes from atan2 in [-PI, PI].)
|
|
506
|
+
return select(theta, theta + TAU, theta < 0.0);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
@fragment
|
|
510
|
+
fn fsMain(in: VSOut) -> @location(0) vec4<f32> {
|
|
511
|
+
let p = in.localPx;
|
|
512
|
+
let r = length(p);
|
|
513
|
+
|
|
514
|
+
let innerPx = in.radiiPx.x;
|
|
515
|
+
let outerPx = in.radiiPx.y;
|
|
516
|
+
|
|
517
|
+
// --- Radial mask: ring between inner and outer radii (inner==0 => pie) ---
|
|
518
|
+
// Positive inside the ring, negative outside.
|
|
519
|
+
let radialDist = min(r - innerPx, outerPx - r);
|
|
520
|
+
let radialW = fwidth(radialDist);
|
|
521
|
+
let radialA = smoothstep(-radialW, radialW, radialDist);
|
|
522
|
+
|
|
523
|
+
if (radialA <= 0.0) {
|
|
524
|
+
discard;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
// Compute fragment angle in [0, TAU).
|
|
528
|
+
let angle = wrapToTau(atan2(p.y, p.x));
|
|
529
|
+
|
|
530
|
+
// --- Angular mask: wedge between start/end angles with wrap ---
|
|
531
|
+
let start = in.startAngleRad;
|
|
532
|
+
let end = in.endAngleRad;
|
|
533
|
+
|
|
534
|
+
// Compute span in [0, 2π) with wrap.
|
|
535
|
+
var span = end - start;
|
|
536
|
+
span = span + select(0.0, TAU, span < 0.0);
|
|
537
|
+
|
|
538
|
+
// Compute rel in [0, 2π) with wrap.
|
|
539
|
+
var rel = angle - start;
|
|
540
|
+
rel = rel + select(0.0, TAU, rel < 0.0);
|
|
541
|
+
|
|
542
|
+
let inside = rel <= span;
|
|
543
|
+
|
|
544
|
+
// Signed angular distance (in radians) to nearest boundary.
|
|
545
|
+
// - Inside: +min(rel, span-rel)
|
|
546
|
+
// - Outside: -min(rel-span, 2π-rel)
|
|
547
|
+
let dIn = min(rel, max(span - rel, 0.0));
|
|
548
|
+
let dOutA = max(rel - span, 0.0);
|
|
549
|
+
let dOutB = max(TAU - rel, 0.0);
|
|
550
|
+
let dOut = min(dOutA, dOutB);
|
|
551
|
+
|
|
552
|
+
let signedAngleDist = select(-dOut, dIn, inside);
|
|
553
|
+
|
|
554
|
+
// Convert to approximate pixel distance to the boundary ray.
|
|
555
|
+
// (For small angles, perpendicular distance to a ray ≈ r * angle.)
|
|
556
|
+
let angleDistPx = signedAngleDist * max(r, 1.0);
|
|
557
|
+
|
|
558
|
+
let angW = fwidth(angleDistPx);
|
|
559
|
+
let angularA = smoothstep(-angW, angW, angleDistPx);
|
|
560
|
+
|
|
561
|
+
let aOut = radialA * angularA;
|
|
562
|
+
if (aOut <= 0.0) {
|
|
563
|
+
discard;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
return vec4<f32>(in.color.rgb, in.color.a * aOut);
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
`,ru="bgra8unorm",Gi=40,Er=Gi/4,Gn=Math.PI*2,fs=e=>Math.min(1,Math.max(0,e)),Si=(e,t,n)=>Math.min(n,Math.max(t,e|0)),ds=e=>{if(!Number.isFinite(e)||e<=0)return 1;const t=Math.ceil(e);return 2**Math.ceil(Math.log2(t))},Dr=e=>{if(!Number.isFinite(e))return 0;const t=e%Gn;return t<0?t+Gn:t},ou=(e,t)=>{const n=pt(e);if(n)return[n[0],n[1],n[2],fs(n[3])];const i=pt(t);return i?[i[0],i[1],i[2],fs(i[3])]:[0,0,0,1]},si=(e,t)=>{if(typeof e=="number")return Number.isFinite(e)?e:null;if(typeof e!="string")return null;const n=e.trim();if(n.length===0)return null;if(n.endsWith("%")){const r=Number.parseFloat(n.slice(0,-1));return Number.isFinite(r)?r/100*t:null}const i=Number.parseFloat(n);return Number.isFinite(i)?i:null},su=(e,t,n)=>{const i=(e==null?void 0:e[0])??"50%",r=(e==null?void 0:e[1])??"50%",o=si(i,t),s=si(r,n);return{x:Number.isFinite(o)?o:t*.5,y:Number.isFinite(s)?s:n*.5}},au=e=>Array.isArray(e),cu=(e,t)=>{if(e==null)return{inner:0,outer:t*.7};if(au(e)){const r=si(e[0],t),o=si(e[1],t),s=Math.max(0,Number.isFinite(r)?r:0),a=Math.max(s,Number.isFinite(o)?o:t*.7);return{inner:s,outer:Math.min(t,a)}}const n=si(e,t),i=Math.max(0,Number.isFinite(n)?n:t*.7);return{inner:0,outer:Math.min(t,i)}},lu=e=>{const{canvasWidth:t,canvasHeight:n,devicePixelRatio:i}=e,r=e.left*i,o=t-e.right*i,s=e.top*i,a=n-e.bottom*i,c=Si(Math.floor(r),0,Math.max(0,t)),u=Si(Math.floor(s),0,Math.max(0,n)),p=Si(Math.ceil(o),0,Math.max(0,t)),h=Si(Math.ceil(a),0,Math.max(0,n)),l=Math.max(0,p-c),m=Math.max(0,h-u);return{x:c,y:u,w:l,h:m}},uu=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);function fu(e,t){let n=!1;const i=(t==null?void 0:t.targetFormat)??ru,r=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}}]}),o=nt(e,80,{label:"pieRenderer/vsUniforms"}),s=new ArrayBuffer(80),a=new Float32Array(s),c=e.createBindGroup({layout:r,entries:[{binding:0,resource:{buffer:o}}]}),u=Tt(e,{label:"pieRenderer/pipeline",bindGroupLayouts:[r],vertex:{code:us,label:"pie.wgsl",buffers:[{arrayStride:Gi,stepMode:"instance",attributes:[{shaderLocation:0,format:"float32x2",offset:0},{shaderLocation:1,format:"float32",offset:8},{shaderLocation:2,format:"float32",offset:12},{shaderLocation:3,format:"float32x2",offset:16},{shaderLocation:4,format:"float32x4",offset:24}]}]},fragment:{code:us,label:"pie.wgsl",formats:i,blend:{color:{operation:"add",srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{operation:"add",srcFactor:"one",dstFactor:"one-minus-src-alpha"}}},primitive:{topology:"triangle-list",cullMode:"none"},multisample:{count:1}});let p=null,h=0,l=new ArrayBuffer(0),m=new Float32Array(l),C=0,F=0,R=null;const S=()=>{if(n)throw new Error("PieRenderer is disposed.")},y=v=>{if(v<=m.length)return;const M=Math.max(8,ds(v));l=new ArrayBuffer(M*4),m=new Float32Array(l)},b=(v,M)=>{const I=Number.isFinite(v)&&v>0?v:1,T=Number.isFinite(M)&&M>0?M:1;a.set(uu,0),a[16]=I,a[17]=T,a[18]=0,a[19]=0,Qe(e,o,s)};return{prepare:(v,M)=>{S();const I=M.devicePixelRatio,T=I>0&&Number.isFinite(I)?I:1;C=M.canvasWidth,F=M.canvasHeight,b(M.canvasWidth,M.canvasHeight),R=lu(M);const E=M.canvasWidth/T,f=M.canvasHeight/T;if(!(E>0)||!(f>0)){h=0;return}const x=E-M.left-M.right,N=f-M.top-M.bottom;if(!(x>0)||!(N>0)){h=0;return}const A=.5*Math.min(x,N);if(!(A>0)){h=0;return}const P=su(v.center,x,N),L=M.left+P.x,B=M.top+P.y,V=L/E*2-1,_=1-B/f*2;if(!Number.isFinite(V)||!Number.isFinite(_)){h=0;return}const re=cu(v.radius,A),Y=Math.max(0,Math.min(re.inner,re.outer)),W=Math.max(Y,re.outer),Z=Y*T,oe=W*T;if(!(oe>0)){h=0;return}let ee=0,q=0;for(let O=0;O<v.data.length;O++){const se=v.data[O],ce=se==null?void 0:se.value;typeof ce=="number"&&Number.isFinite(ce)&&ce>0&&se.visible!==!1&&(ee+=ce,q++)}if(!(ee>0)||q===0){h=0;return}y(q*Er);const de=m,G=typeof v.startAngle=="number"&&Number.isFinite(v.startAngle)?v.startAngle:90;let te=Dr(G*Math.PI/180),X=0,Q=0,ne=0;for(let O=0;O<v.data.length;O++){const se=v.data[O],ce=se==null?void 0:se.value;if(typeof ce!="number"||!Number.isFinite(ce)||ce<=0||se.visible===!1)continue;ne++;const le=ne===q;let ge=ce/ee*Gn;if(le?ge=Math.max(0,Gn-X):ge=Math.max(0,Math.min(Gn,ge)),X+=ge,!(ge>0))continue;const we=te,it=q===1?te+Gn:Dr(te+ge);te=Dr(te+ge);const[Ke,et,ke,he]=ou(se.color,v.color);de[Q+0]=V,de[Q+1]=_,de[Q+2]=we,de[Q+3]=it,de[Q+4]=Z,de[Q+5]=oe,de[Q+6]=Ke,de[Q+7]=et,de[Q+8]=ke,de[Q+9]=he,Q+=Er}h=Q/Er;const H=Math.max(4,h*Gi);if(!p||p.size<H){const O=Math.max(Math.max(4,ds(H)),p?p.size:0);if(p)try{p.destroy()}catch{}p=e.createBuffer({label:"pieRenderer/instanceBuffer",size:O,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST})}p&&h>0&&e.queue.writeBuffer(p,0,l,0,h*Gi)},render:v=>{S(),!(!p||h===0)&&(R&&C>0&&F>0&&v.setScissorRect(R.x,R.y,R.w,R.h),v.setPipeline(u),v.setBindGroup(0,c),v.setVertexBuffer(0,p),v.draw(6,h),R&&C>0&&F>0&&v.setScissorRect(0,0,C,F))},dispose:()=>{if(!n){if(n=!0,p)try{p.destroy()}catch{}p=null,h=0;try{o.destroy()}catch{}C=0,F=0,R=null}}}}const ms=`// candlestick.wgsl
|
|
570
|
+
// Instanced candlestick shader (bodies + wicks):
|
|
571
|
+
// - Per-instance vertex input:
|
|
572
|
+
// - xClip, openClip, closeClip, lowClip, highClip, bodyWidthClip (6 floats)
|
|
573
|
+
// - bodyColor rgba (4 floats)
|
|
574
|
+
// - Draw call: draw(18, instanceCount) using triangle-list expansion in VS
|
|
575
|
+
// - vertices 0-5: body quad (2 triangles)
|
|
576
|
+
// - vertices 6-11: upper wick (2 triangles)
|
|
577
|
+
// - vertices 12-17: lower wick (2 triangles)
|
|
578
|
+
// - Uniforms:
|
|
579
|
+
// - @group(0) @binding(0): VSUniforms { transform, wickWidthClip }
|
|
580
|
+
|
|
581
|
+
struct VSUniforms {
|
|
582
|
+
transform: mat4x4<f32>,
|
|
583
|
+
wickWidthClip: f32,
|
|
584
|
+
_pad0: f32,
|
|
585
|
+
_pad1: f32,
|
|
586
|
+
_pad2: f32,
|
|
587
|
+
};
|
|
588
|
+
|
|
589
|
+
@group(0) @binding(0) var<uniform> vsUniforms: VSUniforms;
|
|
590
|
+
|
|
591
|
+
struct VSIn {
|
|
592
|
+
@location(0) xClip: f32,
|
|
593
|
+
@location(1) openClip: f32,
|
|
594
|
+
@location(2) closeClip: f32,
|
|
595
|
+
@location(3) lowClip: f32,
|
|
596
|
+
@location(4) highClip: f32,
|
|
597
|
+
@location(5) bodyWidthClip: f32,
|
|
598
|
+
@location(6) bodyColor: vec4<f32>,
|
|
599
|
+
};
|
|
600
|
+
|
|
601
|
+
struct VSOut {
|
|
602
|
+
@builtin(position) clipPosition: vec4<f32>,
|
|
603
|
+
@location(0) color: vec4<f32>,
|
|
604
|
+
};
|
|
605
|
+
|
|
606
|
+
@vertex
|
|
607
|
+
fn vsMain(in: VSIn, @builtin(vertex_index) vertexIndex: u32) -> VSOut {
|
|
608
|
+
// Compute body bounds
|
|
609
|
+
let bodyTop = max(in.openClip, in.closeClip);
|
|
610
|
+
let bodyBottom = min(in.openClip, in.closeClip);
|
|
611
|
+
let bodyLeft = in.xClip - in.bodyWidthClip * 0.5;
|
|
612
|
+
let bodyRight = in.xClip + in.bodyWidthClip * 0.5;
|
|
613
|
+
|
|
614
|
+
// Wick bounds
|
|
615
|
+
let wickLeft = in.xClip - vsUniforms.wickWidthClip * 0.5;
|
|
616
|
+
let wickRight = in.xClip + vsUniforms.wickWidthClip * 0.5;
|
|
617
|
+
|
|
618
|
+
var pos: vec2<f32>;
|
|
619
|
+
|
|
620
|
+
if (vertexIndex < 6u) {
|
|
621
|
+
// Body quad (vertices 0-5)
|
|
622
|
+
let corners = array<vec2<f32>, 6>(
|
|
623
|
+
vec2<f32>(0.0, 0.0),
|
|
624
|
+
vec2<f32>(1.0, 0.0),
|
|
625
|
+
vec2<f32>(0.0, 1.0),
|
|
626
|
+
vec2<f32>(0.0, 1.0),
|
|
627
|
+
vec2<f32>(1.0, 0.0),
|
|
628
|
+
vec2<f32>(1.0, 1.0)
|
|
629
|
+
);
|
|
630
|
+
let corner = corners[vertexIndex];
|
|
631
|
+
let bodyMin = vec2<f32>(bodyLeft, bodyBottom);
|
|
632
|
+
let bodyMax = vec2<f32>(bodyRight, bodyTop);
|
|
633
|
+
pos = bodyMin + corner * (bodyMax - bodyMin);
|
|
634
|
+
} else if (vertexIndex < 12u) {
|
|
635
|
+
// Upper wick (vertices 6-11): from bodyTop to highClip
|
|
636
|
+
let idx = vertexIndex - 6u;
|
|
637
|
+
let corners = array<vec2<f32>, 6>(
|
|
638
|
+
vec2<f32>(0.0, 0.0),
|
|
639
|
+
vec2<f32>(1.0, 0.0),
|
|
640
|
+
vec2<f32>(0.0, 1.0),
|
|
641
|
+
vec2<f32>(0.0, 1.0),
|
|
642
|
+
vec2<f32>(1.0, 0.0),
|
|
643
|
+
vec2<f32>(1.0, 1.0)
|
|
644
|
+
);
|
|
645
|
+
let corner = corners[idx];
|
|
646
|
+
let wickMin = vec2<f32>(wickLeft, bodyTop);
|
|
647
|
+
let wickMax = vec2<f32>(wickRight, in.highClip);
|
|
648
|
+
pos = wickMin + corner * (wickMax - wickMin);
|
|
649
|
+
} else {
|
|
650
|
+
// Lower wick (vertices 12-17): from lowClip to bodyBottom
|
|
651
|
+
let idx = vertexIndex - 12u;
|
|
652
|
+
let corners = array<vec2<f32>, 6>(
|
|
653
|
+
vec2<f32>(0.0, 0.0),
|
|
654
|
+
vec2<f32>(1.0, 0.0),
|
|
655
|
+
vec2<f32>(0.0, 1.0),
|
|
656
|
+
vec2<f32>(0.0, 1.0),
|
|
657
|
+
vec2<f32>(1.0, 0.0),
|
|
658
|
+
vec2<f32>(1.0, 1.0)
|
|
659
|
+
);
|
|
660
|
+
let corner = corners[idx];
|
|
661
|
+
let wickMin = vec2<f32>(wickLeft, in.lowClip);
|
|
662
|
+
let wickMax = vec2<f32>(wickRight, bodyBottom);
|
|
663
|
+
pos = wickMin + corner * (wickMax - wickMin);
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
var out: VSOut;
|
|
667
|
+
out.clipPosition = vsUniforms.transform * vec4<f32>(pos, 0.0, 1.0);
|
|
668
|
+
out.color = in.bodyColor;
|
|
669
|
+
return out;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
@fragment
|
|
673
|
+
fn fsMain(in: VSOut) -> @location(0) vec4<f32> {
|
|
674
|
+
return in.color;
|
|
675
|
+
}
|
|
676
|
+
`,du="bgra8unorm",mu=1,kn=40,Sn=kn/4,pu=e=>Math.min(1,Math.max(0,e)),Ni=(e,t,n)=>Math.min(n,Math.max(t,e|0)),ti=e=>pt(e)??[0,0,0,1],Ti=e=>{if(!Number.isFinite(e)||e<=0)return 1;const t=Math.ceil(e);return 2**Math.ceil(Math.log2(t))},hu=e=>{const t=e.trim().match(/^(\d+(?:\.\d+)?)%$/);if(!t)return null;const n=Number(t[1])/100;return Number.isFinite(n)?n:null},yu=e=>Array.isArray(e),aa=e=>yu(e)?{timestamp:e[0],open:e[1],close:e[2],low:e[3],high:e[4]}:{timestamp:e.timestamp,open:e.open,close:e.close,low:e.low,high:e.high},gu=e=>{const t=e.devicePixelRatio;if(!(t>0))return null;const n=e.canvasWidth/t,i=e.canvasHeight/t,r=n-e.left-e.right,o=i-e.top-e.bottom;return!(r>0)||!(o>0)?null:{plotWidthCss:r,plotHeightCss:o}},xu=e=>{const{left:t,right:n,top:i,bottom:r,canvasWidth:o,canvasHeight:s,devicePixelRatio:a}=e,c=t*a,u=o-n*a,p=i*a,h=s-r*a,l=c/o*2-1,m=u/o*2-1,C=1-p/s*2,F=1-h/s*2;return{left:l,right:m,top:C,bottom:F,width:m-l,height:C-F}},bu=e=>{const{canvasWidth:t,canvasHeight:n,devicePixelRatio:i}=e,r=e.left*i,o=t-e.right*i,s=e.top*i,a=n-e.bottom*i,c=Ni(Math.floor(r),0,Math.max(0,t)),u=Ni(Math.floor(s),0,Math.max(0,n)),p=Ni(Math.ceil(o),0,Math.max(0,t)),h=Ni(Math.ceil(a),0,Math.max(0,n)),l=Math.max(0,p-c),m=Math.max(0,h-u);return{x:c,y:u,w:l,h:m}},vu=e=>{const t=[];for(let i=0;i<e.length;i++){const{timestamp:r}=aa(e[i]);Number.isFinite(r)&&t.push(r)}if(t.length<2)return 1;t.sort((i,r)=>i-r);let n=Number.POSITIVE_INFINITY;for(let i=1;i<t.length;i++){const r=t[i]-t[i-1];r>0&&r<n&&(n=r)}return Number.isFinite(n)&&n>0?n:1},wu=(e,t,n,i)=>{if(Number.isFinite(t)&&t>0){const a=e.scale(0),c=e.scale(0+t),u=Math.abs(c-a);if(Number.isFinite(u)&&u>0)return u}const r=Math.abs(n.width);if(!(r>0))return 0;const o=Math.max(1,Math.floor(i));return r/o},Cu=()=>{const e=new ArrayBuffer(64);return new Float32Array(e).set([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),e};function Mu(e,t){let n=!1;const i=(t==null?void 0:t.targetFormat)??du,r=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}}]}),o=nt(e,80,{label:"candlestickRenderer/vsUniforms"});Qe(e,o,Cu());const s=new ArrayBuffer(80),a=new Float32Array(s),c=e.createBindGroup({layout:r,entries:[{binding:0,resource:{buffer:o}}]}),u=Tt(e,{label:"candlestickRenderer/pipeline",bindGroupLayouts:[r],vertex:{code:ms,label:"candlestick.wgsl",buffers:[{arrayStride:kn,stepMode:"instance",attributes:[{shaderLocation:0,format:"float32",offset:0},{shaderLocation:1,format:"float32",offset:4},{shaderLocation:2,format:"float32",offset:8},{shaderLocation:3,format:"float32",offset:12},{shaderLocation:4,format:"float32",offset:16},{shaderLocation:5,format:"float32",offset:20},{shaderLocation:6,format:"float32x4",offset:24}]}]},fragment:{code:ms,label:"candlestick.wgsl",formats:i,blend:{color:{operation:"add",srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{operation:"add",srcFactor:"one",dstFactor:"one-minus-src-alpha"}}},primitive:{topology:"triangle-list",cullMode:"none"},multisample:{count:1}});let p=null,h=0,l=new ArrayBuffer(0),m=new Float32Array(l),C=0,F=0,R=null,S=!1,y=null,b=0,w=new ArrayBuffer(0),d=new Float32Array(w);const g=()=>{if(n)throw new Error("CandlestickRenderer is disposed.")},v=f=>{if(f<=m.length)return;const x=Math.max(8,Ti(f));l=new ArrayBuffer(x*4),m=new Float32Array(l)},M=f=>{if(f<=d.length)return;const x=Math.max(8,Ti(f));w=new ArrayBuffer(x*4),d=new Float32Array(w)};return{prepare:(f,x,N,A,P,L)=>{if(g(),x.length===0){h=0,b=0;return}const B=gu(P);if(!B){h=0,b=0;return}const V=xu(P),_=B.plotWidthCss>0?V.width/B.plotWidthCss:0;C=P.canvasWidth,F=P.canvasHeight,R=bu(P);const re=vu(x),Y=wu(N,re,V,x.length);let W=0;const Z=f.barWidth;if(typeof Z=="number")W=Math.max(0,Z)*_;else if(typeof Z=="string"){const me=hu(Z);W=me==null?0:Y*pu(me)}const oe=f.barMinWidth*_,ee=f.barMaxWidth*_;W=Math.min(Math.max(W,oe),ee);const q=f.itemStyle.borderWidth??mu,de=Math.max(0,q)*_;a.set([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,de,0,0,0]),Qe(e,o,s);const G=ti(f.itemStyle.upColor),te=ti(f.itemStyle.downColor),X=ti(f.itemStyle.upBorderColor),Q=ti(f.itemStyle.downBorderColor),ne=L?ti(L):[0,0,0,1];S=f.style==="hollow",v(x.length*Sn);const H=m;let O=0;S&&M(x.length*Sn);const se=d;let ce=0;for(let me=0;me<x.length;me++){const{timestamp:ge,open:we,close:it,low:Ke,high:et}=aa(x[me]);if(!Number.isFinite(ge)||!Number.isFinite(we)||!Number.isFinite(it)||!Number.isFinite(Ke)||!Number.isFinite(et))continue;const ke=N.scale(ge),he=A.scale(we),be=A.scale(it),Ge=A.scale(Ke),ze=A.scale(et);if(!Number.isFinite(ke)||!Number.isFinite(he)||!Number.isFinite(be)||!Number.isFinite(Ge)||!Number.isFinite(ze))continue;const rt=it>we;if(S){const Ze=rt?X:Q;if(H[O+0]=ke,H[O+1]=he,H[O+2]=be,H[O+3]=Ge,H[O+4]=ze,H[O+5]=W,H[O+6]=Ze[0],H[O+7]=Ze[1],H[O+8]=Ze[2],H[O+9]=Ze[3],O+=Sn,rt){const ht=f.itemStyle.borderWidth*_,gt=Math.max(0,W-2*ht);se[ce+0]=ke,se[ce+1]=he,se[ce+2]=be,se[ce+3]=Ge,se[ce+4]=ze,se[ce+5]=gt,se[ce+6]=ne[0],se[ce+7]=ne[1],se[ce+8]=ne[2],se[ce+9]=ne[3],ce+=Sn}}else{const Ze=rt?G:te;H[O+0]=ke,H[O+1]=he,H[O+2]=be,H[O+3]=Ge,H[O+4]=ze,H[O+5]=W,H[O+6]=Ze[0],H[O+7]=Ze[1],H[O+8]=Ze[2],H[O+9]=Ze[3],O+=Sn}}h=O/Sn,b=ce/Sn;const le=Math.max(4,h*kn);if(!p||p.size<le){const me=Math.max(Math.max(4,Ti(le)),p?p.size:0);if(p)try{p.destroy()}catch{}p=e.createBuffer({label:"candlestickRenderer/instanceBuffer",size:me,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST})}if(h>0&&e.queue.writeBuffer(p,0,l,0,h*kn),S&&b>0){const me=Math.max(4,b*kn);if(!y||y.size<me){const ge=Math.max(Math.max(4,Ti(me)),y?y.size:0);if(y)try{y.destroy()}catch{}y=e.createBuffer({label:"candlestickRenderer/hollowInstanceBuffer",size:ge,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST})}e.queue.writeBuffer(y,0,w,0,b*kn)}},render:f=>{g(),!(!p||h===0)&&(R&&C>0&&F>0&&f.setScissorRect(R.x,R.y,R.w,R.h),f.setPipeline(u),f.setBindGroup(0,c),f.setVertexBuffer(0,p),f.draw(18,h),S&&y&&b>0&&(f.setVertexBuffer(0,y),f.draw(6,b)),R&&C>0&&F>0&&f.setScissorRect(0,0,C,F))},dispose:()=>{if(!n){if(n=!0,p)try{p.destroy()}catch{}if(p=null,h=0,y)try{y.destroy()}catch{}y=null,b=0;try{o.destroy()}catch{}C=0,F=0,R=null}}}}const ps=`// crosshair.wgsl
|
|
677
|
+
// Minimal crosshair line shader:
|
|
678
|
+
// - Vertex input: vec2<f32> position in clip-space coordinates
|
|
679
|
+
// - VS uniform: transform mat4 (identity)
|
|
680
|
+
// - FS uniform: solid RGBA color
|
|
681
|
+
|
|
682
|
+
struct VSUniforms {
|
|
683
|
+
transform: mat4x4<f32>,
|
|
684
|
+
};
|
|
685
|
+
|
|
686
|
+
@group(0) @binding(0) var<uniform> vsUniforms: VSUniforms;
|
|
687
|
+
|
|
688
|
+
struct FSUniforms {
|
|
689
|
+
color: vec4<f32>,
|
|
690
|
+
};
|
|
691
|
+
|
|
692
|
+
@group(0) @binding(1) var<uniform> fsUniforms: FSUniforms;
|
|
693
|
+
|
|
694
|
+
struct VSIn {
|
|
695
|
+
@location(0) position: vec2<f32>,
|
|
696
|
+
};
|
|
697
|
+
|
|
698
|
+
struct VSOut {
|
|
699
|
+
@builtin(position) clipPosition: vec4<f32>,
|
|
700
|
+
};
|
|
701
|
+
|
|
702
|
+
@vertex
|
|
703
|
+
fn vsMain(in: VSIn) -> VSOut {
|
|
704
|
+
var out: VSOut;
|
|
705
|
+
out.clipPosition = vsUniforms.transform * vec4<f32>(in.position, 0.0, 1.0);
|
|
706
|
+
return out;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
@fragment
|
|
710
|
+
fn fsMain() -> @location(0) vec4<f32> {
|
|
711
|
+
return fsUniforms.color;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
`,Fu=e=>e+3&-4,Su=1024,Nu=128,Tu=16384,Iu=e=>{if(e.byteOffset&3)throw new Error("createStreamBuffer.write: data.byteOffset must be 4-byte aligned.");return new Uint32Array(e.buffer,e.byteOffset,e.byteLength>>>2)};function Pu(e,t){if(!Number.isFinite(t)||t<=0)throw new Error(`createStreamBuffer(maxSize): maxSize (bytes) must be a positive number. Received: ${String(t)}`);const n=Math.max(4,Math.floor(t)),i=Fu(n),r=e.limits.maxBufferSize;if(i>r)throw new Error(`createStreamBuffer(maxSize): requested size ${i} bytes exceeds device.limits.maxBufferSize (${r}).`);const o=i>>>2,s=y=>({buffer:e.createBuffer({label:y,size:i,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST}),mirror:new Uint32Array(o)}),a=[s("streamBuffer/a"),s("streamBuffer/b")];let c=!1,u=0,p=0;const h=()=>{if(c)throw new Error("createStreamBuffer: StreamBuffer is disposed.")},l=(y,b,w)=>{const d=a[y],g=d.mirror;if(w<0||w>b.length)throw new Error("createStreamBuffer.write: internal error (invalid usedWords).");if(w===0)return;const v=w<<2;e.queue.writeBuffer(d.buffer,0,b.buffer,b.byteOffset,v),g.set(b.subarray(0,w),0)},m=(y,b,w)=>{const d=a[y],g=d.mirror;if(w<0||w>b.length)throw new Error("createStreamBuffer.write: internal error (invalid usedWords).");const v=w<<2;if(v>0&&v<=Su){l(y,b,w);return}const M=[];let I=0,T=0,E=0;for(;E<w;){for(;E<w&&g[E]===b[E];)E++;if(E>=w)break;const f=E;for(E++;E<w&&g[E]!==b[E];)E++;const x=E;if(M.push([f,x]),I++,T+=x-f,I>Nu||T>Tu){l(y,b,w);return}}for(let f=0;f<M.length;f++){const[x,N]=M[f],A=x<<2,P=N-x<<2;e.queue.writeBuffer(d.buffer,A,b.buffer,b.byteOffset+A,P),g.set(b.subarray(x,N),x)}};return{write:y=>{if(h(),y.length&1)throw new Error("createStreamBuffer.write: data length must be even (vec2<f32> vertices).");const b=y.byteLength;if(b>i)throw new Error(`createStreamBuffer.write: data.byteLength (${b}) exceeds capacity (${i}). Increase maxSize.`);const w=y.length>>>1;if(b===0){p=w;return}const d=Iu(y),g=1-u;m(g,d,d.length),u=g,p=w},getBuffer:()=>(h(),a[u].buffer),getVertexCount:()=>(h(),p),dispose:()=>{if(!c){c=!0,p=0;for(const y of a)try{y.buffer.destroy()}catch{}}}}}const Au="bgra8unorm",Ru=[1,1,1,.8],Eu=8,Du=6,Bu=4,ca=8192,Lu=()=>{const e=new ArrayBuffer(64);return new Float32Array(e).set([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),e},ku=e=>Number.isFinite(e.left)&&Number.isFinite(e.right)&&Number.isFinite(e.top)&&Number.isFinite(e.bottom)&&Number.isFinite(e.canvasWidth)&&Number.isFinite(e.canvasHeight),Ii=(e,t,n)=>Math.min(n,Math.max(t,e|0)),Uu=(e,t)=>{if(!Number.isFinite(e)||e<0)throw new Error("CrosshairRenderer.prepare: lineWidth must be a finite non-negative number.");if(e===0)return[];const n=e*t,i=Math.max(1,Math.min(Eu,Math.round(n))),r=(i-1)/2,o=[];for(let s=0;s<i;s++)o.push(s-r);return o},Dn=(e,t)=>e/t*2-1,Bn=(e,t)=>1-e/t*2,Pi=(e,t)=>{e.push(t[0],t[1],t[2],t[3])},hs=(e,t)=>{if(!Number.isFinite(e)||!Number.isFinite(t))return[];const n=Math.min(e,t),i=Math.max(e,t);if(i<=n)return[];const r=Du,s=r+Bu;if(!Number.isFinite(s))return[];const a=Math.ceil((i-n)/s);if(!Number.isFinite(a)||a<=0)return[];const c=[];let u=n;for(;u<i;){const p=u,h=Math.min(u+r,i);h>p&&c.push([p,h]),u+=s}return c},_u=(e,t,n,i)=>{if(!Number.isFinite(e)||!Number.isFinite(t))throw new Error("CrosshairRenderer.prepare: x and y must be finite numbers.");if(!ku(n))throw new Error("CrosshairRenderer.prepare: gridArea dimensions must be finite numbers.");if(n.canvasWidth<=0||n.canvasHeight<=0)throw new Error("CrosshairRenderer.prepare: canvas dimensions must be positive.");if(n.left<0||n.right<0||n.top<0||n.bottom<0)throw new Error("CrosshairRenderer.prepare: gridArea margins must be non-negative.");const{canvasWidth:r,canvasHeight:o}=n,s=Number.isFinite(n.devicePixelRatio)&&n.devicePixelRatio>0?n.devicePixelRatio:1,a=n.left*s,c=r-n.right*s,u=n.top*s,p=o-n.bottom*s,h=Ii(Math.floor(a),0,Math.max(0,r)),l=Ii(Math.floor(u),0,Math.max(0,o)),m=Ii(Math.ceil(c),0,Math.max(0,r)),C=Ii(Math.ceil(p),0,Math.max(0,o)),F=Math.max(0,m-h),R=Math.max(0,C-l),S=e*s,y=t*s,b=Uu(i.lineWidth,s);if(b.length===0||!i.showX&&!i.showY)return{vertices:new Float32Array(0),scissor:{x:h,y:l,w:F,h:R}};const w=[],d=i.showX?hs(u,p):[],g=i.showY?hs(a,c):[],M=((i.showX?d.length:0)+(i.showY?g.length:0))*b.length*2,I=M>0&&M<=ca,T=x=>{const N=Dn(x,r),A=Bn(u,o),P=Bn(p,o);Pi(w,[N,A,N,P])},E=x=>{const N=Bn(x,o),A=Dn(a,r),P=Dn(c,r);Pi(w,[A,N,P,N])};if(i.showX)for(let x=0;x<b.length;x++){const N=S+b[x];if(!I){T(N);continue}const A=Dn(N,r);for(let P=0;P<d.length;P++){const[L,B]=d[P],V=Bn(L,o),_=Bn(B,o);Pi(w,[A,V,A,_])}}if(i.showY)for(let x=0;x<b.length;x++){const N=y+b[x];if(!I){E(N);continue}const A=Bn(N,o);for(let P=0;P<g.length;P++){const[L,B]=g[P],V=Dn(L,r),_=Dn(B,r);Pi(w,[V,A,_,A])}}return{vertices:new Float32Array(w),scissor:{x:h,y:l,w:F,h:R}}};function Gu(e,t){let n=!1,i=!0;const r=(t==null?void 0:t.targetFormat)??Au,o=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),s=nt(e,64,{label:"crosshairRenderer/vsUniforms"}),a=nt(e,16,{label:"crosshairRenderer/fsUniforms"}),c=e.createBindGroup({layout:o,entries:[{binding:0,resource:{buffer:s}},{binding:1,resource:{buffer:a}}]}),u=Tt(e,{label:"crosshairRenderer/pipeline",bindGroupLayouts:[o],vertex:{code:ps,label:"crosshair.wgsl",buffers:[{arrayStride:8,stepMode:"vertex",attributes:[{shaderLocation:0,format:"float32x2",offset:0}]}]},fragment:{code:ps,label:"crosshair.wgsl",formats:r,blend:{color:{operation:"add",srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{operation:"add",srcFactor:"one",dstFactor:"one-minus-src-alpha"}}},primitive:{topology:"line-list",cullMode:"none"},multisample:{count:1}}),p=Pu(e,ca*8);let h=0,l=0,m=0,C={x:0,y:0,w:0,h:0};const F=()=>{if(n)throw new Error("CrosshairRenderer is disposed.")};return{prepare:(w,d,g,v)=>{if(F(),typeof v.showX!="boolean"||typeof v.showY!="boolean")throw new Error("CrosshairRenderer.prepare: showX/showY must be boolean.");if(typeof v.color!="string")throw new Error("CrosshairRenderer.prepare: color must be a string.");if(!Number.isFinite(v.lineWidth)||v.lineWidth<0)throw new Error("CrosshairRenderer.prepare: lineWidth must be a finite non-negative number.");const{vertices:M,scissor:I}=_u(w,d,g,v);M.byteLength===0?h=0:(p.write(M),h=p.getVertexCount()),Qe(e,s,Lu());const T=pt(v.color)??Ru,E=new ArrayBuffer(4*4);new Float32Array(E).set([T[0],T[1],T[2],T[3]]),Qe(e,a,E),l=g.canvasWidth,m=g.canvasHeight,C=I},render:w=>{F(),i&&h!==0&&(l<=0||m<=0||(w.setScissorRect(C.x,C.y,C.w,C.h),w.setPipeline(u),w.setBindGroup(0,c),w.setVertexBuffer(0,p.getBuffer()),w.draw(h),w.setScissorRect(0,0,l,m)))},setVisible:w=>{F(),i=!!w},dispose:()=>{if(!n){n=!0;try{s.destroy()}catch{}try{a.destroy()}catch{}p.dispose(),h=0,l=0,m=0,C={x:0,y:0,w:0,h:0}}}}}const ys=`// highlight.wgsl
|
|
715
|
+
// Draws an anti-aliased ring highlight around a point.
|
|
716
|
+
//
|
|
717
|
+
// Contract:
|
|
718
|
+
// - \`@builtin(position)\` in the fragment stage is framebuffer-space pixels.
|
|
719
|
+
// - The renderer supplies \`center\` and ring sizes in *device pixels*.
|
|
720
|
+
|
|
721
|
+
struct Uniforms {
|
|
722
|
+
center: vec2<f32>,
|
|
723
|
+
radius: f32,
|
|
724
|
+
thickness: f32,
|
|
725
|
+
color: vec4<f32>,
|
|
726
|
+
outlineColor: vec4<f32>,
|
|
727
|
+
};
|
|
728
|
+
|
|
729
|
+
@group(0) @binding(0) var<uniform> u: Uniforms;
|
|
730
|
+
|
|
731
|
+
struct VSOut {
|
|
732
|
+
@builtin(position) position: vec4<f32>,
|
|
733
|
+
};
|
|
734
|
+
|
|
735
|
+
@vertex
|
|
736
|
+
fn vsMain(@builtin(vertex_index) vertexIndex: u32) -> VSOut {
|
|
737
|
+
// Fullscreen triangle.
|
|
738
|
+
// Covers clip-space [-1,1] with 3 verts: (-1,-1), (3,-1), (-1,3)
|
|
739
|
+
let positions = array<vec2<f32>, 3>(
|
|
740
|
+
vec2<f32>(-1.0, -1.0),
|
|
741
|
+
vec2<f32>(3.0, -1.0),
|
|
742
|
+
vec2<f32>(-1.0, 3.0)
|
|
743
|
+
);
|
|
744
|
+
|
|
745
|
+
var out: VSOut;
|
|
746
|
+
out.position = vec4<f32>(positions[vertexIndex], 0.0, 1.0);
|
|
747
|
+
return out;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
fn ringCoverage(distancePx: f32, radiusPx: f32, thicknessPx: f32) -> f32 {
|
|
751
|
+
let aa = 1.0; // ~1px antialias band (device pixels)
|
|
752
|
+
let halfT = max(0.5, thicknessPx * 0.5);
|
|
753
|
+
let a0 = smoothstep(radiusPx - halfT - aa, radiusPx - halfT + aa, distancePx);
|
|
754
|
+
let a1 = smoothstep(radiusPx + halfT - aa, radiusPx + halfT + aa, distancePx);
|
|
755
|
+
return clamp(a0 - a1, 0.0, 1.0);
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
@fragment
|
|
759
|
+
fn fsMain(@builtin(position) fragPos: vec4<f32>) -> @location(0) vec4<f32> {
|
|
760
|
+
let d = distance(fragPos.xy, u.center);
|
|
761
|
+
|
|
762
|
+
let ring = ringCoverage(d, u.radius, u.thickness);
|
|
763
|
+
let outline = ringCoverage(d, u.radius, u.thickness + 2.0);
|
|
764
|
+
|
|
765
|
+
let cover = max(ring, outline);
|
|
766
|
+
if (cover <= 0.0) {
|
|
767
|
+
discard;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
// Blend between outline and ring color based on relative coverage,
|
|
771
|
+
// then apply total coverage as alpha.
|
|
772
|
+
let t = clamp(select(0.0, ring / cover, cover > 0.0), 0.0, 1.0);
|
|
773
|
+
let rgb = mix(u.outlineColor.rgb, u.color.rgb, t);
|
|
774
|
+
let a = mix(u.outlineColor.a, u.color.a, t) * cover;
|
|
775
|
+
return vec4<f32>(rgb, a);
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
`,zu="bgra8unorm",Vu=[1,1,1,1],Ai=e=>Math.min(1,Math.max(0,e)),Ri=(e,t,n)=>Math.min(n,Math.max(t,e|0)),Ou=e=>Number.isFinite(e.x)&&Number.isFinite(e.y)&&Number.isFinite(e.w)&&Number.isFinite(e.h),$u=(e,t)=>{const n=Number.isFinite(t)?t:1;return[Ai(e[0]*n),Ai(e[1]*n),Ai(e[2]*n),Ai(e[3])]},Wu=e=>.2126*e[0]+.7152*e[1]+.0722*e[2];function Xu(e,t){let n=!1,i=!0;const r=(t==null?void 0:t.targetFormat)??zu,o=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),s=nt(e,48,{label:"highlightRenderer/uniforms"}),a=e.createBindGroup({layout:o,entries:[{binding:0,resource:{buffer:s}}]}),c=Tt(e,{label:"highlightRenderer/pipeline",bindGroupLayouts:[o],vertex:{code:ys,label:"highlight.wgsl"},fragment:{code:ys,label:"highlight.wgsl",formats:r,blend:{color:{operation:"add",srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{operation:"add",srcFactor:"one",dstFactor:"one-minus-src-alpha"}}},primitive:{topology:"triangle-list",cullMode:"none"},multisample:{count:1}});let u=0,p=0,h={x:0,y:0,w:0,h:0},l=!1;const m=()=>{if(n)throw new Error("HighlightRenderer is disposed.")};return{prepare:(y,b,w)=>{if(m(),!Number.isFinite(y.centerDeviceX)||!Number.isFinite(y.centerDeviceY))throw new Error("HighlightRenderer.prepare: point center must be finite.");if(!Number.isFinite(y.canvasWidth)||!Number.isFinite(y.canvasHeight)||y.canvasWidth<=0||y.canvasHeight<=0)throw new Error("HighlightRenderer.prepare: canvasWidth/canvasHeight must be positive finite numbers.");if(!Ou(y.scissor))throw new Error("HighlightRenderer.prepare: scissor must be finite.");if(!Number.isFinite(w)||w<0)throw new Error("HighlightRenderer.prepare: size must be a finite non-negative number.");const d=y.devicePixelRatio,g=Number.isFinite(d)&&d>0?d:1,v=w*g,M=Math.max(1,v*1.5),I=Math.max(1,Math.round(Math.max(2,M*.25))),T=pt(b)??Vu,E=$u(T,1.25),x=Wu(T)>.7?[0,0,0,.9]:[1,1,1,.9],N=new ArrayBuffer(12*4);new Float32Array(N).set([y.centerDeviceX,y.centerDeviceY,M,I,E[0],E[1],E[2],1,x[0],x[1],x[2],x[3]]),Qe(e,s,N),u=y.canvasWidth,p=y.canvasHeight;const A=Ri(Math.floor(y.scissor.x),0,Math.max(0,y.canvasWidth)),P=Ri(Math.floor(y.scissor.y),0,Math.max(0,y.canvasHeight)),L=Ri(Math.ceil(y.scissor.x+y.scissor.w),0,Math.max(0,y.canvasWidth)),B=Ri(Math.ceil(y.scissor.y+y.scissor.h),0,Math.max(0,y.canvasHeight));h={x:A,y:P,w:Math.max(0,L-A),h:Math.max(0,B-P)},l=!0},render:y=>{m(),i&&l&&(u<=0||p<=0||h.w===0||h.h===0||(y.setScissorRect(h.x,h.y,h.w,h.h),y.setPipeline(c),y.setBindGroup(0,a),y.draw(3),y.setScissorRect(0,0,u,p)))},setVisible:y=>{m(),i=!!y},dispose:()=>{if(!n){n=!0;try{s.destroy()}catch{}u=0,p=0,h={x:0,y:0,w:0,h:0},l=!1}}}}const gs=`// Reference line renderer (axis-aligned, instanced quads).
|
|
779
|
+
//
|
|
780
|
+
// Coordinate conventions:
|
|
781
|
+
// - Instance position is provided in CANVAS-LOCAL CSS pixels (same coordinate space as pointer events).
|
|
782
|
+
// - Plot rect is provided in DEVICE pixels (computed from grid margins + DPR).
|
|
783
|
+
// - Line width and dash lengths are provided in CSS pixels and converted in-shader using DPR.
|
|
784
|
+
//
|
|
785
|
+
// Scissoring/clipping:
|
|
786
|
+
// - The render coordinator is expected to set a scissor rect for the plot area before drawing.
|
|
787
|
+
// - This shader simply draws full-height/full-width quads; clipping is handled by scissor.
|
|
788
|
+
//
|
|
789
|
+
// Dash semantics:
|
|
790
|
+
// - lineDash is a repeating on/off sequence in CSS pixels, starting with "on" at t=0.
|
|
791
|
+
// - Up to 8 dash entries are supported per line (truncated on CPU).
|
|
792
|
+
//
|
|
793
|
+
// Performance:
|
|
794
|
+
// - Vertex stage expands each instance into a quad (2 triangles, 6 vertices).
|
|
795
|
+
// - We intentionally avoid snapping to integer device pixels to prevent visible stepping/jiggle
|
|
796
|
+
// while zooming; edge AA is handled in the fragment stage.
|
|
797
|
+
|
|
798
|
+
struct VSUniforms {
|
|
799
|
+
canvasSize : vec2<f32>, // device pixels (canvas.width, canvas.height)
|
|
800
|
+
plotOrigin : vec2<f32>, // device pixels (plotLeft, plotTop)
|
|
801
|
+
plotSize : vec2<f32>, // device pixels (plotWidth, plotHeight)
|
|
802
|
+
devicePixelRatio : f32,
|
|
803
|
+
_pad0 : f32,
|
|
804
|
+
};
|
|
805
|
+
|
|
806
|
+
@group(0) @binding(0) var<uniform> u : VSUniforms;
|
|
807
|
+
|
|
808
|
+
struct VSIn {
|
|
809
|
+
// axisPos.x = axis (0 = vertical, 1 = horizontal)
|
|
810
|
+
// axisPos.y = position in CANVAS-LOCAL CSS pixels (x for vertical, y for horizontal)
|
|
811
|
+
@location(0) axisPos : vec2<f32>,
|
|
812
|
+
|
|
813
|
+
// widthDashCount.x = lineWidth in CSS px
|
|
814
|
+
// widthDashCount.y = dashCount (float, cast to u32)
|
|
815
|
+
@location(1) widthDashCount : vec2<f32>,
|
|
816
|
+
|
|
817
|
+
// dashMeta.x = dashTotal (CSS px)
|
|
818
|
+
// dashMeta.y = reserved (unused)
|
|
819
|
+
@location(2) dashMeta : vec2<f32>,
|
|
820
|
+
|
|
821
|
+
@location(3) dash0_3 : vec4<f32>,
|
|
822
|
+
@location(4) dash4_7 : vec4<f32>,
|
|
823
|
+
|
|
824
|
+
// Premultiplied or straight alpha is fine; blending is handled by pipeline state.
|
|
825
|
+
@location(5) color : vec4<f32>,
|
|
826
|
+
};
|
|
827
|
+
|
|
828
|
+
struct VSOut {
|
|
829
|
+
@builtin(position) position : vec4<f32>,
|
|
830
|
+
|
|
831
|
+
// Distance along the line in CSS pixels (0..plotLengthCss).
|
|
832
|
+
@location(0) alongCss : f32,
|
|
833
|
+
|
|
834
|
+
// Packed dash metadata to avoid extra varyings.
|
|
835
|
+
// dashInfo.x = dashCount (float, cast to u32)
|
|
836
|
+
// dashInfo.y = dashTotal (CSS px)
|
|
837
|
+
@location(1) @interpolate(flat) dashInfo : vec2<f32>,
|
|
838
|
+
|
|
839
|
+
@location(2) @interpolate(flat) dash0_3 : vec4<f32>,
|
|
840
|
+
@location(3) @interpolate(flat) dash4_7 : vec4<f32>,
|
|
841
|
+
@location(4) @interpolate(flat) color : vec4<f32>,
|
|
842
|
+
|
|
843
|
+
// Axis-aligned quad anti-aliasing (device pixels).
|
|
844
|
+
// acrossDevice ranges [0..widthDevice] across the stroke thickness.
|
|
845
|
+
@location(5) acrossDevice : f32,
|
|
846
|
+
@location(6) @interpolate(flat) widthDevice : f32,
|
|
847
|
+
};
|
|
848
|
+
|
|
849
|
+
fn quadUv(vid : u32) -> vec2<f32> {
|
|
850
|
+
// Two triangles covering [0,1]x[0,1].
|
|
851
|
+
// 0: (0,0) 1:(1,0) 2:(0,1) 3:(0,1) 4:(1,0) 5:(1,1)
|
|
852
|
+
switch (vid) {
|
|
853
|
+
case 0u: { return vec2<f32>(0.0, 0.0); }
|
|
854
|
+
case 1u: { return vec2<f32>(1.0, 0.0); }
|
|
855
|
+
case 2u: { return vec2<f32>(0.0, 1.0); }
|
|
856
|
+
case 3u: { return vec2<f32>(0.0, 1.0); }
|
|
857
|
+
case 4u: { return vec2<f32>(1.0, 0.0); }
|
|
858
|
+
default: { return vec2<f32>(1.0, 1.0); }
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
@vertex
|
|
863
|
+
fn vsMain(in : VSIn, @builtin(vertex_index) vid : u32) -> VSOut {
|
|
864
|
+
let uv = quadUv(vid);
|
|
865
|
+
let dpr = max(1e-6, u.devicePixelRatio);
|
|
866
|
+
// IMPORTANT: Do NOT snap reference lines to integer device pixels.
|
|
867
|
+
// Snapping looks crisp at rest but causes visible "jiggle" / stepping while zooming because
|
|
868
|
+
// the line position is continuously changing (data-space → screen-space), and rounding
|
|
869
|
+
// quantizes that motion to adjacent pixels. We rely on analytic AA in the fragment stage
|
|
870
|
+
// to keep strokes stable and reasonably crisp across DPRs.
|
|
871
|
+
|
|
872
|
+
let axis = in.axisPos.x;
|
|
873
|
+
let posCss = in.axisPos.y;
|
|
874
|
+
let widthCss = max(0.0, in.widthDashCount.x);
|
|
875
|
+
let widthDevice = max(1.0, widthCss * dpr);
|
|
876
|
+
|
|
877
|
+
var xDevice : f32;
|
|
878
|
+
var yDevice : f32;
|
|
879
|
+
var alongCss : f32;
|
|
880
|
+
var acrossDevice : f32;
|
|
881
|
+
|
|
882
|
+
if (axis < 0.5) {
|
|
883
|
+
// Vertical line at x = posCss (canvas-local CSS px), spanning plot height.
|
|
884
|
+
let centerX = posCss * dpr;
|
|
885
|
+
let startX = centerX - 0.5 * widthDevice;
|
|
886
|
+
xDevice = startX + uv.x * widthDevice;
|
|
887
|
+
yDevice = u.plotOrigin.y + uv.y * u.plotSize.y;
|
|
888
|
+
alongCss = (uv.y * u.plotSize.y) / dpr;
|
|
889
|
+
acrossDevice = uv.x * widthDevice;
|
|
890
|
+
} else {
|
|
891
|
+
// Horizontal line at y = posCss (canvas-local CSS px), spanning plot width.
|
|
892
|
+
let centerY = posCss * dpr;
|
|
893
|
+
let startY = centerY - 0.5 * widthDevice;
|
|
894
|
+
xDevice = u.plotOrigin.x + uv.x * u.plotSize.x;
|
|
895
|
+
yDevice = startY + uv.y * widthDevice;
|
|
896
|
+
alongCss = (uv.x * u.plotSize.x) / dpr;
|
|
897
|
+
acrossDevice = uv.y * widthDevice;
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
let clipX = (xDevice / u.canvasSize.x) * 2.0 - 1.0;
|
|
901
|
+
let clipY = 1.0 - (yDevice / u.canvasSize.y) * 2.0;
|
|
902
|
+
|
|
903
|
+
var out : VSOut;
|
|
904
|
+
out.position = vec4<f32>(clipX, clipY, 0.0, 1.0);
|
|
905
|
+
out.alongCss = alongCss;
|
|
906
|
+
out.dashInfo = vec2<f32>(in.widthDashCount.y, in.dashMeta.x);
|
|
907
|
+
out.dash0_3 = in.dash0_3;
|
|
908
|
+
out.dash4_7 = in.dash4_7;
|
|
909
|
+
out.color = in.color;
|
|
910
|
+
out.acrossDevice = acrossDevice;
|
|
911
|
+
out.widthDevice = widthDevice;
|
|
912
|
+
return out;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
fn dashValue(i : u32, d0 : vec4<f32>, d1 : vec4<f32>) -> f32 {
|
|
916
|
+
switch (i) {
|
|
917
|
+
case 0u: { return d0.x; }
|
|
918
|
+
case 1u: { return d0.y; }
|
|
919
|
+
case 2u: { return d0.z; }
|
|
920
|
+
case 3u: { return d0.w; }
|
|
921
|
+
case 4u: { return d1.x; }
|
|
922
|
+
case 5u: { return d1.y; }
|
|
923
|
+
case 6u: { return d1.z; }
|
|
924
|
+
default: { return d1.w; }
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
@fragment
|
|
929
|
+
fn fsMain(in : VSOut) -> @location(0) vec4<f32> {
|
|
930
|
+
// Analytic edge anti-aliasing for axis-aligned quads (reduces shimmering during zoom).
|
|
931
|
+
// This is a lightweight alternative to full MSAA for thin strokes.
|
|
932
|
+
let edgeDist = min(in.acrossDevice, in.widthDevice - in.acrossDevice);
|
|
933
|
+
// Slightly widen AA to reduce temporal shimmer on moving 1-2px strokes.
|
|
934
|
+
// Keep conservative so lines remain reasonably crisp.
|
|
935
|
+
let aa = max(fwidth(in.acrossDevice), 1e-3) * 1.25;
|
|
936
|
+
let edgeCoverage = smoothstep(0.0, aa, edgeDist);
|
|
937
|
+
var color = in.color;
|
|
938
|
+
color.a = color.a * edgeCoverage;
|
|
939
|
+
|
|
940
|
+
let dashCount = u32(round(in.dashInfo.x));
|
|
941
|
+
let dashTotal = in.dashInfo.y;
|
|
942
|
+
|
|
943
|
+
// IMPORTANT: derivative ops (fwidth) must execute in uniform control flow.
|
|
944
|
+
// So compute the dash parameterization unconditionally (using a safe total) BEFORE any early-return.
|
|
945
|
+
let dashTotalSafe = max(dashTotal, 1.0);
|
|
946
|
+
let t = in.alongCss - floor(in.alongCss / dashTotalSafe) * dashTotalSafe;
|
|
947
|
+
// Anti-alias dash edges along the line axis (CSS pixels).
|
|
948
|
+
// This reduces shimmer during zoom for dashed reference lines without requiring MSAA.
|
|
949
|
+
let dashAa = max(fwidth(t), 1e-3);
|
|
950
|
+
|
|
951
|
+
// Solid line (no dash pattern).
|
|
952
|
+
if (dashCount == 0u || dashTotal <= 0.0) {
|
|
953
|
+
return color;
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
var acc = 0.0;
|
|
957
|
+
var on = true;
|
|
958
|
+
|
|
959
|
+
for (var i : u32 = 0u; i < 8u; i = i + 1u) {
|
|
960
|
+
if (i >= dashCount) { break; }
|
|
961
|
+
let seg = dashValue(i, in.dash0_3, in.dash4_7);
|
|
962
|
+
if (seg <= 0.0) { continue; }
|
|
963
|
+
|
|
964
|
+
if (t < acc + seg) {
|
|
965
|
+
// IMPORTANT: Avoid \`discard\` for off segments.
|
|
966
|
+
// Discard can cause temporal popping on moving dashed edges; prefer a smooth alpha mask.
|
|
967
|
+
//
|
|
968
|
+
// Fade in/out near dash boundaries for smooth edges. This produces coverage in [0..1]
|
|
969
|
+
// within the current segment, going to 0 at segment boundaries.
|
|
970
|
+
let inFromStart = smoothstep(0.0, dashAa, t - acc);
|
|
971
|
+
let inFromEnd = smoothstep(0.0, dashAa, (acc + seg) - t);
|
|
972
|
+
let segCoverage = min(inFromStart, inFromEnd);
|
|
973
|
+
|
|
974
|
+
// On segments contribute alpha; off segments contribute 0 alpha (no discard).
|
|
975
|
+
let dashMask = select(0.0, segCoverage, on);
|
|
976
|
+
color.a = color.a * dashMask;
|
|
977
|
+
return color;
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
acc = acc + seg;
|
|
981
|
+
on = !on;
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
// Defensive fallback if the dash list is degenerate.
|
|
985
|
+
// If we didn't find a segment (shouldn't happen), default to transparent (safer than solid).
|
|
986
|
+
color.a = 0.0;
|
|
987
|
+
return color;
|
|
988
|
+
}
|
|
989
|
+
`,Un=8,Yu="bgra8unorm",Hu=e=>Number.isFinite(e.left)&&Number.isFinite(e.right)&&Number.isFinite(e.top)&&Number.isFinite(e.bottom)&&Number.isFinite(e.canvasWidth)&&Number.isFinite(e.canvasHeight),qu=e=>{if(!e||e.length===0)return{dashCount:0,dashTotal:0,values:new Array(Un).fill(0)};const t=[];for(let s=0;s<e.length;s++){const a=e[s];typeof a=="number"&&Number.isFinite(a)&&a>0&&t.push(a)}if(t.length===0)return{dashCount:0,dashTotal:0,values:new Array(Un).fill(0)};const n=t.length%2===1?t.concat(t):t,i=Math.min(Un,n.length),r=new Array(Un).fill(0);let o=0;for(let s=0;s<i;s++)r[s]=n[s],o+=n[s];return!Number.isFinite(o)||o<=0?{dashCount:0,dashTotal:0,values:new Array(Un).fill(0)}:{dashCount:i,dashTotal:o,values:r}};function xs(e,t){let n=!1;const i=(t==null?void 0:t.targetFormat)??Yu,r=(t==null?void 0:t.sampleCount)??1,o=Number.isFinite(r)?Math.max(1,Math.floor(r)):1,s=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}}]}),a=nt(e,32,{label:"referenceLineRenderer/vsUniforms"}),c=e.createBindGroup({layout:s,entries:[{binding:0,resource:{buffer:a}}]}),u=72,p=u/4,h=Tt(e,{label:"referenceLineRenderer/pipeline",bindGroupLayouts:[s],vertex:{code:gs,label:"referenceLine.wgsl",buffers:[{arrayStride:u,stepMode:"instance",attributes:[{shaderLocation:0,format:"float32x2",offset:0},{shaderLocation:1,format:"float32x2",offset:8},{shaderLocation:2,format:"float32x2",offset:16},{shaderLocation:3,format:"float32x4",offset:24},{shaderLocation:4,format:"float32x4",offset:40},{shaderLocation:5,format:"float32x4",offset:56}]}]},fragment:{code:gs,label:"referenceLine.wgsl",formats:i,blend:{color:{operation:"add",srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{operation:"add",srcFactor:"one",dstFactor:"one-minus-src-alpha"}}},primitive:{topology:"triangle-list",cullMode:"none"},multisample:{count:o}});let l=null,m=0,C=0;const F=()=>{if(n)throw new Error("ReferenceLineRenderer is disposed.")};return{prepare:(b,w)=>{if(F(),!Array.isArray(w))throw new Error("ReferenceLineRenderer.prepare: lines must be an array.");if(!Hu(b))throw new Error("ReferenceLineRenderer.prepare: gridArea dimensions must be finite numbers.");if(b.canvasWidth<=0||b.canvasHeight<=0)throw new Error("ReferenceLineRenderer.prepare: canvas dimensions must be positive.");if(b.left<0||b.right<0||b.top<0||b.bottom<0)throw new Error("ReferenceLineRenderer.prepare: gridArea margins must be non-negative.");const d=Number.isFinite(b.devicePixelRatio)&&b.devicePixelRatio>0?b.devicePixelRatio:1,g=b.left*d,v=b.top*d,M=b.canvasWidth-b.right*d,I=b.canvasHeight-b.bottom*d,T=M-g,E=I-v;if(!(T>0)||!(E>0)){C=0;return}const f=new Float32Array(8);if(f[0]=b.canvasWidth,f[1]=b.canvasHeight,f[2]=g,f[3]=v,f[4]=T,f[5]=E,f[6]=d,f[7]=0,Qe(e,a,f),w.length===0){C=0;return}if(!l||m<w.length){const N=Math.max(1,Math.ceil(w.length*1.5)),A=Math.max(4,N*u);if(l)try{l.destroy()}catch{}l=e.createBuffer({label:"referenceLineRenderer/instanceBuffer",size:A,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST}),m=N}const x=new Float32Array(w.length*p);for(let N=0;N<w.length;N++){const A=w[N],P=N*p;if(A.axis!=="vertical"&&A.axis!=="horizontal")throw new Error("ReferenceLineRenderer.prepare: line.axis must be 'vertical' or 'horizontal'.");if(!Number.isFinite(A.positionCssPx))throw new Error("ReferenceLineRenderer.prepare: line.positionCssPx must be a finite number.");if(!Number.isFinite(A.lineWidth)||A.lineWidth<0)throw new Error("ReferenceLineRenderer.prepare: line.lineWidth must be a finite non-negative number.");const L=A.rgba;if(!Array.isArray(L)||L.length!==4)throw new Error("ReferenceLineRenderer.prepare: line.rgba must be a tuple [r,g,b,a].");const B=qu(A.lineDash);x[P+0]=A.axis==="vertical"?0:1,x[P+1]=A.positionCssPx,x[P+2]=A.lineWidth,x[P+3]=B.dashCount,x[P+4]=B.dashTotal,x[P+5]=0;for(let V=0;V<Un;V++)x[P+6+V]=B.values[V];x[P+14]=L[0],x[P+15]=L[1],x[P+16]=L[2],x[P+17]=L[3]}e.queue.writeBuffer(l,0,x.buffer,x.byteOffset,x.byteLength),C=w.length},render:(b,w=0,d)=>{if(F(),C===0||!l)return;const g=Number.isFinite(w)?Math.max(0,Math.floor(w)):0,v=Math.max(0,C-g),M=d==null?v:Number.isFinite(d)?Math.max(0,Math.min(v,Math.floor(d))):v;M!==0&&(b.setPipeline(h),b.setBindGroup(0,c),b.setVertexBuffer(0,l),b.draw(6,M,0,g))},dispose:()=>{if(!n){n=!0;try{a.destroy()}catch{}if(l)try{l.destroy()}catch{}l=null,m=0,C=0}}}}const bs=`// annotationMarker.wgsl
|
|
990
|
+
// Instanced annotation marker shader (circle SDF with optional stroke).
|
|
991
|
+
//
|
|
992
|
+
// Coordinate contract:
|
|
993
|
+
// - Instance center is CANVAS-LOCAL CSS pixels (xCssPx, yCssPx)
|
|
994
|
+
// - Instance size is diameter in CSS pixels (sizeCssPx)
|
|
995
|
+
// - Uniform provides render target size in *device* pixels and DPR for CSS→device conversion.
|
|
996
|
+
//
|
|
997
|
+
// Draw call: draw(6, instanceCount) using triangle-list quad expansion in VS.
|
|
998
|
+
|
|
999
|
+
struct VSUniforms {
|
|
1000
|
+
viewportPx: vec2<f32>, // render target size in device pixels (width, height)
|
|
1001
|
+
dpr: f32, // device pixel ratio (CSS px -> device px)
|
|
1002
|
+
_pad0: f32,
|
|
1003
|
+
};
|
|
1004
|
+
|
|
1005
|
+
@group(0) @binding(0) var<uniform> vsUniforms: VSUniforms;
|
|
1006
|
+
|
|
1007
|
+
struct VSIn {
|
|
1008
|
+
// Center in CANVAS-LOCAL CSS pixels.
|
|
1009
|
+
@location(0) centerCssPx: vec2<f32>,
|
|
1010
|
+
// Marker diameter in CSS pixels.
|
|
1011
|
+
@location(1) sizeCssPx: f32,
|
|
1012
|
+
// Stroke width in CSS pixels (0 disables stroke).
|
|
1013
|
+
@location(2) strokeWidthCssPx: f32,
|
|
1014
|
+
// Colors are straight-alpha RGBA in 0..1.
|
|
1015
|
+
@location(3) fillRgba: vec4<f32>,
|
|
1016
|
+
@location(4) strokeRgba: vec4<f32>,
|
|
1017
|
+
};
|
|
1018
|
+
|
|
1019
|
+
struct VSOut {
|
|
1020
|
+
@builtin(position) clipPosition: vec4<f32>,
|
|
1021
|
+
// Local quad coordinates in [-1, 1]^2 (used for circle SDF).
|
|
1022
|
+
@location(0) local: vec2<f32>,
|
|
1023
|
+
// Half-size in device pixels (radius in screen space).
|
|
1024
|
+
@location(1) halfSizePx: f32,
|
|
1025
|
+
@location(2) strokeWidthPx: f32,
|
|
1026
|
+
@location(3) fillRgba: vec4<f32>,
|
|
1027
|
+
@location(4) strokeRgba: vec4<f32>,
|
|
1028
|
+
};
|
|
1029
|
+
|
|
1030
|
+
@vertex
|
|
1031
|
+
fn vsMain(in: VSIn, @builtin(vertex_index) vertexIndex: u32) -> VSOut {
|
|
1032
|
+
// Fixed local corners for 2 triangles (triangle-list).
|
|
1033
|
+
let localCorners = array<vec2<f32>, 6>(
|
|
1034
|
+
vec2<f32>(-1.0, -1.0),
|
|
1035
|
+
vec2<f32>( 1.0, -1.0),
|
|
1036
|
+
vec2<f32>(-1.0, 1.0),
|
|
1037
|
+
vec2<f32>(-1.0, 1.0),
|
|
1038
|
+
vec2<f32>( 1.0, -1.0),
|
|
1039
|
+
vec2<f32>( 1.0, 1.0)
|
|
1040
|
+
);
|
|
1041
|
+
|
|
1042
|
+
let corner = localCorners[vertexIndex];
|
|
1043
|
+
|
|
1044
|
+
let dpr = select(1.0, vsUniforms.dpr, vsUniforms.dpr > 0.0);
|
|
1045
|
+
let centerPx = in.centerCssPx * dpr;
|
|
1046
|
+
let halfSizePx = 0.5 * max(0.0, in.sizeCssPx) * dpr;
|
|
1047
|
+
let strokeWidthPx = max(0.0, in.strokeWidthCssPx) * dpr;
|
|
1048
|
+
|
|
1049
|
+
let posPx = centerPx + corner * halfSizePx;
|
|
1050
|
+
|
|
1051
|
+
// Convert device pixels to clip-space with origin at top-left:
|
|
1052
|
+
// x: [0..w] -> [-1..1], y: [0..h] -> [1..-1]
|
|
1053
|
+
let clipX = (posPx.x / vsUniforms.viewportPx.x) * 2.0 - 1.0;
|
|
1054
|
+
let clipY = 1.0 - (posPx.y / vsUniforms.viewportPx.y) * 2.0;
|
|
1055
|
+
|
|
1056
|
+
var out: VSOut;
|
|
1057
|
+
out.clipPosition = vec4<f32>(clipX, clipY, 0.0, 1.0);
|
|
1058
|
+
out.local = corner;
|
|
1059
|
+
out.halfSizePx = halfSizePx;
|
|
1060
|
+
out.strokeWidthPx = strokeWidthPx;
|
|
1061
|
+
out.fillRgba = in.fillRgba;
|
|
1062
|
+
out.strokeRgba = in.strokeRgba;
|
|
1063
|
+
return out;
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
@fragment
|
|
1067
|
+
fn fsMain(in: VSOut) -> @location(0) vec4<f32> {
|
|
1068
|
+
if (in.halfSizePx <= 0.0) {
|
|
1069
|
+
discard;
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
// Circle SDF in normalized space: dist == 1 at the circle boundary.
|
|
1073
|
+
let dist = length(in.local);
|
|
1074
|
+
let aa = max(1e-6, fwidth(dist));
|
|
1075
|
+
|
|
1076
|
+
// Coverage inside the circle.
|
|
1077
|
+
let outerCoverage = 1.0 - smoothstep(1.0 - aa, 1.0 + aa, dist);
|
|
1078
|
+
if (outerCoverage <= 0.0) {
|
|
1079
|
+
discard;
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
// Optional stroke: compute inner radius in normalized units.
|
|
1083
|
+
let strokeNorm = clamp(in.strokeWidthPx / max(1e-6, in.halfSizePx), 0.0, 1.0);
|
|
1084
|
+
let inner = max(0.0, 1.0 - strokeNorm);
|
|
1085
|
+
let innerCoverage = 1.0 - smoothstep(inner - aa, inner + aa, dist);
|
|
1086
|
+
|
|
1087
|
+
let fillCoverage = clamp(innerCoverage, 0.0, 1.0);
|
|
1088
|
+
let strokeCoverage = clamp(outerCoverage - innerCoverage, 0.0, 1.0);
|
|
1089
|
+
|
|
1090
|
+
let fillA = clamp(in.fillRgba.a, 0.0, 1.0) * fillCoverage;
|
|
1091
|
+
let strokeA = clamp(in.strokeRgba.a, 0.0, 1.0) * strokeCoverage;
|
|
1092
|
+
let outA = fillA + strokeA;
|
|
1093
|
+
if (outA <= 0.0) {
|
|
1094
|
+
discard;
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
// Straight-alpha output: compute a weighted average RGB for correct blending.
|
|
1098
|
+
let rgb = (in.fillRgba.rgb * fillA + in.strokeRgba.rgb * strokeA) / outA;
|
|
1099
|
+
return vec4<f32>(rgb, outA);
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
`,Zu="bgra8unorm",zi=12,Br=zi*4,dn=e=>Math.min(1,Math.max(0,e)),vs=e=>{if(!Number.isFinite(e)||e<=0)return 1;const t=Math.ceil(e);return 2**Math.ceil(Math.log2(t))};function ws(e,t){let n=!1;const i=(t==null?void 0:t.targetFormat)??Zu,r=(t==null?void 0:t.sampleCount)??1,o=Number.isFinite(r)?Math.max(1,Math.floor(r)):1,s=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}}]}),a=nt(e,16,{label:"annotationMarkerRenderer/vsUniforms"}),c=new Float32Array(4),u=e.createBindGroup({layout:s,entries:[{binding:0,resource:{buffer:a}}]}),p=Tt(e,{label:"annotationMarkerRenderer/pipeline",bindGroupLayouts:[s],vertex:{code:bs,label:"annotationMarker.wgsl",buffers:[{arrayStride:Br,stepMode:"instance",attributes:[{shaderLocation:0,format:"float32x2",offset:0},{shaderLocation:1,format:"float32",offset:8},{shaderLocation:2,format:"float32",offset:12},{shaderLocation:3,format:"float32x4",offset:16},{shaderLocation:4,format:"float32x4",offset:32}]}]},fragment:{code:bs,label:"annotationMarker.wgsl",formats:i,blend:{color:{operation:"add",srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{operation:"add",srcFactor:"one",dstFactor:"one-minus-src-alpha"}}},primitive:{topology:"triangle-list",cullMode:"none"},multisample:{count:o}});let h=null,l=0,m=new ArrayBuffer(0),C=new Float32Array(m);const F=()=>{if(n)throw new Error("AnnotationMarkerRenderer is disposed.")},R=d=>{if(d<=C.length)return;const g=Math.max(32,vs(d));m=new ArrayBuffer(g*4),C=new Float32Array(m)},S=(d,g,v)=>{const M=Number.isFinite(d)&&d>0?d:1,I=Number.isFinite(g)&&g>0?g:1,T=Number.isFinite(v)&&v>0?v:1;c[0]=M,c[1]=I,c[2]=T,c[3]=0,Qe(e,a,c)};return{prepare:({canvasWidth:d,canvasHeight:g,devicePixelRatio:v,instances:M})=>{if(F(),!Number.isFinite(d)||!Number.isFinite(g)||d<=0||g<=0)throw new Error("AnnotationMarkerRenderer.prepare: canvasWidth/canvasHeight must be positive finite numbers.");if(!Array.isArray(M))throw new Error("AnnotationMarkerRenderer.prepare: instances must be an array.");S(d,g,v),R(M.length*zi);const I=C;let T=0;for(let f=0;f<M.length;f++){const x=M[f];if(!Number.isFinite(x.xCssPx)||!Number.isFinite(x.yCssPx)||!Number.isFinite(x.sizeCssPx)||x.sizeCssPx<=0)continue;const N=x.strokeWidthCssPx??0,A=x.strokeRgba??[0,0,0,0],P=dn(x.fillRgba[0]),L=dn(x.fillRgba[1]),B=dn(x.fillRgba[2]),V=dn(x.fillRgba[3]),_=dn(A[0]),re=dn(A[1]),Y=dn(A[2]),W=dn(A[3]);I[T+0]=x.xCssPx,I[T+1]=x.yCssPx,I[T+2]=x.sizeCssPx,I[T+3]=Number.isFinite(N)?Math.max(0,N):0,I[T+4]=P,I[T+5]=L,I[T+6]=B,I[T+7]=V,I[T+8]=_,I[T+9]=re,I[T+10]=Y,I[T+11]=W,T+=zi}if(l=T/zi,l===0)return;const E=Math.max(4,l*Br);if(!h||h.size<E){const f=Math.max(Math.max(4,vs(E)),h?h.size:0);if(h)try{h.destroy()}catch{}h=e.createBuffer({label:"annotationMarkerRenderer/instanceBuffer",size:f,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST})}e.queue.writeBuffer(h,0,m,0,l*Br)},render:(d,g=0,v)=>{if(F(),!h||l===0)return;const M=Number.isFinite(g)?Math.max(0,Math.floor(g)):0,I=Math.max(0,l-M),T=v==null?I:Number.isFinite(v)?Math.max(0,Math.min(I,Math.floor(v))):I;T!==0&&(d.setPipeline(p),d.setBindGroup(0,u),d.setVertexBuffer(0,h),d.draw(6,T,0,M))},dispose:()=>{if(!n){if(n=!0,h)try{h.destroy()}catch{}h=null,l=0;try{a.destroy()}catch{}}}}}const ju=6,Ku=500;function Ju(e,t){let n=!1,i=t;const r={mousemove:new Set,click:new Set,mouseleave:new Set};let o=null,s=null;const a=w=>{const d=e.getBoundingClientRect();if(d.width===0||d.height===0)return null;const g=w.clientX-d.left,v=w.clientY-d.top,M=i.left,I=i.top,T=d.width-i.left-i.right,E=d.height-i.top-i.bottom,f=g-M,x=v-I,N=f>=0&&f<=T&&x>=0&&x<=E;return{x:g,y:v,gridX:f,gridY:x,plotWidthCss:T,plotHeightCss:E,isInGrid:N,originalEvent:w}},c=(w,d)=>{const g=a(d);if(g)for(const v of r[w])v(g)},u=w=>{o&&w.isPrimary&&w.pointerId===o.pointerId&&(o=null)},p=w=>{n||c("mousemove",w)},h=w=>{n||(u(w),c("mouseleave",w))},l=w=>{n||(u(w),c("mouseleave",w))},m=w=>{if(!n){if(s===w.pointerId){s=null;return}u(w),c("mouseleave",w)}},C=w=>{if(n||!w.isPrimary||w.pointerType==="mouse"&&w.button!==0)return;const d=e.getBoundingClientRect();if(!(d.width===0||d.height===0)){o={pointerId:w.pointerId,startClientX:w.clientX,startClientY:w.clientY,startTimeMs:w.timeStamp};try{e.setPointerCapture(w.pointerId)}catch{}}},F=w=>{if(n||!w.isPrimary||!o||w.pointerId!==o.pointerId)return;const d=w.timeStamp-o.startTimeMs,g=w.clientX-o.startClientX,v=w.clientY-o.startClientY,M=g*g+v*v;o=null;try{e.hasPointerCapture(w.pointerId)&&(s=w.pointerId,e.releasePointerCapture(w.pointerId))}catch{}const I=ju;d<=Ku&&M<=I*I&&c("click",w)};return e.addEventListener("pointermove",p,{passive:!0}),e.addEventListener("pointerleave",h,{passive:!0}),e.addEventListener("pointercancel",l,{passive:!0}),e.addEventListener("lostpointercapture",m,{passive:!0}),e.addEventListener("pointerdown",C,{passive:!0}),e.addEventListener("pointerup",F,{passive:!0}),{canvas:e,on:(w,d)=>{n||r[w].add(d)},off:(w,d)=>{r[w].delete(d)},updateGridArea:w=>{i=w},dispose:()=>{n||(n=!0,o=null,s=null,e.removeEventListener("pointermove",p),e.removeEventListener("pointerleave",h),e.removeEventListener("pointercancel",l),e.removeEventListener("lostpointercapture",m),e.removeEventListener("pointerdown",C),e.removeEventListener("pointerup",F),r.mousemove.clear(),r.click.clear(),r.mouseleave.clear())}}}const Cs=(e,t,n)=>Math.min(n,Math.max(t,e)),Qu=(e,t)=>{const n=e.deltaY;if(!Number.isFinite(n)||n===0)return 0;switch(e.deltaMode){case WheelEvent.DOM_DELTA_PIXEL:return n;case WheelEvent.DOM_DELTA_LINE:return n*16;case WheelEvent.DOM_DELTA_PAGE:return n*(Number.isFinite(t)&&t>0?t:800);default:return n}},ef=(e,t)=>{const n=e.deltaX;if(!Number.isFinite(n)||n===0)return 0;switch(e.deltaMode){case WheelEvent.DOM_DELTA_PIXEL:return n;case WheelEvent.DOM_DELTA_LINE:return n*16;case WheelEvent.DOM_DELTA_PAGE:return n*(Number.isFinite(t)&&t>0?t:800);default:return n}},tf=e=>{const t=Math.abs(e);if(!Number.isFinite(t)||t===0)return 1;const n=Math.min(t,200);return Math.exp(n*.002)},nf=e=>e.pointerType==="mouse"&&(e.buttons&4)!==0,rf=e=>e.pointerType==="mouse"&&e.shiftKey&&(e.buttons&1)!==0;function of(e,t){let n=!1,i=!1,r=null,o=!1,s=0;const a=()=>{o=!1,s=0},c=C=>{if(r=C,!i)return;const F=C.originalEvent;if(!(C.isInGrid&&(rf(F)||nf(F)))){a();return}const S=C.plotWidthCss;if(!(S>0)||!Number.isFinite(S)){a();return}if(!o){o=!0,s=C.gridX;return}const y=C.gridX-s;if(s=C.gridX,!Number.isFinite(y)||y===0)return;const{start:b,end:w}=t.getRange(),d=w-b;if(!Number.isFinite(d)||d===0)return;const g=-(y/S)*d;!Number.isFinite(g)||g===0||t.pan(g)},u=C=>{r=null,a()},p=C=>{if(!i||n)return;const F=r;if(!F||!F.isInGrid)return;const R=F.plotWidthCss,S=F.plotHeightCss;if(!(R>0)||!(S>0))return;const y=Qu(C,S),b=ef(C,R);if(Math.abs(b)>Math.abs(y)&&b!==0){const{start:T,end:E}=t.getRange(),f=E-T;if(!Number.isFinite(f)||f===0)return;const x=b/R*f;if(!Number.isFinite(x)||x===0)return;C.preventDefault(),t.pan(x);return}if(y===0)return;const w=tf(y);if(!(w>1))return;const{start:d,end:g}=t.getRange(),v=g-d;if(!Number.isFinite(v)||v===0)return;const M=Cs(F.gridX/R,0,1),I=Cs(d+M*v,0,100);C.preventDefault(),y<0?t.zoomIn(I,w):t.zoomOut(I,w)},h=()=>{n||i||(i=!0,e.on("mousemove",c),e.on("mouseleave",u),e.canvas.addEventListener("wheel",p,{passive:!1}))},l=()=>{n||!i||(i=!1,e.off("mousemove",c),e.off("mouseleave",u),e.canvas.removeEventListener("wheel",p),r=null,a())};return{enable:h,disable:l,dispose:()=>{n||(l(),n=!0)}}}const sf=.5,af=100,Vt=(e,t,n)=>Math.min(n,Math.max(t,e)),Lr=e=>Vt(e,0,1),Ms=e=>Object.is(e,-0)?0:e,cf=e=>({start:e.start,end:e.end});function lf(e,t,n){let i=0,r=100,o=null;const s=new Set;let a=(()=>{const g=Number.isFinite(n==null?void 0:n.minSpan)?n.minSpan:sf;return Vt(Number.isFinite(g)?g:0,0,100)})(),c=(()=>{const g=Number.isFinite(n==null?void 0:n.maxSpan)?n.maxSpan:af;return Vt(Number.isFinite(g)?g:100,0,100)})(),u=Math.min(a,c),p=Math.max(a,c);const h=()=>{const g={start:i,end:r};if(o!==null&&o.start===g.start&&o.end===g.end)return;o=cf(g);const v=Array.from(s);for(const M of v)M({start:i,end:r})},l=(g,v,M)=>{if(M){if(typeof M=="string")switch(M){case"start":return{center:g,ratio:0};case"end":return{center:v,ratio:1};case"center":return{center:(g+v)*.5,ratio:.5}}if(M&&Number.isFinite(M.center)&&Number.isFinite(M.ratio))return{center:M.center,ratio:M.ratio}}},m=(g,v,M)=>{if(!Number.isFinite(g)||!Number.isFinite(v))return;let I=g,T=v;if(I>T){const x=I;I=T,T=x}let E=T-I;if(!Number.isFinite(E)||E<0)return;const f=Vt(E,u,p);if(f!==E){const x=M!=null&&M.anchor&&Number.isFinite(M.anchor.center)?Vt(M.anchor.center,0,100):(I+T)*.5,N=M!=null&&M.anchor&&Number.isFinite(M.anchor.ratio)?Lr(M.anchor.ratio):.5;I=x-N*f,T=I+f,E=f}if(E>100&&(I=0,T=100,E=100),I<0){const x=-I;I+=x,T+=x}if(T>100){const x=T-100;I-=x,T-=x}I=Vt(I,0,100),T=Vt(T,0,100),I=Ms(I),T=Ms(T),!(I===i&&T===r)&&(i=I,r=T,(M==null?void 0:M.emit)!==!1&&h())};return m(e,t,{emit:!1}),{getRange:()=>({start:i,end:r}),setRange:(g,v)=>{m(g,v)},setRangeAnchored:(g,v,M)=>{m(g,v,{anchor:l(g,v,M)})},setSpanConstraints:(g,v)=>{const M=typeof g=="number"&&Number.isFinite(g)?Vt(g,0,100):a,I=typeof v=="number"&&Number.isFinite(v)?Vt(v,0,100):c;if(M===a&&I===c)return;a=M,c=I,u=Math.min(a,c),p=Math.max(a,c);const T=i,E=r,f=1e-6,x=E>=100-f?"end":T<=0+f?"start":"center";m(T,E,{anchor:l(T,E,x)})},zoomIn:(g,v)=>{if(!Number.isFinite(g)||!Number.isFinite(v)||v<=1)return;const M=Vt(g,0,100),I=r-i,T=I===0?.5:Lr((M-i)/I),E=I/v,f=M-T*E,x=f+E;m(f,x,{anchor:{center:M,ratio:T}})},zoomOut:(g,v)=>{if(!Number.isFinite(g)||!Number.isFinite(v)||v<=1)return;const M=Vt(g,0,100),I=r-i,T=I===0?.5:Lr((M-i)/I),E=I*v,f=M-T*E,x=f+E;m(f,x,{anchor:{center:M,ratio:T}})},pan:g=>{Number.isFinite(g)&&m(i+g,r+g)},onChange:g=>(s.add(g),()=>{s.delete(g)})}}const kr=new WeakMap,Fs=e=>{const t=typeof e=="object"&&e!==null?e:null;if(t&&kr.has(t))return kr.get(t);let n=!1;const i=Xe(e);for(let r=0;r<i;r++){const o=Ee(e,r);if(Number.isNaN(o)){n=!0;break}}return t&&kr.set(t,n),n},uf=(e,t)=>{const n=[];for(let c=0;c<e.length;c++){const u=e[c];(u==null?void 0:u.type)==="bar"&&n.push({globalSeriesIndex:c,s:u})}if(n.length===0)return null;const i=na(n.map(c=>c.s),t),r=i.barWidthPx,o=i.gapPx,s=i.clusterWidthPx;if(!Number.isFinite(r)||!(r>0))return null;const a=new Map;for(let c=0;c<n.length;c++){const u=n[c].globalSeriesIndex,p=i.clusterSlots.clusterIndexBySeries[c]??0;a.set(u,p)}return{barWidth:r,gap:o,clusterWidth:s,clusterIndexByGlobalSeriesIndex:a}},Ss=(e,t)=>{let n=0,i=Xe(e);for(;n<i;){const r=n+i>>>1;Ee(e,r)<t?n=r+1:i=r}return n};function Ns(e,t,n,i){if(!Number.isFinite(t))return[];const r=Number.POSITIVE_INFINITY,o=r*r,s=n.invert(t);if(!Number.isFinite(s))return[];const a=[],c=uf(e,n);for(let u=0;u<e.length;u++){const p=e[u];if(p.type==="pie"||p.type==="candlestick"||p.visible===!1)continue;const h=p.data,l=Xe(h);if(l===0)continue;if(p.type==="bar"&&c){const S=c.clusterIndexByGlobalSeriesIndex.get(u);if(S!==void 0){const{barWidth:y,gap:b,clusterWidth:w}=c,d=-w/2+S*(y+b),g=0;if(Number.isFinite(y)&&y>0&&Number.isFinite(d)){let v=-1;const M=I=>{if(!Number.isFinite(I))return!1;const T=I+d,E=T+y;return t>=T-g&&t<E+g};if(Fs(h))for(let I=0;I<l;I++){const T=Ee(h,I);if(!Number.isFinite(T))continue;const E=n.scale(T);M(E)&&(v=v<0?I:Math.min(v,I))}else{const I=n.invert(t-d);if(Number.isFinite(I)){const T=Ss(h,I),E=f=>{if(f<0||f>=l)return null;const x=Ee(h,f);if(!Number.isFinite(x))return null;const N=n.scale(x);return Number.isFinite(N)?N:null};for(let f=T-1;f>=0;f--){const x=E(f);if(x===null)continue;const N=x+d,A=N+y;if(A+g<=t)break;t>=N-g&&t<A+g&&(v=v<0?f:Math.min(v,f))}for(let f=T;f<l;f++){const x=E(f);if(x===null)continue;const N=x+d;if(N-g>t)break;const A=N+y;t<A+g&&(v=v<0?f:Math.min(v,f))}}}if(v>=0){const I=Ee(h,v),T=We(h,v),E=mt(h,v),f=E!==void 0?[I,T,E]:[I,T];a.push({seriesIndex:u,dataIndex:v,point:f});continue}}}}let m=-1,C=null,F=o;const R=(S,y)=>{if(!Number.isFinite(y)||!(y<F||y===F&&(m<0||S<m)))return;F=y,m=S;const w=Ee(h,S),d=We(h,S),g=mt(h,S);C=g!==void 0?[w,d,g]:[w,d]};if(Fs(h))for(let S=0;S<l;S++){const y=Ee(h,S);if(!Number.isFinite(y))continue;const b=n.scale(y);if(!Number.isFinite(b))continue;const w=b-t;R(S,w*w)}else{const S=Ss(h,s);let y=S-1,b=S;const w=d=>{const g=Ee(h,d);if(!Number.isFinite(g))return null;const v=n.scale(g);if(!Number.isFinite(v))return null;const M=v-t;return M*M};for(;y>=0||b<l;){for(;y>=0&&w(y)===null;)y--;for(;b<l&&w(b)===null;)b++;if(y<0&&b>=l)break;const d=y>=0?w(y)??Number.POSITIVE_INFINITY:Number.POSITIVE_INFINITY,g=b<l?w(b)??Number.POSITIVE_INFINITY:Number.POSITIVE_INFINITY;if(d>F&&g>F)break;d<=g?(y>=0&&d<=F&&R(y,d),y--,b<l&&g<=F&&g===d&&(R(b,g),b++)):(b<l&&g<=F&&R(b,g),b++)}}C!==null&&a.push({seriesIndex:u,dataIndex:m,point:C})}return a}const ff=e=>Math.min(1,Math.max(0,e)),df=e=>{const t=e.trim().match(/^(\d+(?:\.\d+)?)%$/);if(!t)return null;const n=Number(t[1])/100;return Number.isFinite(n)?n:null},so=e=>Array.isArray(e),Pn=e=>so(e)?e[0]:e.timestamp,mf=e=>so(e)?e[1]:e.open,pf=e=>so(e)?e[2]:e.close,Ts=new WeakMap,hf=e=>{const t=Ts.get(e);if(t!==void 0)return t;const n=[];for(let o=0;o<e.length;o++){const s=Pn(e[o]);Number.isFinite(s)&&n.push(s)}if(n.length<2)return 1;n.sort((o,s)=>o-s);let i=Number.POSITIVE_INFINITY;for(let o=1;o<n.length;o++){const s=n[o]-n[o-1];s>0&&s<i&&(i=s)}const r=Number.isFinite(i)&&i>0?i:1;return Ts.set(e,r),r};function Yr(e,t,n,i){if(t.length===0)return 0;const r=hf(t);let o=0;if(Number.isFinite(r)&&r>0){let h=null;for(let l=0;l<t.length;l++){const m=Pn(t[l]);if(Number.isFinite(m)){h=m;break}}if(h!=null){const l=n.scale(h),m=n.scale(h+r),C=Math.abs(m-l);Number.isFinite(C)&&C>0&&(o=C)}}(!(o>0)||!Number.isFinite(o))&&(o=(Number.isFinite(i??Number.NaN)?i:0)/Math.max(1,t.length));let s=0;const a=e.barWidth;if(typeof a=="number")s=Number.isFinite(a)?Math.max(0,a):0;else if(typeof a=="string"){const h=df(a);s=h==null?0:o*ff(h)}const c=Number.isFinite(e.barMinWidth)?Math.max(0,e.barMinWidth):0,u=Number.isFinite(e.barMaxWidth)?Math.max(0,e.barMaxWidth):Number.POSITIVE_INFINITY,p=Math.max(c,u);return s=Math.min(Math.max(s,c),p),Number.isFinite(s)?s:0}const Ei=new WeakMap,yf=e=>{const t=Ei.get(e);if(t!==void 0)return t;let n=Number.NEGATIVE_INFINITY;for(let i=0;i<e.length;i++){const r=Pn(e[i]);if(!Number.isFinite(r)||r<n)return Ei.set(e,!1),!1;n=r}return Ei.set(e,!0),!0},gf=(e,t)=>{let n=0,i=e.length;for(;n<i;){const r=n+i>>>1;Pn(e[r])<t?n=r+1:i=r}return n};function Hr(e,t,n,i,r,o){if(!Number.isFinite(t)||!Number.isFinite(n)||!Number.isFinite(o)||!(o>0))return null;const s=i.invert(t);if(!Number.isFinite(s))return null;const a=o/2;let c=null,u=Number.POSITIVE_INFINITY;const p=(l,m,C,F)=>{if(Number.isFinite(F)){if(F<u){u=F,c={seriesIndex:l,dataIndex:m,point:C};return}F===u&&c&&(m<c.dataIndex?c={seriesIndex:l,dataIndex:m,point:C}:m===c.dataIndex&&l<c.seriesIndex&&(c={seriesIndex:l,dataIndex:m,point:C}))}},h=l=>{const m=mf(l),C=pf(l);if(!Number.isFinite(m)||!Number.isFinite(C))return!1;const F=r.scale(m),R=r.scale(C);if(!Number.isFinite(F)||!Number.isFinite(R))return!1;const S=Math.min(F,R),y=Math.max(F,R);return n>=S&&n<=y};for(let l=0;l<e.length;l++){const C=e[l].data,F=C.length;if(F===0)continue;if(!yf(C)){for(let y=0;y<F;y++){const b=C[y],w=Pn(b);if(!Number.isFinite(w))continue;const d=i.scale(w);if(!Number.isFinite(d))continue;const g=Math.abs(t-d);g>a||h(b)&&p(l,y,b,g)}continue}const S=gf(C,s);for(let y=S-1;y>=0;y--){const b=C[y],w=Pn(b),d=i.scale(w);if(!Number.isFinite(d))continue;if(d<t-a)break;const g=Math.abs(t-d);g>a||h(b)&&p(l,y,b,g)}for(let y=S;y<F;y++){const b=C[y],w=Pn(b),d=i.scale(w);if(!Number.isFinite(d))continue;if(d>t+a)break;const g=Math.abs(t-d);g>a||h(b)&&p(l,y,b,g)}}return c}const mn=Math.PI*2,Di=e=>{if(!Number.isFinite(e))return 0;const t=e%mn;return t<0?t+mn:t};function qr(e,t,n,i,r){if(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(i.x)||!Number.isFinite(i.y))return null;const o=Number.isFinite(r.inner)?Math.max(0,r.inner):0,s=Number.isFinite(r.outer)?Math.max(0,r.outer):0;if(!(s>0))return null;const a=e-i.x,c=i.y-t,u=Math.hypot(a,c);if(!Number.isFinite(u)||u<=o||u>s)return null;const p=Di(Math.atan2(c,a)),h=n.series,l=h.data;let m=0,C=0;for(let b=0;b<l.length;b++){const w=l[b],d=w==null?void 0:w.value;typeof d=="number"&&Number.isFinite(d)&&d>0&&w.visible!==!1&&(m+=d,C++)}if(!(m>0)||C===0)return null;const F=typeof h.startAngle=="number"&&Number.isFinite(h.startAngle)?h.startAngle:90;let R=Di(F*Math.PI/180),S=0,y=0;for(let b=0;b<l.length;b++){const w=l[b],d=w==null?void 0:w.value;if(typeof d!="number"||!Number.isFinite(d)||d<=0||(w==null?void 0:w.visible)===!1)continue;y++;const g=y===C;let M=d/m*mn;if(g?M=Math.max(0,mn-S):M=Math.max(0,Math.min(mn,M)),S+=M,!(M>0))continue;const I=R,T=C===1?R+mn:Di(R+M);R=Di(R+M);let E=T-I;E<0&&(E+=mn);let f=p-I;if(f<0&&(f+=mn),f<=E)return{seriesIndex:n.seriesIndex,dataIndex:b,slice:w}}return null}const zn=(e,t)=>{if(!Number.isFinite(t))throw new Error(`${e} must be a finite number. Received: ${String(t)}`)};function an(){let e=0,t=1,n=0,i=1;const r={domain(o,s){return zn("domain min",o),zn("domain max",s),e=o,t=s,r},range(o,s){return zn("range min",o),zn("range max",s),n=o,i=s,r},scale(o){if(!Number.isFinite(o))return Number.NaN;if(e===t)return(n+i)/2;const s=(o-e)/(t-e);return n+s*(i-n)},invert(o){if(!Number.isFinite(o))return Number.NaN;if(e===t)return e;if(n===i)return(e+t)/2;const s=(o-n)/(i-n);return e+s*(t-e)}};return r}function xf(){let e=[],t=new Map,n=0,i=1;const r=s=>{const a=new Map;for(let c=0;c<s.length;c++){const u=s[c];if(a.has(u))throw new Error(`Category domain must not contain duplicates. Duplicate: ${JSON.stringify(u)}`);a.set(u,c)}t=a},o={domain(s){return e=[...s],r(e),o},range(s,a){return zn("range min",s),zn("range max",a),n=s,i=a,o},categoryIndex(s){const a=t.get(s);return a===void 0?-1:a},bandwidth(){const s=e.length;return s===0?0:Math.abs((i-n)/s)},scale(s){const a=e.length;if(a===0)return(n+i)/2;const c=o.categoryIndex(s);if(c<0)return Number.NaN;const u=(i-n)/a;return n+(c+.5)*u}};return o}const bf=e=>{switch(e){case"start":return{translateX:"0%",originX:"0%"};case"middle":return{translateX:"-50%",originX:"50%"};case"end":return{translateX:"-100%",originX:"100%"}}};function Is(e){const t=getComputedStyle(e),n=t.position,i=t.overflow,r=n==="static",o=i==="hidden"||i==="scroll"||i==="auto",s=r?e.style.position:null,a=o?e.style.overflow:null;r&&(e.style.position="relative"),o&&(e.style.overflow="visible");const c=document.createElement("div");c.style.position="absolute",c.style.inset="0",c.style.pointerEvents="none",c.style.overflow="visible",c.style.zIndex="10",e.appendChild(c);let u=!1;return{clear:()=>{u||c.replaceChildren()},addLabel:(m,C,F,R)=>{if(u)return document.createElement("span");const S=document.createElement("span");S.textContent=m,S.style.position="absolute",S.style.left=`${C}px`,S.style.top=`${F}px`,S.style.pointerEvents="none",S.style.userSelect="none",S.style.whiteSpace="nowrap",S.style.lineHeight="1",(R==null?void 0:R.fontSize)!=null&&(S.style.fontSize=`${R.fontSize}px`),(R==null?void 0:R.color)!=null&&(S.style.color=R.color);const y=(R==null?void 0:R.rotation)??0,b=(R==null?void 0:R.anchor)??"start",{translateX:w,originX:d}=bf(b);return S.style.transformOrigin=`${d} 50%`,S.style.transform=`translateX(${w}) translateY(-50%) rotate(${y}deg)`,c.appendChild(S),S},dispose:()=>{if(!u){u=!0;try{c.remove()}finally{s!==null&&(e.style.position=s),a!==null&&(e.style.overflow=a)}}}}}const Ps=(e,t)=>{var i;const n=(i=e.name)==null?void 0:i.trim();return n||`Series ${t+1}`},vf=(e,t,n)=>{var o;const i=(o=e.color)==null?void 0:o.trim();if(i)return i;const r=n.colorPalette;return r.length>0?r[t%r.length]??"#000000":"#000000"},As=(e,t)=>{const n=e==null?void 0:e.trim();return n||`Slice ${t+1}`},wf=(e,t,n,i)=>{const r=e==null?void 0:e.trim();if(r)return r;const o=i.colorPalette,s=o.length;return s>0?o[(t+n)%s]??"#000000":"#000000"};function Cf(e,t="right",n){const r=getComputedStyle(e).position==="static",o=r?e.style.position:null;r&&(e.style.position="relative");const s=document.createElement("div");s.style.position="absolute",s.style.pointerEvents="auto",s.style.userSelect="none",s.style.boxSizing="border-box",s.style.padding="8px",s.style.borderRadius="8px",s.style.borderStyle="solid",s.style.borderWidth="1px",s.style.maxHeight="calc(100% - 16px)",s.style.overflow="auto";const a=document.createElement("div");a.style.display="flex",a.style.gap="8px",s.appendChild(a),n&&(a.addEventListener("click",l=>{const C=l.target.closest("[data-series-index]");if(C){const F=parseInt(C.dataset.seriesIndex,10);if(!isNaN(F)){const R=C.dataset.sliceIndex;if(R!==void 0){const S=parseInt(R,10);if(!isNaN(S)){n(F,S);return}}n(F)}}}),a.addEventListener("keydown",l=>{if(l.key==="Enter"||l.key===" "){const C=l.target.closest("[data-series-index]");if(C){l.preventDefault();const F=parseInt(C.dataset.seriesIndex,10);if(!isNaN(F)){const R=C.dataset.sliceIndex;if(R!==void 0){const S=parseInt(R,10);if(!isNaN(S)){n(F,S);return}}n(F)}}}})),(l=>{switch(s.style.top="",s.style.right="",s.style.bottom="",s.style.left="",s.style.maxWidth="",a.style.flexDirection="",a.style.flexWrap="",a.style.alignItems="",l){case"right":{s.style.top="8px",s.style.right="8px",s.style.maxWidth="40%",a.style.flexDirection="column",a.style.flexWrap="nowrap",a.style.alignItems="flex-start";return}case"left":{s.style.top="8px",s.style.left="8px",s.style.maxWidth="40%",a.style.flexDirection="column",a.style.flexWrap="nowrap",a.style.alignItems="flex-start";return}case"top":{s.style.top="8px",s.style.left="8px",s.style.right="8px",a.style.flexDirection="row",a.style.flexWrap="wrap",a.style.alignItems="center";return}case"bottom":{s.style.bottom="8px",s.style.left="8px",s.style.right="8px",a.style.flexDirection="row",a.style.flexWrap="wrap",a.style.alignItems="center";return}}})(t),e.appendChild(s);let u=!1;return{update:(l,m)=>{if(u)return;s.style.color=m.textColor,s.style.background=m.backgroundColor,s.style.borderColor=m.axisLineColor,s.style.fontFamily=m.fontFamily,s.style.fontSize=`${m.fontSize}px`;const C=[];for(let F=0;F<l.length;F++){const R=l[F];if(R.type==="pie")for(let S=0;S<R.data.length;S++){const y=R.data[S],b=(y==null?void 0:y.visible)!==!1,w=document.createElement("div");w.style.display="flex",w.style.alignItems="center",w.style.gap="6px",w.style.lineHeight="1.1",w.style.whiteSpace="nowrap",w.style.cursor=n?"pointer":"default",w.style.opacity=b?"1":"0.5",w.style.transition="opacity 0.2s",n&&(w.setAttribute("role","button"),w.setAttribute("aria-pressed",String(b)),w.setAttribute("aria-label",`Toggle ${As(y==null?void 0:y.name,S)} visibility`),w.tabIndex=0,w.dataset.seriesIndex=String(F),w.dataset.sliceIndex=String(S));const d=document.createElement("div");d.style.width="10px",d.style.height="10px",d.style.borderRadius="2px",d.style.flex="0 0 auto",d.style.background=wf(y==null?void 0:y.color,F,S,m),d.style.border=`1px solid ${m.axisLineColor}`;const g=document.createElement("span");g.textContent=As(y==null?void 0:y.name,S),g.style.textDecoration=b?"none":"line-through",w.appendChild(d),w.appendChild(g),C.push(w)}else{const S=R.visible!==!1,y=document.createElement("div");y.style.display="flex",y.style.alignItems="center",y.style.gap="6px",y.style.lineHeight="1.1",y.style.whiteSpace="nowrap",y.style.cursor=n?"pointer":"default",y.style.opacity=S?"1":"0.5",y.style.transition="opacity 0.2s",n&&(y.setAttribute("role","button"),y.setAttribute("aria-pressed",String(S)),y.setAttribute("aria-label",`Toggle ${Ps(R,F)} visibility`),y.tabIndex=0,y.dataset.seriesIndex=String(F));const b=document.createElement("div");b.style.width="10px",b.style.height="10px",b.style.borderRadius="2px",b.style.flex="0 0 auto",b.style.background=vf(R,F,m),b.style.border=`1px solid ${m.axisLineColor}`;const w=document.createElement("span");w.textContent=Ps(R,F),w.style.textDecoration=S?"none":"line-through",y.appendChild(b),y.appendChild(w),C.push(y)}}a.replaceChildren(...C)},dispose:()=>{if(!u){u=!0;try{s.remove()}finally{o!==null&&(e.style.position=o)}}}}}const Rs=(e,t,n)=>n<t||e<t?t:e>n?n:e;function Es(e){const n=getComputedStyle(e).position==="static",i=n?e.style.position:null;n&&(e.style.position="relative");const r=document.createElement("div");r.style.position="absolute",r.style.left="0",r.style.top="0",r.style.pointerEvents="none",r.style.userSelect="none",r.style.boxSizing="border-box",r.style.zIndex="var(--chartgpu-tooltip-z, 10)",r.style.padding="var(--chartgpu-tooltip-padding, 6px 8px)",r.style.borderRadius="var(--chartgpu-tooltip-radius, 8px)",r.style.borderStyle="solid",r.style.borderWidth="var(--chartgpu-tooltip-border-width, 1px)",r.style.borderColor="var(--chartgpu-tooltip-border, rgba(224,224,224,0.35))",r.style.boxShadow="var(--chartgpu-tooltip-shadow, 0 6px 18px rgba(0,0,0,0.35))",r.style.maxWidth="var(--chartgpu-tooltip-max-width, min(320px, 100%))",r.style.overflow="hidden",r.style.fontFamily='var(--chartgpu-tooltip-font-family, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji")',r.style.fontSize="var(--chartgpu-tooltip-font-size, 12px)",r.style.lineHeight="var(--chartgpu-tooltip-line-height, 1.2)",r.style.color="var(--chartgpu-tooltip-color, #e0e0e0)",r.style.background="var(--chartgpu-tooltip-bg, rgba(26,26,46,0.95))",r.style.whiteSpace="normal",r.style.opacity="0",r.style.transitionProperty="opacity";const o=140;r.style.transitionDuration=`${o}ms`,r.style.transitionTimingFunction="ease",r.style.willChange="opacity",r.style.display="none",r.style.visibility="hidden",r.setAttribute("role","tooltip"),e.appendChild(r);let s=!1,a=0,c=null,u=null;const p=()=>{c!=null&&(window.clearTimeout(c),c=null),u!=null&&(window.cancelAnimationFrame(u),u=null)},h=()=>r.style.display==="none"||r.style.visibility==="hidden",l=()=>{const R=r.style.visibility;r.style.visibility="hidden";const S=r.offsetWidth,y=r.offsetHeight;return r.style.visibility=R,{width:S,height:y}};return{show:(R,S,y)=>{if(s)return;a+=1,p();const b=h();r.innerHTML=y;const w=12,d=12,g=8;r.style.display="block",r.style.visibility="hidden";const{width:v,height:M}=l(),I=e.clientWidth,T=e.clientHeight;let E=R+w,f=S+d;if(E+v>I-g&&(E=R-w-v),f+M>T-g&&(f=S-d-M),E=Rs(E,g,I-g-v),f=Rs(f,g,T-g-M),r.style.left=`${E}px`,r.style.top=`${f}px`,r.style.visibility="visible",b){r.style.opacity="0";const x=a;u=window.requestAnimationFrame(()=>{u=null,!s&&x===a&&(r.style.opacity="1")})}else r.style.opacity="1"},hide:()=>{if(s)return;if(a+=1,p(),r.style.display==="none"||r.style.visibility==="hidden"){r.style.opacity="0",r.style.visibility="hidden",r.style.display="none";return}r.style.opacity="0";const R=a;c=window.setTimeout(()=>{c=null,!s&&R===a&&(r.style.visibility="hidden",r.style.display="none")},o+50)},dispose:()=>{if(!s){s=!0;try{p(),r.remove()}finally{i!==null&&(e.style.position=i)}}}}}const Vi="—";function Yt(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function In(e){if(!Number.isFinite(e))return Vi;const i=(Object.is(e,-0)?0:e).toFixed(2).replace(/\.?0+$/,"");return i==="-0"?"0":i}function la(e){const t=e.seriesName.trim();return t.length>0?t:`Series ${e.seriesIndex+1}`}function ua(e){const t=e.trim();return t.length===0?"#888":/^#[0-9a-fA-F]{3}$/.test(t)||/^#[0-9a-fA-F]{6}$/.test(t)||/^#[0-9a-fA-F]{8}$/.test(t)||/^rgba?\(\s*\d{1,3}\s*(?:,\s*|\s+)\d{1,3}\s*(?:,\s*|\s+)\d{1,3}(?:\s*(?:,\s*|\/\s*)(?:0|1|0?\.\d+))?\s*\)$/.test(t)||/^[a-zA-Z]+$/.test(t)?t:"#888"}function fa(e){return e.length===5}function Mf(e,t){if(!Number.isFinite(e)||!Number.isFinite(t)||e===0)return Vi;const n=(t-e)/e*100;return Number.isFinite(n)?`${n>0?"+":""}${n.toFixed(2)}%`:Vi}function da(e,t){const n=Yt(la(e)),i=Yt(t);return['<div style="display:flex;align-items:center;justify-content:space-between;gap:12px;">','<span style="display:flex;align-items:center;gap:8px;min-width:0;">',`<span style="width:8px;height:8px;border-radius:999px;flex:0 0 auto;background-color:${Yt(ua(e.color))};"></span>`,`<span style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">${n}</span>`,"</span>",`<span style="font-variant-numeric:tabular-nums;white-space:nowrap;">${i}</span>`,"</div>"].join("")}function ma(e){const[,t,n,i,r]=e.value,o=Yt(la(e)),s=Yt(ua(e.color)),a=In(t),c=In(r),u=In(i),p=In(n),h=n>t,l=h?"▲":"▼",m=h?"#22c55e":"#ef4444",C=Mf(t,n),F=`O: ${a} H: ${c} L: ${u} C: ${p}`,R=Yt(F),S=Yt(l),y=Yt(C),b=Yt(m);return['<div style="display:flex;flex-direction:column;gap:4px;">','<div style="display:flex;align-items:center;gap:8px;">',`<span style="width:8px;height:8px;border-radius:999px;flex:0 0 auto;background-color:${s};"></span>`,`<span style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600;">${o}</span>`,"</div>",`<div style="font-variant-numeric:tabular-nums;white-space:nowrap;font-size:0.9em;">${R}</div>`,'<div style="display:flex;align-items:center;gap:6px;font-variant-numeric:tabular-nums;">',`<span style="color:${b};font-weight:700;">${S}</span>`,`<span style="color:${b};font-weight:600;">${y}</span>`,"</div>","</div>"].join("")}function Ff(e){return ma(e)}function ni(e){return fa(e.value)?Ff(e):da(e,In(e.value[1]))}function Ur(e){if(e.length===0)return"";const t=`x: ${In(e[0].value[0])}`,n=`<div style="margin:0 0 6px 0;font-weight:600;font-variant-numeric:tabular-nums;white-space:nowrap;">${Yt(t)}</div>`,i=e.map(r=>fa(r.value)?ma(r):da(r,In(r.value[1]))).join('<div style="height:4px;"></div>');return`${n}${i}`}const Sf=e=>Number.isFinite(e)?e:0,Nf=e=>Number.isFinite(e)?e:null;function Ds(){const e=new Map;function t(o,s,a,c,u,p){const h=Symbol("Animation");if(Array.isArray(o)||Array.isArray(s)){if(!Array.isArray(o)||!Array.isArray(s))throw new Error('Array animation requires both "from" and "to" to be arrays');if(o.length!==s.length)throw new Error(`Array animation length mismatch: from.length=${o.length}, to.length=${s.length}`);const l=new Array(o.length);return e.set(h,{kind:"array",from:o,to:s,duration:a,easing:c,onUpdate:u,onComplete:p,startTime:null,out:l}),h}return e.set(h,{kind:"scalar",from:o,to:s,duration:a,easing:c,onUpdate:u,onComplete:p,startTime:null}),h}function n(o){e.delete(o)}function i(){e.clear()}function r(o){var c;const s=Nf(o);if(s===null)return;const a=Array.from(e.keys());for(const u of a){const p=e.get(u);if(!p)continue;const h=p.startTime??s;p.startTime===null&&e.set(u,{...p,startTime:h});const l=Sf(p.duration),m=Math.max(0,s-h),C=l<=0||m>=l,F=l<=0?1:m/l,R=C?1:p.easing(F);if(p.kind==="scalar"){const S=p.from+(p.to-p.from)*R;if(p.onUpdate(S),!e.has(u))continue}else{const S=p.out.length;for(let y=0;y<S;y++){const b=p.from[y]??0,w=p.to[y]??0;p.out[y]=b+(w-b)*R}if(p.onUpdate(p.out),!e.has(u))continue}C&&((c=p.onComplete)==null||c.call(p),e.delete(u))}}return{animate:t,cancel:n,cancelAll:i,update:r}}const or=e=>Number.isNaN(e)||e<=0?0:e>=1?1:e;function Bs(e){return or(e)}function Tf(e){const n=1-or(e);return 1-n*n*n}function If(e){const t=or(e);if(t<.5)return 4*t*t*t;const n=-2*t+2;return 1-n*n*n/2}function Pf(e){const t=or(e),n=7.5625,i=2.75;if(t<1/i)return n*t*t;if(t<2/i){const o=t-1.5/i;return n*o*o+.75}if(t<2.5/i){const o=t-2.25/i;return n*o*o+.9375}const r=t-2.625/i;return n*r*r+.984375}function Af(e){switch(e){case"linear":return Bs;case"cubicOut":return Tf;case"cubicInOut":return If;case"bounceOut":return Pf;default:return Bs}}const Vn=Ea;function Rf(e){return e?e.clientWidth:0}function Ef(e){if(!e)return{width:0,height:0};const t=Number.isFinite(devicePixelRatio)&&devicePixelRatio>0?devicePixelRatio:1;return{width:e.width/t,height:e.height/t}}const Df="bgra8unorm",Zr=5,Ki=24*60*60*1e3,Bf=30*Ki,Lf=365*Ki,kf=9,_r=1,Uf=6,Ji=e=>typeof e=="number"&&Number.isFinite(e)?e:null,yn=e=>typeof e=="number"&&Number.isFinite(e)?e:void 0,_f=2e4,Gf=e=>{throw new Error(`RenderCoordinator: unreachable value: ${String(e)}`)},Oi=e=>Array.isArray(e),ri=e=>Oi(e)?{x:e[0],y:e[1]}:{x:e.x,y:e.y},ii=e=>{if(Array.isArray(e))return e.length===0?[]:e.slice();const t=Xe(e),n=new Array(t);for(let i=0;i<t;i++){const r=Ee(e,i),o=We(e,i);n[i]=[r,o]}return n},zf=(e,t)=>{if(t.length===0)return e;let n=e;if(!n){const a=sn(t);if(!a)return e;n=a}let i=n.xMin,r=n.xMax,o=n.yMin,s=n.yMax;for(let a=0;a<t.length;a++){const{x:c,y:u}=ri(t[a]);!Number.isFinite(c)||!Number.isFinite(u)||(c<i&&(i=c),c>r&&(r=c),u<o&&(o=u),u>s&&(s=u))}return i===r&&(r=i+1),o===s&&(s=o+1),{xMin:i,xMax:r,yMin:o,yMax:s}},Vf=(e,t)=>{if(t.length===0)return e;let n=(e==null?void 0:e.xMin)??Number.POSITIVE_INFINITY,i=(e==null?void 0:e.xMax)??Number.NEGATIVE_INFINITY,r=(e==null?void 0:e.yMin)??Number.POSITIVE_INFINITY,o=(e==null?void 0:e.yMax)??Number.NEGATIVE_INFINITY;for(let s=0;s<t.length;s++){const a=t[s],c=Ht(a)?a[0]:a.timestamp,u=Ht(a)?a[3]:a.low,p=Ht(a)?a[4]:a.high;!Number.isFinite(c)||!Number.isFinite(u)||!Number.isFinite(p)||(c<n&&(n=c),c>i&&(i=c),u<r&&(r=u),p>o&&(o=p))}return!Number.isFinite(n)||!Number.isFinite(i)||!Number.isFinite(r)||!Number.isFinite(o)?e:(n===i&&(i=n+1),r===o&&(o=r+1),{xMin:n,xMax:i,yMin:r,yMax:o})},pa=(e,t)=>{let n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY,r=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY;for(let s=0;s<e.length;s++){const a=e[s];if(a.type==="pie")continue;const c=(t==null?void 0:t[s])??null;if(c){const l=c;if(Number.isFinite(l.xMin)&&Number.isFinite(l.xMax)&&Number.isFinite(l.yMin)&&Number.isFinite(l.yMax)){l.xMin<n&&(n=l.xMin),l.xMax>i&&(i=l.xMax),l.yMin<r&&(r=l.yMin),l.yMax>o&&(o=l.yMax);continue}}const u=a.rawBounds;if(u){const l=u;if(Number.isFinite(l.xMin)&&Number.isFinite(l.xMax)&&Number.isFinite(l.yMin)&&Number.isFinite(l.yMax)){l.xMin<n&&(n=l.xMin),l.xMax>i&&(i=l.xMax),l.yMin<r&&(r=l.yMin),l.yMax>o&&(o=l.yMax);continue}}if(a.type==="candlestick"){const l=a.rawData??a.data;for(let m=0;m<l.length;m++){const C=l[m];if(Ht(C)){const F=C[0],R=C[3],S=C[4];if(!Number.isFinite(F)||!Number.isFinite(R)||!Number.isFinite(S))continue;const y=Math.min(R,S),b=Math.max(R,S);F<n&&(n=F),F>i&&(i=F),y<r&&(r=y),b>o&&(o=b)}else{const F=C.timestamp,R=C.low,S=C.high;if(!Number.isFinite(F)||!Number.isFinite(R)||!Number.isFinite(S))continue;const y=Math.min(R,S),b=Math.max(R,S);F<n&&(n=F),F>i&&(i=F),y<r&&(r=y),b>o&&(o=b)}}continue}const p=a.data,h=Xe(p);for(let l=0;l<h;l++){const m=Ee(p,l),C=We(p,l);!Number.isFinite(m)||!Number.isFinite(C)||(m<n&&(n=m),m>i&&(i=m),C<r&&(r=C),C>o&&(o=C))}}return!Number.isFinite(n)||!Number.isFinite(i)||!Number.isFinite(r)||!Number.isFinite(o)?{xMin:0,xMax:1,yMin:0,yMax:1}:(n===i&&(i=n+1),r===o&&(o=r+1),{xMin:n,xMax:i,yMin:r,yMax:o})},li=(e,t)=>{let n=e,i=t;if((!Number.isFinite(n)||!Number.isFinite(i))&&(n=0,i=1),n===i)i=n+1;else if(n>i){const r=n;n=i,i=r}return{min:n,max:i}},Ls=(e,t)=>{const n=e.canvas;if(!n)throw new Error("RenderCoordinator: gpuContext.canvas is required.");const i=e.devicePixelRatio??1,r=Number.isFinite(i)&&i>0?i:1,o=n.width,s=n.height;if(!Number.isFinite(o)||!Number.isFinite(s))throw new Error(`RenderCoordinator: Invalid canvas dimensions: width=${o}, height=${s}. Canvas must be initialized with finite dimensions before rendering.`);const a=Math.max(1,Math.floor(o)),c=Math.max(1,Math.floor(s)),u=Number.isFinite(t.grid.left)?t.grid.left:0,p=Number.isFinite(t.grid.right)?t.grid.right:0,h=Number.isFinite(t.grid.top)?t.grid.top:0,l=Number.isFinite(t.grid.bottom)?t.grid.bottom:0,m=Math.max(0,u),C=Math.max(0,p),F=Math.max(0,h),R=Math.max(0,l);return{left:m,right:C,top:F,bottom:R,canvasWidth:a,canvasHeight:c,devicePixelRatio:r}},Of=e=>{const t=Math.max(0,Math.min(255,Math.round(e[0]*255))),n=Math.max(0,Math.min(255,Math.round(e[1]*255))),i=Math.max(0,Math.min(255,Math.round(e[2]*255))),r=Math.max(0,Math.min(1,e[3]));return`rgba(${t},${n},${i},${r})`},ks=(e,t)=>{const n=pt(e);if(!n)return e;const i=Math.max(0,Math.min(1,n[3]*t));return Of([n[0],n[1],n[2],i])},$f=e=>{const{left:t,right:n,top:i,bottom:r,canvasWidth:o,canvasHeight:s,devicePixelRatio:a}=e,c=t*a,u=o-n*a,p=i*a,h=s-r*a,l=c/o*2-1,m=u/o*2-1,C=1-p/s*2,F=1-h/s*2;return{left:l,right:m,top:C,bottom:F}},Xt=e=>Math.min(1,Math.max(0,e)),On=(e,t,n)=>Math.min(n,Math.max(t,e|0)),Qi=(e,t,n)=>e+(t-e)*Xt(n),Bi=(e,t,n)=>li(Qi(e.min,t.min,n),Qi(e.max,t.max,n)),Wf=e=>{const{canvasWidth:t,canvasHeight:n,devicePixelRatio:i}=e,r=e.left*i,o=t-e.right*i,s=e.top*i,a=n-e.bottom*i,c=On(Math.floor(r),0,Math.max(0,t)),u=On(Math.floor(s),0,Math.max(0,n)),p=On(Math.ceil(o),0,Math.max(0,t)),h=On(Math.ceil(a),0,Math.max(0,n)),l=Math.max(0,p-c),m=Math.max(0,h-u);return{x:c,y:u,w:l,h:m}},jr=(e,t)=>(e+1)/2*t,Us=(e,t)=>(1-e)/2*t,Ht=Hi,ai=(e,t)=>{if(typeof e=="number")return Number.isFinite(e)?e:null;if(typeof e!="string")return null;const n=e.trim();if(n.length===0)return null;if(n.endsWith("%")){const r=Number.parseFloat(n.slice(0,-1));return Number.isFinite(r)?r/100*t:null}const i=Number.parseFloat(n);return Number.isFinite(i)?i:null},Xf=(e,t,n)=>{const i=(e==null?void 0:e[0])??"50%",r=(e==null?void 0:e[1])??"50%",o=ai(i,t),s=ai(r,n);return{x:Number.isFinite(o)?o:t*.5,y:Number.isFinite(s)?s:n*.5}},Yf=e=>Array.isArray(e),Hf=(e,t)=>{if(e==null)return{inner:0,outer:t*.7};if(Yf(e)){const r=ai(e[0],t),o=ai(e[1],t),s=Math.max(0,Number.isFinite(r)?r:0),a=Math.max(s,Number.isFinite(o)?o:t*.7);return{inner:s,outer:Math.min(t,a)}}const n=ai(e,t),i=Math.max(0,Number.isFinite(n)?n:t*.7);return{inner:0,outer:Math.min(t,i)}},Gt=e=>String(Math.trunc(e)).padStart(2,"0"),qf=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],Zf=(e,t)=>{if(!Number.isFinite(e))return null;(!Number.isFinite(t)||t<0)&&(t=0);const n=new Date(e);if(!Number.isFinite(n.getTime()))return null;const i=n.getFullYear(),r=n.getMonth()+1,o=n.getDate(),s=n.getHours(),a=n.getMinutes();return t<Ki?`${Gt(s)}:${Gt(a)}`:t<=7*Ki?`${Gt(r)}/${Gt(o)} ${Gt(s)}:${Gt(a)}`:t<3*Bf?`${Gt(r)}/${Gt(o)}`:t<=Lf?`${qf[n.getMonth()]??Gt(r)} ${Gt(o)}`:`${i}/${Gt(r)}`},$i=(e,t,n)=>{const i=Math.max(1,Math.floor(n)),r=new Array(i);for(let o=0;o<i;o++){const s=i===1?.5:o/(i-1);r[o]=e+s*(t-e)}return r},jf=e=>{const{axisMin:t,axisMax:n,xScale:i,plotClipLeft:r,plotClipRight:o,canvasCssWidth:s,visibleRangeMs:a,measureCtx:c,measureCache:u,fontSize:p,fontFamily:h}=e,l=Ji(t)??i.invert(r),m=Ji(n)??i.invert(o);if(!c||s<=0)return{tickCount:Zr,tickValues:$i(l,m,Zr)};c.font=`${p}px ${h}`,u&&u.size>2e3&&u.clear();const C=u?`${p}px ${h}@@`:null;for(let F=kf;F>=_r;F--){const R=$i(l,m,F);let S=Number.NEGATIVE_INFINITY,y=!0;for(let b=0;b<R.length;b++){const w=R[b],d=Zf(w,a);if(d==null)continue;const g=(()=>{if(!C)return c.measureText(d).width;const f=C+d,x=u.get(f);if(x!=null)return x;const N=c.measureText(d).width;return u.set(f,N),N})(),v=i.scale(w),M=jr(v,s),I=F===1?"middle":b===0?"start":b===R.length-1?"end":"middle",T=I==="start"?M:I==="end"?M-g:M-g*.5,E=I==="start"?M+g:I==="end"?M:M+g*.5;if(T<S+Uf){y=!1;break}S=E}if(y)return{tickCount:F,tickValues:R}}return{tickCount:_r,tickValues:$i(l,m,_r)}},Nn=(e,t)=>{const n=pa(e.series,t),i=yn(e.xAxis.min)??n.xMin,r=yn(e.xAxis.max)??n.xMax;return li(i,r)},Kf=e=>{let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY;for(let i=0;i<e.length;i++){const r=e[i];if(r.type==="pie")continue;if(r.type==="candlestick"){const a=r.data;for(let c=0;c<a.length;c++){const u=a[c],p=Ht(u)?u[3]:u.low,h=Ht(u)?u[4]:u.high;if(!Number.isFinite(p)||!Number.isFinite(h))continue;const l=Math.min(p,h),m=Math.max(p,h);l<t&&(t=l),m>n&&(n=m)}continue}const o=r.data,s=Xe(o);for(let a=0;a<s;a++){const c=We(o,a);Number.isFinite(c)&&(c<t&&(t=c),c>n&&(n=c))}}return!Number.isFinite(t)||!Number.isFinite(n)?{xMin:0,xMax:1,yMin:0,yMax:1}:(t===n&&(n=t+1),{xMin:0,xMax:1,yMin:t,yMax:n})},Gr=(e,t,n)=>{const i=yn(e.yAxis.min),r=yn(e.yAxis.max);if(i!==void 0&&r!==void 0)return li(i,r);const o=e.yAxis.autoBounds??"visible";let s;o==="visible"&&n?s=n:s=pa(e.series,t);const a=i??s.yMin,c=r??s.yMax;return li(a,c)},Tn=(e,t)=>{if(!t)return{...e,spanFraction:1};const n=e.max-e.min;if(!Number.isFinite(n)||n===0)return{...e,spanFraction:1};const i=t.start,r=t.end,o=e.min+i/100*n,s=e.min+r/100*n,a=li(o,s),c=(r-i)/100,u=Number.isFinite(c)?Math.max(0,Math.min(1,c)):1;return{min:a.min,max:a.max,spanFraction:u}},ha=e=>{if(e===!1||e==null)return null;const t=e===!0?{}:e;if(!t)return null;const n=t.duration??300,i=t.delay??0,r=Number.isFinite(n)?Math.max(0,n):300,o=Number.isFinite(i)?Math.max(0,i):0;return{durationMs:r,delayMs:o,easing:Af(t.easing)}},Jf=e=>ha(e),Qf=e=>ha(e),zr=(e,t,n,i,r)=>{const o=e.point,s=Ht(o)?o[0]:o.timestamp,a=Ht(o)?o[1]:o.open,c=Ht(o)?o[2]:o.close;if(!Number.isFinite(s)||!Number.isFinite(a)||!Number.isFinite(c))return null;const u=(a+c)/2,p=t.scale(s),h=n.scale(u);if(!Number.isFinite(p)||!Number.isFinite(h))return null;const l=i.left+p,m=i.top+h,C=Vn(r)?r.offsetLeft+l:l,F=Vn(r)?r.offsetTop+m:m;return!Number.isFinite(C)||!Number.isFinite(F)?null:{x:C,y:F}},_s=e=>{let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY;for(let i=0;i<e.length;i++){const r=e[i].data,o=Xe(r);for(let s=0;s<o;s++){const a=We(r,s);Number.isFinite(a)&&(a<t&&(t=a),a>n&&(n=a))}}return!Number.isFinite(t)||!Number.isFinite(n)||t<=0&&0<=n?0:Math.abs(t)<Math.abs(n)?t:n},ed=(e,t,n)=>{const i=t.invert(n.bottom),r=t.invert(n.top),o=Math.min(i,r),s=Math.max(i,r);return!Number.isFinite(o)||!Number.isFinite(s)?_s(e):o<=0&&0<=s?0:o>0?o:s<0?s:_s(e)},td=(e,t,n,i)=>{const r=Xt(i);if(r>=1)return e;const o=ed(n,e,t),s=e.scale(o),a={domain(c,u){return e.domain(c,u),a},range(c,u){return e.range(c,u),a},scale(c){const u=e.scale(c);return!Number.isFinite(u)||!Number.isFinite(s)?u:s+(u-s)*r},invert(c){return e.invert(c)}};return a};function nd(e,t,n){var vo;if(!e.initialized)throw new Error("RenderCoordinator: gpuContext must be initialized.");const i=e.device;if(!i)throw new Error("RenderCoordinator: gpuContext.device is required.");if(!e.canvas)throw new Error("RenderCoordinator: gpuContext.canvas is required.");if(!e.canvasContext)throw new Error("RenderCoordinator: gpuContext.canvasContext is required.");i.lost.then(D=>{var z;(z=n==null?void 0:n.onDeviceLost)==null||z.call(n,D.message||D.reason||"unknown")}).catch(()=>{});const r=e.preferredFormat??Df,o=Vn(e.canvas)?e.canvas.parentElement:null,s=o?Is(o):null,a=o?Is(o):null,u=o?Cf(o,"right",(D,z)=>{if(l)return;const U=m.series;if(D<0||D>=U.length)return;const $=U[D];if(!$)return;if(z!==void 0&&$.type==="pie"){const K=$.data;if(z<0||z>=K.length)return;const ae=K.map((J,xe)=>xe===z?{...J,visible:J.visible===!1}:J),fe=U.map((J,xe)=>xe===D?{...J,data:ae}:J);fr({...m,series:fe});return}const ie=U.map((K,ae)=>ae===D?{...K,visible:K.visible===!1}:K);fr({...m,series:ie})}):null,p=(()=>{if(typeof document>"u")return null;try{return document.createElement("canvas").getContext("2d")}catch{return null}})(),h=p?new Map:null;let l=!1,m=t,C=t.series.length,F="pending",R=0;const S=Ds();let y=null,b=!1;const w=Ds();let d=null,g=1,v=null;const M={cartesianDataBySeriesIndex:[],pieDataBySeriesIndex:[]},I=()=>{M.cartesianDataBySeriesIndex.length=0,M.pieDataBySeriesIndex.length=0},T=(D,z,U,$)=>{if(D.length!==z.length)return null;const ie=z.length;if(ie===0)return $??[];const K=$&&$.length===ie?$:(()=>{const fe=new Array(ie);for(let J=0;J<ie;J++){const xe=z[J],{x:pe}=ri(xe),ye=Oi(xe)?xe[2]:xe==null?void 0:xe.size;fe[J]=Oi(xe)?ye==null?[pe,0]:[pe,0,ye]:ye==null?{x:pe,y:0}:{x:pe,y:0,size:ye}}return fe})(),ae=Xt(U);for(let fe=0;fe<ie;fe++){const J=ri(D[fe]).y,xe=ri(z[fe]).y,pe=Number.isFinite(J)&&Number.isFinite(xe)?Qi(J,xe,ae):xe,ye=K[fe];Oi(ye)?ye[1]=pe:ye.y=pe}return K},E=(D,z,U,$)=>{var xe,pe;const ie=D.data,K=z.data;if(ie.length!==K.length)return z;const ae=K.length,fe=$&&$.length===ae?$:(()=>{const ye=new Array(ae);for(let Ie=0;Ie<ae;Ie++)ye[Ie]={...K[Ie],value:0};return ye})(),J=Xt(U);for(let ye=0;ye<ae;ye++){const Ie=(xe=ie[ye])==null?void 0:xe.value,Ae=(pe=K[ye])==null?void 0:pe.value,Te=typeof Ie=="number"&&typeof Ae=="number"&&Number.isFinite(Ie)&&Number.isFinite(Ae)?Math.max(0,Qi(Ie,Ae,J)):typeof Ae=="number"&&Number.isFinite(Ae)?Ae:0;fe[ye].value=Te}return{...z,data:fe}},f=(D,z,U,$)=>{if(D.length!==z.length)return z;const ie=new Array(z.length);for(let K=0;K<z.length;K++){const ae=D[K],fe=z[K];if(ae.type!==fe.type){ie[K]=fe;continue}if(fe.type==="pie"){const Te=($==null?void 0:$.pieDataBySeriesIndex[K])??null,Nt=E(ae,fe,U,Te);$&&($.pieDataBySeriesIndex[K]=Nt.data),ie[K]=Nt;continue}const J=ae,xe=fe,pe=J.data,ye=xe.data;if(pe.length!==ye.length){ie[K]=fe;continue}if(ye.length>_f){ie[K]=fe;continue}const Ie=($==null?void 0:$.cartesianDataBySeriesIndex[K])??null,Ae=T(pe,ye,U,Ie);if(!Ae){ie[K]=fe;continue}$&&($.cartesianDataBySeriesIndex[K]=Ae),ie[K]={...fe,data:Ae}}return ie},x=(D,z,U)=>{const $=Bi(D.from.xBaseDomain,D.to.xBaseDomain,z),ie=Tn($,U),K=Bi(D.from.yBaseDomain,D.to.yBaseDomain,z),ae=f(D.from.series,D.to.series,z,null);return{xBaseDomain:$,xVisibleDomain:{min:ie.min,max:ie.max},yBaseDomain:K,series:ae}},N=new Set,A=new Set;let P=new Array(t.series.length).fill(null),L=new Array(t.series.length).fill(null),B=m.series,V=m.series,_=null;const re=D=>{if((D.yAxis.autoBounds??"visible")!=="visible")return!1;const U=yn(D.yAxis.min),$=yn(D.yAxis.max);return!(U!==void 0&&$!==void 0)},Y=()=>{re(m)?_=Kf(V):_=null};let W=[],Z=!1,oe=null,ee=null,q=null,de=!1,G=!1;const te=new Map;let X=new Array(m.series.length).fill("unknown");const Q=new Set;let ne=o&&((vo=m.tooltip)==null?void 0:vo.show)!==!1?Es(o):null,H=null,O=null,se=null;const ce=(D,z,U,$)=>{ne==null||ne.show(D,z,U)},le=()=>{ne==null||ne.hide()},me=()=>{H=null,O=null,se=null,le()};((D,z)=>{u==null||u.update(D,z)})(m.series,m.theme);let we=ka(i);const it=dl(i,{targetFormat:r}),Ke=qo(i,{targetFormat:r}),et=qo(i,{targetFormat:r}),ke=Gu(i,{targetFormat:r});ke.setVisible(!1);const he=Xu(i,{targetFormat:r});he.setVisible(!1);const be=4,Ge=xs(i,{targetFormat:r}),ze=ws(i,{targetFormat:r}),rt=xs(i,{targetFormat:r,sampleCount:be}),Ze=ws(i,{targetFormat:r,sampleCount:be});let ht=null,gt=null,ot=null,Ft=null,It=0,Bt=0,Lt=null;const k=`
|
|
1103
|
+
struct VSOut { @builtin(position) pos: vec4f };
|
|
1104
|
+
|
|
1105
|
+
@vertex
|
|
1106
|
+
fn vsMain(@builtin(vertex_index) i: u32) -> VSOut {
|
|
1107
|
+
var positions = array<vec2f, 3>(
|
|
1108
|
+
vec2f(-1.0, -1.0),
|
|
1109
|
+
vec2f( 3.0, -1.0),
|
|
1110
|
+
vec2f(-1.0, 3.0)
|
|
1111
|
+
);
|
|
1112
|
+
var o: VSOut;
|
|
1113
|
+
o.pos = vec4f(positions[i], 0.0, 1.0);
|
|
1114
|
+
return o;
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
// Using textureLoad (no filtering) for pixel-exact blit into the MSAA overlay pass.
|
|
1118
|
+
@group(0) @binding(0) var srcTex: texture_2d<f32>;
|
|
1119
|
+
|
|
1120
|
+
@fragment
|
|
1121
|
+
fn fsMain(@builtin(position) pos: vec4f) -> @location(0) vec4f {
|
|
1122
|
+
let xy = vec2<i32>(pos.xy);
|
|
1123
|
+
return textureLoad(srcTex, xy, 0);
|
|
1124
|
+
}
|
|
1125
|
+
`,j=i.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float",viewDimension:"2d"}}]}),ue=Tt(i,{label:"renderCoordinator/overlayBlitPipeline",bindGroupLayouts:[j],vertex:{code:k,label:"renderCoordinator/overlayBlit.wgsl"},fragment:{code:k,label:"renderCoordinator/overlayBlit.wgsl",formats:r},primitive:{topology:"triangle-list",cullMode:"none"},multisample:{count:be}});let Se=null;const De=D=>{if(D)try{D.destroy()}catch{}},Ye=(D,z)=>{const U=Number.isFinite(D)?Math.max(1,Math.floor(D)):1,$=Number.isFinite(z)?Math.max(1,Math.floor(z)):1;ht&&ot&&Se&&It===U&&Bt===$&&Lt===r||(De(ht),De(ot),ht=i.createTexture({label:"renderCoordinator/mainColorTexture",size:{width:U,height:$},format:r,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING}),gt=ht.createView(),ot=i.createTexture({label:"renderCoordinator/annotationOverlayMsaaTexture",size:{width:U,height:$},sampleCount:be,format:r,usage:GPUTextureUsage.RENDER_ATTACHMENT}),Ft=ot.createView(),Se=i.createBindGroup({label:"renderCoordinator/overlayBlitBindGroup",layout:j,entries:[{binding:0,resource:gt}]}),It=U,Bt=$,Lt=r)},Me=Ls(e,m),ve=Vn(e.canvas)?Ju(e.canvas,Me):null;let Ce={source:"mouse",x:0,y:0,gridX:0,gridY:0,isInGrid:!1,hasPointer:!1},Fe=null,yt;const St=new Set;let tt=null;const kt=(D,z)=>{const U=Array.from(St);for(const $ of U)$(D,z)},qt=(D,z)=>{const U=D!==null&&Number.isFinite(D)?D:null;Fe===U&&yt===z||(Fe=U,yt=z,kt(Fe,yt))},He=()=>{var D;(D=n==null?void 0:n.onRequestRender)==null||D.call(n)},Ut=D=>D?Number.isFinite(D.start)&&Number.isFinite(D.end)&&D.start<=0&&D.end>=100:!0,at=()=>{oe!==null&&(cancelAnimationFrame(oe),oe=null),ee!==null&&(clearTimeout(ee),ee=null),Z=!1},ct=()=>{q!==null&&(clearTimeout(q),q=null)},ar=()=>{var fe;if(te.size===0)return!1;Q.clear();const D=(Ne==null?void 0:Ne.getRange())??null,z=Ut(D),U=m.autoScroll===!0&&Ne!=null&&m.xAxis.min==null&&m.xAxis.max==null,$=Nn(m,L),ie=D?Tn($,D):null;let K=!1;for(const[J,xe]of te){if(xe.length===0)continue;const pe=m.series[J];if(!(!pe||pe.type==="pie")){if(K=!0,pe.type==="candlestick"){let ye=P[J];if(!ye){const Ae=pe.rawData??pe.data;ye=Ae.length===0?[]:Ae.slice(),P[J]=ye,L[J]=pe.rawBounds??null}const Ie=xe;ye.push(...Ie),L[J]=Vf(L[J],Ie)}else{let ye=P[J];if(!ye){const Te=pe.rawData??pe.data;ye=ii(Te),P[J]=ye,L[J]=pe.rawBounds??sn(Te)}const Ie=xe;if(pe.type==="line"&&pe.sampling==="none"&&z&&X[J]==="fullRawLine")try{we.appendSeries(J,Ie),Q.add(J)}catch{}else pe.type==="line"&&pe.sampling!=="none"&&!A.has(J)&&(A.add(J),console.warn(`[ChartGPU] appendData() on series ${J} with sampling='${pe.sampling}' causes full buffer re-upload every frame. For optimal streaming performance, use sampling='none'. See docs/internal/INCREMENTAL_APPEND_OPTIMIZATION.md for details.`));ye.push(...Ie),L[J]=zf(L[J],Ie)}W[J]=null}}if(te.clear(),!K)return!1;if(Ne){const J=cr(),xe=Ne;(fe=xe.setSpanConstraints)==null||fe.call(xe,J.minSpan,J.maxSpan)}if(U&&D&&ie){const J=D;if(J.end>=99.5){const xe=J.end-J.start,pe=Ne;pe.setRangeAnchored?pe.setRangeAnchored(100-xe,100,"end"):Ne.setRange(100-xe,100)}else{const xe=Nn(m,L),pe=xe.max-xe.min;if(Number.isFinite(pe)&&pe>0){const ye=(ie.min-xe.min)/pe*100,Ie=(ie.max-xe.min)/pe*100,Ae=Math.max(0,Math.min(100,ye)),Te=Math.max(0,Math.min(100,Ie));Ne.setRange(Ae,Te)}}}lr();const ae=(Ne==null?void 0:Ne.getRange())??null;return(ae==null||Ut(ae))&&(V=B,Y()),!0},vt=D=>{if(l)return;const z=(D==null?void 0:D.requestRenderAfter)??!0,U=ar(),$=(Ne==null?void 0:Ne.getRange())??null,ie=Ut($),K=$!=null&&!ie;let ae=!1;de?(de=!1,ct(),!$||ie?(V=B,Y()):fi(),ae=!0):U&&K&&(de=!1,ct(),fi(),ae=!0),(U||ae)&&z&&He()},Ot=D=>{l||Z||(oe!==null&&(cancelAnimationFrame(oe),oe=null),ee!==null&&(clearTimeout(ee),ee=null),Z=!0,oe=requestAnimationFrame(()=>{if(oe=null,l){at();return}ee!==null&&(clearTimeout(ee),ee=null),Z=!1,vt()}),ee=(typeof self<"u"?self:window).setTimeout(()=>{if(l){at();return}Z&&(oe!==null&&(cancelAnimationFrame(oe),oe=null),Z=!1,ee=null,vt())},16))},Zt=()=>{l||(ct(),de=!1,q=(typeof self<"u"?self:window).setTimeout(()=>{q=null,!l&&(de=!0,Ot())},100))},Pe=(D,z)=>{let U,$;const ie=D.getBoundingClientRect();if(!(ie.width>0)||!(ie.height>0))return null;U=ie.width,$=ie.height;const K=U-z.left-z.right,ae=$-z.top-z.bottom;return!(K>0)||!(ae>0)?null:{plotWidthCss:K,plotHeightCss:ae}},Be=(D,z)=>{const U=e.canvas;if(!U)return null;const $=Pe(U,D);if(!$)return null;const ie=an().domain(z.xDomain.min,z.xDomain.max).range(0,$.plotWidthCss),K=an().domain(z.yDomain.min,z.yDomain.max).range($.plotHeightCss,0);return{xScale:ie,yScale:K,plotWidthCss:$.plotWidthCss,plotHeightCss:$.plotHeightCss}},je=(D,z,U)=>{const $=m.series[D],{x:ie,y:K}=ri(U);return{seriesName:($==null?void 0:$.name)??"",seriesIndex:D,dataIndex:z,value:[ie,K],color:($==null?void 0:$.color)??"#888"}},xt=(D,z,U)=>{const $=m.series[D];return Ht(U)?{seriesName:($==null?void 0:$.name)??"",seriesIndex:D,dataIndex:z,value:[U[0],U[1],U[2],U[3],U[4]],color:($==null?void 0:$.color)??"#888"}:{seriesName:($==null?void 0:$.name)??"",seriesIndex:D,dataIndex:z,value:[U.timestamp,U.open,U.close,U.low,U.high],color:($==null?void 0:$.color)??"#888"}},lt=(D,z,U,$,ie)=>{const K=.5*Math.min($,ie);if(!(K>0))return null;for(let ae=D.length-1;ae>=0;ae--){const fe=D[ae];if(fe.type!=="pie"||fe.visible===!1)continue;const J=fe,xe=Xf(J.center,$,ie),pe=Hf(J.radius,K),ye=qr(z,U,{seriesIndex:ae,series:J},xe,pe);if(ye)return ye}return null},cn=(D,z,U,$)=>{for(let ie=D.length-1;ie>=0;ie--){const K=D[ie];if(K.type!=="candlestick"||K.visible===!1)continue;const ae=K,fe=Yr(ae,ae.data,$.xScale,$.plotWidthCss),J=Hr([ae],z,U,$.xScale,$.yScale,fe);if(!J)continue;return{params:xt(ie,J.dataIndex,J.point),match:{point:J.point},seriesIndex:ie}}return null},Pt=D=>{if(Ce={source:"mouse",x:D.x,y:D.y,gridX:D.gridX,gridY:D.gridY,isInGrid:D.isInGrid,hasPointer:!0},D.isInGrid&&tt){const z=tt.xScale.invert(D.gridX);qt(Number.isFinite(z)?z:null,"mouse")}else D.isInGrid||qt(null,"mouse");ke.setVisible(D.isInGrid),He()},jt=D=>{Ce.source==="mouse"&&(Ce={...Ce,isInGrid:!1,hasPointer:!1},ke.setVisible(!1),me(),qt(null,"mouse"),He())};ve&&(ve.on("mousemove",Pt),ve.on("mouseleave",jt));let Ne=null,wt=null,Kt=null,xn=null;const ui=new Set,Ma=D=>{const z=Array.from(ui);for(const U of z)U(D)},Fa=D=>{var ae,fe;const z=(ae=D.dataZoom)==null?void 0:ae.find(J=>(J==null?void 0:J.type)==="inside"),U=(fe=D.dataZoom)==null?void 0:fe.find(J=>(J==null?void 0:J.type)==="slider"),$=z??U;if(!$)return null;const ie=Number.isFinite($.start)?$.start:0,K=Number.isFinite($.end)?$.end:100;return{start:ie,end:K,hasInside:!!z}},Wn=D=>Math.min(100,Math.max(0,D)),Sa=D=>{let z=null,U=null;const $=D.dataZoom??[];for(const ie of $)if(ie&&!(ie.type!=="inside"&&ie.type!=="slider")){if(Number.isFinite(ie.minSpan)){const K=Wn(ie.minSpan);z=z==null?K:Math.max(z,K)}if(Number.isFinite(ie.maxSpan)){const K=Wn(ie.maxSpan);U=U==null?K:Math.min(U,K)}}return{minSpan:z??void 0,maxSpan:U??void 0}},Na=()=>{if(m.xAxis.type==="category")return null;let D=0;for(let U=0;U<m.series.length;U++){const $=m.series[U];if($.type==="pie")continue;if($.type==="candlestick"){const K=P[U]??$.rawData??$.data;D=Math.max(D,K.length);continue}const ie=P[U]??ii($.rawData??$.data);D=Math.max(D,ie.length)}if(D<2)return null;const z=100/(D-1);return Number.isFinite(z)?Wn(z):null},cr=()=>{const D=Sa(m),z=Na(),U=Number.isFinite(D.minSpan)?Wn(D.minSpan):z??.5,$=Number.isFinite(D.maxSpan)?Wn(D.maxSpan):100;return{minSpan:U,maxSpan:$}},lo=()=>{var z;const D=Fa(m);if(!D){wt==null||wt.dispose(),wt=null,Kt==null||Kt(),Kt=null,Ne=null,xn=null;return}if(Ne){const U=cr(),$=Ne;(z=$.setSpanConstraints)==null||z.call($,U.minSpan,U.maxSpan),(xn==null||xn.start!==D.start||xn.end!==D.end)&&(Ne.setRange(D.start,D.end),xn={start:D.start,end:D.end})}else{const U=cr();Ne=lf(D.start,D.end,U),xn={start:D.start,end:D.end},Kt=Ne.onChange($=>{G=!0,He(),Zt(),Ma({start:$.start,end:$.end})})}D.hasInside&&ve?wt||(wt=of(ve,Ne),wt.enable()):(wt==null||wt.dispose(),wt=null)},uo=()=>{const D=m.series.length;P=new Array(D).fill(null),L=new Array(D).fill(null),te.clear();for(let z=0;z<D;z++){const U=m.series[z];if(U.type==="pie")continue;if(U.type==="candlestick"){const K=U.rawData??U.data,ae=K.length===0?[]:K.slice();P[z]=ae,L[z]=U.rawBounds??null;continue}const $=U.rawData??U.data,ie=ii($);P[z]=ie,L[z]=U.rawBounds??sn($)}},lr=()=>{const D=new Array(m.series.length);for(let z=0;z<m.series.length;z++){const U=m.series[z];if(U.type==="pie"){D[z]=U;continue}if(U.type==="candlestick"){const ae=P[z]??U.rawData??U.data,fe=L[z]??U.rawBounds??void 0,J=U.sampling==="ohlc"&&ae.length>U.samplingThreshold?Wr(ae,U.samplingThreshold):ae;D[z]={...U,rawData:ae,rawBounds:fe,data:J};continue}const $=P[z]??ii(U.rawData??U.data),ie=L[z]??U.rawBounds??void 0,K=_n($,U.sampling,U.samplingThreshold);D[z]={...U,rawData:$,rawBounds:ie,data:K}}B=D};function Ta(){const D=(Ne==null?void 0:Ne.getRange())??null,z=Nn(m,L),U=Tn(z,D);if(D==null||Number.isFinite(D.start)&&Number.isFinite(D.end)&&D.start<=0&&D.end>=100){V=B,Y();return}const ie=new Array(B.length);for(let K=0;K<B.length;K++){const ae=B[K];if(ae.type==="pie"){ie[K]=ae;continue}const fe=W[K];if(fe&&U.min>=fe.cachedRange.min&&U.max<=fe.cachedRange.max){ae.type==="candlestick"?ie[K]={...ae,data:bi(fe.data,U.min,U.max)}:ie[K]={...ae,data:xi(fe.data,U.min,U.max)};continue}ae.type==="candlestick"?ie[K]={...ae,data:bi(ae.data,U.min,U.max)}:ie[K]={...ae,data:xi(ae.data,U.min,U.max)}}V=ie,Y()}function fi(){const D=(Ne==null?void 0:Ne.getRange())??null,z=Nn(m,L),U=Tn(z,D),K=(U.max-U.min)*.1,ae=U.min-K,fe=U.max+K,J=2,xe=2e5,pe=32,ye=Math.max(.001,Math.min(1,U.spanFraction)),Ie=new Array(B.length);for(let Ae=0;Ae<B.length;Ae++){const Te=B[Ae];if(Te.type==="pie"){Ie[Ae]=Te;continue}if(D==null||Number.isFinite(D.start)&&Number.isFinite(D.end)&&D.start<=0&&D.end>=100){Ie[Ae]=Te;continue}if(Te.type==="candlestick"){const mi=P[Ae]??Te.rawData??Te.data,An=bi(mi,ae,fe),dr=Te.sampling,Yn=Te.samplingThreshold,pi=Number.isFinite(Yn)?Math.max(1,Yn|0):1,mr=Math.min(xe,Math.max(J,pi*pe)),Hn=On(Math.round(pi/ye),J,mr),Rn=dr==="ohlc"&&An.length>Hn?Wr(An,Hn):An;W[Ae]={data:Rn,cachedRange:{min:ae,max:fe},timestamp:Date.now()};const qn=bi(Rn,U.min,U.max);Ie[Ae]={...Te,data:qn};continue}const wn=P[Ae]??ii(Te.rawData??Te.data),ln=xi(wn,ae,fe),un=Te.sampling,ut=Te.samplingThreshold,$t=Number.isFinite(ut)?Math.max(1,ut|0):1,rn=Math.min(xe,Math.max(J,$t*pe)),Xn=On(Math.round($t/ye),J,rn),Ct=_n(ln,un,Xn);W[Ae]={data:Ct,cachedRange:{min:ae,max:fe},timestamp:Date.now()};const di=xi(Ct,U.min,U.max);Ie[Ae]={...Te,data:di}}V=Ie,Y()}uo(),lr(),lo(),fi(),W=new Array(m.series.length).fill(null);const Jt=[],Qt=[],en=[],bn=[],tn=[],nn=[],ur=Ul(i,{targetFormat:r}),fo=D=>{for(;Jt.length>D;){const z=Jt.pop();z==null||z.dispose()}for(;Jt.length<D;)Jt.push(bl(i,{targetFormat:r}))},mo=D=>{for(;Qt.length>D;){const z=Qt.pop();z==null||z.dispose()}for(;Qt.length<D;)Qt.push(Nl(i,{targetFormat:r}))},po=D=>{for(;en.length>D;){const z=en.pop();z==null||z.dispose()}for(;en.length<D;)en.push(Yl(i,{targetFormat:r}))},ho=D=>{for(;bn.length>D;){const z=bn.pop();z==null||z.dispose()}for(;bn.length<D;)bn.push(iu(i,{targetFormat:r}))},yo=D=>{for(;tn.length>D;){const z=tn.pop();z==null||z.dispose()}for(;tn.length<D;)tn.push(fu(i,{targetFormat:r}))},go=D=>{for(;nn.length>D;){const z=nn.pop();z==null||z.dispose()}for(;nn.length<D;)nn.push(Mu(i,{targetFormat:r}))};fo(m.series.length),mo(m.series.length),po(m.series.length),ho(m.series.length),yo(m.series.length),go(m.series.length);const vn=()=>{if(l)throw new Error("RenderCoordinator is disposed.")},xo=()=>{if(d)try{w.cancel(d)}catch{}d=null,g=1,v=null,I()},bo=(D,z)=>D.min===z.min&&D.max===z.max,Ia=(D,z)=>{if(D.length!==z.length)return!0;for(let U=0;U<D.length;U++){const $=D[U],ie=z[U];if($.type!==ie.type)return!0;if($.type==="pie"){const K=$,ae=ie;if(K.data!==ae.data||K.data.length!==ae.data.length)return!0}else{const K=$,ae=ie,fe=K.rawData??K.data,J=ae.rawData??ae.data;if(fe!==J||fe.length!==J.length)return!0}}return!1},Pa=(D,z)=>{if(D.length!==z.length)return!1;let U=!1;for(let $=0;$<D.length;$++){const ie=D[$],K=z[$];if(ie.type!==K.type)return!1;if(ie.type==="pie"){const J=ie,xe=K;if(J.data.length!==xe.data.length)return!1;for(let pe=0;pe<J.data.length;pe++){const ye=J.data[pe],Ie=xe.data[pe];if(!ye&&!Ie)continue;if(!ye||!Ie||ye.name!==Ie.name||ye.value!==Ie.value||ye.color!==Ie.color)return!1;const Ae=ye.visible!==!1,Te=Ie.visible!==!1;Ae!==Te&&(U=!0)}}else{const J=ie,xe=K,pe=J.rawData??J.data,ye=xe.rawData??xe.data;if(pe!==ye||pe.length!==ye.length)return!1}const ae=ie.visible!==!1,fe=K.visible!==!1;ae!==fe&&(U=!0)}return U},fr=D=>{var un;vn();const z=(Ne==null?void 0:Ne.getRange())??null,U=(()=>{if(v&&d){try{w.update(performance.now())}catch{}return x(v,g,z)}const ut=Nn(m,L),$t=Tn(ut,z),rn=Gr(m,L,_);return{xBaseDomain:ut,xVisibleDomain:{min:$t.min,max:$t.max},yBaseDomain:rn,series:V}})();xo();const $=Ia(m.series,D.series),ie=Pa(m.series,D.series);if(m=D,B=D.series,V=D.series,_=null,X=new Array(D.series.length).fill("unknown"),W=new Array(D.series.length).fill(null),u==null||u.update(D.series,D.theme),ct(),de=!1,at(),uo(),lr(),lo(),fi(),o){const ut=((un=m.tooltip)==null?void 0:un.show)!==!1;ut&&!ne&&(ne=Es(o),H=null,O=null,se=null),!ut&&ne&&me()}else me();const K=D.series.length;if(fo(K),mo(K),po(K),ho(K),yo(K),go(K),K<C)for(let ut=K;ut<C;ut++)we.removeSeries(ut);if(C=K,m.animation===!1&&F==="running"&&(S.cancelAll(),y=null,F="done",R=1),m.animation===!1){xo(),He();return}const ae=(Ne==null?void 0:Ne.getRange())??null,fe=Nn(m,L),J=Tn(fe,ae),xe=Gr(m,L,_),pe=V,ye=!bo(U.xBaseDomain,fe)||!bo(U.yBaseDomain,xe);if(!(b&&(ye||$)&&!ie)){ie&&F==="done"&&b&&(S.cancelAll(),y=null,F="pending",R=0),He();return}const Te=Qf(m.animation);if(!Te)return;v={from:{xBaseDomain:U.xBaseDomain,xVisibleDomain:U.xVisibleDomain,yBaseDomain:U.yBaseDomain,series:U.series},to:{xBaseDomain:fe,xVisibleDomain:{min:J.min,max:J.max},yBaseDomain:xe,series:pe}},I();const Nt=Te.delayMs+Te.durationMs,wn=ut=>{const $t=Xt(ut);if(!(Nt>0))return 1;const rn=$t*Nt;if(rn<=Te.delayMs)return 0;if(!(Te.durationMs>0))return 1;const Xn=(rn-Te.delayMs)/Te.durationMs;return Te.easing(Xn)};g=0;const ln=w.animate(0,1,Nt,wn,ut=>{l||d!==ln||(g=Xt(ut),g<1&&He())},()=>{l||d!==ln||(g=1,v=null,d=null,I())});d=ln,He()};return{setOptions:fr,appendData:(D,z)=>{if(vn(),!Number.isFinite(D)||D<0||D>=m.series.length||!z||z.length===0)return;if(m.series[D].type==="pie"){N.has(D)||(N.add(D),console.warn(`RenderCoordinator.appendData(${D}, ...): pie series are not supported by streaming append.`));return}const $=te.get(D);$?$.push(...z):te.set(D,Array.from(z)),Ot()},getInteractionX:()=>Fe,setInteractionX:(D,z)=>{vn();const U=D!==null&&Number.isFinite(D)?D:null;Ce={...Ce,source:U===null?"mouse":"sync"},qt(U,z),U===null&&Ce.hasPointer===!1&&(ke.setVisible(!1),he.setVisible(!1),le()),He()},onInteractionXChange:D=>(vn(),St.add(D),()=>{St.delete(D)}),getZoomRange:()=>(Ne==null?void 0:Ne.getRange())??null,setZoomRange:(D,z)=>{vn(),Ne&&Ne.setRange(D,z)},onZoomRangeChange:D=>(vn(),ui.add(D),()=>{ui.delete(D)}),render:()=>{var No,To,Io;if(vn(),!e.canvasContext||!e.canvas)return;(te.size>0||de)&&(at(),vt({requestRenderAfter:!1})),G&&(G=!1,Ta());const D=m.series.some(Re=>Re.type!=="pie"),z=V;if(F!=="done"){const Re=Jf(m.animation),Ve=(()=>{for(let At=0;At<z.length;At++){const Oe=z[At];switch(Oe.type){case"pie":{if(Oe.data.some(Ue=>typeof(Ue==null?void 0:Ue.value)=="number"&&Number.isFinite(Ue.value)&&Ue.value>0))return!0;break}case"line":case"area":case"bar":case"scatter":case"candlestick":{if((Array.isArray(Oe.data)||ArrayBuffer.isView(Oe.data)?Oe.data.length:Oe.data.x.length)>0)return!0;break}default:Gf(Oe)}}return!1})();if(F==="pending"&&Re&&Ve){const At=Re.delayMs+Re.durationMs,Oe=Ue=>{const ft=Xt(Ue);if(!(At>0))return 1;const _e=ft*At;if(_e<=Re.delayMs)return 0;if(!(Re.durationMs>0))return 1;const Le=(_e-Re.delayMs)/Re.durationMs;return Re.easing(Le)};R=0,F="running",y=S.animate(0,1,At,Oe,Ue=>{l||F!=="running"||(R=Xt(Ue),R<1&&He())},()=>{l||(F="done",R=1,y=null)})}S.update(performance.now())}v!==null&&d&&w.update(performance.now());const U=Ls(e,m);ve==null||ve.updateGridArea(U);const $=(Ne==null?void 0:Ne.getRange())??null,ie=v?Xt(g):1,K=v?Bi(v.from.xBaseDomain,v.to.xBaseDomain,ie):Nn(m,L),ae=v?Bi(v.from.yBaseDomain,v.to.yBaseDomain,ie):Gr(m,L,_),fe=Tn(K,$),J=$f(U),xe=Wf(U),pe=an().domain(fe.min,fe.max).range(J.left,J.right),ye=an().domain(ae.min,ae.max).range(J.bottom,J.top),Ie=e.canvas,Ae=Ef(Ie),Te=Ae.width,Nt=Ae.height,wn=Te>0?jr(J.left,Te):0,ln=Te>0?jr(J.right,Te):0,un=Nt>0?Us(J.top,Nt):0,ut=Nt>0?Us(J.bottom,Nt):0,$t=Math.max(0,ln-wn),rn=Math.max(0,ut-un),Xn=D?m.annotations??[]:[],Ct=Vc({annotations:Xn,xScale:pe,yScale:ye,plotBounds:{leftCss:wn,rightCss:ln,topCss:un,bottomCss:ut,widthCss:$t,heightCss:rn},canvasCssWidth:Te,canvasCssHeight:Nt,theme:m.theme}),di=Ct.linesBelow.length+Ct.linesAbove.length>0?[...Ct.linesBelow,...Ct.linesAbove]:[],mi=Ct.markersBelow.length+Ct.markersAbove.length>0?[...Ct.markersBelow,...Ct.markersAbove]:[],An=Ct.linesBelow.length,dr=Ct.linesAbove.length,Yn=Ct.markersBelow.length,pi=Ct.markersAbove.length,mr=Rf(e.canvas),Hn=Math.abs(fe.max-fe.min);let Rn=Zr,qn=[];if(m.xAxis.type==="time"){const Re=jf({axisMin:Ji(m.xAxis.min),axisMax:Ji(m.xAxis.max),xScale:pe,plotClipLeft:J.left,plotClipRight:J.right,canvasCssWidth:mr,visibleRangeMs:Hn,measureCtx:p,measureCache:h??void 0,fontSize:m.theme.fontSize,fontFamily:m.theme.fontFamily||"sans-serif"});Rn=Re.tickCount,qn=Re.tickValues}else{const Re=yn(m.xAxis.min)??pe.invert(J.left),Ve=yn(m.xAxis.max)??pe.invert(J.right);qn=$i(Re,Ve,Rn)}const $e=Be(U,{xDomain:{min:fe.min,max:fe.max},yDomain:ae});tt=$e;const Wt=v&&ie<1?f(v.from.series,v.to.series,ie,M):V;if(Ce.source==="mouse"&&Ce.hasPointer&&Ce.isInGrid&&$e){const Re=$e.xScale.invert(Ce.gridX);qt(Number.isFinite(Re)?Re:null,"mouse")}let st=Ce;if(Ce.source==="sync")if(Fe===null||!$e)st={...Ce,hasPointer:!1,isInGrid:!1};else{const Re=$e.xScale.scale(Fe),Ve=$e.plotHeightCss*.5,At=Number.isFinite(Re)&&Number.isFinite(Ve)&&Re>=0&&Re<=$e.plotWidthCss&&Ve>=0&&Ve<=$e.plotHeightCss;st={source:"sync",gridX:Number.isFinite(Re)?Re:0,gridY:Number.isFinite(Ve)?Ve:0,x:U.left+(Number.isFinite(Re)?Re:0),y:U.top+(Number.isFinite(Ve)?Ve:0),isInGrid:At,hasPointer:At}}if(Uc({gridRenderer:it,xAxisRenderer:Ke,yAxisRenderer:et,crosshairRenderer:ke,highlightRenderer:he},{currentOptions:m,xScale:pe,yScale:ye,gridArea:U,xTickCount:Rn,hasCartesianSeries:D,effectivePointer:st,interactionScales:$e,seriesForRender:Wt,withAlpha:ks}),st.hasPointer&&st.isInGrid&&((No=m.tooltip)==null?void 0:No.show)!==!1){const Re=e.canvas;if($e&&Re&&Vn(Re)){const Ve=(To=m.tooltip)==null?void 0:To.formatter,At=((Io=m.tooltip)==null?void 0:Io.trigger)??"item",Oe=Re.offsetLeft+st.x,Ue=Re.offsetTop+st.y;if(st.source==="sync"){const ft=Ns(Wt,st.gridX,$e.xScale);if(ft.length===0)me();else if(At==="axis"){const _e=ft.map(qe=>je(qe.seriesIndex,qe.dataIndex,qe.point)),Le=Ve?Ve(_e):Ur(_e);Le&&(Le!==H||Oe!==O||Ue!==se)?(H=Le,O=Oe,se=Ue,ce(Oe,Ue,Le)):Le||me()}else{const _e=ft[0],Le=je(_e.seriesIndex,_e.dataIndex,_e.point),qe=Ve?Ve(Le):ni(Le);qe&&(qe!==H||Oe!==O||Ue!==se)?(H=qe,O=Oe,se=Ue,ce(Oe,Ue,qe)):qe||me()}}else if(At==="axis"){const ft=lt(Wt,st.gridX,st.gridY,$e.plotWidthCss,$e.plotHeightCss);if(ft){const _e={seriesName:ft.slice.name,seriesIndex:ft.seriesIndex,dataIndex:ft.dataIndex,value:[0,ft.slice.value],color:ft.slice.color},Le=Ve?Ve([_e]):ni(_e);Le&&(Le!==H||Oe!==O||Ue!==se)?(H=Le,O=Oe,se=Ue,ce(Oe,Ue,Le)):Le||me()}else{const _e=cn(Wt,st.gridX,st.gridY,$e),Le=Ns(Wt,st.gridX,$e.xScale);if(Le.length===0)if(_e){const qe=[_e.params],Je=Ve?Ve(qe):Ur(qe);if(Je){const dt=zr(_e.match,$e.xScale,$e.yScale,U,Re),Rt=(dt==null?void 0:dt.x)??Oe,Cn=(dt==null?void 0:dt.y)??Ue;(Je!==H||Rt!==O||Cn!==se)&&(H=Je,O=Rt,se=Cn,ce(Rt,Cn,Je))}else me()}else me();else{const qe=Le.map(dt=>je(dt.seriesIndex,dt.dataIndex,dt.point));_e&&qe.push(_e.params);const Je=Ve?Ve(qe):Ur(qe);if(Je){let dt=Oe,Rt=Ue;if(_e){const Cn=zr(_e.match,$e.xScale,$e.yScale,U,Re);Cn&&(dt=Cn.x,Rt=Cn.y)}(Je!==H||dt!==O||Rt!==se)&&(H=Je,O=dt,se=Rt,ce(dt,Rt,Je))}else me()}}}else{const ft=lt(Wt,st.gridX,st.gridY,$e.plotWidthCss,$e.plotHeightCss);if(ft){const _e={seriesName:ft.slice.name,seriesIndex:ft.seriesIndex,dataIndex:ft.dataIndex,value:[0,ft.slice.value],color:ft.slice.color},Le=Ve?Ve(_e):ni(_e);Le&&(Le!==H||Oe!==O||Ue!==se)?(H=Le,O=Oe,se=Ue,ce(Oe,Ue,Le)):Le||me()}else{const _e=cn(Wt,st.gridX,st.gridY,$e);if(_e){const qe=Ve?Ve(_e.params):ni(_e.params);if(qe){const Je=zr(_e.match,$e.xScale,$e.yScale,U,Re),dt=(Je==null?void 0:Je.x)??Oe,Rt=(Je==null?void 0:Je.y)??Ue;(qe!==H||dt!==O||Rt!==se)&&(H=qe,O=dt,se=Rt,ce(dt,Rt,qe,_e.params))}else me();return}const Le=Zi(Wt,st.gridX,st.gridY,$e.xScale,$e.yScale);if(!Le)me();else{const qe=je(Le.seriesIndex,Le.dataIndex,Le.point),Je=Ve?Ve(qe):ni(qe);Je&&(Je!==H||Oe!==O||Ue!==se)?(H=Je,O=Oe,se=Ue,ce(Oe,Ue,Je)):Je||me()}}}}else me()}else me();const Zn=$e??(Ie&&Vn(Ie)?Pe(Ie,U):null),Aa=Zn&&typeof Zn.plotWidthCss=="number"&&typeof Zn.plotHeightCss=="number"?.5*Math.min(Zn.plotWidthCss,Zn.plotHeightCss):0,wo=$c({lineRenderers:Qt,areaRenderers:Jt,scatterRenderers:en,scatterDensityRenderers:bn,pieRenderers:tn,candlestickRenderers:nn},{currentOptions:m,seriesForRender:Wt,xScale:pe,yScale:ye,gridArea:U,dataStore:we,appendedGpuThisFrame:Q,gpuSeriesKindByIndex:X,zoomState:Ne,visibleXDomain:fe,introPhase:F,introProgress01:R,withAlpha:ks,maxRadiusCss:Aa}),{visibleBarSeriesConfigs:Co}=wo,Mo=F==="running"?Xt(R):1,Ra=Mo<1?td(ye,J,Co,Mo):ye;ur.prepare(Co,we,pe,Ra,U),D?(Ge.prepare(U,di),rt.prepare(U,di),ze.prepare({canvasWidth:U.canvasWidth,canvasHeight:U.canvasHeight,devicePixelRatio:U.devicePixelRatio,instances:mi}),Ze.prepare({canvasWidth:U.canvasWidth,canvasHeight:U.canvasHeight,devicePixelRatio:U.devicePixelRatio,instances:mi})):(Ge.prepare(U,[]),rt.prepare(U,[]),ze.prepare({canvasWidth:U.canvasWidth,canvasHeight:U.canvasHeight,devicePixelRatio:U.devicePixelRatio,instances:[]}),Ze.prepare({canvasWidth:U.canvasWidth,canvasHeight:U.canvasHeight,devicePixelRatio:U.devicePixelRatio,instances:[]})),Ye(U.canvasWidth,U.canvasHeight);const Fo=e.canvasContext.getCurrentTexture().createView(),jn=i.createCommandEncoder({label:"renderCoordinator/commandEncoder"}),So=ec(m.theme.backgroundColor,{r:0,g:0,b:0,a:1});Wc({scatterDensityRenderers:bn},Wt,jn);const pr=jn.beginRenderPass({label:"renderCoordinator/mainPass",colorAttachments:[{view:gt,clearValue:So,loadOp:"clear",storeOp:"store"}]});it&&it.render(pr),Xc({lineRenderers:Qt,areaRenderers:Jt,barRenderer:ur,scatterRenderers:en,scatterDensityRenderers:bn,pieRenderers:tn,candlestickRenderers:nn},{referenceLineRenderer:Ge,annotationMarkerRenderer:ze},{hasCartesianSeries:D,gridArea:U,mainPass:pr,plotScissor:xe,introPhase:F,introProgress01:R,referenceLineBelowCount:An,markerBelowCount:Yn},wo),pr.end();const Kn=jn.beginRenderPass({label:"renderCoordinator/annotationOverlayMsaaPass",colorAttachments:[{view:Ft,resolveTarget:Fo,clearValue:So,loadOp:"clear",storeOp:"discard"}]});Kn.setPipeline(ue),Kn.setBindGroup(0,Se),Kn.draw(3),Yc({referenceLineRendererMsaa:rt,annotationMarkerRendererMsaa:Ze},{hasCartesianSeries:D,gridArea:U,overlayPass:Kn,plotScissor:xe,referenceLineBelowCount:An,referenceLineAboveCount:dr,markerBelowCount:Yn,markerAboveCount:pi}),Kn.end();const Jn=jn.beginRenderPass({label:"renderCoordinator/topOverlayPass",colorAttachments:[{view:Fo,loadOp:"load",storeOp:"store"}]});he.render(Jn),D&&(Ke.render(Jn),et.render(Jn)),ke.render(Jn),Jn.end(),i.queue.submit([jn.finish()]),b=!0,mc(s,o,{gpuContext:e,currentOptions:m,xScale:pe,yScale:ye,xTickValues:qn,plotClipRect:J,visibleXRangeMs:Hn}),gc(a,o,{currentOptions:m,xScale:pe,yScale:ye,canvasCssWidthForAnnotations:Te,canvasCssHeightForAnnotations:Nt,plotLeftCss:wn,plotTopCss:un,plotWidthCss:$t,plotHeightCss:rn,canvas:Ie})},dispose:()=>{if(!l){l=!0;try{y&&S.cancel(y),S.cancelAll()}catch{}y=null,F="done",R=1;try{d&&w.cancel(d),w.cancelAll()}catch{}d=null,g=1,v=null,at(),ct(),de=!1,te.clear(),wt==null||wt.dispose(),wt=null,Kt==null||Kt(),Kt=null,Ne=null,xn=null,ui.clear(),ve==null||ve.dispose(),ke.dispose(),he.dispose();for(let D=0;D<Jt.length;D++)Jt[D].dispose();Jt.length=0;for(let D=0;D<Qt.length;D++)Qt[D].dispose();Qt.length=0;for(let D=0;D<en.length;D++)en[D].dispose();en.length=0;for(let D=0;D<tn.length;D++)tn[D].dispose();tn.length=0;for(let D=0;D<nn.length;D++)nn[D].dispose();nn.length=0,ur.dispose(),it.dispose(),Ke.dispose(),et.dispose(),Ge.dispose(),ze.dispose(),rt.dispose(),Ze.dispose(),De(ht),De(ot),ht=null,gt=null,ot=null,Ft=null,Se=null,we.dispose(),ne==null||ne.dispose(),ne=null,u==null||u.dispose(),s==null||s.dispose(),a==null||a.dispose()}}}}const Et={left:60,right:20,top:40,bottom:40},Wi=["#5470C6","#91CC75","#FAC858","#EE6666","#73C0DE","#3BA272","#FC8452","#9A60B4","#EA7CCC"],Gs={width:2,opacity:1},zs={opacity:.25},Dt={style:"classic",itemStyle:{upColor:"#22c55e",downColor:"#ef4444",upBorderColor:"#22c55e",downBorderColor:"#ef4444",borderWidth:1},barWidth:"80%",barMinWidth:1,barMaxWidth:50,sampling:"ohlc",samplingThreshold:5e3},Li={mode:"points",binSize:2,densityColormap:"viridis",densityNormalization:"log"},bt={grid:Et,xAxis:{type:"value"},yAxis:{type:"value",autoBounds:"visible"},autoScroll:!1,theme:"dark",palette:Wi,series:[]},id=["#00E5FF","#FF2D95","#B026FF","#00F5A0","#FFD300","#FF6B00","#4D5BFF","#FF3D3D"],ya={backgroundColor:"#1a1a2e",textColor:"#e0e0e0",axisLineColor:"rgba(224,224,224,0.35)",axisTickColor:"rgba(224,224,224,0.55)",gridLineColor:"rgba(255,255,255,0.1)",colorPalette:[...id],fontFamily:'system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji"',fontSize:12},rd=["#1F77B4","#FF7F0E","#2CA02C","#D62728","#9467BD","#8C564B","#E377C2","#17BECF"],ga={backgroundColor:"#ffffff",textColor:"#333333",axisLineColor:"rgba(0,0,0,0.35)",axisTickColor:"rgba(0,0,0,0.55)",gridLineColor:"rgba(0,0,0,0.1)",colorPalette:[...rd],fontFamily:'system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji"',fontSize:12};function Xi(e){return e==="dark"?ya:ga}const od=e=>{if(!Array.isArray(e))return;const t=[];for(const n of e){if(n===null||typeof n!="object"||Array.isArray(n))continue;const i=n,r=i.type;if(r!=="inside"&&r!=="slider")continue;const o=i.xAxisIndex,s=i.start,a=i.end,c=i.minSpan,u=i.maxSpan,p=typeof o=="number"&&Number.isFinite(o)?o:void 0,h=typeof s=="number"&&Number.isFinite(s)?s:void 0,l=typeof a=="number"&&Number.isFinite(a)?a:void 0,m=typeof c=="number"&&Number.isFinite(c)?c:void 0,C=typeof u=="number"&&Number.isFinite(u)?u:void 0;t.push({type:r,xAxisIndex:p,start:h,end:l,minSpan:m,maxSpan:C})}return t},sd=e=>{if(!Array.isArray(e))return;const t=[],n=u=>u==="start"||u==="center"||u==="end",i=u=>u==="circle"||u==="rect"||u==="triangle",r=u=>{if(typeof u!="string")return;const p=u.trim();return p.length>0?p:void 0},o=u=>typeof u=="number"&&Number.isFinite(u)?u:void 0,s=u=>{const p=o(u);if(p!=null)return Math.min(1,Math.max(0,p))},a=u=>{if(!Array.isArray(u))return;const p=u.filter(h=>typeof h=="number"&&Number.isFinite(h)).map(h=>h);if(p.length!==0)return Object.freeze(p),p},c=u=>{if(typeof u=="number"&&Number.isFinite(u))return u;if(!Array.isArray(u)||u.length!==4)return;const p=o(u[0]),h=o(u[1]),l=o(u[2]),m=o(u[3]);if(!(p==null||h==null||l==null||m==null))return[p,h,l,m]};for(const u of e){if(u===null||typeof u!="object"||Array.isArray(u))continue;const p=u,h=p.type;if(h!=="lineX"&&h!=="lineY"&&h!=="point"&&h!=="text")continue;const l=r(p.id),m=p.layer,C=m==="belowSeries"||m==="aboveSeries"?m:void 0,F=p.style,R=F&&typeof F=="object"&&!Array.isArray(F)?(()=>{const b=F,w=r(b.color),d=o(b.lineWidth),g=a(b.lineDash),v=s(b.opacity),M={...w?{color:w}:{},...d!=null?{lineWidth:d}:{},...g?{lineDash:g}:{},...v!=null?{opacity:v}:{}};return Object.keys(M).length>0?M:void 0})():void 0,S=p.label,y=S&&typeof S=="object"&&!Array.isArray(S)?(()=>{const b=S,w=r(b.text),d=r(b.template),g=b.decimals,v=typeof g=="number"&&Number.isFinite(g)&&g>=0?Math.min(20,Math.floor(g)):void 0,M=b.offset,I=Array.isArray(M)&&M.length===2&&typeof M[0]=="number"&&Number.isFinite(M[0])&&typeof M[1]=="number"&&Number.isFinite(M[1])?[M[0],M[1]]:void 0,T=b.anchor,E=n(T)?T:void 0,f=b.background,x=f&&typeof f=="object"&&!Array.isArray(f)?(()=>{const A=f,P=r(A.color),L=s(A.opacity),B=c(A.padding),V=o(A.borderRadius),_={...P?{color:P}:{},...L!=null?{opacity:L}:{},...B!=null?{padding:B}:{},...V!=null?{borderRadius:V}:{}};return Object.keys(_).length>0?_:void 0})():void 0,N={...w?{text:w}:{},...d?{template:d}:{},...v!=null?{decimals:v}:{},...I?{offset:I}:{},...E?{anchor:E}:{},...x?{background:x}:{}};return Object.keys(N).length>0?N:void 0})():void 0;if(h==="lineX"){const b=o(p.x);if(b==null)continue;const w={type:"lineX",x:b,...l?{id:l}:{},...C?{layer:C}:{},...R?{style:R}:{},...y?{label:y}:{}};t.push(w);continue}if(h==="lineY"){const b=o(p.y);if(b==null)continue;const w={type:"lineY",y:b,...l?{id:l}:{},...C?{layer:C}:{},...R?{style:R}:{},...y?{label:y}:{}};t.push(w);continue}if(h==="point"){const b=o(p.x),w=o(p.y);if(b==null||w==null)continue;const d=p.marker,g=d&&typeof d=="object"&&!Array.isArray(d)?(()=>{const M=d,I=M.symbol,T=i(I)?I:void 0,E=o(M.size),f=M.style,x=f&&typeof f=="object"&&!Array.isArray(f)?(()=>{const A=f,P=r(A.color),L=s(A.opacity),B=o(A.lineWidth),V=a(A.lineDash),_={...P?{color:P}:{},...L!=null?{opacity:L}:{},...B!=null?{lineWidth:B}:{},...V?{lineDash:V}:{}};return Object.keys(_).length>0?_:void 0})():void 0,N={...T?{symbol:T}:{},...E!=null?{size:E}:{},...x?{style:x}:{}};return Object.keys(N).length>0?N:void 0})():void 0,v={type:"point",x:b,y:w,...g?{marker:g}:{},...l?{id:l}:{},...C?{layer:C}:{},...R?{style:R}:{},...y?{label:y}:{}};t.push(v);continue}{const b=p.position,w=r(p.text);if(!w||!b||typeof b!="object"||Array.isArray(b))continue;const d=b,g=d.space;if(g!=="data"&&g!=="plot")continue;const v=o(d.x),M=o(d.y);if(v==null||M==null)continue;const T={type:"text",position:{space:g,x:v,y:M},text:w,...l?{id:l}:{},...C?{layer:C}:{},...R?{style:R}:{},...y?{label:y}:{}};t.push(T);continue}}if(t.length!==0)return Object.freeze(t),t},oi=e=>Array.isArray(e)?e.filter(t=>typeof t=="string").map(t=>t.trim()).filter(t=>t.length>0):[],ad=e=>{const t=Xi("dark");if(typeof e=="string"){const a=e.trim().toLowerCase();return Xi(a==="light"?"light":"dark")}if(e===null||typeof e!="object"||Array.isArray(e))return t;const n=e,i=a=>{const c=n[a];if(typeof c!="string")return;const u=c.trim();return u.length>0?u:void 0},r=n.fontSize,o=typeof r=="number"&&Number.isFinite(r)?r:void 0,s=oi(n.colorPalette);return{backgroundColor:i("backgroundColor")??t.backgroundColor,textColor:i("textColor")??t.textColor,axisLineColor:i("axisLineColor")??t.axisLineColor,axisTickColor:i("axisTickColor")??t.axisTickColor,gridLineColor:i("gridLineColor")??t.gridLineColor,colorPalette:s.length>0?s:Array.from(t.colorPalette),fontFamily:i("fontFamily")??t.fontFamily,fontSize:o??t.fontSize}},on=e=>{if(typeof e!="string")return;const t=e.trim();return t.length>0?t:void 0},cd=e=>{if(typeof e!="string")return;const t=e.trim().toLowerCase();return t==="none"||t==="lttb"||t==="average"||t==="max"||t==="min"||t==="ohlc"?t:void 0},ld=e=>{if(typeof e!="string")return;const t=e.trim().toLowerCase();return t==="points"||t==="density"?t:void 0},ud=e=>{if(typeof e!="string")return;const t=e.trim().toLowerCase();return t==="linear"||t==="sqrt"||t==="log"?t:void 0},fd=e=>{if(typeof e!="number"||!Number.isFinite(e))return;const t=Math.floor(e);return t>0?Math.max(1,t):void 0},dd=e=>{if(typeof e=="string"){const i=e.trim().toLowerCase();return i==="viridis"||i==="plasma"||i==="inferno"?i:void 0}if(!Array.isArray(e))return;if(e.length>0&&e.every(i=>typeof i=="string"&&i.length>0&&i===i.trim())){const i=e;return Object.isFrozen(i)||Object.freeze(i),i}const n=e.filter(i=>typeof i=="string").map(i=>i.trim()).filter(i=>i.length>0);if(n.length!==0)return Object.freeze(n),n},md=e=>{if(typeof e!="string")return;const t=e.trim().toLowerCase();return t==="none"||t==="ohlc"?t:void 0},Vs=e=>{if(typeof e!="number"||!Number.isFinite(e))return;const t=Math.floor(e);return t>0?t:void 0},Os=e=>{if(typeof e!="string")return;const t=e.trim().toLowerCase();return t==="global"||t==="visible"?t:void 0},pd=e=>Array.isArray(e),hd=e=>{if(e.length===0)return;let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;if(pd(e[0])){const s=e;for(let a=0;a<s.length;a++){const c=s[a],u=c[0],p=c[3],h=c[4];if(!Number.isFinite(u)||!Number.isFinite(p)||!Number.isFinite(h))continue;const l=Math.min(p,h),m=Math.max(p,h);u<t&&(t=u),u>n&&(n=u),l<i&&(i=l),m>r&&(r=m)}}else{const s=e;for(let a=0;a<s.length;a++){const c=s[a],u=c.timestamp,p=c.low,h=c.high;if(!Number.isFinite(u)||!Number.isFinite(p)||!Number.isFinite(h))continue;const l=Math.min(p,h),m=Math.max(p,h);u<t&&(t=u),u>n&&(n=u),l<i&&(i=l),m>r&&(r=m)}}if(!(!Number.isFinite(t)||!Number.isFinite(n)||!Number.isFinite(i)||!Number.isFinite(r)))return t===n&&(n=t+1),i===r&&(r=i+1),{xMin:t,xMax:n,yMin:i,yMax:r}},yd=e=>{throw new Error(`Unhandled series type: ${(e==null?void 0:e.type)??"unknown"}`)};let $s=!1;const gd=()=>{$s||(console.warn("ChartGPU: Candlestick series rendering is not yet implemented. Series will be skipped."),$s=!0)};function ao(e={}){var S,y,b,w;const t=ad(e.theme),n=e.autoScroll,i=typeof n=="boolean"?n:bt.autoScroll,r=e.animation,s=(typeof r=="boolean"||r!==null&&typeof r=="object"&&!Array.isArray(r)?r:void 0)??!0,a=oi(e.palette),c=a.length>0?{...t,colorPalette:a}:t,u=oi(c.colorPalette),p=u.length>0?u:oi(bt.palette??Wi).length>0?oi(bt.palette??Wi):Array.from(Wi),h=p.length>0?p:["#000000"],l={...c,colorPalette:h.slice()},m={left:((S=e.grid)==null?void 0:S.left)??bt.grid.left,right:((y=e.grid)==null?void 0:y.right)??bt.grid.right,top:((b=e.grid)==null?void 0:b.top)??bt.grid.top,bottom:((w=e.grid)==null?void 0:w.bottom)??bt.grid.bottom},C=e.xAxis?{...bt.xAxis,...e.xAxis,type:e.xAxis.type??bt.xAxis.type,autoBounds:Os(e.xAxis.autoBounds)??bt.xAxis.autoBounds}:{...bt.xAxis},F=e.yAxis?{...bt.yAxis,...e.yAxis,type:e.yAxis.type??bt.yAxis.type,autoBounds:Os(e.yAxis.autoBounds)??bt.yAxis.autoBounds}:{...bt.yAxis},R=(e.series??[]).map((d,g)=>{var x,N,A,P,L,B,V,_,re,Y;const v=on(d.color),M=l.colorPalette[g%l.colorPalette.length],I=v??M,T=d.visible!==!1,E=cd(d.sampling)??"lttb",f=Vs(d.samplingThreshold)??5e3;switch(d.type){case"area":{const Z=on((x=d.areaStyle)==null?void 0:x.color)??v??M,oe={opacity:((N=d.areaStyle)==null?void 0:N.opacity)??zs.opacity,color:Z},ee=sn(d.data)??void 0;return{...d,visible:T,rawData:d.data,data:_n(d.data,E,f),color:Z,areaStyle:oe,sampling:E,samplingThreshold:f,rawBounds:ee}}case"line":{const Z=on((A=d.lineStyle)==null?void 0:A.color)??v??M,oe={width:((P=d.lineStyle)==null?void 0:P.width)??Gs.width,opacity:((L=d.lineStyle)==null?void 0:L.opacity)??Gs.opacity,color:Z},{areaStyle:ee,...q}=d,de=sn(d.data)??void 0,G=_n(d.data,E,f);return{...q,visible:T,rawData:d.data,data:G,color:Z,lineStyle:oe,...d.areaStyle?{areaStyle:{opacity:d.areaStyle.opacity??zs.opacity,color:on(d.areaStyle.color)??Z}}:{},sampling:E,samplingThreshold:f,rawBounds:de}}case"bar":{const W=sn(d.data)??void 0;return{...d,visible:T,rawData:d.data,data:_n(d.data,E,f),color:I,sampling:E,samplingThreshold:f,rawBounds:W}}case"scatter":{const W=sn(d.data)??void 0,Z=ld(d.mode)??Li.mode,oe=fd(d.binSize)??Li.binSize,ee=dd(d.densityColormap)??Li.densityColormap,q=ud(d.densityNormalization)??Li.densityNormalization;return{...d,visible:T,rawData:d.data,data:_n(d.data,E,f),color:I,mode:Z,binSize:oe,densityColormap:ee,densityNormalization:q,sampling:E,samplingThreshold:f,rawBounds:W}}case"pie":{const{sampling:W,samplingThreshold:Z,...oe}=d,ee=(d.data??[]).map((q,de)=>{const G=on(q==null?void 0:q.color),te=l.colorPalette[(g+de)%l.colorPalette.length],X=(q==null?void 0:q.visible)!==!1;return{...q,color:G??te,visible:X}});return{...oe,visible:T,color:I,data:ee}}case"candlestick":{gd();const W=md(d.sampling)??Dt.sampling,Z=Vs(d.samplingThreshold)??Dt.samplingThreshold,oe={upColor:on((B=d.itemStyle)==null?void 0:B.upColor)??Dt.itemStyle.upColor,downColor:on((V=d.itemStyle)==null?void 0:V.downColor)??Dt.itemStyle.downColor,upBorderColor:on((_=d.itemStyle)==null?void 0:_.upBorderColor)??Dt.itemStyle.upBorderColor,downBorderColor:on((re=d.itemStyle)==null?void 0:re.downBorderColor)??Dt.itemStyle.downBorderColor,borderWidth:typeof((Y=d.itemStyle)==null?void 0:Y.borderWidth)=="number"&&Number.isFinite(d.itemStyle.borderWidth)?d.itemStyle.borderWidth:Dt.itemStyle.borderWidth},ee=hd(d.data),q=W==="ohlc"&&d.data.length>Z?Wr(d.data,Z):d.data;return{...d,visible:T,rawData:d.data,data:q,color:I,style:d.style??Dt.style,itemStyle:oe,barWidth:d.barWidth??Dt.barWidth,barMinWidth:d.barMinWidth??Dt.barMinWidth,barMaxWidth:d.barMaxWidth??Dt.barMaxWidth,sampling:W,samplingThreshold:Z,rawBounds:ee}}default:return yd(d)}});return{grid:m,xAxis:C,yAxis:F,autoScroll:i,dataZoom:od(e.dataZoom),annotations:sd(e.annotations),animation:s,theme:l,palette:l.colorPalette,series:R,legend:e.legend}}const xd=32,bd=8,vd=xd+bd,wd=e=>{var t;return((t=e.dataZoom)==null?void 0:t.some(n=>(n==null?void 0:n.type)==="slider"))??!1};function Ws(e={}){const t={...ao(e),tooltip:e.tooltip};return wd(e)?{...t,grid:{...t.grid,bottom:t.grid.bottom+vd}}:t}const Cd={resolve:ao},Kr=(e,t,n)=>Math.min(n,Math.max(t,e)),Md=e=>{let{start:t,end:n}=e;if(t>n){const i=t;t=n,n=i}return{start:Kr(t,0,100),end:Kr(n,0,100)}};function Fd(e,t,n){const i=n==null?void 0:n.height,r=n==null?void 0:n.marginTop,o=(n==null?void 0:n.zIndex)??4,s=(n==null?void 0:n.showPreview)??!1,a=document.createElement("div");a.style.display="block",a.style.width="100%",a.style.height=`${i}px`,a.style.marginTop=`${r}px`,a.style.boxSizing="border-box",a.style.position="relative",a.style.zIndex=`${o}`,a.style.userSelect="none",a.style.touchAction="none";const c=document.createElement("div");c.style.position="relative",c.style.height="100%",c.style.width="100%",c.style.boxSizing="border-box",c.style.borderRadius="8px",c.style.borderStyle="solid",c.style.borderWidth="1px",c.style.overflow="hidden",a.appendChild(c);const u=document.createElement("div");u.style.position="absolute",u.style.inset="0",u.style.pointerEvents="none",u.style.opacity="0.4",u.style.display=s?"block":"none",c.appendChild(u);const p=document.createElement("div");p.style.position="absolute",p.style.top="0",p.style.bottom="0",p.style.left="0%",p.style.width="100%",p.style.boxSizing="border-box",p.style.cursor="grab",c.appendChild(p);const h=document.createElement("div");h.style.position="absolute",h.style.left="0",h.style.top="0",h.style.bottom="0",h.style.width="10px",h.style.cursor="ew-resize",p.appendChild(h);const l=document.createElement("div");l.style.position="absolute",l.style.right="0",l.style.top="0",l.style.bottom="0",l.style.width="10px",l.style.cursor="ew-resize",p.appendChild(l);const m=document.createElement("div");m.style.position="absolute",m.style.left="10px",m.style.right="10px",m.style.top="0",m.style.bottom="0",m.style.cursor="grab",p.appendChild(m),e.appendChild(a);let C=!1,F=null;const R=f=>{const x=Md(f),N=Kr(x.end-x.start,0,100);p.style.left=`${x.start}%`,p.style.width=`${N}%`},S=()=>{const f=c.getBoundingClientRect().width;return Number.isFinite(f)&&f>0?f:null},y=f=>{const x=S();if(x===null)return null;const N=f/x*100;return Number.isFinite(N)?N:null},b=(f,x)=>{try{f.setPointerCapture(x)}catch{}},w=(f,x)=>{try{f.releasePointerCapture(x)}catch{}},d=(f,x)=>{if(C||f.button!==0)return;f.preventDefault(),F==null||F(),F=null;const N=f.clientX,A=t.getRange(),P=f.currentTarget instanceof Element?f.currentTarget:p;b(P,f.pointerId),x==="pan-window"&&(p.style.cursor="grabbing",m.style.cursor="grabbing");const L=re=>{if(C||re.pointerId!==f.pointerId)return;re.preventDefault();const Y=y(re.clientX-N);if(Y!==null)switch(x){case"left-handle":{const W=Math.min(A.end,A.start+Y),Z=t;Z.setRangeAnchored?Z.setRangeAnchored(W,A.end,"end"):t.setRange(W,A.end);return}case"right-handle":{const W=Math.max(A.start,A.end+Y),Z=t;Z.setRangeAnchored?Z.setRangeAnchored(A.start,W,"start"):t.setRange(A.start,W);return}case"pan-window":{t.setRange(A.start+Y,A.end+Y);return}}};let B=!1;const V=()=>{B||(B=!0,window.removeEventListener("pointermove",L),window.removeEventListener("pointerup",_),window.removeEventListener("pointercancel",_),x==="pan-window"&&(p.style.cursor="grab",m.style.cursor="grab"),w(P,f.pointerId),F===V&&(F=null))},_=re=>{re.pointerId===f.pointerId&&V()};F=V,window.addEventListener("pointermove",L,{passive:!1}),window.addEventListener("pointerup",_,{passive:!0}),window.addEventListener("pointercancel",_,{passive:!0})},g=f=>d(f,"left-handle"),v=f=>d(f,"right-handle"),M=f=>d(f,"pan-window");h.addEventListener("pointerdown",g,{passive:!1}),l.addEventListener("pointerdown",v,{passive:!1}),m.addEventListener("pointerdown",M,{passive:!1});const I=t.onChange(f=>{C||R(f)});return R(t.getRange()),{update:f=>{if(C)return;c.style.background=f.backgroundColor,c.style.borderColor=f.axisLineColor,u.style.background=f.gridLineColor,p.style.background=f.gridLineColor,p.style.border=`1px solid ${f.axisTickColor}`,p.style.borderRadius="8px",p.style.boxSizing="border-box";const x=`1px solid ${f.axisLineColor}`;h.style.background=f.axisTickColor,h.style.borderRight=x,l.style.background=f.axisTickColor,l.style.borderLeft=x,m.style.background="transparent",m.style.backgroundImage="linear-gradient(90deg, rgba(255,255,255,0.0) 0, rgba(255,255,255,0.0) 42%, rgba(255,255,255,0.18) 42%, rgba(255,255,255,0.18) 46%, rgba(255,255,255,0.0) 46%, rgba(255,255,255,0.0) 54%, rgba(255,255,255,0.18) 54%, rgba(255,255,255,0.18) 58%, rgba(255,255,255,0.0) 58%, rgba(255,255,255,0.0) 100%)",m.style.mixBlendMode="normal"},dispose:()=>{if(!C){C=!0,F==null||F(),F=null;try{I()}catch{}h.removeEventListener("pointerdown",g),l.removeEventListener("pointerdown",v),m.removeEventListener("pointerdown",M),a.remove()}}}}let ki=null;async function Sd(){return ki||(ki=(async()=>{if(typeof window>"u")return{supported:!1,reason:"Not running in a browser environment (window is undefined)."};if(typeof navigator>"u")return{supported:!1,reason:"Navigator is not available in this environment."};if(!navigator.gpu)return{supported:!1,reason:"WebGPU API (navigator.gpu) is not available. Your browser does not support WebGPU."};try{let e=await navigator.gpu.requestAdapter({powerPreference:"high-performance"});return e||(e=await navigator.gpu.requestAdapter()),e?{supported:!0}:{supported:!1,reason:"No compatible WebGPU adapter found. This may occur if: (1) no GPU is available, (2) GPU drivers are outdated or incompatible, (3) running in a VM or headless environment, or (4) WebGPU is disabled in browser settings."}}catch(e){let t="Failed to request WebGPU adapter.";return e instanceof DOMException?(t=`Failed to request WebGPU adapter: ${e.name}`,e.message&&(t+=` - ${e.message}`)):e instanceof Error?t=`Failed to request WebGPU adapter: ${e.message}`:t=`Failed to request WebGPU adapter: ${String(e)}`,{supported:!1,reason:t}}})(),ki)}const zt=120,Nd=1e3/60,Td=1.5,Id=6,Pd=500,Ad=e=>Array.isArray(e),$n=e=>Array.isArray(e),er=e=>Ad(e)?{x:e[0],y:e[1]}:{x:e.x,y:e.y},Rd=e=>{if(Array.isArray(e))return e.length===0?[]:e.slice();const t=Xe(e);if(t===0)return[];const n=new Array(t);for(let i=0;i<t;i++){const r=Ee(e,i),o=We(e,i),s=mt(e,i);n[i]=s===void 0?[r,o]:[r,o,s]}return n},tr=e=>$n(e)?e[0]:e.timestamp,Xs=e=>$n(e)?e[2]:e.close,Ed=e=>{var t;return((t=e.dataZoom)==null?void 0:t.some(n=>(n==null?void 0:n.type)==="slider"))??!1},Vr=(e,t,n)=>Math.min(n,Math.max(t,e)),Dd=e=>{let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;for(let o=0;o<e.length;o++){const{x:s,y:a}=er(e[o]);!Number.isFinite(s)||!Number.isFinite(a)||(s<t&&(t=s),s>n&&(n=s),a<i&&(i=a),a>r&&(r=a))}return!Number.isFinite(t)||!Number.isFinite(n)||!Number.isFinite(i)||!Number.isFinite(r)?null:(t===n&&(n=t+1),i===r&&(r=i+1),{xMin:t,xMax:n,yMin:i,yMax:r})},Bd=(e,t)=>{if(t.length===0)return e;let n=e;if(!n){const a=Dd(t);if(!a)return e;n=a}let i=n.xMin,r=n.xMax,o=n.yMin,s=n.yMax;for(let a=0;a<t.length;a++){const{x:c,y:u}=er(t[a]);!Number.isFinite(c)||!Number.isFinite(u)||(c<i&&(i=c),c>r&&(r=c),u<o&&(o=u),u>s&&(s=u))}return i===r&&(r=i+1),o===s&&(s=o+1),{xMin:i,xMax:r,yMin:o,yMax:s}},Ld=(e,t)=>{if(t.length===0)return e;let n=(e==null?void 0:e.xMin)??Number.POSITIVE_INFINITY,i=(e==null?void 0:e.xMax)??Number.NEGATIVE_INFINITY,r=(e==null?void 0:e.yMin)??Number.POSITIVE_INFINITY,o=(e==null?void 0:e.yMax)??Number.NEGATIVE_INFINITY;for(let s=0;s<t.length;s++){const a=t[s],c=tr(a),u=$n(a)?a[3]:a.low,p=$n(a)?a[4]:a.high;!Number.isFinite(c)||!Number.isFinite(u)||!Number.isFinite(p)||(c<n&&(n=c),c>i&&(i=c),u<r&&(r=u),p>o&&(o=p))}return!Number.isFinite(n)||!Number.isFinite(i)||!Number.isFinite(r)||!Number.isFinite(o)?e:(n===i&&(i=n+1),r===o&&(o=r+1),{xMin:n,xMax:i,yMin:r,yMax:o})},Or=(e,t)=>{let n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY,r=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY;for(let s=0;s<e.length;s++){const a=e[s];if(a.type==="pie")continue;const c=(t==null?void 0:t[s])??null;if(c){const h=c;if(Number.isFinite(h.xMin)&&Number.isFinite(h.xMax)&&Number.isFinite(h.yMin)&&Number.isFinite(h.yMax)){h.xMin<n&&(n=h.xMin),h.xMax>i&&(i=h.xMax),h.yMin<r&&(r=h.yMin),h.yMax>o&&(o=h.yMax);continue}}const u=a.rawBounds??null;if(u){const h=u;if(Number.isFinite(h.xMin)&&Number.isFinite(h.xMax)&&Number.isFinite(h.yMin)&&Number.isFinite(h.yMax)){h.xMin<n&&(n=h.xMin),h.xMax>i&&(i=h.xMax),h.yMin<r&&(r=h.yMin),h.yMax>o&&(o=h.yMax);continue}}if(a.type==="candlestick"){const h=a.data;for(let l=0;l<h.length;l++){const m=h[l],C=tr(m),F=$n(m)?m[3]:m.low,R=$n(m)?m[4]:m.high;!Number.isFinite(C)||!Number.isFinite(F)||!Number.isFinite(R)||(C<n&&(n=C),C>i&&(i=C),F<r&&(r=F),R>o&&(o=R))}continue}const p=sn(a.data);p&&(p.xMin<n&&(n=p.xMin),p.xMax>i&&(i=p.xMax),p.yMin<r&&(r=p.yMin),p.yMax>o&&(o=p.yMax))}return!Number.isFinite(n)||!Number.isFinite(i)||!Number.isFinite(r)||!Number.isFinite(o)?{xMin:0,xMax:1,yMin:0,yMax:1}:(n===i&&(i=n+1),r===o&&(o=r+1),{xMin:n,xMax:i,yMin:r,yMax:o})},Ln=(e,t)=>{let n=e,i=t;if((!Number.isFinite(n)||!Number.isFinite(i))&&(n=0,i=1),n===i)i=n+1;else if(n>i){const r=n;n=i,i=r}return{min:n,max:i}},ci=(e,t)=>{if(typeof e=="number")return Number.isFinite(e)?e:null;if(typeof e!="string")return null;const n=e.trim();if(n.length===0)return null;if(n.endsWith("%")){const r=Number.parseFloat(n.slice(0,-1));return Number.isFinite(r)?r/100*t:null}const i=Number.parseFloat(n);return Number.isFinite(i)?i:null},Ys=(e,t,n)=>{const i=(e==null?void 0:e[0])??"50%",r=(e==null?void 0:e[1])??"50%",o=ci(i,t),s=ci(r,n);return{x:Number.isFinite(o)?o:t*.5,y:Number.isFinite(s)?s:n*.5}},kd=e=>Array.isArray(e),Hs=(e,t)=>{if(e==null)return{inner:0,outer:t*.7};if(kd(e)){const r=ci(e[0],t),o=ci(e[1],t),s=Math.max(0,Number.isFinite(r)?r:0),a=Math.max(s,Number.isFinite(o)?o:t*.7);return{inner:s,outer:Math.min(t,a)}}const n=ci(e,t),i=Math.max(0,Number.isFinite(n)?n:t*.7);return{inner:0,outer:Math.min(t,i)}};async function xa(e,t){var Lt;const n=await Sd();if(!n.supported){const k=n.reason||"Unknown reason";throw new Error(`ChartGPU: WebGPU is not available.
|
|
1126
|
+
Reason: ${k}
|
|
1127
|
+
Browser support: Chrome/Edge 113+, Safari 18+, Firefox not yet supported.
|
|
1128
|
+
Resources:
|
|
1129
|
+
- MDN WebGPU API: https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API
|
|
1130
|
+
- Browser compatibility: https://caniuse.com/webgpu
|
|
1131
|
+
- WebGPU specification: https://www.w3.org/TR/webgpu/
|
|
1132
|
+
- Check your system: https://webgpureport.org/`)}const i=document.createElement("canvas");i.style.display="block",i.style.width="100%",i.style.height="100%",e.appendChild(i);let r=!1,o=null,s=null,a=null,c=null,u=null,p=null,h=t,l=Ws(h),m=new Array(l.series.length).fill(null).map(()=>[]),C=new Array(l.series.length).fill(null),F=null;const R=()=>{m=new Array(l.series.length).fill(null).map(()=>[]),C=new Array(l.series.length).fill(null),F=null;for(let k=0;k<l.series.length;k++){const j=l.series[k];if(j.type!=="pie")if(j.type==="candlestick"){const ue=j.rawData??j.data;m[k]=ue.length===0?[]:ue.slice(),C[k]=j.rawBounds??null}else{const ue=j.rawData??j.data;m[k]=Rd(ue),C[k]=j.rawBounds??null??sn(ue)}}},S=()=>F||(F=l.series.map((k,j)=>k.type==="pie"?k:k.type==="candlestick"?{...k,data:m[j]??k.data}:{...k,data:m[j]??k.data}),F);R();let y=Or(l.series,C),b=null;const w={click:new Set,mouseover:new Set,mouseout:new Set,crosshairMove:new Set};let d=null,g=null,v=null;const M=new Set;let I=null,T=null,E=!0;const f=new Float64Array(zt);let x=0,N=0,A=0,P=0,L=0,B=0;const V=performance.now();let _=0,re=0;const Y=new Set,W=()=>w.mouseover.size>0||w.mouseout.size>0,Z=()=>w.click.size>0,oe=()=>{I!==null&&(cancelAnimationFrame(I),I=null)},ee=()=>{r||(E=!0,I===null&&(I=requestAnimationFrame(()=>{if(I=null,r)return;const k=performance.now();f[x]=k,x=(x+1)%zt,N<zt&&N++,A++,_>0&&(k-_>Nd*Td?(P++,L++,B=k):L=0),_=k,ge(!1),E&&(E=!1,s==null||s.render()),re=performance.now()-k;const ue=ke();for(const Se of Y)try{Se(ue)}catch(De){console.error("Error in performance update callback:",De)}})))},q=()=>{if(c)try{c()}finally{c=null}},de=()=>{p==null||p.dispose(),p=null},G=()=>{u==null||u.remove(),u=null},te=()=>{de(),G()},X=32,Q=8,ne=X+Q,H=()=>{if(u)return u;try{window.getComputedStyle(e).position==="static"&&(e.style.position="relative")}catch{}const k=document.createElement("div");return k.style.position="absolute",k.style.left="0",k.style.right="0",k.style.bottom="0",k.style.height=`${ne}px`,k.style.paddingTop=`${Q}px`,k.style.boxSizing="border-box",k.style.pointerEvents="auto",k.style.zIndex="5",e.appendChild(k),u=k,k},O=(k,j)=>{const ue=k.end-k.start;return!Number.isFinite(ue)||ue===0?.5:Vr((j-k.start)/ue,0,1)},se=()=>({getRange:()=>(s==null?void 0:s.getZoomRange())??{start:0,end:100},setRange:(Me,ve)=>{s==null||s.setZoomRange(Me,ve)},zoomIn:(Me,ve)=>{if(!Number.isFinite(Me)||!Number.isFinite(ve)||ve<=1)return;const Ce=s==null?void 0:s.getZoomRange();if(!Ce)return;const Fe=Vr(Me,0,100),yt=O(Ce,Fe),tt=(Ce.end-Ce.start)/ve,kt=Fe-yt*tt;s==null||s.setZoomRange(kt,kt+tt)},zoomOut:(Me,ve)=>{if(!Number.isFinite(Me)||!Number.isFinite(ve)||ve<=1)return;const Ce=s==null?void 0:s.getZoomRange();if(!Ce)return;const Fe=Vr(Me,0,100),yt=O(Ce,Fe),tt=(Ce.end-Ce.start)*ve,kt=Fe-yt*tt;s==null||s.setZoomRange(kt,kt+tt)},pan:Me=>{if(!Number.isFinite(Me))return;const ve=s==null?void 0:s.getZoomRange();ve&&(s==null||s.setZoomRange(ve.start+Me,ve.end+Me))},onChange:Me=>(s==null?void 0:s.onZoomRangeChange(Me))??(()=>{})}),ce=()=>{if(!Ed(h)){te();return}if(!s||!s.getZoomRange())return;const j=H();p||(p=Fd(j,se(),{height:X,marginTop:0})),p.update(l.theme)},le=()=>{q(),!r&&s&&(c=s.onInteractionXChange((k,j)=>{be("crosshairMove",{x:k,source:j})}))},me=()=>{if(r||!o||!o.initialized)return;const k=(s==null?void 0:s.getZoomRange())??null;q(),de(),s==null||s.dispose(),s=nd(o,l,{onRequestRender:ee}),a=o.preferredFormat,le(),k&&s.setZoomRange(k.start,k.end),ce()},ge=k=>{var St;if(r)return;const j=i.getBoundingClientRect(),ue=window.devicePixelRatio||1,Se=((St=o==null?void 0:o.device)==null?void 0:St.limits.maxTextureDimension2D)??8192,De=Math.min(Se,Math.max(1,Math.round(j.width*ue))),Ye=Math.min(Se,Math.max(1,Math.round(j.height*ue))),Me=i.width!==De||i.height!==Ye;Me&&(i.width=De,i.height=Ye);const ve=o==null?void 0:o.device,Ce=o==null?void 0:o.canvasContext,Fe=o==null?void 0:o.preferredFormat;let yt=!1;ve&&Ce&&Fe&&(Me||!T||T.width!==i.width||T.height!==i.height||T.format!==Fe)&&(Ce.configure({device:ve,format:Fe,alphaMode:"opaque"}),T={width:i.width,height:i.height,format:Fe},yt=!0,s&&a!==Fe&&me()),k&&(Me||yt)&&ee()},we=()=>ge(!0),it=k=>{const j=i.getBoundingClientRect();if(!(j.width>0)||!(j.height>0))return{match:null,isInGrid:!1};const ue=k.clientX-j.left,Se=k.clientY-j.top,De=l.grid.left,Ye=l.grid.top,Me=j.width-l.grid.left-l.grid.right,ve=j.height-l.grid.top-l.grid.bottom;if(!(Me>0)||!(ve>0))return{match:null,isInGrid:!1};const Ce=ue-De,Fe=Se-Ye;if(!(Ce>=0&&Ce<=Me&&Fe>=0&&Fe<=ve))return{match:null,isInGrid:!1};const St=l.xAxis.min??y.xMin,tt=l.xAxis.max??y.xMax,kt=l.yAxis.min??y.yMin,qt=l.yAxis.max??y.yMax,He=Ln(St,tt),Ut=(s==null?void 0:s.getZoomRange())??null,at=(()=>{if(!Ut)return He;const Pe=He.max-He.min;if(!Number.isFinite(Pe)||Pe===0)return He;const Be=Ut.start,je=Ut.end,xt=He.min+Be/100*Pe,lt=He.min+je/100*Pe;return Ln(xt,lt)})(),ct=Ln(kt,qt);if(!(b!==null&&b.rectWidthCss===j.width&&b.rectHeightCss===j.height&&b.plotWidthCss===Me&&b.plotHeightCss===ve&&b.xDomainMin===at.min&&b.xDomainMax===at.max&&b.yDomainMin===ct.min&&b.yDomainMax===ct.max)){const Pe=an().domain(at.min,at.max).range(0,Me),Be=an().domain(ct.min,ct.max).range(ve,0);b={rectWidthCss:j.width,rectHeightCss:j.height,plotWidthCss:Me,plotHeightCss:ve,xDomainMin:at.min,xDomainMax:at.max,yDomainMin:ct.min,yDomainMax:ct.max,xScale:Pe,yScale:Be}}const vt=b,Ot=(()=>{const Pe=.5*Math.min(Me,ve);if(!(Pe>0))return null;for(let Be=l.series.length-1;Be>=0;Be--){const je=l.series[Be];if(je.type!=="pie"||je.visible===!1)continue;const xt=je,lt=Ys(xt.center,Me,ve),cn=Hs(xt.radius,Pe),Pt=qr(Ce,Fe,{seriesIndex:Be,series:xt},lt,cn);if(!Pt)continue;const jt=Pt.slice.value;return{kind:"pie",seriesIndex:Pt.seriesIndex,dataIndex:Pt.dataIndex,sliceValue:typeof jt=="number"&&Number.isFinite(jt)?jt:0}}return null})();if(Ot)return{match:Ot,isInGrid:!0};for(let Pe=l.series.length-1;Pe>=0;Pe--){const Be=l.series[Pe];if((Be==null?void 0:Be.type)!=="candlestick"||Be.visible===!1)continue;const je=Be,xt=Yr(je,je.data,vt.xScale,Me),lt=Hr([je],Ce,Fe,vt.xScale,vt.yScale,xt);if(lt)return{match:{kind:"candlestick",seriesIndex:Pe,dataIndex:lt.dataIndex,point:lt.point},isInGrid:!0}}const Zt=Zi(S(),Ce,Fe,vt.xScale,vt.yScale);return{match:Zt?{kind:"cartesian",match:Zt}:null,isInGrid:!0}},Ke=()=>{if(N<2)return 0;const k=(x-N+zt)%zt;let j=0;for(let De=1;De<N;De++){const Ye=(k+De-1)%zt,Me=(k+De)%zt,ve=f[Me]-f[Ye];j+=ve}const ue=j/(N-1);return ue>0?1e3/ue:0},et=()=>{if(N<2)return{min:0,max:0,avg:0,p50:0,p95:0,p99:0};const k=(x-N+zt)%zt,j=new Array(N-1);let ue=Number.POSITIVE_INFINITY,Se=Number.NEGATIVE_INFINITY,De=0;for(let Fe=1;Fe<N;Fe++){const yt=(k+Fe-1)%zt,St=(k+Fe)%zt,tt=f[St]-f[yt];j[Fe-1]=tt,tt<ue&&(ue=tt),tt>Se&&(Se=tt),De+=tt}const Ye=De/j.length;j.sort((Fe,yt)=>Fe-yt);const Me=Math.floor(j.length*.5),ve=Math.floor(j.length*.95),Ce=Math.floor(j.length*.99);return{min:ue,max:Se,avg:Ye,p50:j[Me],p95:j[ve],p99:j[Ce]}},ke=()=>{const k=Ke(),j=et(),ue={enabled:!1,cpuTime:re,gpuTime:0},Se={used:0,peak:0,allocated:0},De={totalDrops:P,consecutiveDrops:L,lastDropTimestamp:B},Ye=performance.now()-V;return{fps:k,frameTimeStats:j,gpuTiming:ue,memory:Se,frameDrops:De,totalFrames:A,elapsedTime:Ye}},he=(k,j)=>{if(!k)return{seriesIndex:null,dataIndex:null,value:null,seriesName:null,event:j};const ue=k.kind==="cartesian"?k.match.seriesIndex:k.seriesIndex,Se=k.kind==="cartesian"?k.match.dataIndex:k.dataIndex,De=l.series[ue],Ye=(De==null?void 0:De.name)??null,Me=Ye&&Ye.trim().length>0?Ye:null;if(k.kind==="pie")return{seriesIndex:ue,dataIndex:Se,value:[0,k.sliceValue],seriesName:Me,event:j};if(k.kind==="candlestick"){const Fe=tr(k.point),yt=Xs(k.point);return{seriesIndex:ue,dataIndex:Se,value:[Fe,yt],seriesName:Me,event:j}}const{x:ve,y:Ce}=er(k.match.point);return{seriesIndex:ue,dataIndex:Se,value:[ve,Ce],seriesName:Me,event:j}},be=(k,j)=>{if(!r)for(const ue of w[k])ue(j)},Ge=(k,j)=>{const ue=v;if(v=k,ue===null&&k===null)return;if(ue===null&&k!==null){be("mouseover",he(k,j));return}if(ue!==null&&k===null){be("mouseout",he(ue,j));return}if(ue===null||k===null)return;const Se=ue.kind==="cartesian"?ue.match.seriesIndex:ue.seriesIndex,De=ue.kind==="cartesian"?ue.match.dataIndex:ue.dataIndex,Ye=k.kind==="cartesian"?k.match.seriesIndex:k.seriesIndex,Me=k.kind==="cartesian"?k.match.dataIndex:k.dataIndex;Se===Ye&&De===Me||(be("mouseout",he(ue,j)),be("mouseover",he(k,j)))},ze=k=>{d&&k.isPrimary&&k.pointerId===d.pointerId&&(d=null)},rt=k=>{if(r||!W())return;const{match:j,isInGrid:ue}=it(k);if(!ue){Ge(null,k);return}Ge(j,k)},Ze=k=>{r||!W()&&!d||(ze(k),Ge(null,k))},ht=k=>{r||!W()&&!d||(ze(k),Ge(null,k))},gt=k=>{if(!r&&!(!W()&&!d&&g!==k.pointerId)){if(g===k.pointerId){g=null;return}ze(k),Ge(null,k)}},ot=k=>{if(!r&&Z()&&k.isPrimary&&!(k.pointerType==="mouse"&&k.button!==0)){d={pointerId:k.pointerId,startClientX:k.clientX,startClientY:k.clientY,startTimeMs:k.timeStamp};try{i.setPointerCapture(k.pointerId)}catch{}}},Ft=k=>{if(r||!Z()||!k.isPrimary||!d||k.pointerId!==d.pointerId)return;const j=k.timeStamp-d.startTimeMs,ue=k.clientX-d.startClientX,Se=k.clientY-d.startClientY,De=ue*ue+Se*Se;d=null;try{i.hasPointerCapture(k.pointerId)&&(g=k.pointerId,i.releasePointerCapture(k.pointerId))}catch{}const Ye=Id;if(!(j<=Pd&&De<=Ye*Ye))return;const{match:ve}=it(k);be("click",he(ve,k))};i.addEventListener("pointermove",rt,{passive:!0}),i.addEventListener("pointerleave",Ze,{passive:!0}),i.addEventListener("pointercancel",ht,{passive:!0}),i.addEventListener("lostpointercapture",gt,{passive:!0}),i.addEventListener("pointerdown",ot,{passive:!0}),i.addEventListener("pointerup",Ft,{passive:!0});const It=()=>{if(!r){r=!0;try{oe(),te(),q(),s==null||s.dispose(),s=null,a=null,o==null||o.destroy()}finally{d=null,g=null,v=null,b=null,i.removeEventListener("pointermove",rt),i.removeEventListener("pointerleave",Ze),i.removeEventListener("pointercancel",ht),i.removeEventListener("lostpointercapture",gt),i.removeEventListener("pointerdown",ot),i.removeEventListener("pointerup",Ft),w.click.clear(),w.mouseover.clear(),w.mouseout.clear(),w.crosshairMove.clear(),o=null,i.remove()}}},Bt={get options(){return h},get disposed(){return r},setOption(k){r||(h=k,l=Ws(k),s==null||s.setOptions(l),R(),y=Or(l.series,C),b=null,ce(),ee())},appendData(k,j){if(r||!Number.isFinite(k)||k<0||k>=l.series.length||!j||j.length===0)return;const ue=l.series[k];if(ue.type==="pie"){M.has(k)||(M.add(k),console.warn(`ChartGPU.appendData(${k}, ...): pie series are not supported by streaming append. Use setOption(...) to replace pie data.`));return}if(s==null||s.appendData(k,j),ue.type==="candlestick"){const Se=m[k]??[];Se.push(...j),m[k]=Se,C[k]=Ld(C[k],j)}else{const Se=m[k]??[];Se.push(...j),m[k]=Se,C[k]=Bd(C[k],j)}y=Or(l.series,C),F=null,b=null,ee()},resize:we,dispose:It,on(k,j){r||w[k].add(j)},off(k,j){w[k].delete(j)},getInteractionX(){return r?null:(s==null?void 0:s.getInteractionX())??null},setInteractionX(k,j){r||s==null||s.setInteractionX(k,j)},setCrosshairX(k,j){r||s==null||s.setInteractionX(k,j)},onInteractionXChange(k){return r?()=>{}:(s==null?void 0:s.onInteractionXChange(k))??(()=>{})},getZoomRange(){return r?null:(s==null?void 0:s.getZoomRange())??null},setZoomRange(k,j){r||s==null||s.setZoomRange(k,j)},getPerformanceMetrics(){return r?null:ke()},getPerformanceCapabilities(){return r?null:{gpuTimingSupported:!1,highResTimerSupported:typeof performance<"u"&&typeof performance.now=="function",performanceMetricsSupported:!0}},onPerformanceUpdate(k){return r?()=>{}:(Y.add(k),()=>{Y.delete(k)})},hitTest(k){const j=i.getBoundingClientRect(),ue=k.clientX-j.left,Se=k.clientY-j.top;if(r||!(j.width>0)||!(j.height>0))return{isInGrid:!1,canvasX:ue,canvasY:Se,gridX:0,gridY:0,match:null};const De=l.grid.left,Ye=l.grid.top,Me=j.width-l.grid.left-l.grid.right,ve=j.height-l.grid.top-l.grid.bottom,Ce=ue-De,Fe=Se-Ye;if(!(Me>0)||!(ve>0))return{isInGrid:!1,canvasX:ue,canvasY:Se,gridX:Ce,gridY:Fe,match:null};if(!(Ce>=0&&Ce<=Me&&Fe>=0&&Fe<=ve))return{isInGrid:!1,canvasX:ue,canvasY:Se,gridX:Ce,gridY:Fe,match:null};const St=l.xAxis.min??y.xMin,tt=l.xAxis.max??y.xMax,kt=l.yAxis.min??y.yMin,qt=l.yAxis.max??y.yMax,He=Ln(St,tt),Ut=(s==null?void 0:s.getZoomRange())??null,at=(()=>{if(!Ut)return He;const Pe=He.max-He.min;if(!Number.isFinite(Pe)||Pe===0)return He;const Be=Ut.start,je=Ut.end,xt=He.min+Be/100*Pe,lt=He.min+je/100*Pe;return Ln(xt,lt)})(),ct=Ln(kt,qt);if(!(b!==null&&b.rectWidthCss===j.width&&b.rectHeightCss===j.height&&b.plotWidthCss===Me&&b.plotHeightCss===ve&&b.xDomainMin===at.min&&b.xDomainMax===at.max&&b.yDomainMin===ct.min&&b.yDomainMax===ct.max)){const Pe=an().domain(at.min,at.max).range(0,Me),Be=an().domain(ct.min,ct.max).range(ve,0);b={rectWidthCss:j.width,rectHeightCss:j.height,plotWidthCss:Me,plotHeightCss:ve,xDomainMin:at.min,xDomainMax:at.max,yDomainMin:ct.min,yDomainMax:ct.max,xScale:Pe,yScale:Be}}const vt=b,Ot=(()=>{const Pe=.5*Math.min(Me,ve);if(!(Pe>0))return null;for(let Be=l.series.length-1;Be>=0;Be--){const je=l.series[Be];if(je.type!=="pie")continue;const xt=je,lt=Ys(xt.center,Me,ve),cn=Hs(xt.radius,Pe),Pt=qr(Ce,Fe,{seriesIndex:Be,series:xt},lt,cn);if(!Pt)continue;const jt=Pt.slice.value;return{kind:"pie",seriesIndex:Pt.seriesIndex,dataIndex:Pt.dataIndex,sliceValue:typeof jt=="number"&&Number.isFinite(jt)?jt:0}}return null})();if(Ot)return{isInGrid:!0,canvasX:ue,canvasY:Se,gridX:Ce,gridY:Fe,match:{kind:"pie",seriesIndex:Ot.seriesIndex,dataIndex:Ot.dataIndex,value:[0,Ot.sliceValue]}};for(let Pe=l.series.length-1;Pe>=0;Pe--){const Be=l.series[Pe];if((Be==null?void 0:Be.type)!=="candlestick")continue;const je=Be,xt=Yr(je,je.data,vt.xScale,Me),lt=Hr([je],Ce,Fe,vt.xScale,vt.yScale,xt);if(!lt)continue;const cn=tr(lt.point),Pt=Xs(lt.point);return{isInGrid:!0,canvasX:ue,canvasY:Se,gridX:Ce,gridY:Fe,match:{kind:"candlestick",seriesIndex:Pe,dataIndex:lt.dataIndex,value:[cn,Pt]}}}const Zt=Zi(S(),Ce,Fe,vt.xScale,vt.yScale);if(Zt){const{x:Pe,y:Be}=er(Zt.point);return{isInGrid:!0,canvasX:ue,canvasY:Se,gridX:Ce,gridY:Fe,match:{kind:"cartesian",seriesIndex:Zt.seriesIndex,dataIndex:Zt.dataIndex,value:[Pe,Be]}}}return{isInGrid:!0,canvasX:ue,canvasY:Se,gridX:Ce,gridY:Fe,match:null}}};try{ge(!1);try{o=await nr.create(i)}catch(k){const j=k instanceof Error?k.message:String(k);throw new Error(`ChartGPU: WebGPU is not available.
|
|
1133
|
+
Reason: ${j}
|
|
1134
|
+
Browser support: Chrome/Edge 113+, Safari 18+, Firefox not yet supported.
|
|
1135
|
+
Resources:
|
|
1136
|
+
- MDN WebGPU API: https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API
|
|
1137
|
+
- Browser compatibility: https://caniuse.com/webgpu
|
|
1138
|
+
- WebGPU specification: https://www.w3.org/TR/webgpu/
|
|
1139
|
+
- Check your system: https://webgpureport.org/`)}return(Lt=o.device)==null||Lt.lost.then(k=>{r||(k.reason!=="destroyed"&&console.warn("WebGPU device lost:",k),It())}),ge(!1),me(),ce(),ee(),Bt}catch(k){throw Bt.dispose(),k}}const Ud={create:xa};function _d(e){const t=Symbol("ChartGPU.connectCharts");let n=!1;const i=[],r=(o,s)=>{for(const a of e)a!==o&&(a.disposed||a.setCrosshairX(s,t))};for(const o of e){if(o.disposed)continue;const s=c=>{n||c.source!==t&&(o.disposed||r(o,c.x))};o.on("crosshairMove",s);const a=()=>o.off("crosshairMove",s);i.push(a)}return()=>{if(!n){n=!0;for(const o of i)o();i.length=0;for(const o of e)o.disposed||o.setCrosshairX(null,t)}}}function Gd(e,t,n={}){const i=n.lineTolerance??20,r=n.textTolerance??8,o=n.pointTolerance??16;let s=new Map,a=new Map,c=!1;const u=f=>Array.isArray(f),p=f=>Array.isArray(f),h=f=>u(f)?f[0]:f.x,l=f=>u(f)?f[1]:f.y,m=f=>p(f)?f[0]:f.timestamp,C=f=>p(f)?f[2]:f.high,F=f=>p(f)?f[3]:f.low;function R(){var P,L;const f=e.options;let x=(P=f.xAxis)==null?void 0:P.min,N=(L=f.xAxis)==null?void 0:L.max;if(x===void 0||N===void 0){const B=f.series??[];let V=Number.POSITIVE_INFINITY,_=Number.NEGATIVE_INFINITY;for(const re of B)if(re.type!=="pie")if(re.type==="candlestick"){const Y=re.data;for(const W of Y){const Z=m(W);Z<V&&(V=Z),Z>_&&(_=Z)}}else{const Y=re.data;for(const W of Y){const Z=h(W);Z<V&&(V=Z),Z>_&&(_=Z)}}x===void 0&&(x=Number.isFinite(V)?V:0),N===void 0&&(N=Number.isFinite(_)?_:100)}const A=e.getZoomRange();if(A){const B=N-x,V=x+A.start/100*B,_=x+A.end/100*B;return{min:V,max:_}}return{min:x,max:N}}function S(){var A,P;const f=e.options;let x=(A=f.yAxis)==null?void 0:A.min,N=(P=f.yAxis)==null?void 0:P.max;if(x===void 0||N===void 0){const L=f.series??[];let B=Number.POSITIVE_INFINITY,V=Number.NEGATIVE_INFINITY;for(const _ of L)if(_.type!=="pie")if(_.type==="candlestick"){const re=_.data;for(const Y of re){const W=C(Y),Z=F(Y);W>V&&(V=W),Z<B&&(B=Z)}}else{const re=_.data;for(const Y of re){const W=l(Y);W<B&&(B=W),W>V&&(V=W)}}x===void 0&&(x=Number.isFinite(B)?B:0),N===void 0&&(N=Number.isFinite(V)?V:100)}return{min:x,max:N}}function y(f,x){const N=e.options,A=t.getBoundingClientRect(),P=N.grid??{left:60,right:20,top:40,bottom:40},L=A.width,B=A.height,V=P.left??60,_=L-(P.right??20),re=P.top??40,Y=B-(P.bottom??40),W=_-V,Z=Y-re,oe=N.xAxis,ee=N.yAxis;let q=0,de=0;if(f!==void 0&&oe)if(oe.type==="category"&&Array.isArray(oe.data)){const G=oe.data,te=G.indexOf(String(f));if(te>=0){const X=te/(G.length-1||1);q=V+X*W}}else{const G=R(),te=G.min,X=G.max,Q=(f-te)/(X-te||1);q=V+Q*W}if(x!==void 0&&ee){const G=S(),te=G.min,X=G.max,Q=(x-te)/(X-te||1);de=Y-Q*Z}return{x:q,y:de}}function b(f,x){const N=e.options,A=t.getBoundingClientRect(),P=N.grid??{left:60,right:20,top:40,bottom:40},L=A.width,B=A.height,V=P.left??60,_=L-(P.right??20),re=P.top??40,Y=B-(P.bottom??40),W=_-V,Z=Y-re;return{x:V+f*W,y:re+x*Z}}function w(f){s.clear(),f.forEach((x,N)=>{const A={};if(x.type==="lineX"&&x.x!==void 0){const{x:P}=y(x.x,void 0);A.canvasX=P}else if(x.type==="lineY"&&x.y!==void 0){const{y:P}=y(void 0,x.y);A.canvasY=P}else if(x.type==="point"&&x.x!==void 0&&x.y!==void 0){const{x:P,y:L}=y(x.x,x.y);A.canvasX=P,A.canvasY=L}else if(x.type==="text"){const P=x.position;if(P.space==="plot"){const{x:L,y:B}=b(P.x,P.y);A.canvasX=L,A.canvasY=B}else if(P.space==="data"){const{x:L,y:B}=y(P.x,P.y);A.canvasX=L,A.canvasY=B}}s.set(N,A)}),c=!0}function d(f,x,N,A){return N!==void 0?Math.abs(f-N):A!==void 0?Math.abs(x-A):1/0}function g(f,x,N,A){const P=f-N,L=x-A;return Math.sqrt(P*P+L*L)}function v(f,x,N,A){return f>=N.left-A&&f<=N.right+A&&x>=N.top-A&&x<=N.bottom+A}function M(f,x){const N=e.options.annotations??[];if(N.length===0)return null;c||w(N);let A=null,P=1/0;for(let L=0;L<N.length;L++){const B=N[L],V=s.get(L);if(V){if(B.type==="lineX"&&V.canvasX!==void 0){const _=d(f,x,V.canvasX,void 0);_<=i&&_<P&&(P=_,A={annotationIndex:L,annotation:B,hitType:"line",distanceCssPx:_})}else if(B.type==="lineY"&&V.canvasY!==void 0){const _=d(f,x,void 0,V.canvasY);_<=i&&_<P&&(P=_,A={annotationIndex:L,annotation:B,hitType:"line",distanceCssPx:_})}}}for(let L=0;L<N.length;L++){const B=N[L],V=a.get(L);if(B.type==="text"&&V&&v(f,x,V,r)){const _=V.left+V.width/2,re=V.top+V.height/2,Y=g(f,x,_,re);Y<P&&(P=Y,A={annotationIndex:L,annotation:B,hitType:"text",distanceCssPx:Y})}}for(let L=0;L<N.length;L++){const B=N[L],V=s.get(L);if(V&&B.type==="point"&&V.canvasX!==void 0&&V.canvasY!==void 0){const _=g(f,x,V.canvasX,V.canvasY);_<=o&&_<P&&(P=_,A={annotationIndex:L,annotation:B,hitType:"point",distanceCssPx:_})}}return A}function I(f){a=new Map(f)}function T(){c=!1}function E(){s.clear(),a.clear()}return{hitTest:M,updateTextBounds:I,invalidateCache:T,dispose:E}}function zd(e,t,n){let i=null;const r=v=>Array.isArray(v),o=v=>Array.isArray(v),s=v=>r(v)?v[0]:v.x,a=v=>r(v)?v[1]:v.y,c=v=>o(v)?v[0]:v.timestamp,u=v=>o(v)?v[2]:v.high,p=v=>o(v)?v[3]:v.low;function h(){var E,f;const v=e.options;let M=(E=v.xAxis)==null?void 0:E.min,I=(f=v.xAxis)==null?void 0:f.max;if(M===void 0||I===void 0){const x=v.series??[];let N=Number.POSITIVE_INFINITY,A=Number.NEGATIVE_INFINITY;for(const P of x)if(P.type!=="pie")if(P.type==="candlestick"){const L=P.data;for(const B of L){const V=c(B);V<N&&(N=V),V>A&&(A=V)}}else{const L=P.data;for(const B of L){const V=s(B);V<N&&(N=V),V>A&&(A=V)}}M===void 0&&(M=Number.isFinite(N)?N:0),I===void 0&&(I=Number.isFinite(A)?A:100)}const T=e.getZoomRange();if(T){const x=I-M,N=M+T.start/100*x,A=M+T.end/100*x;return{min:N,max:A}}return{min:M,max:I}}function l(){var T,E;const v=e.options;let M=(T=v.yAxis)==null?void 0:T.min,I=(E=v.yAxis)==null?void 0:E.max;if(M===void 0||I===void 0){const f=v.series??[];let x=Number.POSITIVE_INFINITY,N=Number.NEGATIVE_INFINITY;for(const A of f)if(A.type!=="pie")if(A.type==="candlestick"){const P=A.data;for(const L of P){const B=u(L),V=p(L);B>N&&(N=B),V<x&&(x=V)}}else{const P=A.data;for(const L of P){const B=a(L);B<x&&(x=B),B>N&&(N=B)}}M===void 0&&(M=Number.isFinite(x)?x:0),I===void 0&&(I=Number.isFinite(N)?N:100)}return{min:M,max:I}}function m(v,M){const I=e.options,T=t.getBoundingClientRect(),E=I.grid??{left:60,right:20,top:40,bottom:40},f=T.width,x=T.height,N=E.left??60,A=f-(E.right??20),P=E.top??40,L=x-(E.bottom??40),B=A-N,V=L-P,_=I.xAxis,re=I.yAxis;let Y=0,W=0;if(_){const Z=(v-N)/B;if(_.type==="category"&&Array.isArray(_.data)){const oe=_.data,ee=Math.round(Z*(oe.length-1||1));Y=oe[Math.max(0,Math.min(ee,oe.length-1))]}else{const oe=h();Y=oe.min+Z*(oe.max-oe.min)}}if(re){const Z=(L-M)/V,oe=l();W=oe.min+Z*(oe.max-oe.min)}return{x:Y,y:W}}function C(v,M){const I=e.options,T=t.getBoundingClientRect(),E=I.grid??{left:60,right:20,top:40,bottom:40},f=T.width,x=T.height,N=E.left??60,A=f-(E.right??20),P=E.top??40,L=x-(E.bottom??40),B=A-N,V=L-P,_=(v-N)/B,re=(M-P)/V;return{x:Math.max(0,Math.min(1,_)),y:Math.max(0,Math.min(1,re))}}function F(v){if(!i)return;v.preventDefault();const M=t.getBoundingClientRect(),I=v.clientX-M.left,T=v.clientY-M.top,E=i.annotation,f={};if(E.type==="lineX"){const{x}=m(I,0);f.x=x}else if(E.type==="lineY"){const{y:x}=m(0,T);f.y=x}else if(E.type==="text"){const x=E.position.space;if(x==="plot"){const{x:N,y:A}=C(I,T);f.position={space:x,x:N,y:A}}else{const{x:N,y:A}=m(I,T);f.position={space:x,x:N,y:A}}}else if(E.type==="point"){const{x,y:N}=m(I,T);f.x=x,f.y=N}n.onDragMove(i.annotationIndex,f)}function R(v){if(!i)return;const M=t.getBoundingClientRect(),I=v.clientX-M.left,T=v.clientY-M.top,E=i.annotation,f={};if(E.type==="lineX"){const{x}=m(I,0);f.x=x}else if(E.type==="lineY"){const{y:x}=m(0,T);f.y=x}else if(E.type==="text"){const x=E.position.space;if(x==="plot"){const{x:N,y:A}=C(I,T);f.position={space:x,x:N,y:A}}else{const{x:N,y:A}=m(I,T);f.position={space:x,x:N,y:A}}}else if(E.type==="point"){const{x,y:N}=m(I,T);f.x=x,f.y=N}n.onDragEnd(i.annotationIndex,f),b()}function S(){i&&(n.onDragCancel(),b())}function y(v){i&&v.key==="Escape"&&(v.preventDefault(),S())}function b(){if(i){if(window.removeEventListener("pointermove",F),window.removeEventListener("pointerup",R),window.removeEventListener("pointercancel",S),document.removeEventListener("keydown",y),i.pointerId!==null)try{t.releasePointerCapture(i.pointerId)}catch{}document.body.style.cursor="",i=null}}function w(v,M,I,T){i&&b(),i={annotationIndex:v,annotation:M,startPointerX:I,startPointerY:T,pointerId:null},M.type==="lineX"?document.body.style.cursor="ew-resize":M.type==="lineY"?document.body.style.cursor="ns-resize":document.body.style.cursor="grabbing",window.addEventListener("pointermove",F,{passive:!1}),window.addEventListener("pointerup",R,{passive:!0}),window.addEventListener("pointercancel",S,{passive:!0}),document.addEventListener("keydown",y,{passive:!1}),n.onDragMove(v,{style:{...M.style,opacity:.7}})}function d(){return i!==null}function g(){b()}return{startDrag:w,isDragging:d,dispose:g}}const Vd=["#ef4444","#f97316","#eab308","#22c55e","#06b6d4","#3b82f6","#8b5cf6","#ec4899","#ffffff","#94a3b8","#64748b","#1e293b"];function Od(e,t={}){const n=t.palette??Vd,i=t.zIndex??1e3;let r=null,o=null,s=null,a=null,c="create";function u(){const f=document.createElement("div");return f.style.cssText=`
|
|
1140
|
+
position: fixed;
|
|
1141
|
+
top: 0;
|
|
1142
|
+
left: 0;
|
|
1143
|
+
right: 0;
|
|
1144
|
+
bottom: 0;
|
|
1145
|
+
background: rgba(0, 0, 0, 0.4);
|
|
1146
|
+
z-index: ${i+1};
|
|
1147
|
+
display: flex;
|
|
1148
|
+
align-items: center;
|
|
1149
|
+
justify-content: center;
|
|
1150
|
+
`,f.addEventListener("click",x=>{x.target===f&&g()}),f}function p(){const f=document.createElement("div");return f.style.cssText=`
|
|
1151
|
+
width: 320px;
|
|
1152
|
+
background: #1a1a2e;
|
|
1153
|
+
border: 1px solid #333;
|
|
1154
|
+
border-radius: 8px;
|
|
1155
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.7);
|
|
1156
|
+
padding: 20px;
|
|
1157
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
1158
|
+
color: #e0e0e0;
|
|
1159
|
+
`,f}function h(f,x){const N=document.createElement("div");N.style.cssText=`
|
|
1160
|
+
margin-bottom: 16px;
|
|
1161
|
+
`;const A=document.createElement("label");return A.textContent=f,A.style.cssText=`
|
|
1162
|
+
display: block;
|
|
1163
|
+
margin-bottom: 8px;
|
|
1164
|
+
font-size: 13px;
|
|
1165
|
+
font-weight: 500;
|
|
1166
|
+
color: #b0b0b0;
|
|
1167
|
+
`,N.appendChild(A),N.appendChild(x),N}function l(f,x,N=""){const A=document.createElement("input");return A.type="text",A.placeholder=f,A.maxLength=x,A.value=N,A.style.cssText=`
|
|
1168
|
+
width: 100%;
|
|
1169
|
+
padding: 8px 12px;
|
|
1170
|
+
background: #2a2a3e;
|
|
1171
|
+
border: 1px solid #444;
|
|
1172
|
+
border-radius: 4px;
|
|
1173
|
+
color: #e0e0e0;
|
|
1174
|
+
font-size: 14px;
|
|
1175
|
+
box-sizing: border-box;
|
|
1176
|
+
`,A.addEventListener("focus",()=>{A.style.borderColor="#3b82f6"}),A.addEventListener("blur",()=>{A.style.borderColor="#444"}),A}function m(f,x,N=""){const A=document.createElement("textarea");return A.placeholder=f,A.maxLength=x,A.value=N,A.rows=3,A.style.cssText=`
|
|
1177
|
+
width: 100%;
|
|
1178
|
+
padding: 8px 12px;
|
|
1179
|
+
background: #2a2a3e;
|
|
1180
|
+
border: 1px solid #444;
|
|
1181
|
+
border-radius: 4px;
|
|
1182
|
+
color: #e0e0e0;
|
|
1183
|
+
font-size: 14px;
|
|
1184
|
+
box-sizing: border-box;
|
|
1185
|
+
resize: vertical;
|
|
1186
|
+
font-family: inherit;
|
|
1187
|
+
`,A.addEventListener("focus",()=>{A.style.borderColor="#3b82f6"}),A.addEventListener("blur",()=>{A.style.borderColor="#444"}),A}function C(f){const x=document.createElement("div");x.style.cssText=`
|
|
1188
|
+
display: grid;
|
|
1189
|
+
grid-template-columns: repeat(4, 1fr);
|
|
1190
|
+
gap: 8px;
|
|
1191
|
+
`;let N=f;return n.forEach(A=>{const P=document.createElement("button");P.type="button",P.dataset.color=A,P.style.cssText=`
|
|
1192
|
+
position: relative;
|
|
1193
|
+
width: 100%;
|
|
1194
|
+
aspect-ratio: 1;
|
|
1195
|
+
background: ${A};
|
|
1196
|
+
border: none;
|
|
1197
|
+
border-radius: 4px;
|
|
1198
|
+
cursor: pointer;
|
|
1199
|
+
transition: transform 0.15s ease-out, box-shadow 0.15s ease-out;
|
|
1200
|
+
box-shadow: ${A===N?"inset 0 0 0 2px #ffffff, inset 0 0 0 3px rgba(0, 0, 0, 0.3), 0 2px 8px rgba(0, 0, 0, 0.3)":"inset 0 0 0 1px rgba(255, 255, 255, 0.1)"};
|
|
1201
|
+
transform: ${A===N?"scale(1.05)":"scale(1)"};
|
|
1202
|
+
`;const L=document.createElementNS("http://www.w3.org/2000/svg","svg");L.setAttribute("viewBox","0 0 24 24"),L.setAttribute("fill","none"),L.style.cssText=`
|
|
1203
|
+
position: absolute;
|
|
1204
|
+
top: 50%;
|
|
1205
|
+
left: 50%;
|
|
1206
|
+
transform: translate(-50%, -50%);
|
|
1207
|
+
width: 60%;
|
|
1208
|
+
height: 60%;
|
|
1209
|
+
pointer-events: none;
|
|
1210
|
+
opacity: ${A===N?"1":"0"};
|
|
1211
|
+
transition: opacity 0.15s ease-out;
|
|
1212
|
+
`;const B=document.createElementNS("http://www.w3.org/2000/svg","path");B.setAttribute("d","M20 6L9 17l-5-5"),B.setAttribute("stroke","#ffffff"),B.setAttribute("stroke-width","3"),B.setAttribute("stroke-linecap","round"),B.setAttribute("stroke-linejoin","round"),B.style.cssText=`
|
|
1213
|
+
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.8)) drop-shadow(0 0 1px rgba(0, 0, 0, 0.9));
|
|
1214
|
+
`,L.appendChild(B),P.appendChild(L),P.addEventListener("click",()=>{N=A,Array.from(x.children).forEach(V=>{const _=V,Y=_.dataset.color===A;_.style.boxShadow=Y?"inset 0 0 0 2px #ffffff, inset 0 0 0 3px rgba(0, 0, 0, 0.3), 0 2px 8px rgba(0, 0, 0, 0.3)":"inset 0 0 0 1px rgba(255, 255, 255, 0.1)",_.style.transform=Y?"scale(1.05)":"scale(1)";const W=_.querySelector("svg");W&&(W.style.opacity=Y?"1":"0")})}),P.addEventListener("mouseenter",()=>{A!==N&&(P.style.transform="scale(1.1)",P.style.boxShadow="inset 0 0 0 2px rgba(255, 255, 255, 0.2), 0 4px 12px rgba(0, 0, 0, 0.4)")}),P.addEventListener("mouseleave",()=>{A!==N&&(P.style.transform="scale(1)",P.style.boxShadow="inset 0 0 0 1px rgba(255, 255, 255, 0.1)")}),x.appendChild(P)}),{container:x,getValue:()=>N}}function F(f,x){const N=document.createElement("select");return N.style.cssText=`
|
|
1215
|
+
width: 100%;
|
|
1216
|
+
padding: 8px 12px;
|
|
1217
|
+
background: #2a2a3e;
|
|
1218
|
+
border: 1px solid #444;
|
|
1219
|
+
border-radius: 4px;
|
|
1220
|
+
color: #e0e0e0;
|
|
1221
|
+
font-size: 14px;
|
|
1222
|
+
cursor: pointer;
|
|
1223
|
+
`,f.forEach(A=>{const P=document.createElement("option");P.value=A.value,P.textContent=A.label,A.value===x&&(P.selected=!0),N.appendChild(P)}),{container:N,getValue:()=>N.value}}function R(f,x,N,A,P=""){const L=document.createElement("div");L.style.cssText=`
|
|
1224
|
+
display: flex;
|
|
1225
|
+
align-items: center;
|
|
1226
|
+
gap: 12px;
|
|
1227
|
+
`;const B=document.createElement("input");B.type="range",B.min=String(f),B.max=String(x),B.step=String(N),B.value=String(A),B.style.cssText=`
|
|
1228
|
+
flex: 1;
|
|
1229
|
+
cursor: pointer;
|
|
1230
|
+
`;const V=document.createElement("span");return V.textContent=`${A}${P}`,V.style.cssText=`
|
|
1231
|
+
min-width: 40px;
|
|
1232
|
+
text-align: right;
|
|
1233
|
+
font-size: 13px;
|
|
1234
|
+
color: #b0b0b0;
|
|
1235
|
+
`,B.addEventListener("input",()=>{V.textContent=`${B.value}${P}`}),L.appendChild(B),L.appendChild(V),{container:L,getValue:()=>parseFloat(B.value)}}function S(f,x,N){const A=document.createElement("div");A.style.cssText=`
|
|
1236
|
+
display: flex;
|
|
1237
|
+
justify-content: flex-end;
|
|
1238
|
+
gap: 12px;
|
|
1239
|
+
margin-top: 24px;
|
|
1240
|
+
`;const P=document.createElement("button");P.type="button",P.textContent="Cancel",P.style.cssText=`
|
|
1241
|
+
padding: 8px 16px;
|
|
1242
|
+
background: transparent;
|
|
1243
|
+
border: 1px solid #444;
|
|
1244
|
+
border-radius: 4px;
|
|
1245
|
+
color: #888;
|
|
1246
|
+
font-size: 14px;
|
|
1247
|
+
cursor: pointer;
|
|
1248
|
+
transition: background 0.15s;
|
|
1249
|
+
`,P.addEventListener("mouseenter",()=>{P.style.background="#2a2a3e"}),P.addEventListener("mouseleave",()=>{P.style.background="transparent"}),P.addEventListener("click",N);const L=document.createElement("button");return L.type="button",L.textContent=f,L.style.cssText=`
|
|
1250
|
+
padding: 8px 16px;
|
|
1251
|
+
background: #2a2a3e;
|
|
1252
|
+
border: 1px solid #444;
|
|
1253
|
+
border-radius: 4px;
|
|
1254
|
+
color: #e0e0e0;
|
|
1255
|
+
font-size: 14px;
|
|
1256
|
+
font-weight: 500;
|
|
1257
|
+
cursor: pointer;
|
|
1258
|
+
transition: background 0.15s;
|
|
1259
|
+
`,L.addEventListener("mouseenter",()=>{L.style.background="#3a3a4e"}),L.addEventListener("mouseleave",()=>{L.style.background="#2a2a3e"}),L.addEventListener("click",x),A.appendChild(P),A.appendChild(L),A}function y(f){var _,re,Y,W;const x=document.createElement("div"),N=((_=f.label)==null?void 0:_.text)??"",A=l("Line label",100,N),P=C(((re=f.style)==null?void 0:re.color)??n[0]),L=F([{label:"Solid",value:"solid"},{label:"Dashed",value:"dashed"},{label:"Dotted",value:"dotted"}],(Y=f.style)!=null&&Y.lineDash?f.style.lineDash.length===4?"dashed":"dotted":"solid"),B=R(1,8,1,((W=f.style)==null?void 0:W.lineWidth)??2,"px");x.appendChild(h("Label (optional)",A)),x.appendChild(h("Color",P.container)),x.appendChild(h("Line Style",L.container)),x.appendChild(h("Line Width",B.container));const V=S(c==="create"?"Create":"Save",()=>{const Z={solid:void 0,dashed:[4,4],dotted:[2,2]},oe=A.value.trim(),ee={...f,label:oe?{...f.label,text:oe}:void 0,style:{...f.style,color:P.getValue(),lineWidth:B.getValue(),lineDash:Z[L.getValue()]}};d(ee)},()=>g());return x.appendChild(V),x}function b(f){var B;const x=document.createElement("div"),N=f.text??"",A=m("Text content",500,N),P=C(((B=f.style)==null?void 0:B.color)??n[0]);x.appendChild(h("Text",A)),x.appendChild(h("Color",P.container));const L=S(c==="create"?"Create":"Save",()=>{const V=A.value.trim();if(!V){A.style.borderColor="#ef4444",A.focus();return}const _={...f,text:V,style:{...f.style,color:P.getValue()}};d(_)},()=>g());return x.appendChild(L),x}function w(f){var _,re,Y,W,Z;const x=document.createElement("div"),N=((_=f.label)==null?void 0:_.text)??"",A=l("Point label",100,N),P=C(((re=f.style)==null?void 0:re.color)??n[0]),L=((Y=f.marker)==null?void 0:Y.size)??((Z=(W=f.marker)==null?void 0:W.style)==null?void 0:Z.markerSize)??8,B=R(4,16,1,L,"px");x.appendChild(h("Label (optional)",A)),x.appendChild(h("Color",P.container)),x.appendChild(h("Marker Size",B.container));const V=S(c==="create"?"Create":"Save",()=>{var q;const oe=A.value.trim(),ee={...f,label:oe?{...f.label,text:oe}:void 0,marker:{...f.marker,size:B.getValue(),style:{...(q=f.marker)==null?void 0:q.style,color:P.getValue()}}};d(ee)},()=>g());return x.appendChild(V),x}function d(f){s&&s(f),T()}function g(){a&&a(),T()}function v(f){f.key==="Escape"&&(f.preventDefault(),g())}function M(f,x,N,A){c="create",s=N,a=A,r=u(),o=p();const P=document.createElement("h3");P.textContent=`Add ${f==="lineX"?"Vertical Line":f==="lineY"?"Horizontal Line":f==="text"?"Text Note":"Point Marker"}`,P.style.cssText=`
|
|
1260
|
+
margin: 0 0 20px 0;
|
|
1261
|
+
font-size: 16px;
|
|
1262
|
+
font-weight: 600;
|
|
1263
|
+
color: #ffffff;
|
|
1264
|
+
`,o.appendChild(P);let L;f==="lineX"||f==="lineY"?L=y(x):f==="text"?L=b(x):L=w(x),o.appendChild(L),r.appendChild(o),e.appendChild(r),document.addEventListener("keydown",v);const B=o.querySelector("input, textarea");B&&setTimeout(()=>B.focus(),50)}function I(f,x,N){c="edit",s=x,a=N,r=u(),o=p();const A=document.createElement("h3");A.textContent="Edit Annotation",A.style.cssText=`
|
|
1265
|
+
margin: 0 0 20px 0;
|
|
1266
|
+
font-size: 16px;
|
|
1267
|
+
font-weight: 600;
|
|
1268
|
+
color: #ffffff;
|
|
1269
|
+
`,o.appendChild(A);let P;f.type==="lineX"||f.type==="lineY"?P=y(f):f.type==="text"?P=b(f):P=w(f),o.appendChild(P),r.appendChild(o),e.appendChild(r),document.addEventListener("keydown",v);const L=o.querySelector("input, textarea");L&&setTimeout(()=>L.focus(),50)}function T(){r&&r.parentNode&&r.parentNode.removeChild(r),r=null,o=null,s=null,a=null,document.removeEventListener("keydown",v)}function E(){T()}return{showCreate:M,showEdit:I,hide:T,dispose:E}}const ba=e=>Array.isArray(e),Jr=e=>Array.isArray(e),$d=e=>ba(e)?e[0]:e.x,Wd=e=>ba(e)?e[1]:e.y,Xd=e=>Jr(e)?e[0]:e.timestamp;function Yd(e,t,n={}){const{menuZIndex:i=1e3,enableContextMenu:r=!0}=n,o=e.querySelector("canvas");if(!o)throw new Error("createAnnotationAuthoring: canvas element not found in container");let s=[{annotations:t.options.annotations??[]}],a=0,c=!1;const u=Gd(t,o,{lineTolerance:20,textTolerance:8,pointTolerance:16}),p=Od(e,{zIndex:i}),h=zd(t,o,{onDragMove:(G,te)=>{const Q=l().map((ne,H)=>H===G?{...ne,...te}:ne);C(Q)},onDragEnd:(G,te)=>{const Q=l().map((ne,H)=>H===G?{...ne,...te}:ne);C(Q),m(Q)},onDragCancel:()=>{const G=s[a];G&&C(G.annotations)}}),l=()=>t.options.annotations??[],m=G=>{s=s.slice(0,a+1),s.push({annotations:[...G]}),a=s.length-1,s.length>50&&(s.shift(),a--)},C=G=>{t.setOption({...t.options,annotations:[...G]}),u.invalidateCache()};let F=null;const R=()=>{const G=document.createElement("div");return G.style.position="fixed",G.style.display="none",G.style.backgroundColor="#1a1a2e",G.style.border="1px solid #333",G.style.borderRadius="8px",G.style.boxShadow="0 4px 12px rgba(0, 0, 0, 0.5)",G.style.zIndex=String(i),G.style.minWidth="180px",G.style.padding="6px 0",G.style.fontFamily='-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',G.style.fontSize="14px",G.style.color="#e0e0e0",document.body.appendChild(G),G},S=(G,te)=>{const X=document.createElement("div");return X.textContent=G,X.style.padding="8px 16px",X.style.cursor="pointer",X.style.transition="background-color 0.15s",X.style.userSelect="none",X.addEventListener("mouseenter",()=>{X.style.backgroundColor="#2a2a3e"}),X.addEventListener("mouseleave",()=>{X.style.backgroundColor="transparent"}),X.addEventListener("click",()=>{te(),v()}),X},y=()=>{const G=document.createElement("div");return G.style.height="1px",G.style.backgroundColor="#333",G.style.margin="6px 0",G},b=(G,te,X)=>{G.innerHTML="",G.appendChild(S("Edit annotation...",()=>A(te,X))),G.appendChild(S("Delete annotation",()=>P(te))),G.appendChild(y()),G.appendChild(S("Add vertical line here",()=>f())),G.appendChild(S("Add horizontal line here",()=>x())),G.appendChild(S("Add text note here",()=>N()))},w=G=>{G.innerHTML="",G.appendChild(S("Add vertical line here",()=>f())),G.appendChild(S("Add horizontal line here",()=>x())),G.appendChild(S("Add text note here",()=>N()))};let d=null;const g=G=>{if(!F)return;d=t.hitTest(G);const te=o.getBoundingClientRect(),X=G.clientX-te.left,Q=G.clientY-te.top,ne=u.hitTest(X,Q);ne?b(F,ne.annotationIndex,ne.annotation):w(F),F.style.display="block",F.style.left=`${G.clientX}px`,F.style.top=`${G.clientY}px`,requestAnimationFrame(()=>{if(!F||F.style.display!=="block")return;const H=F.getBoundingClientRect();let O=G.clientX,se=G.clientY;H.right>window.innerWidth&&(O=Math.max(0,G.clientX-H.width)),H.bottom>window.innerHeight&&(se=Math.max(0,G.clientY-H.height)),(O!==G.clientX||se!==G.clientY)&&(F.style.left=`${O}px`,F.style.top=`${se}px`)})},v=()=>{F&&(F.style.display="none",d=null)},M=()=>{var ne,H;const G=t.options;let te=(ne=G.xAxis)==null?void 0:ne.min,X=(H=G.xAxis)==null?void 0:H.max;if(te===void 0||X===void 0){const O=G.series??[];let se=Number.POSITIVE_INFINITY,ce=Number.NEGATIVE_INFINITY;for(const le of O)if(le.type!=="pie")if(le.type==="candlestick"){const me=le.data;for(const ge of me){const we=Xd(ge);we<se&&(se=we),we>ce&&(ce=we)}}else{const me=le.data;for(const ge of me){const we=$d(ge);we<se&&(se=we),we>ce&&(ce=we)}}te===void 0&&(te=Number.isFinite(se)?se:0),X===void 0&&(X=Number.isFinite(ce)?ce:100)}const Q=t.getZoomRange();if(Q){const O=X-te,se=te+Q.start/100*O,ce=te+Q.end/100*O;return{min:se,max:ce}}return{min:te,max:X}},I=()=>{var Q,ne;const G=t.options;let te=(Q=G.yAxis)==null?void 0:Q.min,X=(ne=G.yAxis)==null?void 0:ne.max;if(te===void 0||X===void 0){const H=G.series??[];let O=Number.POSITIVE_INFINITY,se=Number.NEGATIVE_INFINITY;for(const ce of H)if(ce.type!=="pie")if(ce.type==="candlestick"){const le=ce.data;for(const me of le){const ge=Jr(me)?me[3]:me.low,we=Jr(me)?me[4]:me.high;ge<O&&(O=ge),we>se&&(se=we)}}else{const le=ce.data;for(const me of le){const ge=Wd(me);ge<O&&(O=ge),ge>se&&(se=ge)}}te===void 0&&(te=Number.isFinite(O)?O:0),X===void 0&&(X=Number.isFinite(se)?se:100)}return{min:te,max:X}},T=G=>{const te=o.getBoundingClientRect(),X=t.options.grid??Et,Q=te.width-(X.left??Et.left)-(X.right??Et.right),ne=M(),H=Q>0?G/Q:0;return ne.min+H*(ne.max-ne.min)},E=(G,te)=>{const X=o.getBoundingClientRect(),Q=t.options.grid??Et,ne=X.width-(Q.left??Et.left)-(Q.right??Et.right),H=X.height-(Q.top??Et.top)-(Q.bottom??Et.bottom),O=ne>0?G/ne:0,se=H>0?te/H:0;return{x:O,y:se}},f=()=>{if(!d)return;const{match:G,isInGrid:te,gridX:X}=d;let Q;if(G)Q=G.value[0];else if(te)Q=T(X);else return;p.showCreate("lineX",{type:"lineX",x:Q,layer:"aboveSeries",style:{color:"#ffa500",lineWidth:2}},ne=>{const O=[...l(),ne];C(O),m(O)},()=>{})},x=()=>{if(!d)return;const{match:G,isInGrid:te,gridY:X}=d;let Q;if(G)Q=G.value[1];else if(te){const ne=o.getBoundingClientRect(),H=t.options.grid??Et,O=ne.height-(H.top??Et.top)-(H.bottom??Et.bottom),se=I(),ce=O>0?1-X/O:.5;Q=se.min+ce*(se.max-se.min)}else return;p.showCreate("lineY",{type:"lineY",y:Q,layer:"aboveSeries",style:{color:"#ffa500",lineWidth:2}},ne=>{const O=[...l(),ne];C(O),m(O)},()=>{})},N=()=>{if(!d)return;const{match:G,isInGrid:te,gridX:X,gridY:Q}=d;let ne,H,O;if(G)ne="data",H=G.value[0],O=G.value[1];else if(te){const se=E(X,Q);ne="plot",H=se.x,O=se.y}else return;p.showCreate("text",{type:"text",position:{space:ne,x:H,y:O},text:"Note",layer:"aboveSeries",style:{color:"#00d4ff"}},se=>{const le=[...l(),se];C(le),m(le)},()=>{})},A=(G,te)=>{p.showEdit(te,X=>{const ne=l().map((H,O)=>O===G?{...H,...X}:H);C(ne),m(ne)},()=>{})},P=G=>{const X=l().filter((Q,ne)=>ne!==G);C(X),m(X)},L=G=>{if(c||G.button===2)return;const te=o.getBoundingClientRect(),X=G.clientX-te.left,Q=G.clientY-te.top,ne=u.hitTest(X,Q);ne&&(G.preventDefault(),h.startDrag(ne.annotationIndex,ne.annotation,G.clientX,G.clientY))},B=G=>{c||!r||(G.preventDefault(),G.stopPropagation(),g(G))},V=G=>{c||F&&!F.contains(G.target)&&v()},_=G=>{c||G.key==="Escape"&&F&&F.style.display==="block"&&v()},re=()=>{c||F&&F.style.display==="block"&&v()},Y=G=>{const te=l(),X={type:"lineX",x:G,layer:"aboveSeries",style:{color:"#ffa500",lineWidth:2,opacity:.9}},Q=[...te,X];C(Q),m(Q)},W=(G,te,X,Q="data")=>{const ne=l(),H={type:"text",position:{space:Q,x:G,y:te},text:X,layer:"aboveSeries",style:{color:"#00d4ff",opacity:1}},O=[...ne,H];C(O),m(O)},Z=()=>{if(a<=0)return!1;a--;const G=s[a];return G?(C(G.annotations),!0):!1},oe=()=>{if(a>=s.length-1)return!1;a++;const G=s[a];return G?(C(G.annotations),!0):!1},ee=()=>{const G=l();return JSON.stringify(G,null,2)},q=()=>l(),de=()=>{c||(c=!0,o.removeEventListener("pointerdown",L),o.removeEventListener("contextmenu",B),document.removeEventListener("click",V),document.removeEventListener("keydown",_),window.removeEventListener("scroll",re,!0),window.removeEventListener("resize",re),F==null||F.remove(),F=null,u.dispose(),h.dispose(),p.dispose(),s=[])};return r&&(F=R(),o.addEventListener("contextmenu",B),document.addEventListener("click",V),document.addEventListener("keydown",_),window.addEventListener("scroll",re,!0),window.addEventListener("resize",re)),o.addEventListener("pointerdown",L),{addVerticalLine:Y,addTextNote:W,undo:Z,redo:oe,exportJSON:ee,getAnnotations:q,dispose:de}}const Qr=120,Hd=1e3/60,qd=1.5,gn=new Map;function sr(){const e=Symbol("RenderScheduler"),t={id:e,running:!1};return gn.set(e,{rafId:null,callback:null,lastFrameTime:0,dirty:!1,frameHandler:null,frameTimestamps:new Float64Array(Qr),frameTimestampIndex:0,frameTimestampCount:0,totalFrames:0,totalDroppedFrames:0,consecutiveDroppedFrames:0,lastDropTimestamp:0,startTime:performance.now()}),t}function co(e,t){if(!t)throw new Error("Render callback is required");const n=gn.get(e.id);if(!n)throw new Error("Invalid scheduler state. Use createRenderScheduler() to create a new state.");if(e.running)throw new Error("RenderScheduler is already running. Call stopRenderScheduler() before starting again.");n.callback=t,n.lastFrameTime=performance.now(),n.dirty=!0;const i=e.id,r=o=>{const s=gn.get(i);if(!s||!s.callback)return;s.rafId=null;const a=performance.now();s.frameTimestamps[s.frameTimestampIndex]=a,s.frameTimestampIndex=(s.frameTimestampIndex+1)%Qr,s.frameTimestampCount<Qr&&s.frameTimestampCount++,s.totalFrames++;let c=o-s.lastFrameTime;const u=100;if(c>u&&(c=u),s.lastFrameTime>0&&c>Hd*qd?(s.totalDroppedFrames++,s.consecutiveDroppedFrames++,s.lastDropTimestamp=a):s.lastFrameTime>0&&(s.consecutiveDroppedFrames=0),s.lastFrameTime=o,s.dirty){s.dirty=!1,s.callback(c);const p=gn.get(i);p&&p.callback&&p.dirty&&(p.rafId=requestAnimationFrame(r))}};return n.frameHandler=r,n.rafId=requestAnimationFrame(r),{id:e.id,running:!0}}function va(e){const t=gn.get(e.id);if(!t)throw new Error("Invalid scheduler state. Use createRenderScheduler() to create a new state.");return t.callback=null,t.frameHandler=null,t.rafId!==null&&(cancelAnimationFrame(t.rafId),t.rafId=null),{id:e.id,running:!1}}function wa(e){const t=gn.get(e.id);if(!t)throw new Error("Invalid scheduler state. Use createRenderScheduler() to create a new state.");t.dirty=!0,t.callback!==null&&t.rafId===null&&(t.lastFrameTime=performance.now(),t.frameHandler&&(t.rafId=requestAnimationFrame(t.frameHandler)))}function Ca(e){const t=gn.get(e.id);return t&&(t.rafId!==null&&(cancelAnimationFrame(t.rafId),t.rafId=null),t.callback=null,t.frameHandler=null,gn.delete(e.id)),sr()}function Zd(e){const t=sr();return co(t,e)}class jd{get running(){return this._state.running}constructor(){this._state=sr()}start(t){this._state=co(this._state,t)}stop(){this._state=va(this._state)}requestRender(){wa(this._state)}destroy(){this._state=Ca(this._state)}}const Kd="1.0.0",Jd=Ud;exports.ChartGPU=Jd;exports.GPUContext=nr;exports.OptionResolver=Cd;exports.RenderScheduler=jd;exports.candlestickDefaults=Dt;exports.clearScreen=qs;exports.connectCharts=_d;exports.createAnnotationAuthoring=Yd;exports.createCategoryScale=xf;exports.createChart=xa;exports.createGPUContext=eo;exports.createGPUContextAsync=Ba;exports.createLinearScale=an;exports.createRenderScheduler=sr;exports.createRenderSchedulerAsync=Zd;exports.darkTheme=ya;exports.defaultOptions=bt;exports.destroyGPUContext=Zs;exports.destroyRenderScheduler=Ca;exports.getCanvasTexture=no;exports.getTheme=Xi;exports.initializeGPUContext=to;exports.lightTheme=ga;exports.requestRender=wa;exports.resolveOptions=ao;exports.startRenderScheduler=co;exports.stopRenderScheduler=va;exports.version=Kd;
|
|
1270
|
+
//# sourceMappingURL=index.cjs.map
|