UNPKG

openalgo-charts

Version:

From-scratch, dependency-free canvas charting engine for OpenAlgo: professional-grade interactive rendering, advanced on-chart trading, and a one-call widget tier that adds the toolbar, drawing rail, dialogs and shortcuts.

2 lines (1 loc) • 23.2 kB
if("undefined"==typeof OpenAlgoCharts)throw new Error("openalgo-charts.webgl.standalone.js needs openalgo-charts.standalone.js loaded before it");this.OpenAlgoCharts=this.OpenAlgoCharts||{},this.OpenAlgoCharts.webgl=function(e,t){"use strict";function r(e,t){return{...e,upColor:e.upColor??t.upColor,downColor:e.downColor??t.downColor}}function o(e,t,r){return{...e,color:e.color??t.lineColor,...r}}const i={upColor:"#26a69a",downColor:"#ef5350",borderUpColor:"#26a69a",borderDownColor:"#ef5350",wickUpColor:"#26a69a",wickDownColor:"#ef5350",borderVisible:!0,wickVisible:!0};function n(e,t,r={}){return{...i,upColor:e.upColor??t.upColor,downColor:e.downColor??t.downColor,borderUpColor:e.borderUpColor??t.upColor,borderDownColor:e.borderDownColor??t.downColor,wickUpColor:e.wickUpColor??t.wickUpColor,wickDownColor:e.wickDownColor??t.wickDownColor,borderVisible:e.borderVisible??i.borderVisible,bodyVisible:e.bodyVisible??!0,wickVisible:e.wickVisible??i.wickVisible,colorByPreviousClose:e.colorByPreviousClose,...r}}function l(e,t){const r=Math.floor(e*t*.8);let o=Math.max(1,r);if(o>=2){o%2!=Math.max(1,Math.floor(t))%2&&(o-=1)}return Math.max(1,o)}function a(e,t,r){return r.wickVisible?!0===r.hollow||!1===r.bodyVisible||e>t||r.borderVisible&&e>=3||r.upColor!==r.wickUpColor||r.downColor!==r.wickDownColor?"full":"wick":"full"}function s(e,t,r,o=1){const i=l(t,r),n=Math.max(1,Math.floor(r)),a=Math.round(e*r),s=function(e,t){const r=Math.max(.05,Math.min(1,t));return 1===r?e:Math.max(1,Math.round(e*r))}(i,o);return{cx:a,bodyX:a-Math.floor(s/2),bodyW:s,wickX:a-Math.floor(n/2),wickW:n}}const c="#3a4666";function h(e,t,r){const o=e.bar;return{cx:Math.round(e.x*r),yOpen:Math.round(t(o.open)*r),yClose:Math.round(t(o.close)*r),yHigh:Math.round(t(o.high)*r),yLow:Math.round(t(o.low)*r),up:o.close>=o.open}}const u=[];function b(e,t){e.s=0,e.a=e.b=-1,e.n=t,e.xs.length>16384&&4*t<e.xs.length&&(e.xs.length=e.ys.length=t)}function f(e,t,r,o){const i=e.xs,n=e.ys;for(let e=0;e<t.length;e++){const l=t[e],a=l.bar;i[e]=l.x,n[e]=r(0===o?a.close:1===o?a.high:a.low)}b(e,t.length)}function d(e,t,r,o,i){const n=t.length;if(0===n)return;const l=t[0].edgeX,a=t[n-1].edgeX;if(void 0===l&&void 0===a)return;if(1===n)return void(e.n=0);const s=e.xs,c=e.ys;if(void 0!==l){const t=l-i,n=s[1],a=c[1],h=s[0],u=c[0];if(n<t||!Number.isFinite(u)||!Number.isFinite(a))e.s=r?2:1,c[0]=NaN;else{const i=Math.hypot(h-n,u-a);let l=h<t?i*(n-t)/(n-h):i;const b=r&&Number.isFinite(c[2]),f=b?Math.abs(c[2]-a):0;if(o>0&&(l=Math.ceil((l+f)/o)*o-f),l!==i){const e=l/i;s[0]=n+(h-n)*e,c[0]=a+(u-a)*e}e.a=b?2:1}}if(void 0!==a){const t=a+i,o=r?e.n-2:e.n-1,n=s[o-1],l=c[o-1],h=s[o],u=c[o];n>t||!Number.isFinite(l)||!Number.isFinite(u)?(e.n=o,c[o]=NaN):(h>t&&(c[o]=l+(t-n)/(h-n)*(u-l),s[o]=t,e.n=o+1),e.b=o-1)}}const _=11,g=1e6,m=e=>e===Math.round(e);class p{constructor(e=256){Object.defineProperty(this,"vertices",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"indices",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"quadCount",{enumerable:!0,configurable:!0,writable:!0,value:0}),Object.defineProperty(this,"_capacity",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this._capacity=Math.max(1,e),this.vertices=new Float32Array(4*this._capacity*_),this.indices=new Uint32Array(6*this._capacity),this._fillIndices(0)}get capacity(){return this._capacity}get vertexCount(){return 4*this.quadCount}get indexCount(){return 6*this.quadCount}get floatCount(){return this.vertexCount*_}reset(){this.quadCount=0}rect(e,t,r,o,i){if(!(r>0&&o>0))return;const n=r/2,l=o/2,a=e+n,s=t+l,c=m(e)&&m(t)&&m(e+r)&&m(t+o)?0:1,h=n+c,u=l+c,b=this._claim(),f=this.vertices;this._vertex(f,b,a-h,s-u,i,-h,-u,n,l,0),this._vertex(f,b+_,a+h,s-u,i,h,-u,n,l,0),this._vertex(f,b+22,a-h,s+u,i,-h,u,n,l,0),this._vertex(f,b+33,a+h,s+u,i,h,u,n,l,0)}segment(e,t,r,o,i,n,l){if(!(i>0))return;const a=r-e,s=o-t,c=Math.hypot(a,s);if(!Number.isFinite(c))return;if(0===c&&!l)return;const h=0===c?1:a/c,u=0===c?0:s/c,b=(e+r)/2,f=(t+o)/2,d=c/2,g=d,m=l?0:i,p=l?i:0,v=d+i+1,w=i+1,x=this._claim(),C=this.vertices;this._vertex(C,x,b-h*v+u*w,f-u*v-h*w,n,-v,-w,g,m,p),this._vertex(C,x+_,b+h*v+u*w,f+u*v-h*w,n,v,-w,g,m,p),this._vertex(C,x+22,b-h*v-u*w,f-u*v+h*w,n,-v,w,g,m,p),this._vertex(C,x+33,b+h*v-u*w,f+u*v+h*w,n,v,w,g,m,p)}quad(e,t,r,o,i,n,l,a,s,c,h,u){const b=this._claim(),f=this.vertices;this._vertex(f,b,e,t,r,0,0,g,g,0),this._vertex(f,b+_,o,i,n,0,0,g,g,0),this._vertex(f,b+22,l,a,s,0,0,g,g,0),this._vertex(f,b+33,c,h,u,0,0,g,g,0)}triangle(e,t,r,o,i,n,l,a,s){this.quad(e,t,r,o,i,n,l,a,s,l,a,s)}_claim(){this.quadCount===this._capacity&&this._grow();const e=4*this.quadCount*_;return this.quadCount++,e}_vertex(e,t,r,o,i,n,l,a,s,c){e[t]=r,e[t+1]=o,e[t+2]=i[0],e[t+3]=i[1],e[t+4]=i[2],e[t+5]=i[3],e[t+6]=n,e[t+7]=l,e[t+8]=a,e[t+9]=s,e[t+10]=c}_grow(){const e=this._capacity;this._capacity*=2;const t=new Float32Array(4*this._capacity*_);t.set(this.vertices),this.vertices=t;const r=new Uint32Array(6*this._capacity);r.set(this.indices),this.indices=r,this._fillIndices(e)}_fillIndices(e){const t=this.indices;for(let r=e;r<this._capacity;r++){const e=4*r,o=6*r;t[o]=e,t[o+1]=e+1,t[o+2]=e+2,t[o+3]=e+2,t[o+4]=e+1,t[o+5]=e+3}}}const v=[0,0,0,0];function w(e){return e>0?e<1?e:1:0}function x(e){const t=function(e){const t=e.trim();if(t.startsWith("#")){const e=t.slice(1);if(3===e.length||4===e.length){const[t,r,o,i]=[...e].map(e=>parseInt(e+e,16));return[t,r,o].some(Number.isNaN)?null:{r:t,g:r,b:o,a:4===e.length?i/255:1}}if(6===e.length||8===e.length){const t=parseInt(e.slice(0,6),16);if(Number.isNaN(t))return null;const r=8===e.length?parseInt(e.slice(6,8),16)/255:1;return{r:t>>16&255,g:t>>8&255,b:255&t,a:Number.isNaN(r)?1:r}}return null}const r=/^rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\s*(?:,\s*([\d.]+)\s*)?\)$/i.exec(t);return null===r?null:{r:Number(r[1]),g:Number(r[2]),b:Number(r[3]),a:void 0===r[4]?1:Number(r[4])}}(e);if(null===t)return null;const r=w(t.a);return[w(t.r/255)*r,w(t.g/255)*r,w(t.b/255)*r,r]}function C(e,t,r){return[e[0]+(t[0]-e[0])*r,e[1]+(t[1]-e[1])*r,e[2]+(t[2]-e[2])*r,e[3]+(t[3]-e[3])*r]}class y{constructor(){Object.defineProperty(this,"_map",{enumerable:!0,configurable:!0,writable:!0,value:new Map})}get(e,t){let r=this._map.get(e);if(void 0!==r)return r;if(r=x(e)??void 0,void 0===r&&void 0!==t){const o=t(e);null!==o&&(r=x(o)??void 0)}return void 0===r&&(r=v),this._map.size>=4096&&this._map.clear(),this._map.set(e,r),r}get size(){return this._map.size}clear(){this._map.clear()}}function M(e,t,r){const o=e.createShader(t);if(null===o)throw new Error("openalgo-charts: could not create a WebGL shader");if(e.shaderSource(o,r),e.compileShader(o),!e.getShaderParameter(o,e.COMPILE_STATUS)&&!e.isContextLost()){const t=e.getShaderInfoLog(o)??"";throw e.deleteShader(o),new Error(`openalgo-charts: WebGL shader failed to compile: ${t}`)}return o}const P={alpha:!0,antialias:!1,premultipliedAlpha:!0,preserveDrawingBuffer:!1,depth:!1,stencil:!1};function A(){const e=globalThis.document;if(void 0!==e&&"function"==typeof e.createElement)return e.createElement("canvas");const t=globalThis.OffscreenCanvas;return void 0!==t?new t(1,1):null}class N{constructor(e=A){Object.defineProperty(this,"colors",{enumerable:!0,configurable:!0,writable:!0,value:new y}),Object.defineProperty(this,"_createSurface",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_surface",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_gl",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_program",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_vao",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_vbo",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_ibo",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_indexCapacity",{enumerable:!0,configurable:!0,writable:!0,value:0}),Object.defineProperty(this,"_refs",{enumerable:!0,configurable:!0,writable:!0,value:0}),Object.defineProperty(this,"_lost",{enumerable:!0,configurable:!0,writable:!0,value:!1}),Object.defineProperty(this,"_probed",{enumerable:!0,configurable:!0,writable:!0,value:!1}),Object.defineProperty(this,"_onLost",{enumerable:!0,configurable:!0,writable:!0,value:e=>{e.preventDefault(),this._lost=!0,this._program=null,this._vao=null,this._vbo=null,this._ibo=null,this._indexCapacity=0}}),Object.defineProperty(this,"_onRestored",{enumerable:!0,configurable:!0,writable:!0,value:()=>{this._lost=!1}}),this._createSurface=e}get available(){if(!this._probed){this._probed=!0,this._surface=this._createSurface();const e=this._surface?.getContext("webgl2",P)??null;null!==e&&(this._gl=e,this._surface?.addEventListener?.("webglcontextlost",this._onLost),this._surface?.addEventListener?.("webglcontextrestored",this._onRestored))}return null!==this._gl}get lost(){return this._lost||null!==this._gl&&this._gl.isContextLost()}get surface(){return this._surface}get refs(){return this._refs}get gl(){return this._gl}acquire(){return!!this.available&&(this._refs++,!0)}release(){0!==this._refs&&(this._refs--,0===this._refs&&null!==this._surface&&(this._surface.width=1,this._surface.height=1))}ensureSize(e,t){const r=this._surface;null!==r&&(r.width<e&&(r.width=e),r.height<t&&(r.height=t))}render(e,t,r){if(null===this._gl||null===this._surface||this.lost)return!1;const o=this._gl;if(null===this._program&&!this._setup(o))return!1;const i=this._program;this.ensureSize(t,r);const n=this._surface.height-r;return o.viewport(0,n,t,r),o.enable(o.SCISSOR_TEST),o.scissor(0,n,t,r),o.clearColor(0,0,0,0),o.clear(o.COLOR_BUFFER_BIT),0===e.quadCount||(o.useProgram(i.program),o.uniform2f(i.uResolution,t,r),o.bindVertexArray(this._vao),o.bindBuffer(o.ARRAY_BUFFER,this._vbo),o.bufferData(o.ARRAY_BUFFER,e.vertices,o.STREAM_DRAW,0,e.floatCount),e.indices.length>this._indexCapacity&&(o.bindBuffer(o.ELEMENT_ARRAY_BUFFER,this._ibo),o.bufferData(o.ELEMENT_ARRAY_BUFFER,e.indices,o.STATIC_DRAW),this._indexCapacity=e.indices.length),o.drawElements(o.TRIANGLES,e.indexCount,o.UNSIGNED_INT,0),o.bindVertexArray(null)),!0}_setup(e){let t;try{t=function(e){const t=M(e,e.VERTEX_SHADER,"#version 300 es\nprecision highp float;\nuniform vec2 u_resolution;\nin vec2 a_pos;\nin vec4 a_color;\nin vec2 a_local;\nin vec3 a_shape;\nout vec4 v_color;\nout vec2 v_local;\nflat out vec3 v_shape;\nvoid main() {\n vec2 clip = vec2(a_pos.x / u_resolution.x * 2.0 - 1.0, 1.0 - a_pos.y / u_resolution.y * 2.0);\n gl_Position = vec4(clip, 0.0, 1.0);\n v_color = a_color;\n v_local = a_local;\n v_shape = a_shape;\n}\n"),r=M(e,e.FRAGMENT_SHADER,"#version 300 es\nprecision highp float;\nin vec4 v_color;\nin vec2 v_local;\nflat in vec3 v_shape;\nout vec4 fragColor;\nvoid main() {\n vec2 q = abs(v_local) - v_shape.xy;\n float d = length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - v_shape.z;\n float cov = clamp(0.5 - d, 0.0, 1.0);\n fragColor = clamp(v_color, 0.0, 1.0) * cov;\n}\n"),o=e.createProgram();if(null===o)throw new Error("openalgo-charts: could not create a WebGL program");if(e.attachShader(o,t),e.attachShader(o,r),e.linkProgram(o),e.deleteShader(t),e.deleteShader(r),!e.getProgramParameter(o,e.LINK_STATUS)&&!e.isContextLost()){const t=e.getProgramInfoLog(o)??"";throw e.deleteProgram(o),new Error(`openalgo-charts: WebGL program failed to link: ${t}`)}return{program:o,aPos:e.getAttribLocation(o,"a_pos"),aColor:e.getAttribLocation(o,"a_color"),aLocal:e.getAttribLocation(o,"a_local"),aShape:e.getAttribLocation(o,"a_shape"),uResolution:e.getUniformLocation(o,"u_resolution")}}(e)}catch{return this._gl=null,!1}return this._program=t,this._vao=e.createVertexArray(),this._vbo=e.createBuffer(),this._ibo=e.createBuffer(),this._indexCapacity=0,e.bindVertexArray(this._vao),e.bindBuffer(e.ARRAY_BUFFER,this._vbo),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this._ibo),function(e,t){e.enableVertexAttribArray(t.aPos),e.vertexAttribPointer(t.aPos,2,e.FLOAT,!1,44,0),e.enableVertexAttribArray(t.aColor),e.vertexAttribPointer(t.aColor,4,e.FLOAT,!1,44,8),e.enableVertexAttribArray(t.aLocal),e.vertexAttribPointer(t.aLocal,2,e.FLOAT,!1,44,24),e.enableVertexAttribArray(t.aShape),e.vertexAttribPointer(t.aShape,3,e.FLOAT,!1,44,32)}(e,t),e.bindVertexArray(null),e.disable(e.DEPTH_TEST),e.disable(e.CULL_FACE),e.enable(e.BLEND),e.blendFunc(e.ONE,e.ONE_MINUS_SRC_ALPHA),!0}}let S=null;function k(){return null===S&&(S=new N),S}function F(){return void 0!==globalThis.WebGL2RenderingContext&&k().available}function O(e,t,r,o,i,n,l){const a=t-n/2,s=r-n/2,c=o+n,h=i+n;o-n<=0||i-n<=0?e.rect(a,s,c,h,l):(e.rect(a,s,c,n,l),e.rect(a,s+h-n,c,n,l),e.rect(a,s+n,n,h-2*n,l),e.rect(a+c-n,s+n,n,h-2*n,l))}function L(e,t,r,o,i,n,c){const h=l(o,i),u=Math.max(1,Math.floor(i)),b=n.widthScale?null:a(h,u,n);for(let l=0;l<t.length;l++){const{x:h,bar:f}=t[l],d=l>0?t[l-1].bar.close:t[l].prevClose,_=!0===n.colorByPreviousClose&&void 0!==d&&Number.isFinite(d)?f.close>=d:f.close>=f.open,g=Math.round(r(f.open)*i),m=Math.round(r(f.close)*i),p=Math.round(r(f.high)*i),v=Math.round(r(f.low)*i),w=s(h,o,i,n.widthScale?n.widthScale(f):1),x=w.cx,C=w.bodyW,y=x-w.bodyX,M=f.color,P=M??(_?n.upColor:n.downColor),A=f.wickColor??M??(_?n.wickUpColor:n.wickDownColor),N=f.borderColor??M??(_?n.borderUpColor:n.borderDownColor);if(n.wickVisible&&e.rect(w.wickX,p,w.wickW,Math.max(1,v-p),c(A)),"wick"===(b??a(C,u,n))&&A===P)continue;const S=Math.min(g,m),k=Math.max(1,Math.abs(m-g));if(n.hollow&&_)O(e,x-y+.5,S+.5,C-1,k-1,Math.max(1,u),c(n.borderVisible?N:P));else{const t=!1!==n.bodyVisible;t&&e.rect(x-y,S,C,k,c(P)),n.borderVisible&&(!t||C>=3)&&O(e,x-y+.5,S+.5,C-1,k-1,1,c(N))}}}function E(e,t,r,o,i,n,a,s){const c=function(e,t){return Math.max(Math.max(1,Math.floor(t)),Math.floor(e*t*.2))}(o,i),u=Math.floor(c/2),b=Math.max(1,Math.floor(l(o,i)/2),u+1);for(let o=0;o<t.length;o++){const l=t[o],f=h(l,r,i),d=o>0?t[o-1].bar.close:l.prevClose,_=!0===n.colorByPreviousClose&&void 0!==d&&Number.isFinite(d)?l.bar.close>=d:f.up,g=s(l.bar.color??(_?n.upColor??"#26a69a":n.downColor??"#ef5350"));e.rect(f.cx-u,f.yHigh,c,Math.max(1,f.yLow-f.yHigh),g),a||(e.rect(f.cx-b,f.yOpen-u,b,c,g),e.rect(f.cx,f.yClose-u,b,c,g))}}function T(e,t,r,o,i,n,l,a,s){const c=Math.hypot(o-t,i-r);if(0===c)return;const h=(o-t)/c,u=(i-r)/c;let b=0;for(;b<c;){const o=Math.min(s.rem,c-b);s.idx%2==0&&o>0&&e.segment(t+h*b,r+u*b,t+h*(b+o),r+u*(b+o),n,l,!0),b+=o,s.rem-=o,s.rem<=1e-9&&(s.idx=(s.idx+1)%a.length,s.rem=a[s.idx])}}const R={xs:[],ys:[],s:0,n:0,a:-1,b:-1},B={xs:[],ys:[],s:0,n:0,a:-1,b:-1},j={xs:[],ys:[],s:0,n:0,a:-1,b:-1},V={xs:[],ys:[],s:0,n:0,a:-1,b:-1};function W(e,t,r,o,i,n,l,a){let s=l;s.length%2==1&&(s=s.concat(s));let c=0;for(const e of s)c+=e;const h=s.length>0&&c>0,u={idx:0,rem:h?s[0]:0},b=t.xs,f=t.ys;let d,_=-1,g=a(i);for(let l=t.s;l<t.n;l++){const c=b[l],m=f[l];if(!Number.isFinite(c)||!Number.isFinite(m)){_=-1;continue}if(_<0){_=l,u.idx=0,u.rem=h?s[0]:0;continue}const p=void 0===n?d:n[l];p!==d&&(d=p,g=a(p??i),u.idx=0,u.rem=h?s[0]:0),h?T(e,b[_]*r,f[_]*r,c*r,m*r,o,g,s,u):e.segment(b[_]*r,f[_]*r,c*r,m*r,o,g,!0),l===t.a&&(u.idx=0,u.rem=h?s[0]:0),_=l}}function U(e,t,r,o,i,n){const l=R;f(l,t,r,0);let a=l;i.step&&function(e,t){const r=e.xs,o=e.ys,i=t.xs,n=t.ys;let l=0;for(let t=0;t<e.n;t++)t>0&&(i[l]=r[t],n[l++]=o[t-1]),i[l]=r[t],n[l++]=o[t];b(t,l)}(l,a=B);const s=function(e,t){let r=!1;for(let t=0;t<e.length;t++)if(void 0!==e[t].bar.color){r=!0;break}if(!r)return;let o=0;for(let r=0;r<e.length;r++){const i=e[r].bar.color;t&&o>0&&(u[o++]=i),u[o++]=i}return u.length=o,u}(t,!0===i.step),c=i.color??"#4f8cff",h=i.lineWidth??1.5,_=Math.max(1,h*o)/2,g=function(e,t){return"dashed"===e?[6*t,4*t]:"dotted"===e?[1*t,3*t]:[]}(i.lineStyle,o);if(d(a,t,!0===i.step,function(e,t){let r=0;for(let t=0;t<e.length;t++)r+=e[t];return r>0?(e.length%2==1?2*r:r)/t:0}(g,o),8+h),i.markersOnly||W(e,a,o,_,c,s,g,n),i.markers||i.markersOnly){const r=(i.markerRadius??2)*o;for(let i=0;i<t.length;i++){const a=l.xs[i],h=l.ys[i];if(!Number.isFinite(a)||!Number.isFinite(h)||void 0!==t[i].edgeX)continue;const u=n(void 0!==s?t[i].bar.color??c:c);e.segment(a*o,h*o,a*o,h*o,r,u,!0)}}}function D(e,t,r,o,i,n){const l=i(o);let a=NaN,s=NaN;for(let c=t.s;c<t.n;c++){const h=t.xs[c]*r,u=t.ys[c]*r;if(Number.isFinite(h)&&Number.isFinite(u)){if(Number.isFinite(a)){const t=s<=o,r=u<=o;if(t===r)"both"!==n&&"above"===n!==t||e.quad(a,s,i(s),h,u,i(u),a,o,l,h,o,l);else{const c=a+(h-a)*(o-s)/(u-s);"both"!==n&&"above"===n!==t||e.triangle(a,s,i(s),c,o,l,a,o,l),"both"!==n&&"above"===n!==r||e.triangle(h,u,i(u),c,o,l,h,o,l)}}a=h,s=u}}}const q=["candlestick","hollow-candle","volume-candle","bar","high-low","line","line-markers","step","area","hlc-area","baseline","column","histogram"],I=new WeakMap;class G{constructor(e=k()){Object.defineProperty(this,"kind",{enumerable:!0,configurable:!0,writable:!0,value:"webgl2"}),Object.defineProperty(this,"device",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_batch",{enumerable:!0,configurable:!0,writable:!0,value:new p}),Object.defineProperty(this,"_canvas",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_ctx",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_widthPx",{enumerable:!0,configurable:!0,writable:!0,value:0}),Object.defineProperty(this,"_heightPx",{enumerable:!0,configurable:!0,writable:!0,value:0}),Object.defineProperty(this,"_acquired",{enumerable:!0,configurable:!0,writable:!0,value:!1}),Object.defineProperty(this,"_frame2d",{enumerable:!0,configurable:!0,writable:!0,value:!1}),Object.defineProperty(this,"_color",{enumerable:!0,configurable:!0,writable:!0,value:e=>this.device.colors.get(e,this._normalise)}),Object.defineProperty(this,"_normalise",{enumerable:!0,configurable:!0,writable:!0,value:e=>null===this._ctx?null:function(e,t){const r=e.fillStyle;e.fillStyle="#000000",e.fillStyle=t;const o=e.fillStyle;e.fillStyle="#ffffff",e.fillStyle=t;const i=e.fillStyle;return e.fillStyle=r,"string"==typeof o&&o===i?o:null}(this._ctx,e)}),this.device=e}get batch(){return this._batch}mount(e,t){if(this._canvas=e,this._ctx=t??e.getContext("2d"),null===this._ctx)throw new Error("openalgo-charts: 2D canvas context is not available");this._widthPx=e.width,this._heightPx=e.height,this._acquired=this.device.acquire(),this.device.ensureSize(this._widthPx,this._heightPx)}resize(e,t,r){this._widthPx=Math.round(e*r),this._heightPx=Math.round(t*r),this.device.ensureSize(this._widthPx,this._heightPx)}beginFrame(e){this._batch.reset(),this._frame2d=this.device.lost||null===this.device.gl,e&&null!==this._ctx&&null!==this._canvas&&(this._ctx.setTransform(1,0,0,1,0,0),this._ctx.clearRect(0,0,this._canvas.width,this._canvas.height))}drawSeries(e,i,a,s,u,b,_){if(null===this._ctx)return;!this._frame2d&&this.device.lost&&(this._frame2d=!0,this._batch.reset());const g=this._frame2d?null:function(e){let r=I.get(e);if(void 0===r){r=null;const o=new Set(t.registeredChartTypes());for(const i of q)if(o.has(i)&&t.getChartType(i)===e){r=i;break}I.set(e,r)}return r}(e);if(null===g)return this._flush(),void e.draw(this._ctx,i,a,s,u,b,_);const m=this._batch,p=this._color,w=_.theme;switch(g){case"candlestick":L(m,i,a,s,u,n(b,w),p);break;case"hollow-candle":L(m,i,a,s,u,n(b,w,{hollow:!0}),p);break;case"volume-candle":{const e=_.maxVolume;L(m,i,a,s,u,n(b,w,{widthScale:t=>e>0?(t.volume??0)/e:1}),p);break}case"bar":case"high-low":E(m,i,a,s,u,r(b,w),"high-low"===g,p);break;case"line":U(m,i,a,u,o(b,w),p);break;case"line-markers":U(m,i,a,u,o(b,w,{markers:!0}),p);break;case"step":U(m,i,a,u,o(b,w,{step:!0}),p);break;case"area":!function(e,t,r,o,i,n,l){const a=R;if(f(a,t,r,0),d(a,t,!1,0,8+(n.lineWidth??1.5)),a.n<=a.s)return;const s=i*o;if(s>0){const t=l(n.areaTopColor??"rgba(79,140,255,0.40)"),r=l(n.areaBottomColor??"rgba(79,140,255,0.00)");D(e,a,o,s,e=>C(t,r,e/s),"both")}U(e,t,r,o,{color:n.color??"#4f8cff",lineWidth:n.lineWidth??1.5,lineStyle:n.lineStyle},l)}(m,i,a,u,_.plotHeight,(x=b,y=w,{...x,color:x.color??y.lineColor,areaTopColor:x.areaTopColor??y.areaTopColor,areaBottomColor:x.areaBottomColor??y.areaBottomColor}),p);break;case"hlc-area":!function(e,t,r,o,i,n){if(0===t.length)return;const l=j,a=V,s=8+(i.lineWidth??1.5);f(l,t,r,1),f(a,t,r,2),d(l,t,!1,0,s),d(a,t,!1,0,s);const c=n(i.areaTopColor??"rgba(79,140,255,0.15)"),h=l.xs,u=l.ys,b=a.xs,_=a.ys;let g=-1;for(let t=l.s;t<l.n;t++)Number.isFinite(h[t])&&Number.isFinite(u[t])&&Number.isFinite(_[t])&&(g>=0&&e.quad(h[g]*o,u[g]*o,c,h[t]*o,u[t]*o,c,b[g]*o,_[g]*o,c,b[t]*o,_[t]*o,c),g=t);const m=Math.max(1,Math.round((i.lineWidth??1.5)*o))/2;for(const[t,r]of[[i.highColor,l],[i.lowColor,a]])void 0!==t&&W(e,r,o,m,t,void 0,[],n);U(e,t,r,o,{color:i.closeColor??"#4f8cff",lineWidth:i.lineWidth??1.5},n)}(m,i,a,u,function(e,t){return{...e,closeColor:e.closeColor??t.lineColor}}(b,w),p);break;case"baseline":!function(e,t,r,o,i,n){const l=r(i.baseValue??0)*o,a=R;if(f(a,t,r,0),d(a,t,!1,0,8+(i.lineWidth??1.5)),a.n<=a.s||!Number.isFinite(l))return;if(l>0){const t=n(i.areaTopColor??"rgba(38,166,154,0.20)");D(e,a,o,l,e=>C(t,v,e/l),"above")}const s=n(i.areaBottomColor??"rgba(239,83,80,0.20)");D(e,a,o,l,()=>s,"below");const c=Math.max(1,Math.round((i.lineWidth??1.5)*o))/2,h=n(i.topColor??"#26a69a"),u=n(i.bottomColor??"#ef5350"),b=a.xs,_=a.ys;for(let t=a.s+1;t<a.n;t++){const r=b[t-1],i=_[t-1],n=b[t],a=_[t];if(!(Number.isFinite(r)&&Number.isFinite(i)&&Number.isFinite(n)&&Number.isFinite(a)))continue;const s=(i+a)/2<=l/o;e.segment(r*o,i*o,n*o,a*o,c,s?h:u,!1)}}(m,i,a,u,function(e,t){return{...e,topColor:e.topColor??t.baselineTopLine,bottomColor:e.bottomColor??t.baselineBottomLine,areaTopColor:e.areaTopColor??t.baselineTopFill,areaBottomColor:e.areaBottomColor??t.baselineBottomFill}}(b,w),p);break;case"column":!function(e,t,r,o,i,n,a){const s=l(o,i),c=Math.floor(s/2),u=Math.round(r(n.base??0)*i);for(const o of t){const t=h(o,r,i),l=o.bar.color??n.color??(t.up?n.upColor??"#26a69a":n.downColor??"#ef5350"),b=Math.min(u,t.yClose);e.rect(t.cx-c,b,s,Math.max(1,Math.abs(u-t.yClose)),a(l))}}(m,i,a,s,u,r(b,w),p);break;case"histogram":!function(e,t,r,o,i,n,a,s){const c=l(o,i),h=Math.floor(c/2),u=Math.round(r(a)*i);for(const{x:o,bar:l}of t){const t=Math.round(o*i),a=Math.round(r(l.close)*i),b=Math.min(u,a);e.rect(t-h,b,c,Math.max(1,Math.abs(u-a)),s(l.color??n))}}(m,i,a,s,u,b.color??c,b.base??0,p)}var x,y}endFrame(){this._flush()}overlay2d(){return this._ctx}destroy(){this._acquired&&this.device.release(),this._acquired=!1,this._batch.reset(),this._ctx=null,this._canvas=null}_flush(){const e=this._batch;if(0===e.quadCount||null===this._ctx)return;const t=this._widthPx,r=this._heightPx,o=this.device.surface;t>0&&r>0&&null!==o&&this.device.render(e,t,r)&&this._ctx.drawImage(o,0,0,t,r,0,0,t,r),e.reset()}}function z(e){return void 0===e?F()?new G(k()):null:e.available?new G(e):null}let H=!1;function X(){var e;H||(H=!0,t.registerRenderBackend("webgl2",()=>z(e)))}return X(),e.GlDevice=N,e.WEBGL_TIER="webgl",e.WebGL2Backend=G,e.createWebGL2Backend=z,e.isWebGL2Supported=F,e.registerWebGL2Renderer=X,e.sharedGlDevice=k,e}({},OpenAlgoCharts);