diff --git a/README.md b/README.md index 9bb6568..e420a99 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,10 @@ Open source javascript module for rendering high performance, large scale heatma Visual Heatmap is based on advanced graphical rendering context - WebGL/Shaders. It can render 500,000+ data points with a good framerate.

- - - + + + +

## Installing diff --git a/demo/heatmap1.html b/demo/heatmap1.html index 44d1b62..fceb73b 100644 --- a/demo/heatmap1.html +++ b/demo/heatmap1.html @@ -7,7 +7,7 @@
- Smiley face +
@@ -18,6 +18,11 @@ size: 15.0, max: 100, intensity: 1.0, + backgroundImage: { + url: "./world_map_PNG14.png", + x: 0, + y: 0 + }, gradient: [{ color: [0, 0, 0, 0.0], offset: 0 @@ -38,7 +43,7 @@ var gui = new dat.GUI(); var Params = function() { - this.points = 100; + this.points = 20000; this.size = 15; this.opacity = 1.0; this.intensity = 1.0; @@ -77,7 +82,7 @@ instance.setRotationAngle(params.rotationAngle); } ); - data = generateData(100000); + data = generateData(20000); instance.renderData(data); function generateData (count) { diff --git a/demo/heatmap2.html b/demo/heatmap2.html index 0b6c035..8c22eb1 100644 --- a/demo/heatmap2.html +++ b/demo/heatmap2.html @@ -7,7 +7,7 @@
- Smiley face +
@@ -19,6 +19,13 @@ let instance = Heatmap('#canvas', { size: 15.0, max: 100, + backgroundImage: { + url: "./world_map_PNG14.png", + // height: 553.5* 2, + // width: 864*2, + x: 0, + y: 0 + }, gradient: [{ color: [0, 0, 0, 0.0], offset: 0.0 @@ -35,7 +42,7 @@ }); var gui = new dat.GUI(); - var Params = function() { + var ParamsCon = function() { this.points = 100000; this.size = 15; this.opacity = 1.0; @@ -48,7 +55,7 @@ } }; - var params = new Params(); + var params = new ParamsCon(); gui.add( params, 'size', 10, 100 ).onChange( function () { instance.setSize(params.size); } ); diff --git a/demo/heatmap3.html b/demo/heatmap3.html index e49a5e7..4d474db 100644 --- a/demo/heatmap3.html +++ b/demo/heatmap3.html @@ -20,6 +20,13 @@ max: 100, intensity: 1.0, zoom: 1.0, + backgroundImage: { + url: "./world_map_PNG14.png", + // height: 553.5* 2, + // width: 864*2, + x: 0, + y: 0 + }, gradient: [{ color: [255, 255, 255, 0.0], offset: 0 @@ -39,7 +46,7 @@ }); var gui = new dat.GUI(); - var Params = function() { + var ParamsCon = function() { this.points = 10000; this.size = 100; this.opacity = 1.0; @@ -52,7 +59,7 @@ } }; - var params = new Params(); + var params = new ParamsCon(); gui.add( params, 'size', 1, 100 ).onChange( function () { instance.setSize(params.size); } ); diff --git a/demo/heatmapWithLabels.html b/demo/heatmapWithLabels.html index 2e83c1f..1ca9125 100644 --- a/demo/heatmapWithLabels.html +++ b/demo/heatmapWithLabels.html @@ -8,8 +8,7 @@
- - + @@ -45,7 +44,7 @@ }); var gui = new dat.GUI(); - var Params = function() { + var ParamsCon = function() { this.points = 100; this.size = 50; this.opacity = 1.0; @@ -59,7 +58,7 @@ } }; - var params = new Params(); + var params = new ParamsCon(); gui.add( params, 'points', 1, 1000000 ).onChange( function () { data = generateData(params.points); instance.renderData(data); diff --git a/demo/heatmap_withImage.html b/demo/heatmap_withImage.html deleted file mode 100644 index 16b5ad9..0000000 --- a/demo/heatmap_withImage.html +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - - - -
-
- - - - - - - \ No newline at end of file diff --git a/dist/visualHeatmap.esm.js b/dist/visualHeatmap.esm.js index 730405d..6081a79 100644 --- a/dist/visualHeatmap.esm.js +++ b/dist/visualHeatmap.esm.js @@ -226,8 +226,8 @@ function Heatmap (context, config = {}) { this.gradient = gradientMapper(config.gradient); this.ctx = ctx; - this.width = width * ratio; - this.height = height * ratio; + this.width = width; + this.height = height; this.layer = layer; this.dom = res; this.gradShadOP = createGradiantShader(this.ctx); @@ -264,9 +264,9 @@ function Heatmap (context, config = {}) { this.layer.setAttribute('width', width * ratio); this.layer.style.height = `${height}px`; this.layer.style.width = `${width}px`; - this.width = width * ratio; - this.height = height * ratio; - this.ctx.viewport(0, 0, this.width, this.height); + this.width = width; + this.height = height; + this.ctx.viewport(0, 0, this.width * ratio, this.height * ratio); /* Perform update */ this.render(this.exData); @@ -387,16 +387,19 @@ function Heatmap (context, config = {}) { Chart.prototype.projection = function (data) { // Pre-compute constants and repetitive calculations const zoomFactor = this.zoom || 0.1; - const halfWidth = this.width / (2 * ratio); - const halfHeight = this.height / (2 * ratio); + const halfWidth = this.width / 2; + const halfHeight = this.height / 2; const translateX = this.translate[0]; const translateY = this.translate[1]; const angle = this.angle; + const aspect = this.width / this.height; // Calculate the adjusted positions let posX = (data.x + translateX - halfWidth) / (halfWidth * zoomFactor); let posY = (data.y + translateY - halfHeight) / (halfHeight * zoomFactor); + posX *= aspect; + // Rotate the point if there's an angle if (angle !== 0.0) { const cosAngle = Math.cos(-angle); @@ -406,6 +409,8 @@ function Heatmap (context, config = {}) { posX = xNew; } + posX *= 1.0 / aspect; + // Scale back and adjust the position posX = (posX * halfWidth) + halfWidth; posY = (posY * halfHeight) + halfHeight; @@ -420,7 +425,7 @@ function Heatmap (context, config = {}) { ctx.clear(ctx.COLOR_BUFFER_BIT | ctx.DEPTH_BUFFER_BIT); ctx.bindTexture(ctx.TEXTURE_2D, this.fbTexObj); - ctx.texImage2D(ctx.TEXTURE_2D, 0, ctx.RGBA, this.width, this.height, 0, ctx.RGBA, ctx.UNSIGNED_BYTE, null); + ctx.texImage2D(ctx.TEXTURE_2D, 0, ctx.RGBA, this.width * this.ratio, this.height * this.ratio, 0, ctx.RGBA, ctx.UNSIGNED_BYTE, null); ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_S, ctx.CLAMP_TO_EDGE); ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_T, ctx.CLAMP_TO_EDGE); ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.LINEAR); @@ -444,7 +449,7 @@ function Heatmap (context, config = {}) { this.gradShadOP.attr[0].data = exData.posVec || []; this.gradShadOP.attr[1].data = exData.rVec || []; - ctx.uniform2fv(this.gradShadOP.uniform.u_resolution, new Float32Array([this.width, this.height])); + ctx.uniform2fv(this.gradShadOP.uniform.u_resolution, new Float32Array([this.width * this.ratio, this.height * this.ratio])); ctx.uniform2fv(this.gradShadOP.uniform.u_translate, new Float32Array([this.translate[0], this.translate[1]])); ctx.uniform1f(this.gradShadOP.uniform.u_zoom, this.zoom ? this.zoom : 0.01); ctx.uniform1f(this.gradShadOP.uniform.u_angle, this.angle); @@ -469,7 +474,7 @@ function Heatmap (context, config = {}) { ctx.useProgram(this.imageShaOP.program); - ctx.uniform2fv(this.imageShaOP.uniform.u_resolution, new Float32Array([this.width, this.height])); + ctx.uniform2fv(this.imageShaOP.uniform.u_resolution, new Float32Array([this.width * this.ratio, this.height * this.ratio])); ctx.uniform2fv(this.imageShaOP.uniform.u_translate, new Float32Array([this.translate[0], this.translate[1]])); ctx.uniform1f(this.imageShaOP.uniform.u_zoom, this.zoom ? this.zoom : 0.01); ctx.uniform1f(this.imageShaOP.uniform.u_angle, this.angle); @@ -514,8 +519,8 @@ function Heatmap (context, config = {}) { function transCoOr (data) { const zoomFactor = this.zoom || 0.1; - const halfWidth = this.width / (2 * ratio); - const halfHeight = this.height / (2 * ratio); + const halfWidth = this.width / 2; + const halfHeight = this.height / 2; const angle = this.angle; // Combine operations to reduce the number of arithmetic steps @@ -573,9 +578,11 @@ var GradShaders = { uniform float u_density; varying float v_i; - vec2 rotation(vec2 v, float a) { + vec2 rotation(vec2 v, float a, float aspect) { float s = sin(a); float c = cos(a); mat2 m = mat2(c, -s, s, c); - return m * v; + mat2 scaleMat = mat2(aspect, 0.0, 0.0, 1.0); + mat2 scaleMatInv = mat2(1.0/aspect, 0.0, 0.0, 1.0); + return scaleMatInv * m * scaleMat * v; } void main() { @@ -587,7 +594,7 @@ var GradShaders = { } zeroToTwo = zeroToTwo / zoomFactor; if (u_angle != 0.0) { - zeroToTwo = rotation(zeroToTwo, u_angle); + zeroToTwo = rotation(zeroToTwo, u_angle, u_resolution.x / u_resolution.y); } gl_Position = vec4(zeroToTwo , 0, 1); gl_PointSize = u_size * u_density; @@ -698,9 +705,11 @@ var imageShaders = { uniform float u_density; out vec2 v_texCoord; - vec2 rotation(vec2 v, float a) { - float s = sin(a); float c = cos(a); mat2 m = mat2(c, -s, s, c); - return m * v; + vec2 rotation(vec2 v, float a, float aspect) { + float s = sin(a); float c = cos(a); mat2 m = mat2(c, -s, s, c); + mat2 scaleMat = mat2(aspect, 0.0, 0.0, 1.0); + mat2 scaleMatInv = mat2(1.0/aspect, 0.0, 0.0, 1.0); + return scaleMatInv * m * scaleMat * v; } void main() { @@ -713,7 +722,7 @@ var imageShaders = { } zeroToTwo = zeroToTwo / zoomFactor; if (u_angle != 0.0) { - zeroToTwo = rotation(zeroToTwo, u_angle); + zeroToTwo = rotation(zeroToTwo, u_angle * -1.0, u_resolution.x / u_resolution.y); } gl_Position = vec4(zeroToTwo , 0, 1); diff --git a/dist/visualHeatmap.esm.min.js b/dist/visualHeatmap.esm.min.js index 1cc89bc..4175c16 100644 --- a/dist/visualHeatmap.esm.min.js +++ b/dist/visualHeatmap.esm.min.js @@ -3,4 +3,4 @@ * (c) 2023 Narayana Swamy (narayanaswamy14@gmail.com) * @license BSD-3-Clause */ -function t(t,i={}){let a,n,u,f,s,l=[],c=[],_=0,h=null,m=null,d=null;function g(t,o,e){var r=t.createShader(t[o]);if(t.shaderSource(r,e),t.compileShader(r),!t.getShaderParameter(r,t.COMPILE_STATUS)){var i=t.getShaderInfoLog(r);console.error("*** Error compiling shader '"+r+"':"+i),t.deleteShader(r)}return r}function p(t,o){var e=g(t,"VERTEX_SHADER",o.vertex),r=g(t,"FRAGMENT_SHADER",o.fragment),i=t.createProgram();if(t.attachShader(i,e),t.attachShader(i,r),t.linkProgram(i),t.getProgramParameter(i,t.LINK_STATUS))return i;var a=t.getProgramInfoLog(i);return console.error("Error in program linking:"+a),t.deleteProgram(i),null}function T(t,i){let n;if("string"==typeof t)n=document.querySelector(t);else{if(!(t instanceof Element))throw new Error("Context must be either a string or an Element");n=t}const u=n.clientHeight,f=n.clientWidth,s=document.createElement("canvas"),l=s.getContext("webgl2",{premultipliedAlpha:!1,depth:!1,antialias:!0,alpha:!0,preserveDrawingBuffer:!1});a=function(t){const o=window.devicePixelRatio||1,e=t.webkitBackingStorePixelRatio||t.mozBackingStorePixelRatio||t.msBackingStorePixelRatio||t.oBackingStorePixelRatio||t.backingStorePixelRatio||1;return o/e}(l),l.clearColor(0,0,0,0),l.enable(l.BLEND),l.blendEquation(l.FUNC_ADD),l.blendFunc(l.ONE,l.ONE_MINUS_SRC_ALPHA),l.depthMask(!0),s.setAttribute("height",u*a),s.setAttribute("width",f*a),s.style.height=`${u}px`,s.style.width=`${f}px`,s.style.position="absolute",n.appendChild(s),this.gradient=function(t){const o=[],e=t.length,r=[];return t.forEach((function(t){o.push(t.color[0]/255),o.push(t.color[1]/255),o.push(t.color[2]/255),o.push(void 0===t.color[3]?1:t.color[3]),r.push(t.offset)})),{value:new Float32Array(o),length:e,offset:r}}(i.gradient),this.ctx=l,this.width=f*a,this.height=u*a,this.layer=s,this.dom=n,this.gradShadOP=function(t){var e=p(t,o);return{program:e,attr:[{bufferType:t.ARRAY_BUFFER,buffer:t.createBuffer(),drawType:t.STATIC_DRAW,valueType:t.FLOAT,size:2,attribute:t.getAttribLocation(e,"a_position"),data:new Float32Array([])},{bufferType:t.ARRAY_BUFFER,buffer:t.createBuffer(),drawType:t.STATIC_DRAW,valueType:t.FLOAT,size:1,attribute:t.getAttribLocation(e,"a_intensity"),data:new Float32Array([])}],uniform:{u_resolution:t.getUniformLocation(e,"u_resolution"),u_max:t.getUniformLocation(e,"u_max"),u_min:t.getUniformLocation(e,"u_min"),u_size:t.getUniformLocation(e,"u_size"),u_intensity:t.getUniformLocation(e,"u_intensity"),u_translate:t.getUniformLocation(e,"u_translate"),u_zoom:t.getUniformLocation(e,"u_zoom"),u_angle:t.getUniformLocation(e,"u_angle"),u_density:t.getUniformLocation(e,"u_density")}}}(this.ctx),this.colorShadOP=function(t){var o=p(t,e);return{program:o,attr:[{bufferType:t.ARRAY_BUFFER,buffer:t.createBuffer(),drawType:t.STATIC_DRAW,valueType:t.FLOAT,size:2,attribute:t.getAttribLocation(o,"a_texCoord"),data:new Float32Array([0,0,1,0,0,1,0,1,1,0,1,1])}],uniform:{u_framebuffer:t.getUniformLocation(o,"u_framebuffer"),u_colorArr:t.getUniformLocation(o,"u_colorArr"),u_colorCount:t.getUniformLocation(o,"u_colorCount"),u_opacity:t.getUniformLocation(o,"u_opacity"),u_offset:t.getUniformLocation(o,"u_offset")}}}(this.ctx),this.imageShaOP=function(t){var o=p(t,r);return{program:o,attr:[{bufferType:t.ARRAY_BUFFER,buffer:t.createBuffer(),drawType:t.STATIC_DRAW,valueType:t.FLOAT,size:2,attribute:t.getAttribLocation(o,"a_position"),data:new Float32Array([])},{bufferType:t.ARRAY_BUFFER,buffer:t.createBuffer(),drawType:t.STATIC_DRAW,valueType:t.FLOAT,size:2,attribute:t.getAttribLocation(o,"a_texCoord"),data:new Float32Array([0,0,1,0,0,1,0,1,1,0,1,1])}],uniform:{u_resolution:t.getUniformLocation(o,"u_resolution"),u_image:t.getUniformLocation(o,"u_image"),u_translate:t.getUniformLocation(o,"u_translate"),u_zoom:t.getUniformLocation(o,"u_zoom"),u_angle:t.getUniformLocation(o,"u_angle"),u_density:t.getUniformLocation(o,"u_density")}}}(this.ctx),this.fbTexObj=l.createTexture(),this.fbo=l.createFramebuffer(),this.size=i.size?i.size:20,m=i.max?i.max:null,h=i.min?i.min:null,this.intensity=i.intensity?i.intensity:1,this.translate=i.translate&&2===i.translate.length?i.translate:[0,0],this.zoom=i.zoom?i.zoom:1,this.angle=i.rotationAngle?i.rotationAngle:0,this.opacity=i.opacity?i.opacity:1,this.ratio=a,i.backgroundImage&&i.backgroundImage.url&&this.setBackgroundImage(i.backgroundImage),this.rawData=[],l.viewport(0,0,l.canvas.width,l.canvas.height),this.render(this.exData||{})}function x(t,o){t.useProgram(this.gradShadOP.program),this.min=null!==h?h:o?.minMax?.min??0,this.max=null!==m?m:o?.minMax?.max??0,this.gradShadOP.attr[0].data=o.posVec||[],this.gradShadOP.attr[1].data=o.rVec||[],t.uniform2fv(this.gradShadOP.uniform.u_resolution,new Float32Array([this.width,this.height])),t.uniform2fv(this.gradShadOP.uniform.u_translate,new Float32Array([this.translate[0],this.translate[1]])),t.uniform1f(this.gradShadOP.uniform.u_zoom,this.zoom?this.zoom:.01),t.uniform1f(this.gradShadOP.uniform.u_angle,this.angle),t.uniform1f(this.gradShadOP.uniform.u_density,this.ratio),t.uniform1f(this.gradShadOP.uniform.u_max,this.max),t.uniform1f(this.gradShadOP.uniform.u_min,this.min),t.uniform1f(this.gradShadOP.uniform.u_size,this.size),t.uniform1f(this.gradShadOP.uniform.u_intensity,this.intensity),this.gradShadOP.attr.forEach((function(o){t.bindBuffer(o.bufferType,o.buffer),t.bufferData(o.bufferType,o.data,o.drawType),t.enableVertexAttribArray(o.attribute),t.vertexAttribPointer(o.attribute,o.size,o.valueType,!0,0,0)})),t.drawArrays(t.POINTS,0,(this.exData.posVec||[]).length/2)}function A(t){const{x:o=0,y:e=0,width:r=0,height:i=0}=this.imageConfig;t.useProgram(this.imageShaOP.program),t.uniform2fv(this.imageShaOP.uniform.u_resolution,new Float32Array([this.width,this.height])),t.uniform2fv(this.imageShaOP.uniform.u_translate,new Float32Array([this.translate[0],this.translate[1]])),t.uniform1f(this.imageShaOP.uniform.u_zoom,this.zoom?this.zoom:.01),t.uniform1f(this.imageShaOP.uniform.u_angle,this.angle),t.uniform1f(this.imageShaOP.uniform.u_density,this.ratio),this.imageShaOP.attr[0].data=new Float32Array([o,e,o+r,e,o,e+i,o,e+i,o+r,e,o+r,e+i]),this.imageShaOP.attr.forEach((function(o){t.bindBuffer(o.bufferType,o.buffer),t.bufferData(o.bufferType,o.data,o.drawType),t.enableVertexAttribArray(o.attribute),t.vertexAttribPointer(o.attribute,o.size,o.valueType,!0,0,0)})),t.uniform1i(this.imageShaOP.uniform.u_image,0),t.activeTexture(this.ctx.TEXTURE0),t.bindTexture(this.ctx.TEXTURE_2D,this.imageTexture),t.drawArrays(t.TRIANGLES,0,6)}function y(t){t.useProgram(this.colorShadOP.program),t.uniform4fv(this.colorShadOP.uniform.u_colorArr,this.gradient.value),t.uniform1f(this.colorShadOP.uniform.u_colorCount,this.gradient.length),t.uniform1fv(this.colorShadOP.uniform.u_offset,new Float32Array(this.gradient.offset)),t.uniform1f(this.colorShadOP.uniform.u_opacity,this.opacity),this.colorShadOP.attr.forEach((function(o){t.bindBuffer(o.bufferType,o.buffer),t.bufferData(o.bufferType,o.data,o.drawType),t.enableVertexAttribArray(o.attribute),t.vertexAttribPointer(o.attribute,o.size,o.valueType,!0,0,0)})),t.uniform1i(this.colorShadOP.uniform.u_framebuffer,0),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this.fbTexObj),t.drawArrays(t.TRIANGLES,0,6)}function v(t){const o=this.zoom||.1,e=this.width/(2*a),r=this.height/(2*a),i=this.angle;let n=(t.x-e)/e*o,u=(t.y-r)/r*o;if(0!==i){const t=Math.cos(i),o=Math.sin(i),e=t*n-o*u;u=o*n+t*u,n=e}return n=n*e+e-this.translate[0],u=u*r+r-this.translate[1],{x:n,y:u}}return T.prototype.resize=function(){const t=this.dom.clientHeight,o=this.dom.clientWidth;this.layer.setAttribute("height",t*a),this.layer.setAttribute("width",o*a),this.layer.style.height=`${t}px`,this.layer.style.width=`${o}px`,this.width=o*a,this.height=t*a,this.ctx.viewport(0,0,this.width,this.height),this.render(this.exData)},T.prototype.clear=function(){this.ctx.clear(this.ctx.COLOR_BUFFER_BIT|this.ctx.DEPTH_BUFFER_BIT)},T.prototype.setMax=function(t){m=t,this.render(this.exData)},T.prototype.setMin=function(t){h=t,this.render(this.exData)},T.prototype.setTranslate=function(t){this.translate=2===t.length?t:[0,0],this.render(this.exData)},T.prototype.setZoom=function(t){this.zoom=void 0!==t?t:1,this.render(this.exData)},T.prototype.setRotationAngle=function(t){this.angle=void 0!==t?t:0,this.render(this.exData)},T.prototype.setSize=function(t){this.size=void 0!==t?t:20,this.render(this.exData)},T.prototype.setIntensity=function(t){this.intensity=void 0!==t?t:1,this.render(this.exData)},T.prototype.setOpacity=function(t){this.opacity=void 0!==t?t:1,this.render(this.exData)},T.prototype.setBackgroundImage=function(t){const o=this;t.url&&(d=this.ctx.getParameter(this.ctx.MAX_TEXTURE_SIZE),this.imageTexture=this.ctx.createTexture(),this.type="TEXTURE_2D",this.imageConfig=null,f=t.width||this.width,s=t.height||this.height,f=f>d?d:f,s=s>d?d:s,function(t,o,e){const r=new Image;r.crossOrigin="anonymous",r.onload=o,r.onerror=e,r.src=t}(t.url,(function(){o.ctx.activeTexture(o.ctx.TEXTURE0),o.ctx.bindTexture(o.ctx.TEXTURE_2D,o.imageTexture),o.ctx.texParameteri(o.ctx.TEXTURE_2D,o.ctx.TEXTURE_WRAP_S,o.ctx.CLAMP_TO_EDGE),o.ctx.texParameteri(o.ctx.TEXTURE_2D,o.ctx.TEXTURE_WRAP_T,o.ctx.CLAMP_TO_EDGE),o.ctx.texParameteri(o.ctx.TEXTURE_2D,o.ctx.TEXTURE_MIN_FILTER,o.ctx.LINEAR),o.ctx.texParameteri(o.ctx.TEXTURE_2D,o.ctx.TEXTURE_MAG_FILTER,o.ctx.LINEAR),o.ctx.texImage2D(o.ctx.TEXTURE_2D,0,o.ctx.RGBA,this.naturalWidth,this.naturalHeight,0,o.ctx.RGBA,o.ctx.UNSIGNED_BYTE,this),o.imageConfig={x:t.x||0,y:t.y||0,height:s,width:f,image:this},o.render(o.exData||{})}),(function(t){console.error("Image Load Error",t)})))},T.prototype.addData=function(t,o){const e=this;for(let r=0;rt[r].value&&(e.min=t[r].value),e.max 0.0 && alpha <= 1.0) {\n\t\t\tvec4 color_;\n\t\t\tif (alpha <= u_offset[0]) {\n\t\t\t\tcolor_ = u_colorArr[0];\n\t\t\t} else if (alpha <= u_offset[1]) {\n\t\t\t\tcolor_ = mix( u_colorArr[0], u_colorArr[1], remap( u_offset[0], u_offset[1], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[0][3], u_colorArr[1][3], remap( u_offset[0], u_offset[1], alpha ));\n\t\t\t} else if (alpha <= u_offset[2]) {\n\t\t\t\tcolor_ = mix( u_colorArr[1], u_colorArr[2], remap( u_offset[1], u_offset[2], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[1][3], u_colorArr[2][3], remap( u_offset[1], u_offset[2], alpha ));\n\t\t\t} else if (alpha <= u_offset[3]) {\n\t\t\t\tcolor_ = mix( u_colorArr[2], u_colorArr[3], remap( u_offset[2], u_offset[3], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[2][3], u_colorArr[3][3], remap( u_offset[2], u_offset[3], alpha ));\n\t\t\t} else if (alpha <= u_offset[4]) {\n\t\t\t\tcolor_ = mix( u_colorArr[3], u_colorArr[4], remap( u_offset[3], u_offset[4], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[3][3], u_colorArr[4][3], remap( u_offset[3], u_offset[4], alpha ));\n\t\t\t} else if (alpha <= u_offset[5]) {\n\t\t\t\tcolor_ = mix( u_colorArr[4], u_colorArr[5], remap( u_offset[4], u_offset[5], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[4][3], u_colorArr[5][3], remap( u_offset[4], u_offset[5], alpha ));\n\t\t\t} else if (alpha <= u_offset[6]) {\n\t\t\t\tcolor_ = mix( u_colorArr[5], u_colorArr[6], remap( u_offset[5], u_offset[6], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[5][3], u_colorArr[6][3], remap( u_offset[5], u_offset[6], alpha ));\n\t\t\t} else if (alpha <= u_offset[7]) {\n\t\t\t\tcolor_ = mix( u_colorArr[6], u_colorArr[7], remap( u_offset[6], u_offset[7], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[6][3], u_colorArr[7][3], remap( u_offset[6], u_offset[7], alpha ));\n\t\t\t} else if (alpha <= u_offset[8]) {\n\t\t\t\tcolor_ = mix( u_colorArr[7], u_colorArr[8], remap( u_offset[7], u_offset[8], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[7][3], u_colorArr[8][3], remap( u_offset[7], u_offset[8], alpha ));\n\t\t\t} else if (alpha <= u_offset[9]) {\n\t\t\t\tcolor_ = mix( u_colorArr[8], u_colorArr[9], remap( u_offset[8], u_offset[9], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[8][3], u_colorArr[9][3], remap( u_offset[8], u_offset[9], alpha ));\n\t\t\t} else if (alpha <= u_offset[10]) {\n\t\t\t\tcolor_ = mix( u_colorArr[9], u_colorArr[10], remap( u_offset[9], u_offset[10], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[9][3], u_colorArr[10][3], remap( u_offset[9], u_offset[10], alpha ));\n\t\t\t} else {\n\t\t\t\tcolor_ = vec4(0.0, 0.0, 0.0, 0.0);\n\t\t\t}\n\t\t\tcolor_ = color_ * u_opacity;\n\t\t\tif (color_.a < 0.0) {\n\t\t\t\tcolor_.a = 0.0;\n\t\t\t}\n\t\t\tfragColor = color_;\n\t\t} else {\n\t\t\tfragColor = vec4(0.0, 0.0, 0.0, 0.0);\n\t\t}\n\t}"},r={vertex:"#version 300 es\n precision highp float;\n in vec2 a_position;\n in vec2 a_texCoord;\n uniform vec2 u_resolution;\n\t\t\t\t\tuniform vec2 u_translate; \n\t\t\t\t\tuniform float u_zoom; \n\t\t\t\t\tuniform float u_angle; \n\t\t\t\t\tuniform float u_density;\n out vec2 v_texCoord;\n\n vec2 rotation(vec2 v, float a) {\n\t\t\t\t\t\tfloat s = sin(a); float c = cos(a); mat2 m = mat2(c, -s, s, c); \n\t\t\t\t\t\treturn m * v;\n\t\t\t\t\t}\n\n void main() {\n \tvec2 zeroToOne = (a_position * u_density + u_translate * u_density) / (u_resolution);\n \tzeroToOne.y = 1.0 - zeroToOne.y;\n\t\t\t\t\t\tvec2 zeroToTwo = zeroToOne * 2.0 - 1.0;\n\t\t\t\t\t\tfloat zoomFactor = u_zoom;\n\t\t\t\t\t\tif (zoomFactor == 0.0) {\n\t\t\t\t\t\t\tzoomFactor = 0.1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tzeroToTwo = zeroToTwo / zoomFactor;\n\t\t\t\t\t\tif (u_angle != 0.0) {\n\t\t\t\t\t\t\tzeroToTwo = rotation(zeroToTwo, u_angle);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgl_Position = vec4(zeroToTwo , 0, 1);\n\t\t\t\t\t\tv_texCoord = a_texCoord;\n }\n \t\t",fragment:"#version 300 es\n precision mediump float;\n uniform sampler2D u_image;\n in vec2 v_texCoord;\n out vec4 fragColor;\n void main() {\n fragColor = texture(u_image, v_texCoord);\n }\n "};export{t as default}; \ No newline at end of file +function t(t,a={}){let i,n,u,s,f,l=[],c=[],h=0,_=null,m=null,d=null;function g(t,o,e){var r=t.createShader(t[o]);if(t.shaderSource(r,e),t.compileShader(r),!t.getShaderParameter(r,t.COMPILE_STATUS)){var a=t.getShaderInfoLog(r);console.error("*** Error compiling shader '"+r+"':"+a),t.deleteShader(r)}return r}function p(t,o){var e=g(t,"VERTEX_SHADER",o.vertex),r=g(t,"FRAGMENT_SHADER",o.fragment),a=t.createProgram();if(t.attachShader(a,e),t.attachShader(a,r),t.linkProgram(a),t.getProgramParameter(a,t.LINK_STATUS))return a;var i=t.getProgramInfoLog(a);return console.error("Error in program linking:"+i),t.deleteProgram(a),null}function x(t,a){let n;if("string"==typeof t)n=document.querySelector(t);else{if(!(t instanceof Element))throw new Error("Context must be either a string or an Element");n=t}const u=n.clientHeight,s=n.clientWidth,f=document.createElement("canvas"),l=f.getContext("webgl2",{premultipliedAlpha:!1,depth:!1,antialias:!0,alpha:!0,preserveDrawingBuffer:!1});i=function(t){const o=window.devicePixelRatio||1,e=t.webkitBackingStorePixelRatio||t.mozBackingStorePixelRatio||t.msBackingStorePixelRatio||t.oBackingStorePixelRatio||t.backingStorePixelRatio||1;return o/e}(l),l.clearColor(0,0,0,0),l.enable(l.BLEND),l.blendEquation(l.FUNC_ADD),l.blendFunc(l.ONE,l.ONE_MINUS_SRC_ALPHA),l.depthMask(!0),f.setAttribute("height",u*i),f.setAttribute("width",s*i),f.style.height=`${u}px`,f.style.width=`${s}px`,f.style.position="absolute",n.appendChild(f),this.gradient=function(t){const o=[],e=t.length,r=[];return t.forEach((function(t){o.push(t.color[0]/255),o.push(t.color[1]/255),o.push(t.color[2]/255),o.push(void 0===t.color[3]?1:t.color[3]),r.push(t.offset)})),{value:new Float32Array(o),length:e,offset:r}}(a.gradient),this.ctx=l,this.width=s,this.height=u,this.layer=f,this.dom=n,this.gradShadOP=function(t){var e=p(t,o);return{program:e,attr:[{bufferType:t.ARRAY_BUFFER,buffer:t.createBuffer(),drawType:t.STATIC_DRAW,valueType:t.FLOAT,size:2,attribute:t.getAttribLocation(e,"a_position"),data:new Float32Array([])},{bufferType:t.ARRAY_BUFFER,buffer:t.createBuffer(),drawType:t.STATIC_DRAW,valueType:t.FLOAT,size:1,attribute:t.getAttribLocation(e,"a_intensity"),data:new Float32Array([])}],uniform:{u_resolution:t.getUniformLocation(e,"u_resolution"),u_max:t.getUniformLocation(e,"u_max"),u_min:t.getUniformLocation(e,"u_min"),u_size:t.getUniformLocation(e,"u_size"),u_intensity:t.getUniformLocation(e,"u_intensity"),u_translate:t.getUniformLocation(e,"u_translate"),u_zoom:t.getUniformLocation(e,"u_zoom"),u_angle:t.getUniformLocation(e,"u_angle"),u_density:t.getUniformLocation(e,"u_density")}}}(this.ctx),this.colorShadOP=function(t){var o=p(t,e);return{program:o,attr:[{bufferType:t.ARRAY_BUFFER,buffer:t.createBuffer(),drawType:t.STATIC_DRAW,valueType:t.FLOAT,size:2,attribute:t.getAttribLocation(o,"a_texCoord"),data:new Float32Array([0,0,1,0,0,1,0,1,1,0,1,1])}],uniform:{u_framebuffer:t.getUniformLocation(o,"u_framebuffer"),u_colorArr:t.getUniformLocation(o,"u_colorArr"),u_colorCount:t.getUniformLocation(o,"u_colorCount"),u_opacity:t.getUniformLocation(o,"u_opacity"),u_offset:t.getUniformLocation(o,"u_offset")}}}(this.ctx),this.imageShaOP=function(t){var o=p(t,r);return{program:o,attr:[{bufferType:t.ARRAY_BUFFER,buffer:t.createBuffer(),drawType:t.STATIC_DRAW,valueType:t.FLOAT,size:2,attribute:t.getAttribLocation(o,"a_position"),data:new Float32Array([])},{bufferType:t.ARRAY_BUFFER,buffer:t.createBuffer(),drawType:t.STATIC_DRAW,valueType:t.FLOAT,size:2,attribute:t.getAttribLocation(o,"a_texCoord"),data:new Float32Array([0,0,1,0,0,1,0,1,1,0,1,1])}],uniform:{u_resolution:t.getUniformLocation(o,"u_resolution"),u_image:t.getUniformLocation(o,"u_image"),u_translate:t.getUniformLocation(o,"u_translate"),u_zoom:t.getUniformLocation(o,"u_zoom"),u_angle:t.getUniformLocation(o,"u_angle"),u_density:t.getUniformLocation(o,"u_density")}}}(this.ctx),this.fbTexObj=l.createTexture(),this.fbo=l.createFramebuffer(),this.size=a.size?a.size:20,m=a.max?a.max:null,_=a.min?a.min:null,this.intensity=a.intensity?a.intensity:1,this.translate=a.translate&&2===a.translate.length?a.translate:[0,0],this.zoom=a.zoom?a.zoom:1,this.angle=a.rotationAngle?a.rotationAngle:0,this.opacity=a.opacity?a.opacity:1,this.ratio=i,a.backgroundImage&&a.backgroundImage.url&&this.setBackgroundImage(a.backgroundImage),this.rawData=[],l.viewport(0,0,l.canvas.width,l.canvas.height),this.render(this.exData||{})}function T(t,o){t.useProgram(this.gradShadOP.program),this.min=null!==_?_:o?.minMax?.min??0,this.max=null!==m?m:o?.minMax?.max??0,this.gradShadOP.attr[0].data=o.posVec||[],this.gradShadOP.attr[1].data=o.rVec||[],t.uniform2fv(this.gradShadOP.uniform.u_resolution,new Float32Array([this.width*this.ratio,this.height*this.ratio])),t.uniform2fv(this.gradShadOP.uniform.u_translate,new Float32Array([this.translate[0],this.translate[1]])),t.uniform1f(this.gradShadOP.uniform.u_zoom,this.zoom?this.zoom:.01),t.uniform1f(this.gradShadOP.uniform.u_angle,this.angle),t.uniform1f(this.gradShadOP.uniform.u_density,this.ratio),t.uniform1f(this.gradShadOP.uniform.u_max,this.max),t.uniform1f(this.gradShadOP.uniform.u_min,this.min),t.uniform1f(this.gradShadOP.uniform.u_size,this.size),t.uniform1f(this.gradShadOP.uniform.u_intensity,this.intensity),this.gradShadOP.attr.forEach((function(o){t.bindBuffer(o.bufferType,o.buffer),t.bufferData(o.bufferType,o.data,o.drawType),t.enableVertexAttribArray(o.attribute),t.vertexAttribPointer(o.attribute,o.size,o.valueType,!0,0,0)})),t.drawArrays(t.POINTS,0,(this.exData.posVec||[]).length/2)}function A(t){const{x:o=0,y:e=0,width:r=0,height:a=0}=this.imageConfig;t.useProgram(this.imageShaOP.program),t.uniform2fv(this.imageShaOP.uniform.u_resolution,new Float32Array([this.width*this.ratio,this.height*this.ratio])),t.uniform2fv(this.imageShaOP.uniform.u_translate,new Float32Array([this.translate[0],this.translate[1]])),t.uniform1f(this.imageShaOP.uniform.u_zoom,this.zoom?this.zoom:.01),t.uniform1f(this.imageShaOP.uniform.u_angle,this.angle),t.uniform1f(this.imageShaOP.uniform.u_density,this.ratio),this.imageShaOP.attr[0].data=new Float32Array([o,e,o+r,e,o,e+a,o,e+a,o+r,e,o+r,e+a]),this.imageShaOP.attr.forEach((function(o){t.bindBuffer(o.bufferType,o.buffer),t.bufferData(o.bufferType,o.data,o.drawType),t.enableVertexAttribArray(o.attribute),t.vertexAttribPointer(o.attribute,o.size,o.valueType,!0,0,0)})),t.uniform1i(this.imageShaOP.uniform.u_image,0),t.activeTexture(this.ctx.TEXTURE0),t.bindTexture(this.ctx.TEXTURE_2D,this.imageTexture),t.drawArrays(t.TRIANGLES,0,6)}function y(t){t.useProgram(this.colorShadOP.program),t.uniform4fv(this.colorShadOP.uniform.u_colorArr,this.gradient.value),t.uniform1f(this.colorShadOP.uniform.u_colorCount,this.gradient.length),t.uniform1fv(this.colorShadOP.uniform.u_offset,new Float32Array(this.gradient.offset)),t.uniform1f(this.colorShadOP.uniform.u_opacity,this.opacity),this.colorShadOP.attr.forEach((function(o){t.bindBuffer(o.bufferType,o.buffer),t.bufferData(o.bufferType,o.data,o.drawType),t.enableVertexAttribArray(o.attribute),t.vertexAttribPointer(o.attribute,o.size,o.valueType,!0,0,0)})),t.uniform1i(this.colorShadOP.uniform.u_framebuffer,0),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this.fbTexObj),t.drawArrays(t.TRIANGLES,0,6)}function v(t){const o=this.zoom||.1,e=this.width/2,r=this.height/2,a=this.angle;let i=(t.x-e)/e*o,n=(t.y-r)/r*o;if(0!==a){const t=Math.cos(a),o=Math.sin(a),e=t*i-o*n;n=o*i+t*n,i=e}return i=i*e+e-this.translate[0],n=n*r+r-this.translate[1],{x:i,y:n}}return x.prototype.resize=function(){const t=this.dom.clientHeight,o=this.dom.clientWidth;this.layer.setAttribute("height",t*i),this.layer.setAttribute("width",o*i),this.layer.style.height=`${t}px`,this.layer.style.width=`${o}px`,this.width=o,this.height=t,this.ctx.viewport(0,0,this.width*i,this.height*i),this.render(this.exData)},x.prototype.clear=function(){this.ctx.clear(this.ctx.COLOR_BUFFER_BIT|this.ctx.DEPTH_BUFFER_BIT)},x.prototype.setMax=function(t){m=t,this.render(this.exData)},x.prototype.setMin=function(t){_=t,this.render(this.exData)},x.prototype.setTranslate=function(t){this.translate=2===t.length?t:[0,0],this.render(this.exData)},x.prototype.setZoom=function(t){this.zoom=void 0!==t?t:1,this.render(this.exData)},x.prototype.setRotationAngle=function(t){this.angle=void 0!==t?t:0,this.render(this.exData)},x.prototype.setSize=function(t){this.size=void 0!==t?t:20,this.render(this.exData)},x.prototype.setIntensity=function(t){this.intensity=void 0!==t?t:1,this.render(this.exData)},x.prototype.setOpacity=function(t){this.opacity=void 0!==t?t:1,this.render(this.exData)},x.prototype.setBackgroundImage=function(t){const o=this;t.url&&(d=this.ctx.getParameter(this.ctx.MAX_TEXTURE_SIZE),this.imageTexture=this.ctx.createTexture(),this.type="TEXTURE_2D",this.imageConfig=null,s=t.width||this.width,f=t.height||this.height,s=s>d?d:s,f=f>d?d:f,function(t,o,e){const r=new Image;r.crossOrigin="anonymous",r.onload=o,r.onerror=e,r.src=t}(t.url,(function(){o.ctx.activeTexture(o.ctx.TEXTURE0),o.ctx.bindTexture(o.ctx.TEXTURE_2D,o.imageTexture),o.ctx.texParameteri(o.ctx.TEXTURE_2D,o.ctx.TEXTURE_WRAP_S,o.ctx.CLAMP_TO_EDGE),o.ctx.texParameteri(o.ctx.TEXTURE_2D,o.ctx.TEXTURE_WRAP_T,o.ctx.CLAMP_TO_EDGE),o.ctx.texParameteri(o.ctx.TEXTURE_2D,o.ctx.TEXTURE_MIN_FILTER,o.ctx.LINEAR),o.ctx.texParameteri(o.ctx.TEXTURE_2D,o.ctx.TEXTURE_MAG_FILTER,o.ctx.LINEAR),o.ctx.texImage2D(o.ctx.TEXTURE_2D,0,o.ctx.RGBA,this.naturalWidth,this.naturalHeight,0,o.ctx.RGBA,o.ctx.UNSIGNED_BYTE,this),o.imageConfig={x:t.x||0,y:t.y||0,height:f,width:s,image:this},o.render(o.exData||{})}),(function(t){console.error("Image Load Error",t)})))},x.prototype.addData=function(t,o){const e=this;for(let r=0;rt[r].value&&(e.min=t[r].value),e.max 0.0 && alpha <= 1.0) {\n\t\t\tvec4 color_;\n\t\t\tif (alpha <= u_offset[0]) {\n\t\t\t\tcolor_ = u_colorArr[0];\n\t\t\t} else if (alpha <= u_offset[1]) {\n\t\t\t\tcolor_ = mix( u_colorArr[0], u_colorArr[1], remap( u_offset[0], u_offset[1], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[0][3], u_colorArr[1][3], remap( u_offset[0], u_offset[1], alpha ));\n\t\t\t} else if (alpha <= u_offset[2]) {\n\t\t\t\tcolor_ = mix( u_colorArr[1], u_colorArr[2], remap( u_offset[1], u_offset[2], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[1][3], u_colorArr[2][3], remap( u_offset[1], u_offset[2], alpha ));\n\t\t\t} else if (alpha <= u_offset[3]) {\n\t\t\t\tcolor_ = mix( u_colorArr[2], u_colorArr[3], remap( u_offset[2], u_offset[3], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[2][3], u_colorArr[3][3], remap( u_offset[2], u_offset[3], alpha ));\n\t\t\t} else if (alpha <= u_offset[4]) {\n\t\t\t\tcolor_ = mix( u_colorArr[3], u_colorArr[4], remap( u_offset[3], u_offset[4], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[3][3], u_colorArr[4][3], remap( u_offset[3], u_offset[4], alpha ));\n\t\t\t} else if (alpha <= u_offset[5]) {\n\t\t\t\tcolor_ = mix( u_colorArr[4], u_colorArr[5], remap( u_offset[4], u_offset[5], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[4][3], u_colorArr[5][3], remap( u_offset[4], u_offset[5], alpha ));\n\t\t\t} else if (alpha <= u_offset[6]) {\n\t\t\t\tcolor_ = mix( u_colorArr[5], u_colorArr[6], remap( u_offset[5], u_offset[6], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[5][3], u_colorArr[6][3], remap( u_offset[5], u_offset[6], alpha ));\n\t\t\t} else if (alpha <= u_offset[7]) {\n\t\t\t\tcolor_ = mix( u_colorArr[6], u_colorArr[7], remap( u_offset[6], u_offset[7], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[6][3], u_colorArr[7][3], remap( u_offset[6], u_offset[7], alpha ));\n\t\t\t} else if (alpha <= u_offset[8]) {\n\t\t\t\tcolor_ = mix( u_colorArr[7], u_colorArr[8], remap( u_offset[7], u_offset[8], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[7][3], u_colorArr[8][3], remap( u_offset[7], u_offset[8], alpha ));\n\t\t\t} else if (alpha <= u_offset[9]) {\n\t\t\t\tcolor_ = mix( u_colorArr[8], u_colorArr[9], remap( u_offset[8], u_offset[9], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[8][3], u_colorArr[9][3], remap( u_offset[8], u_offset[9], alpha ));\n\t\t\t} else if (alpha <= u_offset[10]) {\n\t\t\t\tcolor_ = mix( u_colorArr[9], u_colorArr[10], remap( u_offset[9], u_offset[10], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[9][3], u_colorArr[10][3], remap( u_offset[9], u_offset[10], alpha ));\n\t\t\t} else {\n\t\t\t\tcolor_ = vec4(0.0, 0.0, 0.0, 0.0);\n\t\t\t}\n\t\t\tcolor_ = color_ * u_opacity;\n\t\t\tif (color_.a < 0.0) {\n\t\t\t\tcolor_.a = 0.0;\n\t\t\t}\n\t\t\tfragColor = color_;\n\t\t} else {\n\t\t\tfragColor = vec4(0.0, 0.0, 0.0, 0.0);\n\t\t}\n\t}"},r={vertex:"#version 300 es\n precision highp float;\n in vec2 a_position;\n in vec2 a_texCoord;\n uniform vec2 u_resolution;\n\t\t\t\t\tuniform vec2 u_translate; \n\t\t\t\t\tuniform float u_zoom; \n\t\t\t\t\tuniform float u_angle; \n\t\t\t\t\tuniform float u_density;\n out vec2 v_texCoord;\n\n vec2 rotation(vec2 v, float a, float aspect) {\n\t\t\t\t\t\tfloat s = sin(a); float c = cos(a); mat2 m = mat2(c, -s, s, c);\n\t\t\t\t\t\tmat2 scaleMat = mat2(aspect, 0.0, 0.0, 1.0);\n\t\t\t\t\t\tmat2 scaleMatInv = mat2(1.0/aspect, 0.0, 0.0, 1.0);\n\t\t\t\t\t\treturn scaleMatInv * m * scaleMat * v;\n\t\t\t\t\t}\n\n void main() {\n \tvec2 zeroToOne = (a_position * u_density + u_translate * u_density) / (u_resolution);\n \tzeroToOne.y = 1.0 - zeroToOne.y;\n\t\t\t\t\t\tvec2 zeroToTwo = zeroToOne * 2.0 - 1.0;\n\t\t\t\t\t\tfloat zoomFactor = u_zoom;\n\t\t\t\t\t\tif (zoomFactor == 0.0) {\n\t\t\t\t\t\t\tzoomFactor = 0.1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tzeroToTwo = zeroToTwo / zoomFactor;\n\t\t\t\t\t\tif (u_angle != 0.0) {\n\t\t\t\t\t\t\tzeroToTwo = rotation(zeroToTwo, u_angle * -1.0, u_resolution.x / u_resolution.y);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgl_Position = vec4(zeroToTwo , 0, 1);\n\t\t\t\t\t\tv_texCoord = a_texCoord;\n }\n \t\t",fragment:"#version 300 es\n precision mediump float;\n uniform sampler2D u_image;\n in vec2 v_texCoord;\n out vec4 fragColor;\n void main() {\n fragColor = texture(u_image, v_texCoord);\n }\n "};export{t as default}; \ No newline at end of file diff --git a/dist/visualHeatmap.js b/dist/visualHeatmap.js index 396c067..41b8e5b 100644 --- a/dist/visualHeatmap.js +++ b/dist/visualHeatmap.js @@ -232,8 +232,8 @@ this.gradient = gradientMapper(config.gradient); this.ctx = ctx; - this.width = width * ratio; - this.height = height * ratio; + this.width = width; + this.height = height; this.layer = layer; this.dom = res; this.gradShadOP = createGradiantShader(this.ctx); @@ -270,9 +270,9 @@ this.layer.setAttribute('width', width * ratio); this.layer.style.height = `${height}px`; this.layer.style.width = `${width}px`; - this.width = width * ratio; - this.height = height * ratio; - this.ctx.viewport(0, 0, this.width, this.height); + this.width = width; + this.height = height; + this.ctx.viewport(0, 0, this.width * ratio, this.height * ratio); /* Perform update */ this.render(this.exData); @@ -393,16 +393,19 @@ Chart.prototype.projection = function (data) { // Pre-compute constants and repetitive calculations const zoomFactor = this.zoom || 0.1; - const halfWidth = this.width / (2 * ratio); - const halfHeight = this.height / (2 * ratio); + const halfWidth = this.width / 2; + const halfHeight = this.height / 2; const translateX = this.translate[0]; const translateY = this.translate[1]; const angle = this.angle; + const aspect = this.width / this.height; // Calculate the adjusted positions let posX = (data.x + translateX - halfWidth) / (halfWidth * zoomFactor); let posY = (data.y + translateY - halfHeight) / (halfHeight * zoomFactor); + posX *= aspect; + // Rotate the point if there's an angle if (angle !== 0.0) { const cosAngle = Math.cos(-angle); @@ -412,6 +415,8 @@ posX = xNew; } + posX *= 1.0 / aspect; + // Scale back and adjust the position posX = (posX * halfWidth) + halfWidth; posY = (posY * halfHeight) + halfHeight; @@ -426,7 +431,7 @@ ctx.clear(ctx.COLOR_BUFFER_BIT | ctx.DEPTH_BUFFER_BIT); ctx.bindTexture(ctx.TEXTURE_2D, this.fbTexObj); - ctx.texImage2D(ctx.TEXTURE_2D, 0, ctx.RGBA, this.width, this.height, 0, ctx.RGBA, ctx.UNSIGNED_BYTE, null); + ctx.texImage2D(ctx.TEXTURE_2D, 0, ctx.RGBA, this.width * this.ratio, this.height * this.ratio, 0, ctx.RGBA, ctx.UNSIGNED_BYTE, null); ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_S, ctx.CLAMP_TO_EDGE); ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_T, ctx.CLAMP_TO_EDGE); ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.LINEAR); @@ -450,7 +455,7 @@ this.gradShadOP.attr[0].data = exData.posVec || []; this.gradShadOP.attr[1].data = exData.rVec || []; - ctx.uniform2fv(this.gradShadOP.uniform.u_resolution, new Float32Array([this.width, this.height])); + ctx.uniform2fv(this.gradShadOP.uniform.u_resolution, new Float32Array([this.width * this.ratio, this.height * this.ratio])); ctx.uniform2fv(this.gradShadOP.uniform.u_translate, new Float32Array([this.translate[0], this.translate[1]])); ctx.uniform1f(this.gradShadOP.uniform.u_zoom, this.zoom ? this.zoom : 0.01); ctx.uniform1f(this.gradShadOP.uniform.u_angle, this.angle); @@ -475,7 +480,7 @@ ctx.useProgram(this.imageShaOP.program); - ctx.uniform2fv(this.imageShaOP.uniform.u_resolution, new Float32Array([this.width, this.height])); + ctx.uniform2fv(this.imageShaOP.uniform.u_resolution, new Float32Array([this.width * this.ratio, this.height * this.ratio])); ctx.uniform2fv(this.imageShaOP.uniform.u_translate, new Float32Array([this.translate[0], this.translate[1]])); ctx.uniform1f(this.imageShaOP.uniform.u_zoom, this.zoom ? this.zoom : 0.01); ctx.uniform1f(this.imageShaOP.uniform.u_angle, this.angle); @@ -520,8 +525,8 @@ function transCoOr (data) { const zoomFactor = this.zoom || 0.1; - const halfWidth = this.width / (2 * ratio); - const halfHeight = this.height / (2 * ratio); + const halfWidth = this.width / 2; + const halfHeight = this.height / 2; const angle = this.angle; // Combine operations to reduce the number of arithmetic steps @@ -579,9 +584,11 @@ uniform float u_density; varying float v_i; - vec2 rotation(vec2 v, float a) { + vec2 rotation(vec2 v, float a, float aspect) { float s = sin(a); float c = cos(a); mat2 m = mat2(c, -s, s, c); - return m * v; + mat2 scaleMat = mat2(aspect, 0.0, 0.0, 1.0); + mat2 scaleMatInv = mat2(1.0/aspect, 0.0, 0.0, 1.0); + return scaleMatInv * m * scaleMat * v; } void main() { @@ -593,7 +600,7 @@ } zeroToTwo = zeroToTwo / zoomFactor; if (u_angle != 0.0) { - zeroToTwo = rotation(zeroToTwo, u_angle); + zeroToTwo = rotation(zeroToTwo, u_angle, u_resolution.x / u_resolution.y); } gl_Position = vec4(zeroToTwo , 0, 1); gl_PointSize = u_size * u_density; @@ -704,9 +711,11 @@ uniform float u_density; out vec2 v_texCoord; - vec2 rotation(vec2 v, float a) { - float s = sin(a); float c = cos(a); mat2 m = mat2(c, -s, s, c); - return m * v; + vec2 rotation(vec2 v, float a, float aspect) { + float s = sin(a); float c = cos(a); mat2 m = mat2(c, -s, s, c); + mat2 scaleMat = mat2(aspect, 0.0, 0.0, 1.0); + mat2 scaleMatInv = mat2(1.0/aspect, 0.0, 0.0, 1.0); + return scaleMatInv * m * scaleMat * v; } void main() { @@ -719,7 +728,7 @@ } zeroToTwo = zeroToTwo / zoomFactor; if (u_angle != 0.0) { - zeroToTwo = rotation(zeroToTwo, u_angle); + zeroToTwo = rotation(zeroToTwo, u_angle * -1.0, u_resolution.x / u_resolution.y); } gl_Position = vec4(zeroToTwo , 0, 1); diff --git a/dist/visualHeatmap.min.js b/dist/visualHeatmap.min.js index 39a7f44..fca4ab6 100644 --- a/dist/visualHeatmap.min.js +++ b/dist/visualHeatmap.min.js @@ -3,4 +3,4 @@ * (c) 2023 Narayana Swamy (narayanaswamy14@gmail.com) * @license BSD-3-Clause */ -!function(t,o){"object"==typeof exports&&"undefined"!=typeof module?module.exports=o():"function"==typeof define&&define.amd?define(o):(t="undefined"!=typeof globalThis?globalThis:t||self).visualHeatmap=o()}(this,(function(){"use strict";var t={vertex:"attribute vec2 a_position;\n\tattribute float a_intensity;\n\tuniform float u_size;\n\tuniform vec2 u_resolution;\n\tuniform vec2 u_translate; \n\tuniform float u_zoom; \n\tuniform float u_angle; \n\tuniform float u_density;\n\tvarying float v_i;\n\n\tvec2 rotation(vec2 v, float a) {\n\t\tfloat s = sin(a); float c = cos(a); mat2 m = mat2(c, -s, s, c); \n\t\treturn m * v;\n\t}\n\n\tvoid main() {\n\t\tvec2 zeroToOne = (a_position * u_density + u_translate * u_density) / (u_resolution);\n\t\tvec2 zeroToTwo = zeroToOne * 2.0 - 1.0;\n\t\tfloat zoomFactor = u_zoom;\n\t\tif (zoomFactor == 0.0) {\n\t\t\tzoomFactor = 0.1;\n\t\t}\n\t\tzeroToTwo = zeroToTwo / zoomFactor;\n\t\tif (u_angle != 0.0) {\n\t\t\tzeroToTwo = rotation(zeroToTwo, u_angle);\n\t\t}\n\t\tgl_Position = vec4(zeroToTwo , 0, 1);\n\t\tgl_PointSize = u_size * u_density;\n\t\tv_i = a_intensity;\n\t}",fragment:"precision mediump float;\n\tuniform float u_max;\n\tuniform float u_min;\n\tuniform float u_intensity;\n\tvarying float v_i;\n\tvoid main() {\n\t\tfloat r = 0.0; \n\t\tvec2 cxy = 2.0 * gl_PointCoord - 1.0;\n\t\tr = dot(cxy, cxy);\n\t\tfloat deno = u_max - u_min;\n\t\tif (deno <= 0.0) {\n\t\t\tdeno = 1.0;\n\t\t}\n\t\tif(r <= 1.0) {\n\t\t\tgl_FragColor = vec4(0, 0, 0, ((v_i - u_min) / (deno)) * u_intensity * (1.0 - sqrt(r)));\n\t\t}\n\t}"},o={vertex:"#version 300 es\n\tprecision highp float;\n\tin vec2 a_texCoord;\n\tout vec2 v_texCoord;\n\tvoid main() {\n\t\tvec2 clipSpace = a_texCoord * 2.0 - 1.0;\n\t\tgl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);\n\t\tv_texCoord = a_texCoord;\n\t}",fragment:"#version 300 es\n\tprecision mediump float;\n\tin vec2 v_texCoord;\n\tout vec4 fragColor;\n\tuniform sampler2D u_framebuffer;\n\tuniform vec4 u_colorArr[11];\n\tuniform float u_colorCount;\n\tuniform float u_opacity;\n\tuniform float u_offset[11];\n\n\tfloat remap ( float minval, float maxval, float curval ) {\n\t\treturn ( curval - minval ) / ( maxval - minval );\n\t}\n\n\tvoid main() {\n\t\tfloat alpha = texture(u_framebuffer, v_texCoord.xy).a;\n\t\tif (alpha > 0.0 && alpha <= 1.0) {\n\t\t\tvec4 color_;\n\t\t\tif (alpha <= u_offset[0]) {\n\t\t\t\tcolor_ = u_colorArr[0];\n\t\t\t} else if (alpha <= u_offset[1]) {\n\t\t\t\tcolor_ = mix( u_colorArr[0], u_colorArr[1], remap( u_offset[0], u_offset[1], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[0][3], u_colorArr[1][3], remap( u_offset[0], u_offset[1], alpha ));\n\t\t\t} else if (alpha <= u_offset[2]) {\n\t\t\t\tcolor_ = mix( u_colorArr[1], u_colorArr[2], remap( u_offset[1], u_offset[2], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[1][3], u_colorArr[2][3], remap( u_offset[1], u_offset[2], alpha ));\n\t\t\t} else if (alpha <= u_offset[3]) {\n\t\t\t\tcolor_ = mix( u_colorArr[2], u_colorArr[3], remap( u_offset[2], u_offset[3], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[2][3], u_colorArr[3][3], remap( u_offset[2], u_offset[3], alpha ));\n\t\t\t} else if (alpha <= u_offset[4]) {\n\t\t\t\tcolor_ = mix( u_colorArr[3], u_colorArr[4], remap( u_offset[3], u_offset[4], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[3][3], u_colorArr[4][3], remap( u_offset[3], u_offset[4], alpha ));\n\t\t\t} else if (alpha <= u_offset[5]) {\n\t\t\t\tcolor_ = mix( u_colorArr[4], u_colorArr[5], remap( u_offset[4], u_offset[5], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[4][3], u_colorArr[5][3], remap( u_offset[4], u_offset[5], alpha ));\n\t\t\t} else if (alpha <= u_offset[6]) {\n\t\t\t\tcolor_ = mix( u_colorArr[5], u_colorArr[6], remap( u_offset[5], u_offset[6], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[5][3], u_colorArr[6][3], remap( u_offset[5], u_offset[6], alpha ));\n\t\t\t} else if (alpha <= u_offset[7]) {\n\t\t\t\tcolor_ = mix( u_colorArr[6], u_colorArr[7], remap( u_offset[6], u_offset[7], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[6][3], u_colorArr[7][3], remap( u_offset[6], u_offset[7], alpha ));\n\t\t\t} else if (alpha <= u_offset[8]) {\n\t\t\t\tcolor_ = mix( u_colorArr[7], u_colorArr[8], remap( u_offset[7], u_offset[8], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[7][3], u_colorArr[8][3], remap( u_offset[7], u_offset[8], alpha ));\n\t\t\t} else if (alpha <= u_offset[9]) {\n\t\t\t\tcolor_ = mix( u_colorArr[8], u_colorArr[9], remap( u_offset[8], u_offset[9], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[8][3], u_colorArr[9][3], remap( u_offset[8], u_offset[9], alpha ));\n\t\t\t} else if (alpha <= u_offset[10]) {\n\t\t\t\tcolor_ = mix( u_colorArr[9], u_colorArr[10], remap( u_offset[9], u_offset[10], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[9][3], u_colorArr[10][3], remap( u_offset[9], u_offset[10], alpha ));\n\t\t\t} else {\n\t\t\t\tcolor_ = vec4(0.0, 0.0, 0.0, 0.0);\n\t\t\t}\n\t\t\tcolor_ = color_ * u_opacity;\n\t\t\tif (color_.a < 0.0) {\n\t\t\t\tcolor_.a = 0.0;\n\t\t\t}\n\t\t\tfragColor = color_;\n\t\t} else {\n\t\t\tfragColor = vec4(0.0, 0.0, 0.0, 0.0);\n\t\t}\n\t}"},e={vertex:"#version 300 es\n precision highp float;\n in vec2 a_position;\n in vec2 a_texCoord;\n uniform vec2 u_resolution;\n\t\t\t\t\tuniform vec2 u_translate; \n\t\t\t\t\tuniform float u_zoom; \n\t\t\t\t\tuniform float u_angle; \n\t\t\t\t\tuniform float u_density;\n out vec2 v_texCoord;\n\n vec2 rotation(vec2 v, float a) {\n\t\t\t\t\t\tfloat s = sin(a); float c = cos(a); mat2 m = mat2(c, -s, s, c); \n\t\t\t\t\t\treturn m * v;\n\t\t\t\t\t}\n\n void main() {\n \tvec2 zeroToOne = (a_position * u_density + u_translate * u_density) / (u_resolution);\n \tzeroToOne.y = 1.0 - zeroToOne.y;\n\t\t\t\t\t\tvec2 zeroToTwo = zeroToOne * 2.0 - 1.0;\n\t\t\t\t\t\tfloat zoomFactor = u_zoom;\n\t\t\t\t\t\tif (zoomFactor == 0.0) {\n\t\t\t\t\t\t\tzoomFactor = 0.1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tzeroToTwo = zeroToTwo / zoomFactor;\n\t\t\t\t\t\tif (u_angle != 0.0) {\n\t\t\t\t\t\t\tzeroToTwo = rotation(zeroToTwo, u_angle);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgl_Position = vec4(zeroToTwo , 0, 1);\n\t\t\t\t\t\tv_texCoord = a_texCoord;\n }\n \t\t",fragment:"#version 300 es\n precision mediump float;\n uniform sampler2D u_image;\n in vec2 v_texCoord;\n out vec4 fragColor;\n void main() {\n fragColor = texture(u_image, v_texCoord);\n }\n "};return function(r,i={}){let a,n,u,f,s,l=[],c=[],h=0,_=null,m=null,d=null;function g(t,o,e){var r=t.createShader(t[o]);if(t.shaderSource(r,e),t.compileShader(r),!t.getShaderParameter(r,t.COMPILE_STATUS)){var i=t.getShaderInfoLog(r);console.error("*** Error compiling shader '"+r+"':"+i),t.deleteShader(r)}return r}function p(t,o){var e=g(t,"VERTEX_SHADER",o.vertex),r=g(t,"FRAGMENT_SHADER",o.fragment),i=t.createProgram();if(t.attachShader(i,e),t.attachShader(i,r),t.linkProgram(i),t.getProgramParameter(i,t.LINK_STATUS))return i;var a=t.getProgramInfoLog(i);return console.error("Error in program linking:"+a),t.deleteProgram(i),null}function T(r,i){let n;if("string"==typeof r)n=document.querySelector(r);else{if(!(r instanceof Element))throw new Error("Context must be either a string or an Element");n=r}const u=n.clientHeight,f=n.clientWidth,s=document.createElement("canvas"),l=s.getContext("webgl2",{premultipliedAlpha:!1,depth:!1,antialias:!0,alpha:!0,preserveDrawingBuffer:!1});a=function(t){const o=window.devicePixelRatio||1,e=t.webkitBackingStorePixelRatio||t.mozBackingStorePixelRatio||t.msBackingStorePixelRatio||t.oBackingStorePixelRatio||t.backingStorePixelRatio||1;return o/e}(l),l.clearColor(0,0,0,0),l.enable(l.BLEND),l.blendEquation(l.FUNC_ADD),l.blendFunc(l.ONE,l.ONE_MINUS_SRC_ALPHA),l.depthMask(!0),s.setAttribute("height",u*a),s.setAttribute("width",f*a),s.style.height=`${u}px`,s.style.width=`${f}px`,s.style.position="absolute",n.appendChild(s),this.gradient=function(t){const o=[],e=t.length,r=[];return t.forEach((function(t){o.push(t.color[0]/255),o.push(t.color[1]/255),o.push(t.color[2]/255),o.push(void 0===t.color[3]?1:t.color[3]),r.push(t.offset)})),{value:new Float32Array(o),length:e,offset:r}}(i.gradient),this.ctx=l,this.width=f*a,this.height=u*a,this.layer=s,this.dom=n,this.gradShadOP=function(o){var e=p(o,t);return{program:e,attr:[{bufferType:o.ARRAY_BUFFER,buffer:o.createBuffer(),drawType:o.STATIC_DRAW,valueType:o.FLOAT,size:2,attribute:o.getAttribLocation(e,"a_position"),data:new Float32Array([])},{bufferType:o.ARRAY_BUFFER,buffer:o.createBuffer(),drawType:o.STATIC_DRAW,valueType:o.FLOAT,size:1,attribute:o.getAttribLocation(e,"a_intensity"),data:new Float32Array([])}],uniform:{u_resolution:o.getUniformLocation(e,"u_resolution"),u_max:o.getUniformLocation(e,"u_max"),u_min:o.getUniformLocation(e,"u_min"),u_size:o.getUniformLocation(e,"u_size"),u_intensity:o.getUniformLocation(e,"u_intensity"),u_translate:o.getUniformLocation(e,"u_translate"),u_zoom:o.getUniformLocation(e,"u_zoom"),u_angle:o.getUniformLocation(e,"u_angle"),u_density:o.getUniformLocation(e,"u_density")}}}(this.ctx),this.colorShadOP=function(t){var e=p(t,o);return{program:e,attr:[{bufferType:t.ARRAY_BUFFER,buffer:t.createBuffer(),drawType:t.STATIC_DRAW,valueType:t.FLOAT,size:2,attribute:t.getAttribLocation(e,"a_texCoord"),data:new Float32Array([0,0,1,0,0,1,0,1,1,0,1,1])}],uniform:{u_framebuffer:t.getUniformLocation(e,"u_framebuffer"),u_colorArr:t.getUniformLocation(e,"u_colorArr"),u_colorCount:t.getUniformLocation(e,"u_colorCount"),u_opacity:t.getUniformLocation(e,"u_opacity"),u_offset:t.getUniformLocation(e,"u_offset")}}}(this.ctx),this.imageShaOP=function(t){var o=p(t,e);return{program:o,attr:[{bufferType:t.ARRAY_BUFFER,buffer:t.createBuffer(),drawType:t.STATIC_DRAW,valueType:t.FLOAT,size:2,attribute:t.getAttribLocation(o,"a_position"),data:new Float32Array([])},{bufferType:t.ARRAY_BUFFER,buffer:t.createBuffer(),drawType:t.STATIC_DRAW,valueType:t.FLOAT,size:2,attribute:t.getAttribLocation(o,"a_texCoord"),data:new Float32Array([0,0,1,0,0,1,0,1,1,0,1,1])}],uniform:{u_resolution:t.getUniformLocation(o,"u_resolution"),u_image:t.getUniformLocation(o,"u_image"),u_translate:t.getUniformLocation(o,"u_translate"),u_zoom:t.getUniformLocation(o,"u_zoom"),u_angle:t.getUniformLocation(o,"u_angle"),u_density:t.getUniformLocation(o,"u_density")}}}(this.ctx),this.fbTexObj=l.createTexture(),this.fbo=l.createFramebuffer(),this.size=i.size?i.size:20,m=i.max?i.max:null,_=i.min?i.min:null,this.intensity=i.intensity?i.intensity:1,this.translate=i.translate&&2===i.translate.length?i.translate:[0,0],this.zoom=i.zoom?i.zoom:1,this.angle=i.rotationAngle?i.rotationAngle:0,this.opacity=i.opacity?i.opacity:1,this.ratio=a,i.backgroundImage&&i.backgroundImage.url&&this.setBackgroundImage(i.backgroundImage),this.rawData=[],l.viewport(0,0,l.canvas.width,l.canvas.height),this.render(this.exData||{})}function x(t,o){t.useProgram(this.gradShadOP.program),this.min=null!==_?_:o?.minMax?.min??0,this.max=null!==m?m:o?.minMax?.max??0,this.gradShadOP.attr[0].data=o.posVec||[],this.gradShadOP.attr[1].data=o.rVec||[],t.uniform2fv(this.gradShadOP.uniform.u_resolution,new Float32Array([this.width,this.height])),t.uniform2fv(this.gradShadOP.uniform.u_translate,new Float32Array([this.translate[0],this.translate[1]])),t.uniform1f(this.gradShadOP.uniform.u_zoom,this.zoom?this.zoom:.01),t.uniform1f(this.gradShadOP.uniform.u_angle,this.angle),t.uniform1f(this.gradShadOP.uniform.u_density,this.ratio),t.uniform1f(this.gradShadOP.uniform.u_max,this.max),t.uniform1f(this.gradShadOP.uniform.u_min,this.min),t.uniform1f(this.gradShadOP.uniform.u_size,this.size),t.uniform1f(this.gradShadOP.uniform.u_intensity,this.intensity),this.gradShadOP.attr.forEach((function(o){t.bindBuffer(o.bufferType,o.buffer),t.bufferData(o.bufferType,o.data,o.drawType),t.enableVertexAttribArray(o.attribute),t.vertexAttribPointer(o.attribute,o.size,o.valueType,!0,0,0)})),t.drawArrays(t.POINTS,0,(this.exData.posVec||[]).length/2)}function A(t){const{x:o=0,y:e=0,width:r=0,height:i=0}=this.imageConfig;t.useProgram(this.imageShaOP.program),t.uniform2fv(this.imageShaOP.uniform.u_resolution,new Float32Array([this.width,this.height])),t.uniform2fv(this.imageShaOP.uniform.u_translate,new Float32Array([this.translate[0],this.translate[1]])),t.uniform1f(this.imageShaOP.uniform.u_zoom,this.zoom?this.zoom:.01),t.uniform1f(this.imageShaOP.uniform.u_angle,this.angle),t.uniform1f(this.imageShaOP.uniform.u_density,this.ratio),this.imageShaOP.attr[0].data=new Float32Array([o,e,o+r,e,o,e+i,o,e+i,o+r,e,o+r,e+i]),this.imageShaOP.attr.forEach((function(o){t.bindBuffer(o.bufferType,o.buffer),t.bufferData(o.bufferType,o.data,o.drawType),t.enableVertexAttribArray(o.attribute),t.vertexAttribPointer(o.attribute,o.size,o.valueType,!0,0,0)})),t.uniform1i(this.imageShaOP.uniform.u_image,0),t.activeTexture(this.ctx.TEXTURE0),t.bindTexture(this.ctx.TEXTURE_2D,this.imageTexture),t.drawArrays(t.TRIANGLES,0,6)}function y(t){t.useProgram(this.colorShadOP.program),t.uniform4fv(this.colorShadOP.uniform.u_colorArr,this.gradient.value),t.uniform1f(this.colorShadOP.uniform.u_colorCount,this.gradient.length),t.uniform1fv(this.colorShadOP.uniform.u_offset,new Float32Array(this.gradient.offset)),t.uniform1f(this.colorShadOP.uniform.u_opacity,this.opacity),this.colorShadOP.attr.forEach((function(o){t.bindBuffer(o.bufferType,o.buffer),t.bufferData(o.bufferType,o.data,o.drawType),t.enableVertexAttribArray(o.attribute),t.vertexAttribPointer(o.attribute,o.size,o.valueType,!0,0,0)})),t.uniform1i(this.colorShadOP.uniform.u_framebuffer,0),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this.fbTexObj),t.drawArrays(t.TRIANGLES,0,6)}function v(t){const o=this.zoom||.1,e=this.width/(2*a),r=this.height/(2*a),i=this.angle;let n=(t.x-e)/e*o,u=(t.y-r)/r*o;if(0!==i){const t=Math.cos(i),o=Math.sin(i),e=t*n-o*u;u=o*n+t*u,n=e}return n=n*e+e-this.translate[0],u=u*r+r-this.translate[1],{x:n,y:u}}return T.prototype.resize=function(){const t=this.dom.clientHeight,o=this.dom.clientWidth;this.layer.setAttribute("height",t*a),this.layer.setAttribute("width",o*a),this.layer.style.height=`${t}px`,this.layer.style.width=`${o}px`,this.width=o*a,this.height=t*a,this.ctx.viewport(0,0,this.width,this.height),this.render(this.exData)},T.prototype.clear=function(){this.ctx.clear(this.ctx.COLOR_BUFFER_BIT|this.ctx.DEPTH_BUFFER_BIT)},T.prototype.setMax=function(t){m=t,this.render(this.exData)},T.prototype.setMin=function(t){_=t,this.render(this.exData)},T.prototype.setTranslate=function(t){this.translate=2===t.length?t:[0,0],this.render(this.exData)},T.prototype.setZoom=function(t){this.zoom=void 0!==t?t:1,this.render(this.exData)},T.prototype.setRotationAngle=function(t){this.angle=void 0!==t?t:0,this.render(this.exData)},T.prototype.setSize=function(t){this.size=void 0!==t?t:20,this.render(this.exData)},T.prototype.setIntensity=function(t){this.intensity=void 0!==t?t:1,this.render(this.exData)},T.prototype.setOpacity=function(t){this.opacity=void 0!==t?t:1,this.render(this.exData)},T.prototype.setBackgroundImage=function(t){const o=this;t.url&&(d=this.ctx.getParameter(this.ctx.MAX_TEXTURE_SIZE),this.imageTexture=this.ctx.createTexture(),this.type="TEXTURE_2D",this.imageConfig=null,f=t.width||this.width,s=t.height||this.height,f=f>d?d:f,s=s>d?d:s,function(t,o,e){const r=new Image;r.crossOrigin="anonymous",r.onload=o,r.onerror=e,r.src=t}(t.url,(function(){o.ctx.activeTexture(o.ctx.TEXTURE0),o.ctx.bindTexture(o.ctx.TEXTURE_2D,o.imageTexture),o.ctx.texParameteri(o.ctx.TEXTURE_2D,o.ctx.TEXTURE_WRAP_S,o.ctx.CLAMP_TO_EDGE),o.ctx.texParameteri(o.ctx.TEXTURE_2D,o.ctx.TEXTURE_WRAP_T,o.ctx.CLAMP_TO_EDGE),o.ctx.texParameteri(o.ctx.TEXTURE_2D,o.ctx.TEXTURE_MIN_FILTER,o.ctx.LINEAR),o.ctx.texParameteri(o.ctx.TEXTURE_2D,o.ctx.TEXTURE_MAG_FILTER,o.ctx.LINEAR),o.ctx.texImage2D(o.ctx.TEXTURE_2D,0,o.ctx.RGBA,this.naturalWidth,this.naturalHeight,0,o.ctx.RGBA,o.ctx.UNSIGNED_BYTE,this),o.imageConfig={x:t.x||0,y:t.y||0,height:s,width:f,image:this},o.render(o.exData||{})}),(function(t){console.error("Image Load Error",t)})))},T.prototype.addData=function(t,o){const e=this;for(let r=0;rt[r].value&&(e.min=t[r].value),e.max 0.0 && alpha <= 1.0) {\n\t\t\tvec4 color_;\n\t\t\tif (alpha <= u_offset[0]) {\n\t\t\t\tcolor_ = u_colorArr[0];\n\t\t\t} else if (alpha <= u_offset[1]) {\n\t\t\t\tcolor_ = mix( u_colorArr[0], u_colorArr[1], remap( u_offset[0], u_offset[1], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[0][3], u_colorArr[1][3], remap( u_offset[0], u_offset[1], alpha ));\n\t\t\t} else if (alpha <= u_offset[2]) {\n\t\t\t\tcolor_ = mix( u_colorArr[1], u_colorArr[2], remap( u_offset[1], u_offset[2], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[1][3], u_colorArr[2][3], remap( u_offset[1], u_offset[2], alpha ));\n\t\t\t} else if (alpha <= u_offset[3]) {\n\t\t\t\tcolor_ = mix( u_colorArr[2], u_colorArr[3], remap( u_offset[2], u_offset[3], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[2][3], u_colorArr[3][3], remap( u_offset[2], u_offset[3], alpha ));\n\t\t\t} else if (alpha <= u_offset[4]) {\n\t\t\t\tcolor_ = mix( u_colorArr[3], u_colorArr[4], remap( u_offset[3], u_offset[4], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[3][3], u_colorArr[4][3], remap( u_offset[3], u_offset[4], alpha ));\n\t\t\t} else if (alpha <= u_offset[5]) {\n\t\t\t\tcolor_ = mix( u_colorArr[4], u_colorArr[5], remap( u_offset[4], u_offset[5], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[4][3], u_colorArr[5][3], remap( u_offset[4], u_offset[5], alpha ));\n\t\t\t} else if (alpha <= u_offset[6]) {\n\t\t\t\tcolor_ = mix( u_colorArr[5], u_colorArr[6], remap( u_offset[5], u_offset[6], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[5][3], u_colorArr[6][3], remap( u_offset[5], u_offset[6], alpha ));\n\t\t\t} else if (alpha <= u_offset[7]) {\n\t\t\t\tcolor_ = mix( u_colorArr[6], u_colorArr[7], remap( u_offset[6], u_offset[7], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[6][3], u_colorArr[7][3], remap( u_offset[6], u_offset[7], alpha ));\n\t\t\t} else if (alpha <= u_offset[8]) {\n\t\t\t\tcolor_ = mix( u_colorArr[7], u_colorArr[8], remap( u_offset[7], u_offset[8], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[7][3], u_colorArr[8][3], remap( u_offset[7], u_offset[8], alpha ));\n\t\t\t} else if (alpha <= u_offset[9]) {\n\t\t\t\tcolor_ = mix( u_colorArr[8], u_colorArr[9], remap( u_offset[8], u_offset[9], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[8][3], u_colorArr[9][3], remap( u_offset[8], u_offset[9], alpha ));\n\t\t\t} else if (alpha <= u_offset[10]) {\n\t\t\t\tcolor_ = mix( u_colorArr[9], u_colorArr[10], remap( u_offset[9], u_offset[10], alpha ) );\n\t\t\t\tcolor_ = color_ * mix( u_colorArr[9][3], u_colorArr[10][3], remap( u_offset[9], u_offset[10], alpha ));\n\t\t\t} else {\n\t\t\t\tcolor_ = vec4(0.0, 0.0, 0.0, 0.0);\n\t\t\t}\n\t\t\tcolor_ = color_ * u_opacity;\n\t\t\tif (color_.a < 0.0) {\n\t\t\t\tcolor_.a = 0.0;\n\t\t\t}\n\t\t\tfragColor = color_;\n\t\t} else {\n\t\t\tfragColor = vec4(0.0, 0.0, 0.0, 0.0);\n\t\t}\n\t}"},e={vertex:"#version 300 es\n precision highp float;\n in vec2 a_position;\n in vec2 a_texCoord;\n uniform vec2 u_resolution;\n\t\t\t\t\tuniform vec2 u_translate; \n\t\t\t\t\tuniform float u_zoom; \n\t\t\t\t\tuniform float u_angle; \n\t\t\t\t\tuniform float u_density;\n out vec2 v_texCoord;\n\n vec2 rotation(vec2 v, float a, float aspect) {\n\t\t\t\t\t\tfloat s = sin(a); float c = cos(a); mat2 m = mat2(c, -s, s, c);\n\t\t\t\t\t\tmat2 scaleMat = mat2(aspect, 0.0, 0.0, 1.0);\n\t\t\t\t\t\tmat2 scaleMatInv = mat2(1.0/aspect, 0.0, 0.0, 1.0);\n\t\t\t\t\t\treturn scaleMatInv * m * scaleMat * v;\n\t\t\t\t\t}\n\n void main() {\n \tvec2 zeroToOne = (a_position * u_density + u_translate * u_density) / (u_resolution);\n \tzeroToOne.y = 1.0 - zeroToOne.y;\n\t\t\t\t\t\tvec2 zeroToTwo = zeroToOne * 2.0 - 1.0;\n\t\t\t\t\t\tfloat zoomFactor = u_zoom;\n\t\t\t\t\t\tif (zoomFactor == 0.0) {\n\t\t\t\t\t\t\tzoomFactor = 0.1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tzeroToTwo = zeroToTwo / zoomFactor;\n\t\t\t\t\t\tif (u_angle != 0.0) {\n\t\t\t\t\t\t\tzeroToTwo = rotation(zeroToTwo, u_angle * -1.0, u_resolution.x / u_resolution.y);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgl_Position = vec4(zeroToTwo , 0, 1);\n\t\t\t\t\t\tv_texCoord = a_texCoord;\n }\n \t\t",fragment:"#version 300 es\n precision mediump float;\n uniform sampler2D u_image;\n in vec2 v_texCoord;\n out vec4 fragColor;\n void main() {\n fragColor = texture(u_image, v_texCoord);\n }\n "};return function(r,a={}){let i,n,u,s,f,l=[],c=[],h=0,_=null,m=null,d=null;function p(t,o,e){var r=t.createShader(t[o]);if(t.shaderSource(r,e),t.compileShader(r),!t.getShaderParameter(r,t.COMPILE_STATUS)){var a=t.getShaderInfoLog(r);console.error("*** Error compiling shader '"+r+"':"+a),t.deleteShader(r)}return r}function g(t,o){var e=p(t,"VERTEX_SHADER",o.vertex),r=p(t,"FRAGMENT_SHADER",o.fragment),a=t.createProgram();if(t.attachShader(a,e),t.attachShader(a,r),t.linkProgram(a),t.getProgramParameter(a,t.LINK_STATUS))return a;var i=t.getProgramInfoLog(a);return console.error("Error in program linking:"+i),t.deleteProgram(a),null}function T(r,a){let n;if("string"==typeof r)n=document.querySelector(r);else{if(!(r instanceof Element))throw new Error("Context must be either a string or an Element");n=r}const u=n.clientHeight,s=n.clientWidth,f=document.createElement("canvas"),l=f.getContext("webgl2",{premultipliedAlpha:!1,depth:!1,antialias:!0,alpha:!0,preserveDrawingBuffer:!1});i=function(t){const o=window.devicePixelRatio||1,e=t.webkitBackingStorePixelRatio||t.mozBackingStorePixelRatio||t.msBackingStorePixelRatio||t.oBackingStorePixelRatio||t.backingStorePixelRatio||1;return o/e}(l),l.clearColor(0,0,0,0),l.enable(l.BLEND),l.blendEquation(l.FUNC_ADD),l.blendFunc(l.ONE,l.ONE_MINUS_SRC_ALPHA),l.depthMask(!0),f.setAttribute("height",u*i),f.setAttribute("width",s*i),f.style.height=`${u}px`,f.style.width=`${s}px`,f.style.position="absolute",n.appendChild(f),this.gradient=function(t){const o=[],e=t.length,r=[];return t.forEach((function(t){o.push(t.color[0]/255),o.push(t.color[1]/255),o.push(t.color[2]/255),o.push(void 0===t.color[3]?1:t.color[3]),r.push(t.offset)})),{value:new Float32Array(o),length:e,offset:r}}(a.gradient),this.ctx=l,this.width=s,this.height=u,this.layer=f,this.dom=n,this.gradShadOP=function(o){var e=g(o,t);return{program:e,attr:[{bufferType:o.ARRAY_BUFFER,buffer:o.createBuffer(),drawType:o.STATIC_DRAW,valueType:o.FLOAT,size:2,attribute:o.getAttribLocation(e,"a_position"),data:new Float32Array([])},{bufferType:o.ARRAY_BUFFER,buffer:o.createBuffer(),drawType:o.STATIC_DRAW,valueType:o.FLOAT,size:1,attribute:o.getAttribLocation(e,"a_intensity"),data:new Float32Array([])}],uniform:{u_resolution:o.getUniformLocation(e,"u_resolution"),u_max:o.getUniformLocation(e,"u_max"),u_min:o.getUniformLocation(e,"u_min"),u_size:o.getUniformLocation(e,"u_size"),u_intensity:o.getUniformLocation(e,"u_intensity"),u_translate:o.getUniformLocation(e,"u_translate"),u_zoom:o.getUniformLocation(e,"u_zoom"),u_angle:o.getUniformLocation(e,"u_angle"),u_density:o.getUniformLocation(e,"u_density")}}}(this.ctx),this.colorShadOP=function(t){var e=g(t,o);return{program:e,attr:[{bufferType:t.ARRAY_BUFFER,buffer:t.createBuffer(),drawType:t.STATIC_DRAW,valueType:t.FLOAT,size:2,attribute:t.getAttribLocation(e,"a_texCoord"),data:new Float32Array([0,0,1,0,0,1,0,1,1,0,1,1])}],uniform:{u_framebuffer:t.getUniformLocation(e,"u_framebuffer"),u_colorArr:t.getUniformLocation(e,"u_colorArr"),u_colorCount:t.getUniformLocation(e,"u_colorCount"),u_opacity:t.getUniformLocation(e,"u_opacity"),u_offset:t.getUniformLocation(e,"u_offset")}}}(this.ctx),this.imageShaOP=function(t){var o=g(t,e);return{program:o,attr:[{bufferType:t.ARRAY_BUFFER,buffer:t.createBuffer(),drawType:t.STATIC_DRAW,valueType:t.FLOAT,size:2,attribute:t.getAttribLocation(o,"a_position"),data:new Float32Array([])},{bufferType:t.ARRAY_BUFFER,buffer:t.createBuffer(),drawType:t.STATIC_DRAW,valueType:t.FLOAT,size:2,attribute:t.getAttribLocation(o,"a_texCoord"),data:new Float32Array([0,0,1,0,0,1,0,1,1,0,1,1])}],uniform:{u_resolution:t.getUniformLocation(o,"u_resolution"),u_image:t.getUniformLocation(o,"u_image"),u_translate:t.getUniformLocation(o,"u_translate"),u_zoom:t.getUniformLocation(o,"u_zoom"),u_angle:t.getUniformLocation(o,"u_angle"),u_density:t.getUniformLocation(o,"u_density")}}}(this.ctx),this.fbTexObj=l.createTexture(),this.fbo=l.createFramebuffer(),this.size=a.size?a.size:20,m=a.max?a.max:null,_=a.min?a.min:null,this.intensity=a.intensity?a.intensity:1,this.translate=a.translate&&2===a.translate.length?a.translate:[0,0],this.zoom=a.zoom?a.zoom:1,this.angle=a.rotationAngle?a.rotationAngle:0,this.opacity=a.opacity?a.opacity:1,this.ratio=i,a.backgroundImage&&a.backgroundImage.url&&this.setBackgroundImage(a.backgroundImage),this.rawData=[],l.viewport(0,0,l.canvas.width,l.canvas.height),this.render(this.exData||{})}function x(t,o){t.useProgram(this.gradShadOP.program),this.min=null!==_?_:o?.minMax?.min??0,this.max=null!==m?m:o?.minMax?.max??0,this.gradShadOP.attr[0].data=o.posVec||[],this.gradShadOP.attr[1].data=o.rVec||[],t.uniform2fv(this.gradShadOP.uniform.u_resolution,new Float32Array([this.width*this.ratio,this.height*this.ratio])),t.uniform2fv(this.gradShadOP.uniform.u_translate,new Float32Array([this.translate[0],this.translate[1]])),t.uniform1f(this.gradShadOP.uniform.u_zoom,this.zoom?this.zoom:.01),t.uniform1f(this.gradShadOP.uniform.u_angle,this.angle),t.uniform1f(this.gradShadOP.uniform.u_density,this.ratio),t.uniform1f(this.gradShadOP.uniform.u_max,this.max),t.uniform1f(this.gradShadOP.uniform.u_min,this.min),t.uniform1f(this.gradShadOP.uniform.u_size,this.size),t.uniform1f(this.gradShadOP.uniform.u_intensity,this.intensity),this.gradShadOP.attr.forEach((function(o){t.bindBuffer(o.bufferType,o.buffer),t.bufferData(o.bufferType,o.data,o.drawType),t.enableVertexAttribArray(o.attribute),t.vertexAttribPointer(o.attribute,o.size,o.valueType,!0,0,0)})),t.drawArrays(t.POINTS,0,(this.exData.posVec||[]).length/2)}function A(t){const{x:o=0,y:e=0,width:r=0,height:a=0}=this.imageConfig;t.useProgram(this.imageShaOP.program),t.uniform2fv(this.imageShaOP.uniform.u_resolution,new Float32Array([this.width*this.ratio,this.height*this.ratio])),t.uniform2fv(this.imageShaOP.uniform.u_translate,new Float32Array([this.translate[0],this.translate[1]])),t.uniform1f(this.imageShaOP.uniform.u_zoom,this.zoom?this.zoom:.01),t.uniform1f(this.imageShaOP.uniform.u_angle,this.angle),t.uniform1f(this.imageShaOP.uniform.u_density,this.ratio),this.imageShaOP.attr[0].data=new Float32Array([o,e,o+r,e,o,e+a,o,e+a,o+r,e,o+r,e+a]),this.imageShaOP.attr.forEach((function(o){t.bindBuffer(o.bufferType,o.buffer),t.bufferData(o.bufferType,o.data,o.drawType),t.enableVertexAttribArray(o.attribute),t.vertexAttribPointer(o.attribute,o.size,o.valueType,!0,0,0)})),t.uniform1i(this.imageShaOP.uniform.u_image,0),t.activeTexture(this.ctx.TEXTURE0),t.bindTexture(this.ctx.TEXTURE_2D,this.imageTexture),t.drawArrays(t.TRIANGLES,0,6)}function y(t){t.useProgram(this.colorShadOP.program),t.uniform4fv(this.colorShadOP.uniform.u_colorArr,this.gradient.value),t.uniform1f(this.colorShadOP.uniform.u_colorCount,this.gradient.length),t.uniform1fv(this.colorShadOP.uniform.u_offset,new Float32Array(this.gradient.offset)),t.uniform1f(this.colorShadOP.uniform.u_opacity,this.opacity),this.colorShadOP.attr.forEach((function(o){t.bindBuffer(o.bufferType,o.buffer),t.bufferData(o.bufferType,o.data,o.drawType),t.enableVertexAttribArray(o.attribute),t.vertexAttribPointer(o.attribute,o.size,o.valueType,!0,0,0)})),t.uniform1i(this.colorShadOP.uniform.u_framebuffer,0),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this.fbTexObj),t.drawArrays(t.TRIANGLES,0,6)}function v(t){const o=this.zoom||.1,e=this.width/2,r=this.height/2,a=this.angle;let i=(t.x-e)/e*o,n=(t.y-r)/r*o;if(0!==a){const t=Math.cos(a),o=Math.sin(a),e=t*i-o*n;n=o*i+t*n,i=e}return i=i*e+e-this.translate[0],n=n*r+r-this.translate[1],{x:i,y:n}}return T.prototype.resize=function(){const t=this.dom.clientHeight,o=this.dom.clientWidth;this.layer.setAttribute("height",t*i),this.layer.setAttribute("width",o*i),this.layer.style.height=`${t}px`,this.layer.style.width=`${o}px`,this.width=o,this.height=t,this.ctx.viewport(0,0,this.width*i,this.height*i),this.render(this.exData)},T.prototype.clear=function(){this.ctx.clear(this.ctx.COLOR_BUFFER_BIT|this.ctx.DEPTH_BUFFER_BIT)},T.prototype.setMax=function(t){m=t,this.render(this.exData)},T.prototype.setMin=function(t){_=t,this.render(this.exData)},T.prototype.setTranslate=function(t){this.translate=2===t.length?t:[0,0],this.render(this.exData)},T.prototype.setZoom=function(t){this.zoom=void 0!==t?t:1,this.render(this.exData)},T.prototype.setRotationAngle=function(t){this.angle=void 0!==t?t:0,this.render(this.exData)},T.prototype.setSize=function(t){this.size=void 0!==t?t:20,this.render(this.exData)},T.prototype.setIntensity=function(t){this.intensity=void 0!==t?t:1,this.render(this.exData)},T.prototype.setOpacity=function(t){this.opacity=void 0!==t?t:1,this.render(this.exData)},T.prototype.setBackgroundImage=function(t){const o=this;t.url&&(d=this.ctx.getParameter(this.ctx.MAX_TEXTURE_SIZE),this.imageTexture=this.ctx.createTexture(),this.type="TEXTURE_2D",this.imageConfig=null,s=t.width||this.width,f=t.height||this.height,s=s>d?d:s,f=f>d?d:f,function(t,o,e){const r=new Image;r.crossOrigin="anonymous",r.onload=o,r.onerror=e,r.src=t}(t.url,(function(){o.ctx.activeTexture(o.ctx.TEXTURE0),o.ctx.bindTexture(o.ctx.TEXTURE_2D,o.imageTexture),o.ctx.texParameteri(o.ctx.TEXTURE_2D,o.ctx.TEXTURE_WRAP_S,o.ctx.CLAMP_TO_EDGE),o.ctx.texParameteri(o.ctx.TEXTURE_2D,o.ctx.TEXTURE_WRAP_T,o.ctx.CLAMP_TO_EDGE),o.ctx.texParameteri(o.ctx.TEXTURE_2D,o.ctx.TEXTURE_MIN_FILTER,o.ctx.LINEAR),o.ctx.texParameteri(o.ctx.TEXTURE_2D,o.ctx.TEXTURE_MAG_FILTER,o.ctx.LINEAR),o.ctx.texImage2D(o.ctx.TEXTURE_2D,0,o.ctx.RGBA,this.naturalWidth,this.naturalHeight,0,o.ctx.RGBA,o.ctx.UNSIGNED_BYTE,this),o.imageConfig={x:t.x||0,y:t.y||0,height:f,width:s,image:this},o.render(o.exData||{})}),(function(t){console.error("Image Load Error",t)})))},T.prototype.addData=function(t,o){const e=this;for(let r=0;rt[r].value&&(e.min=t[r].value),e.max