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.
3 lines (2 loc) • 23.1 kB
JavaScript
import{registerRenderBackend as e,registeredChartTypes as t,getChartType as r}from"./openalgo-charts.mjs";function o(e,t){return{...e,upColor:e.upColor??t.upColor,downColor:e.downColor??t.downColor}}function i(e,t,r){return{...e,color:e.color??t.lineColor,...r}}const n={upColor:"#26a69a",downColor:"#ef5350",borderUpColor:"#26a69a",borderDownColor:"#ef5350",wickUpColor:"#26a69a",wickDownColor:"#ef5350",borderVisible:!0,wickVisible:!0};function l(e,t,r={}){return{...n,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??n.borderVisible,bodyVisible:e.bodyVisible??!0,wickVisible:e.wickVisible??n.wickVisible,colorByPreviousClose:e.colorByPreviousClose,...r}}function a(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 s(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 c(e,t,r,o=1){const i=a(t,r),n=Math.max(1,Math.floor(r)),l=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:l,bodyX:l-Math.floor(s/2),bodyW:s,wickX:l-Math.floor(n/2),wickW:n}}const u="#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 b=[];function f(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 d(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)}f(e,t.length)}function _(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],u=s[0],h=c[0];if(n<t||!Number.isFinite(h)||!Number.isFinite(a))e.s=r?2:1,c[0]=NaN;else{const i=Math.hypot(u-n,h-a);let l=u<t?i*(n-t)/(n-u):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+(u-n)*e,c[0]=a+(h-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],u=s[o],h=c[o];n>t||!Number.isFinite(l)||!Number.isFinite(h)?(e.n=o,c[o]=NaN):(u>t&&(c[o]=l+(t-n)/(u-n)*(h-l),s[o]=t,e.n=o+1),e.b=o-1)}}const m=11,g=1e6,v=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*m),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*m}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=v(e)&&v(t)&&v(e+r)&&v(t+o)?0:1,u=n+c,h=l+c,b=this._claim(),f=this.vertices;this._vertex(f,b,a-u,s-h,i,-u,-h,n,l,0),this._vertex(f,b+m,a+u,s-h,i,u,-h,n,l,0),this._vertex(f,b+22,a-u,s+h,i,-u,h,n,l,0),this._vertex(f,b+33,a+u,s+h,i,u,h,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 u=0===c?1:a/c,h=0===c?0:s/c,b=(e+r)/2,f=(t+o)/2,d=c/2,_=d,g=l?0:i,v=l?i:0,p=d+i+1,w=i+1,x=this._claim(),C=this.vertices;this._vertex(C,x,b-u*p+h*w,f-h*p-u*w,n,-p,-w,_,g,v),this._vertex(C,x+m,b+u*p+h*w,f+h*p-u*w,n,p,-w,_,g,v),this._vertex(C,x+22,b-u*p-h*w,f-h*p+u*w,n,-p,w,_,g,v),this._vertex(C,x+33,b+u*p-h*w,f+h*p+u*w,n,p,w,_,g,v)}quad(e,t,r,o,i,n,l,a,s,c,u,h){const b=this._claim(),f=this.vertices;this._vertex(f,b,e,t,r,0,0,g,g,0),this._vertex(f,b+m,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,u,h,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*m;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*m);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 w=[0,0,0,0];function x(e){return e>0?e<1?e:1:0}function C(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=x(t.a);return[x(t.r/255)*r,x(t.g/255)*r,x(t.b/255)*r,r]}function y(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 M{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=C(e)??void 0,void 0===r&&void 0!==t){const o=t(e);null!==o&&(r=C(o)??void 0)}return void 0===r&&(r=w),this._map.size>=4096&&this._map.clear(),this._map.set(e,r),r}get size(){return this._map.size}clear(){this._map.clear()}}function P(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 N={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 S{constructor(e=A){Object.defineProperty(this,"colors",{enumerable:!0,configurable:!0,writable:!0,value:new M}),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",N)??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=P(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=P(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 k=null;function F(){return null===k&&(k=new S),k}function O(){return void 0!==globalThis.WebGL2RenderingContext&&F().available}function E(e,t,r,o,i,n,l){const a=t-n/2,s=r-n/2,c=o+n,u=i+n;o-n<=0||i-n<=0?e.rect(a,s,c,u,l):(e.rect(a,s,c,n,l),e.rect(a,s+u-n,c,n,l),e.rect(a,s+n,n,u-2*n,l),e.rect(a+c-n,s+n,n,u-2*n,l))}function L(e,t,r,o,i,n,l){const u=a(o,i),h=Math.max(1,Math.floor(i)),b=n.widthScale?null:s(u,h,n);for(let a=0;a<t.length;a++){const{x:u,bar:f}=t[a],d=a>0?t[a-1].bar.close:t[a].prevClose,_=!0===n.colorByPreviousClose&&void 0!==d&&Number.isFinite(d)?f.close>=d:f.close>=f.open,m=Math.round(r(f.open)*i),g=Math.round(r(f.close)*i),v=Math.round(r(f.high)*i),p=Math.round(r(f.low)*i),w=c(u,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),N=f.wickColor??M??(_?n.wickUpColor:n.wickDownColor),A=f.borderColor??M??(_?n.borderUpColor:n.borderDownColor);if(n.wickVisible&&e.rect(w.wickX,v,w.wickW,Math.max(1,p-v),l(N)),"wick"===(b??s(C,h,n))&&N===P)continue;const S=Math.min(m,g),k=Math.max(1,Math.abs(g-m));if(n.hollow&&_)E(e,x-y+.5,S+.5,C-1,k-1,Math.max(1,h),l(n.borderVisible?A:P));else{const t=!1!==n.bodyVisible;t&&e.rect(x-y,S,C,k,l(P)),n.borderVisible&&(!t||C>=3)&&E(e,x-y+.5,S+.5,C-1,k-1,1,l(A))}}}function T(e,t,r,o,i,n,l,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(a(o,i)/2),u+1);for(let o=0;o<t.length;o++){const a=t[o],f=h(a,r,i),d=o>0?t[o-1].bar.close:a.prevClose,_=!0===n.colorByPreviousClose&&void 0!==d&&Number.isFinite(d)?a.bar.close>=d:f.up,m=s(a.bar.color??(_?n.upColor??"#26a69a":n.downColor??"#ef5350"));e.rect(f.cx-u,f.yHigh,c,Math.max(1,f.yLow-f.yHigh),m),l||(e.rect(f.cx-b,f.yOpen-u,b,c,m),e.rect(f.cx,f.yClose-u,b,c,m))}}function R(e,t,r,o,i,n,l,a,s){const c=Math.hypot(o-t,i-r);if(0===c)return;const u=(o-t)/c,h=(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+u*b,r+h*b,t+u*(b+o),r+h*(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 j={xs:[],ys:[],s:0,n:0,a:-1,b:-1},B={xs:[],ys:[],s:0,n:0,a:-1,b:-1},V={xs:[],ys:[],s:0,n:0,a:-1,b:-1},U={xs:[],ys:[],s:0,n:0,a:-1,b:-1};function q(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 u=s.length>0&&c>0,h={idx:0,rem:u?s[0]:0},b=t.xs,f=t.ys;let d,_=-1,m=a(i);for(let l=t.s;l<t.n;l++){const c=b[l],g=f[l];if(!Number.isFinite(c)||!Number.isFinite(g)){_=-1;continue}if(_<0){_=l,h.idx=0,h.rem=u?s[0]:0;continue}const v=void 0===n?d:n[l];v!==d&&(d=v,m=a(v??i),h.idx=0,h.rem=u?s[0]:0),u?R(e,b[_]*r,f[_]*r,c*r,g*r,o,m,s,h):e.segment(b[_]*r,f[_]*r,c*r,g*r,o,m,!0),l===t.a&&(h.idx=0,h.rem=u?s[0]:0),_=l}}function W(e,t,r,o,i,n){const l=j;d(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];f(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&&(b[o++]=i),b[o++]=i}return b.length=o,b}(t,!0===i.step),c=i.color??"#4f8cff",u=i.lineWidth??1.5,h=Math.max(1,u*o)/2,m=function(e,t){return"dashed"===e?[6*t,4*t]:"dotted"===e?[1*t,3*t]:[]}(i.lineStyle,o);if(_(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}(m,o),8+u),i.markersOnly||q(e,a,o,h,c,s,m,n),i.markers||i.markersOnly){const r=(i.markerRadius??2)*o;for(let i=0;i<t.length;i++){const a=l.xs[i],u=l.ys[i];if(!Number.isFinite(a)||!Number.isFinite(u)||void 0!==t[i].edgeX)continue;const h=n(void 0!==s?t[i].bar.color??c:c);e.segment(a*o,u*o,a*o,u*o,r,h,!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 u=t.xs[c]*r,h=t.ys[c]*r;if(Number.isFinite(u)&&Number.isFinite(h)){if(Number.isFinite(a)){const t=s<=o,r=h<=o;if(t===r)"both"!==n&&"above"===n!==t||e.quad(a,s,i(s),u,h,i(h),a,o,l,u,o,l);else{const c=a+(u-a)*(o-s)/(h-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(u,h,i(h),c,o,l,u,o,l)}}a=u,s=h}}}const I=["candlestick","hollow-candle","volume-candle","bar","high-low","line","line-markers","step","area","hlc-area","baseline","column","histogram"],z=new WeakMap;class G{constructor(e=F()){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,n,s,c,b,f,m){if(null===this._ctx)return;!this._frame2d&&this.device.lost&&(this._frame2d=!0,this._batch.reset());const g=this._frame2d?null:function(e){let o=z.get(e);if(void 0===o){o=null;const i=new Set(t());for(const t of I)if(i.has(t)&&r(t)===e){o=t;break}z.set(e,o)}return o}(e);if(null===g)return this._flush(),void e.draw(this._ctx,n,s,c,b,f,m);const v=this._batch,p=this._color,x=m.theme;switch(g){case"candlestick":L(v,n,s,c,b,l(f,x),p);break;case"hollow-candle":L(v,n,s,c,b,l(f,x,{hollow:!0}),p);break;case"volume-candle":{const e=m.maxVolume;L(v,n,s,c,b,l(f,x,{widthScale:t=>e>0?(t.volume??0)/e:1}),p);break}case"bar":case"high-low":T(v,n,s,c,b,o(f,x),"high-low"===g,p);break;case"line":W(v,n,s,b,i(f,x),p);break;case"line-markers":W(v,n,s,b,i(f,x,{markers:!0}),p);break;case"step":W(v,n,s,b,i(f,x,{step:!0}),p);break;case"area":!function(e,t,r,o,i,n,l){const a=j;if(d(a,t,r,0),_(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=>y(t,r,e/s),"both")}W(e,t,r,o,{color:n.color??"#4f8cff",lineWidth:n.lineWidth??1.5,lineStyle:n.lineStyle},l)}(v,n,s,b,m.plotHeight,(C=f,M=x,{...C,color:C.color??M.lineColor,areaTopColor:C.areaTopColor??M.areaTopColor,areaBottomColor:C.areaBottomColor??M.areaBottomColor}),p);break;case"hlc-area":!function(e,t,r,o,i,n){if(0===t.length)return;const l=V,a=U,s=8+(i.lineWidth??1.5);d(l,t,r,1),d(a,t,r,2),_(l,t,!1,0,s),_(a,t,!1,0,s);const c=n(i.areaTopColor??"rgba(79,140,255,0.15)"),u=l.xs,h=l.ys,b=a.xs,f=a.ys;let m=-1;for(let t=l.s;t<l.n;t++)Number.isFinite(u[t])&&Number.isFinite(h[t])&&Number.isFinite(f[t])&&(m>=0&&e.quad(u[m]*o,h[m]*o,c,u[t]*o,h[t]*o,c,b[m]*o,f[m]*o,c,b[t]*o,f[t]*o,c),m=t);const g=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&&q(e,r,o,g,t,void 0,[],n);W(e,t,r,o,{color:i.closeColor??"#4f8cff",lineWidth:i.lineWidth??1.5},n)}(v,n,s,b,function(e,t){return{...e,closeColor:e.closeColor??t.lineColor}}(f,x),p);break;case"baseline":!function(e,t,r,o,i,n){const l=r(i.baseValue??0)*o,a=j;if(d(a,t,r,0),_(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=>y(t,w,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,u=n(i.topColor??"#26a69a"),h=n(i.bottomColor??"#ef5350"),b=a.xs,f=a.ys;for(let t=a.s+1;t<a.n;t++){const r=b[t-1],i=f[t-1],n=b[t],a=f[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?u:h,!1)}}(v,n,s,b,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}}(f,x),p);break;case"column":!function(e,t,r,o,i,n,l){const s=a(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),a=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)),l(a))}}(v,n,s,c,b,o(f,x),p);break;case"histogram":!function(e,t,r,o,i,n,l,s){const c=a(o,i),u=Math.floor(c/2),h=Math.round(r(l)*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(h,a);e.rect(t-u,b,c,Math.max(1,Math.abs(h-a)),s(l.color??n))}}(v,n,s,c,b,f.color??u,f.base??0,p)}var C,M}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 H(e){return void 0===e?O()?new G(F()):null:e.available?new G(e):null}const X="webgl";let Y=!1;function $(){var t;Y||(Y=!0,e("webgl2",()=>H(t)))}$();export{S as GlDevice,X as WEBGL_TIER,G as WebGL2Backend,H as createWebGL2Backend,O as isWebGL2Supported,$ as registerWebGL2Renderer,F as sharedGlDevice};
//# sourceMappingURL=openalgo-charts.webgl.mjs.map