@rfkit/renderer 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +1 -1
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
let t=new Map;function e(t,e){let a,r,i,l;if(!/^#([A-Fa-f0-9]{3}){1,2}([A-Fa-f0-9]{2})?$/.test(t))throw Error("Invalid hex color format");let s=t.replace("#","");if(3===s.length)a=Number.parseInt(s[0]+s[0],16),r=Number.parseInt(s[1]+s[1],16),i=Number.parseInt(s[2]+s[2],16),l=255;else if(6===s.length)a=Number.parseInt(s.substring(0,2),16),r=Number.parseInt(s.substring(2,4),16),i=Number.parseInt(s.substring(4,6),16),l=255;else if(8===s.length)a=Number.parseInt(s.substring(0,2),16),r=Number.parseInt(s.substring(2,4),16),i=Number.parseInt(s.substring(4,6),16),l=Number.parseInt(s.substring(6,8),16);else throw Error("Invalid hex color length");return"number"==typeof e&&(l=Math.round(255*Math.max(0,Math.min(1,e)))),{r:a,g:r,b:i,a:l}}function a(t,e,r,i=255){let l=t=>t.toString(16).padStart(2,"0"),s=`#${l(t)}${l(e)}${l(r)}`;return i<255?`${s}${l(i)}`:s}function r(e){if("string"==typeof e){let a=t.get(e);if(a)return a;let r=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i.exec(e),i=r?{r:parseInt(r[1],16),g:parseInt(r[2],16),b:parseInt(r[3],16),a:r[4]?parseInt(r[4],16):255}:{r:0,g:0,b:0,a:255};return t.set(e,i),i}return{r:e.r,g:e.g,b:e.b,a:e.a??255}}function i(t,e=100){let a=[];for(let r=0;r<=e;r++){let i=Math.round(r/e*255).toString(16).padStart(2,"0").toUpperCase(),l=`${t}${i}`;a.push(l)}return a}function l(){t.clear()}class s{colorsPresetList=[];range=[0,0,0];static transparent={r:0,g:0,b:0,a:0};constructor(t,e,a,r=.1){this.setColors(t,e,a,r)}setColors(t,e,a,i){this.colorsPresetList=[];let l=Math.max(1,Math.floor((a-e)/i)),s=a-e;this.range=[e,a,s];let n=t.map(r);for(let t=0;t<=l;t++){let a=(e+t*i-e)/s;this.colorsPresetList.push(this.interpolateColor(n,a))}}interpolateColor(t,e){let r=Math.floor(e*(t.length-1)),i=e*(t.length-1)-r,l=t[r],s=t[r+1]||t[r],n={r:Math.round(l.r+i*(s.r-l.r)),g:Math.round(l.g+i*(s.g-l.g)),b:Math.round(l.b+i*(s.b-l.b)),a:Math.round(l.a+i*(s.a-l.a))};return{...n,hax:a(n.r,n.g,n.b,n.a)}}getColor(t){if(!Number.isFinite(t))return s.transparent;let[e,,a]=this.range,r=(t-e)/a;if(r<=0)return this.colorsPresetList[0];if(r>=1)return this.colorsPresetList[this.colorsPresetList.length-1];let i=Math.min(Math.floor(r*this.colorsPresetList.length),this.colorsPresetList.length-1);return this.colorsPresetList[i]}}class n{state;constructor(t){this.state={id:t.id,container:void 0,canvas:null,ctx:null,range:t.range??[-20,100]},this.init(t)}updateProps(t){this.state={...this.state,...t}}init(t){let{id:e}=this.state,a=document.getElementById(e),r=document.createElement("canvas"),i=r.getContext?.("2d");r.style.transform="scaleY(-1)",i&&(i.imageSmoothingEnabled=!1,i.lineJoin="miter",i.lineCap="butt",i.textBaseline="middle"),i&&this.updateProps({container:a??void 0,canvas:r,ctx:i}),a?.appendChild(r),this.resize(!1)}clearRect(){let{ctx:t,canvas:e}=this.state;t.clearRect(0,0,e.width,e.height)}resize(t=!0){let{canvas:e,container:a}=this.state,{clientWidth:r,clientHeight:i}=a;r&&i&&(e.width=r,e.height=i,t&&setTimeout(()=>{this.draw()}))}draw(){}dispose(){let{canvas:t,container:e}=this.state;e?.removeChild(t)}}let o={COLOR:"#000000",THICKNESS:1,FILL_STYLE:"#ffffffB0",FILL_STYLE_PRIMARY:"#1890ff",FILL_STYLE_TRANSPARENT_BASE:"#ffffff10",LINE_COLOR:"#00ff00",POINT_COLOR:"#ff0000",DIAL_NORTH_COLOR:"#ff4d4f",DIAL_SOUTH_COLOR:"#1890ff",FLUORESCENCE_COLORS:["#000080","#0000FF","#00FFFF","#00FF00","#FFFF00","#FF0000"],RANGE:[-20,100]},h={LEVEL_MIN:-20,LEVEL_MAX:140,LEVEL_RANGE:161,MAX_GAUSSIAN_RADIUS:30},u={Y_RANGE:[-1,1],SEGMENT_SIZE:5,MODE:"classic",DECAY_FACTOR:.98,MAX_ACCUMULATION:1e3,MODERN_COLORS:["#000080","#0000FF","#00FFFF","#00FF00","#FFFF00","#FF0000"],CLASSIC_COLORS:["#00ff00","#ff0000"],CLASSIC_ALPHA_GAIN:50};var c=/*#__PURE__*/function(t){return t.Horizontal="horizontal",t.Vertical="vertical",t}({}),d=/*#__PURE__*/function(t){return t.Circle="circle",t.Rect="rect",t.Line="line",t.Stepline="stepline",t.Bar="bar",t.Area="area",t}({}),f=/*#__PURE__*/function(t){return t.Canvas="canvas",t.WebGL="webgl",t}({}),g=/*#__PURE__*/function(t){return t.Gaussian="gaussian",t.Grid="grid",t}({});class p extends n{init(t){super.init(t);let{colors:e,display:a,fluorescenceRenderMode:r}=t;this.updateProps({colors:e,data:new Uint32Array(0),display:a,renderMode:r??g.Gaussian}),this.resize()}updateProps(t){let e=t.range&&(t.range[0]!==this.state.range?.[0]||t.range[1]!==this.state.range?.[1]),a=void 0!==t.renderMode&&t.renderMode!==this.state.renderMode;super.updateProps(t),(e||a)&&this.state.data?.length>0&&this.draw()}setRenderMode(t){this.updateProps({renderMode:t})}clearImageData(){let{ctx:t,canvas:{height:e,width:a}}=this.state;e&&a&&this.updateProps({imageData:t.createImageData(a,e)})}clearRect(){super.clearRect(),this.clearImageData()}clear(){this.clearRect(),this.updateProps({data:new Uint32Array(0)})}dispose(){this.intensityMatrixCache=null,this.gridCentersCache=null,this.weightLookupCache=null,this.colorLookupCache=null,this.colorCache.clear(),this.lastRenderParams=null,this.blockPositionsCache=null,this.lastBlockRenderParams=null}drawBlocks(){let{imageData:t,data:e,canvas:a,ctx:r,colors:i=o.FLUORESCENCE_COLORS,range:l=o.RANGE}=this.state;if(!e||0===e.length||!t)return;let{width:s,height:n}=a,[u,c]=l,d=c-u;if(d<=0)return;let f=e.length/h.LEVEL_RANGE;if(!Number.isInteger(f)||f<=0)return;let g={dataLength:f,width:s,height:n,rangeMin:u,rangeMax:c};if(!this.lastBlockRenderParams||Object.keys(g).some(t=>this.lastBlockRenderParams?.[t]!==g[t])||!this.blockPositionsCache||this.blockPositionsCache.length!==f){this.blockPositionsCache=Array(f);let t=Math.max(1,Math.floor(s/f));for(let e=0;e<f;e++){let a=Math.floor(e*s/f),r=Math.min(s-1,a+t-1);this.blockPositionsCache[e]={startX:a,endX:r,width:r-a+1}}}this.lastBlockRenderParams=g;let p=t.data;p.fill(0);let m=1/d,T=n-1,C=Math.max(1,Math.ceil(n/d)),M=0;for(let t=0;t<f;t++){let a=t*h.LEVEL_RANGE;for(let t=0;t<h.LEVEL_RANGE;t++){let r=e[a+t];if(r<=0)continue;let i=t+h.LEVEL_MIN;i<u||i>c||!(r>M)||(M=r)}}let E=Math.log(Math.max(M,1)+1);for(let t=0;t<f;t++){let{startX:a,endX:r}=this.blockPositionsCache[t],l=t*h.LEVEL_RANGE;for(let t=0;t<h.LEVEL_RANGE;t++){let n=e[l+t];if(n<=0)continue;let o=t+h.LEVEL_MIN;if(o<u||o>c)continue;let d=Math.max(0,Math.floor((o-u)*m*T-C/2)),f=Math.min(T,d+C-1),g=Math.log(n+1)/E,M=Math.round(255*g),{r:R,g:L,b:A}=this.interpolateColor(i,g);for(let t=d;t<=f;t++){let e=t*s;for(let t=a;t<=r;t++){let a=(e+t)*4;p[a]=R,p[a+1]=L,p[a+2]=A,p[a+3]=M}}}}r.putImageData(t,0,0)}resize(){super.resize(),this.clearImageData()}setRange(t){t&&(this.updateProps({range:t}),this.draw())}render(t){t?.fluorescenceData?.length>=0&&((this.state.data?.length??0)!==t.fluorescenceData.length&&(this.clearImageData(),this.intensityMatrixCache=null,this.gridCentersCache=null,this.blockPositionsCache=null,this.lastRenderParams=null,this.lastBlockRenderParams=null),this.state.data=t.fluorescenceData,this.state.fluorescenceMaxCount=t.fluorescenceMaxCount,this.draw())}interpolateColor(t,e){if(!t||0===t.length)return{r:255,g:255,b:255,a:255};e=Math.max(0,Math.min(1,e));let a=t=>"string"==typeof t?this.hexToRgb(t):{r:t.r,g:t.g,b:t.b};if(1===t.length||0===e)return{...a(t[0]),a:255};if(1===e)return{...a(t[t.length-1]),a:255};let r=e*(t.length-1),i=Math.floor(r),l=r-i,s=Math.min(i,t.length-2),n=a(t[s]),o=a(t[s+1]);return{r:Math.round(n.r+(o.r-n.r)*l),g:Math.round(n.g+(o.g-n.g)*l),b:Math.round(n.b+(o.b-n.b)*l),a:255}}colorCache=new Map;hexToRgb(t){let e=this.colorCache.get(t);if(e)return e;let a=r(t),i={r:a.r,g:a.g,b:a.b};return this.colorCache.set(t,i),i}lastRenderParams=null;intensityMatrixCache=null;gridCentersCache=null;weightLookupCache=null;colorLookupCache=null;blockPositionsCache=null;lastBlockRenderParams=null;draw(){let{imageData:t,data:e,canvas:a,ctx:r,colors:i=o.FLUORESCENCE_COLORS,range:l=o.RANGE,fluorescenceMaxCount:s=1,display:n,renderMode:u=g.Gaussian}=this.state;if(!n||!e||0===e.length||!t)return;if(u===g.Grid){this.drawBlocks();return}let{width:c,height:d}=a,[f,p]=l,m=p-f;if(m<=0)return;let T=e.length/h.LEVEL_RANGE;if(!Number.isInteger(T)||T<=0)return;let C={dataLength:T,rangeMin:f,rangeMax:p,width:c,height:d,maxCount:s},M=!this.lastRenderParams||this.lastRenderParams.dataLength!==C.dataLength||this.lastRenderParams.width!==C.width,E=!this.lastRenderParams||this.lastRenderParams.height!==C.height,R=!this.colorLookupCache;this.lastRenderParams=C;let L=t.data;L.fill(0);let A=Math.min(Math.max(2,Math.ceil(d/m),Math.floor(d/50)),h.MAX_GAUSSIAN_RADIUS),S=A*A,_=c*d,P=Math.min(Math.max(A,Math.ceil(c/T)),h.MAX_GAUSSIAN_RADIUS);this.intensityMatrixCache&&this.intensityMatrixCache.length===_?this.intensityMatrixCache.fill(0):this.intensityMatrixCache=new Float32Array(_);let I=this.intensityMatrixCache;if(M||!this.gridCentersCache||this.gridCentersCache.length!==T){this.gridCentersCache=new Float32Array(T);let t=c/T;for(let e=0;e<T;e++){let a=Math.floor(t*e),r=Math.ceil(t*(e+1));this.gridCentersCache[e]=(a+r)/2}}let x=this.gridCentersCache,b=Math.ceil(10*A)+1;if(E||!this.weightLookupCache||this.weightLookupCache.length!==b){this.weightLookupCache=new Float32Array(b);for(let t=0;t<=10*A;t++){let e=t/10;this.weightLookupCache[t]=Math.exp(-(e*e)/(2*S))}}let w=this.weightLookupCache,y=0;for(let t=0;t<T;t++){let a=x[t],r=t*h.LEVEL_RANGE;for(let t=0;t<h.LEVEL_RANGE;t++){let i=e[r+t];if(i<=0)continue;let l=t+h.LEVEL_MIN;if(l<f||l>p)continue;let n=(l-f)/m*(d-1),o=Math.log(i+1)/Math.log(Math.max(s,1)+1),u=Math.max(0,Math.floor(a-P)),g=Math.min(c-1,Math.ceil(a+P)),T=Math.max(0,Math.floor(n-A)),C=Math.min(d-1,Math.ceil(n+A));for(let t=T;t<=C;t++){let e=t-n,r=e*e,i=t*c;for(let t=u;t<=g;t++){let e=(t-a)*A/P,l=e*e+r;if(l>S)continue;let s=Math.floor(10*Math.sqrt(l)),n=s<w.length?w[s]:0,h=i+t,u=I[h]+o*n;I[h]=u,u>y&&(y=u)}}}}let N=y>0?1/y:0;if(R||!this.colorLookupCache||256!==this.colorLookupCache.length){this.colorLookupCache=Array(256);for(let t=0;t<256;t++){let e=t/255;this.colorLookupCache[t]=this.interpolateColor(i,e)}}let v=this.colorLookupCache;for(let t=0;t<I.length;t++){let e=I[t];if(e<=.001)continue;let a=Math.min(e*N,1),r=v[Math.min(Math.floor(255*a),255)],i=4*t;L[i]=r.r,L[i+1]=r.g,L[i+2]=r.b,L[i+3]=Math.round(255*a)}r.putImageData(t,0,0)}}function m(t,e,a,r,i){if(!a)return;let l=a.length,s=e/l,n=0;for(let e=0;e<l;e++){let l=a[e],o=l.length;if(0===o)continue;0===n&&(n=t/o);let h=Math.floor(s*e),u=Math.ceil(s*(e+1));for(let e=0;e<o;e++){let a=l[e],s=Math.floor(n*e),o=Math.ceil(n*(e+1)),c=i(a);for(let e=h;e<u;e++){let a=e*t;for(let t=s;t<o;t++){let e=(a+t)*4;r[e]=c.r,r[e+1]=c.g,r[e+2]=c.b,r[e+3]=c.a}}}}}function T(t){if(!Array.isArray(t)||0===t.length)throw Error("Input must be a non-empty array.");let e=t[0],a=t[0];for(let r=1;r<t.length;r++)t[r]<e?e=t[r]:t[r]>a&&(a=t[r]);return[e,a]}function C(t){return"number"==typeof t&&Number.isFinite(t)}function M(t){return new Float64Array(t.flatMap(e=>0===e.length?Array(t[0].length).fill(Number.NaN):e))}let E=null;function R(){if(null!==E)return E;try{let t=document.createElement("canvas").getContext("webgl2");if(E=!!t,t){let e=t.getExtension("WEBGL_lose_context");e?.loseContext()}}catch{E=!1}return E}class L extends n{init(t){super.init(t),this.state.canvas.style.transform="scaleY(1)";let e=t.fillStyle??o.FILL_STYLE,a=t.fillStylePrimary??o.FILL_STYLE_PRIMARY,r=t.fillStyleTransparentBase??o.FILL_STYLE_TRANSPARENT_BASE;this.updateProps({fillStyle:e,fillStylePrimary:a,fillStyleTransparentBase:r,baseWidth:6,padding:t.padding??0,step:t.ticksStep??10,lineWidth:1,data:{value:0,limit:0}})}clear(){this.clearRect();let{ctx:t,BGCanvas:e}=this.state;e&&t.drawImage(e,0,0)}resize(){super.resize(),this.state.lineWidth&&this.drawBackground()}render(t){this.state.data={...this.state.data,...t},this.draw()}draw(){let{data:{value:t},range:[e,a],canvas:r,ctx:i,baseWidth:l,padding:s,BGCanvas:n,fillStylePrimary:o}=this.state;this.clearRect(),n&&i.drawImage(n,0,0);let h=3*l,u=r.height-2*s,c=(r.width-h)/2,d=(t-e)/(a-e)*u;i.fillStyle=o,i.fillRect(c,u-d+s,h,d),this.drawLimit()}drawLimit(){let{data:{limit:t},range:[e,a],canvas:r,ctx:i,baseWidth:l,padding:s,lineWidth:n,fillStylePrimary:o}=this.state;if(!C(t))return;let h=3*l,u=r.height-2*s,c=(r.width-h)/2,d=u*(a-t)/(a-e)+s;i.beginPath(),i.moveTo(c+h,d),i.lineTo(c+h+9,d-9),i.lineTo(c+h+9+30,d-9),i.lineTo(c+h+9+30,d+9),i.lineTo(c+h+9,d+9),i.lineTo(c+h,d),i.lineTo(c,d),i.lineWidth=n,i.strokeStyle=o,i.stroke(),i.fillStyle=o,i.font="12px Arial",i.textAlign="center",i.textBaseline="middle",i.fillText(t.toString(),c+h+9+15,d+1)}drawBackground(){let{canvas:t,baseWidth:e,padding:a,lineWidth:r,step:i,range:[l,s],fillStyle:n,fillStyleTransparentBase:o}=this.state,h=document.createElement("canvas");h.width=t.width,h.height=t.height;let u=h.getContext("2d");if(!u)return;let c=3*e,d=t.height-2*a,f=(t.width-c)/2,g=Array.from({length:11},(t,e)=>l+Math.round(e*(s-l)/10/i)*i);u.fillStyle=o,u.fillRect(f,a,c,d);for(let t=l;t<=s;t+=i){let i=g.includes(t),o=d*(s-t)/(s-l)+a;u.beginPath(),u.moveTo(f-(i?e:e/2),o),u.lineTo(f,o),u.strokeStyle=n,u.lineWidth=i?r:r/2,u.stroke(),i&&(u.fillStyle=n,u.font="12px Arial",u.textAlign="right",u.textBaseline="middle",u.fillText(t.toString(),f-1.2*e,o))}this.state.BGCanvas=h}}class A{state;constructor(t){this.state={id:t.id,container:void 0,canvas:null,gl:null,range:t.range??[-20,100]},this.init(t)}updateProps(t){this.state={...this.state,...t}}init(t){let{id:e}=this.state,a=document.getElementById(e),r=document.createElement("canvas"),i=r.getContext("webgl2",{alpha:!0,antialias:!1,premultipliedAlpha:!1,preserveDrawingBuffer:!1});if(!i){console.error("WebGL 2.0 not supported");return}r.style.transform="scaleY(-1)",this.updateProps({container:a??void 0,canvas:r,gl:i}),a?.appendChild(r),this.resize(!1)}compileShader(t,e){let{gl:a}=this.state,r=a.createShader(t);return r?(a.shaderSource(r,e),a.compileShader(r),a.getShaderParameter(r,a.COMPILE_STATUS))?r:(console.error("Shader compile error:",a.getShaderInfoLog(r)),a.deleteShader(r),null):null}createProgram(t){let{gl:e}=this.state,a=this.compileShader(e.VERTEX_SHADER,t.vertex),r=this.compileShader(e.FRAGMENT_SHADER,t.fragment);if(!a||!r)return null;let i=e.createProgram();return i?(e.attachShader(i,a),e.attachShader(i,r),e.linkProgram(i),e.getProgramParameter(i,e.LINK_STATUS))?(e.deleteShader(a),e.deleteShader(r),i):(console.error("Program link error:",e.getProgramInfoLog(i)),e.deleteProgram(i),null):null}createTexture(){let{gl:t}=this.state,e=t.createTexture();return e?(t.bindTexture(t.TEXTURE_2D,e),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),e):null}createQuadBuffer(){let{gl:t}=this.state,e=t.createBuffer();if(!e)return null;t.bindBuffer(t.ARRAY_BUFFER,e);let a=new Float32Array([-1,-1,1,-1,-1,1,-1,1,1,-1,1,1]);return t.bufferData(t.ARRAY_BUFFER,a,t.STATIC_DRAW),e}clearRect(){let{gl:t}=this.state;t.clearColor(0,0,0,0),t.clear(t.COLOR_BUFFER_BIT)}resize(t=!0){let{canvas:e,container:a,gl:r}=this.state;if(!a)return;let{clientWidth:i,clientHeight:l}=a;i&&l&&(e.width=i,e.height=l,r.viewport(0,0,i,l),t&&setTimeout(()=>{this.draw()}))}draw(){}dispose(){let{gl:t,canvas:e}=this.state;if(t){let e=t.getExtension("WEBGL_lose_context");e&&e.loseContext()}e?.remove()}}let S=`#version 300 es
|
|
1
|
+
let t=new Map;function e(t,e){let a,r,i,l;if(!/^#([A-Fa-f0-9]{3}){1,2}([A-Fa-f0-9]{2})?$/.test(t))throw Error("Invalid hex color format");let s=t.replace("#","");if(3===s.length)a=Number.parseInt(s[0]+s[0],16),r=Number.parseInt(s[1]+s[1],16),i=Number.parseInt(s[2]+s[2],16),l=255;else if(6===s.length)a=Number.parseInt(s.substring(0,2),16),r=Number.parseInt(s.substring(2,4),16),i=Number.parseInt(s.substring(4,6),16),l=255;else if(8===s.length)a=Number.parseInt(s.substring(0,2),16),r=Number.parseInt(s.substring(2,4),16),i=Number.parseInt(s.substring(4,6),16),l=Number.parseInt(s.substring(6,8),16);else throw Error("Invalid hex color length");return"number"==typeof e&&(l=Math.round(255*Math.max(0,Math.min(1,e)))),{r:a,g:r,b:i,a:l}}function a(t,e,r,i=255){let l=t=>t.toString(16).padStart(2,"0"),s=`#${l(t)}${l(e)}${l(r)}`;return i<255?`${s}${l(i)}`:s}function r(e){if("string"==typeof e){let a=t.get(e);if(a)return a;let r=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i.exec(e),i=r?{r:parseInt(r[1],16),g:parseInt(r[2],16),b:parseInt(r[3],16),a:r[4]?parseInt(r[4],16):255}:{r:0,g:0,b:0,a:255};return t.set(e,i),i}return{r:e.r,g:e.g,b:e.b,a:e.a??255}}function i(t,e=100){let a=[];for(let r=0;r<=e;r++){let i=Math.round(r/e*255).toString(16).padStart(2,"0").toUpperCase(),l=`${t}${i}`;a.push(l)}return a}function l(){t.clear()}class s{colorsPresetList=[];range=[0,0,0];static transparent={r:0,g:0,b:0,a:0};constructor(t,e,a,r=.1){this.setColors(t,e,a,r)}setColors(t,e,a,i){this.colorsPresetList=[];let l=Math.max(1,Math.floor((a-e)/i)),s=a-e;this.range=[e,a,s];let n=t.map(r);for(let t=0;t<=l;t++){let a=(e+t*i-e)/s;this.colorsPresetList.push(this.interpolateColor(n,a))}}interpolateColor(t,e){let r=Math.floor(e*(t.length-1)),i=e*(t.length-1)-r,l=t[r],s=t[r+1]||t[r],n={r:Math.round(l.r+i*(s.r-l.r)),g:Math.round(l.g+i*(s.g-l.g)),b:Math.round(l.b+i*(s.b-l.b)),a:Math.round(l.a+i*(s.a-l.a))};return{...n,hax:a(n.r,n.g,n.b,n.a)}}getColor(t){if(!Number.isFinite(t))return s.transparent;let[e,,a]=this.range,r=(t-e)/a;if(r<=0)return this.colorsPresetList[0];if(r>=1)return this.colorsPresetList[this.colorsPresetList.length-1];let i=Math.min(Math.floor(r*this.colorsPresetList.length),this.colorsPresetList.length-1);return this.colorsPresetList[i]}}class n{state;constructor(t){this.state={id:t.id,container:void 0,canvas:null,ctx:null,range:t.range??[-20,100]},this.init(t)}updateProps(t){this.state={...this.state,...t}}init(t){let{id:e}=this.state,a=document.getElementById(e),r=document.createElement("canvas"),i=r.getContext?.("2d");r.style.transform="scaleY(-1)",i&&(i.imageSmoothingEnabled=!1,i.lineJoin="miter",i.lineCap="butt",i.textBaseline="middle"),i&&this.updateProps({container:a??void 0,canvas:r,ctx:i}),a?.appendChild(r),this.resize(!1)}clearRect(){let{ctx:t,canvas:e}=this.state;t.clearRect(0,0,e.width,e.height)}resize(t=!0){let{canvas:e,container:a}=this.state,{clientWidth:r,clientHeight:i}=a;r&&i&&(e.width=r,e.height=i,t&&setTimeout(()=>{this.draw()}))}draw(){}dispose(){let{canvas:t,container:e}=this.state;e?.removeChild(t)}}let o={COLOR:"#000000",THICKNESS:1,FILL_STYLE:"#ffffffB0",FILL_STYLE_PRIMARY:"#1890ff",FILL_STYLE_TRANSPARENT_BASE:"#ffffff10",LINE_COLOR:"#00ff00",POINT_COLOR:"#ff0000",DIAL_NORTH_COLOR:"#ff4d4f",DIAL_SOUTH_COLOR:"#1890ff",FLUORESCENCE_COLORS:["#000080","#0000FF","#00FFFF","#00FF00","#FFFF00","#FF0000"],RANGE:[-20,100]},h={LEVEL_MIN:-20,LEVEL_MAX:140,LEVEL_RANGE:161,MAX_GAUSSIAN_RADIUS:30},u={Y_RANGE:[-1,1],SEGMENT_SIZE:5,MODE:"classic",DECAY_FACTOR:.98,MAX_ACCUMULATION:1e3,MODERN_COLORS:["#000080","#0000FF","#00FFFF","#00FF00","#FFFF00","#FF0000"],CLASSIC_COLORS:["#00ff00","#ff0000"],CLASSIC_ALPHA_GAIN:50};var c=/*#__PURE__*/function(t){return t.Horizontal="horizontal",t.Vertical="vertical",t}({}),d=/*#__PURE__*/function(t){return t.Circle="circle",t.Rect="rect",t.Line="line",t.Stepline="stepline",t.Bar="bar",t.Area="area",t}({}),f=/*#__PURE__*/function(t){return t.Canvas="canvas",t.WebGL="webgl",t}({}),g=/*#__PURE__*/function(t){return t.Gaussian="gaussian",t.Grid="grid",t}({});class p extends n{init(t){super.init(t);let{colors:e,display:a,fluorescenceRenderMode:r}=t;this.updateProps({colors:e,data:new Uint32Array(0),display:a,renderMode:r??g.Gaussian}),this.resize()}updateProps(t){let e=t.range&&(t.range[0]!==this.state.range?.[0]||t.range[1]!==this.state.range?.[1]),a=void 0!==t.renderMode&&t.renderMode!==this.state.renderMode;super.updateProps(t),(e||a)&&this.state.data?.length>0&&this.draw()}setRenderMode(t){this.updateProps({renderMode:t})}clearImageData(){let{ctx:t,canvas:{height:e,width:a}}=this.state;e&&a&&this.updateProps({imageData:t.createImageData(a,e)})}clearRect(){super.clearRect(),this.clearImageData()}clear(){this.clearRect(),this.updateProps({data:new Uint32Array(0)})}dispose(){this.intensityMatrixCache=null,this.gridCentersCache=null,this.weightLookupCache=null,this.colorLookupCache=null,this.colorCache.clear(),this.lastRenderParams=null,this.blockPositionsCache=null,this.lastBlockRenderParams=null}drawBlocks(){let{imageData:t,data:e,canvas:a,ctx:r,colors:i=o.FLUORESCENCE_COLORS,range:l=o.RANGE}=this.state;if(!e||0===e.length||!t)return;let{width:s,height:n}=a,[u,c]=l,d=c-u;if(d<=0)return;let f=e.length/h.LEVEL_RANGE;if(!Number.isInteger(f)||f<=0)return;let g={dataLength:f,width:s,height:n,rangeMin:u,rangeMax:c};if(!this.lastBlockRenderParams||Object.keys(g).some(t=>this.lastBlockRenderParams?.[t]!==g[t])||!this.blockPositionsCache||this.blockPositionsCache.length!==f){this.blockPositionsCache=Array(f);let t=Math.max(1,Math.floor(s/f));for(let e=0;e<f;e++){let a=Math.floor(e*s/f),r=Math.min(s-1,a+t-1);this.blockPositionsCache[e]={startX:a,endX:r,width:r-a+1}}}this.lastBlockRenderParams=g;let p=t.data;p.fill(0);let m=1/d,T=n-1,C=Math.max(1,Math.ceil(n/d)),M=0;for(let t=0;t<f;t++){let a=t*h.LEVEL_RANGE;for(let t=0;t<h.LEVEL_RANGE;t++){let r=e[a+t];if(r<=0)continue;let i=t+h.LEVEL_MIN;i<u||i>c||!(r>M)||(M=r)}}let E=Math.log(Math.max(M,1)+1);for(let t=0;t<f;t++){let{startX:a,endX:r}=this.blockPositionsCache[t],l=t*h.LEVEL_RANGE;for(let t=0;t<h.LEVEL_RANGE;t++){let n=e[l+t];if(n<=0)continue;let o=t+h.LEVEL_MIN;if(o<u||o>c)continue;let d=Math.max(0,Math.floor((o-u)*m*T-C/2)),f=Math.min(T,d+C-1),g=Math.log(n+1)/E,M=Math.round(255*g),{r:R,g:L,b:A}=this.interpolateColor(i,g);for(let t=d;t<=f;t++){let e=t*s;for(let t=a;t<=r;t++){let a=(e+t)*4;p[a]=R,p[a+1]=L,p[a+2]=A,p[a+3]=M}}}}r.putImageData(t,0,0)}resize(){super.resize(),this.clearImageData()}setRange(t){t&&(this.updateProps({range:t}),this.draw())}render(t){t?.fluorescenceData?.length>=0&&((this.state.data?.length??0)!==t.fluorescenceData.length&&(this.clearImageData(),this.intensityMatrixCache=null,this.gridCentersCache=null,this.blockPositionsCache=null,this.lastRenderParams=null,this.lastBlockRenderParams=null),this.state.data=t.fluorescenceData,this.state.fluorescenceMaxCount=t.fluorescenceMaxCount,this.draw())}interpolateColor(t,e){if(!t||0===t.length)return{r:255,g:255,b:255,a:255};e=Math.max(0,Math.min(1,e));let a=t=>"string"==typeof t?this.hexToRgb(t):{r:t.r,g:t.g,b:t.b};if(1===t.length||0===e)return{...a(t[0]),a:255};if(1===e)return{...a(t[t.length-1]),a:255};let r=e*(t.length-1),i=Math.floor(r),l=r-i,s=Math.min(i,t.length-2),n=a(t[s]),o=a(t[s+1]);return{r:Math.round(n.r+(o.r-n.r)*l),g:Math.round(n.g+(o.g-n.g)*l),b:Math.round(n.b+(o.b-n.b)*l),a:255}}colorCache=new Map;hexToRgb(t){let e=this.colorCache.get(t);if(e)return e;let a=r(t),i={r:a.r,g:a.g,b:a.b};return this.colorCache.set(t,i),i}lastRenderParams=null;intensityMatrixCache=null;gridCentersCache=null;weightLookupCache=null;colorLookupCache=null;blockPositionsCache=null;lastBlockRenderParams=null;draw(){let{imageData:t,data:e,canvas:a,ctx:r,colors:i=o.FLUORESCENCE_COLORS,range:l=o.RANGE,fluorescenceMaxCount:s=1,display:n,renderMode:u=g.Gaussian}=this.state;if(!n||!e||0===e.length||!t)return;if(u===g.Grid){this.drawBlocks();return}let{width:c,height:d}=a,[f,p]=l,m=p-f;if(m<=0)return;let T=e.length/h.LEVEL_RANGE;if(!Number.isInteger(T)||T<=0)return;let C={dataLength:T,rangeMin:f,rangeMax:p,width:c,height:d,maxCount:s},M=!this.lastRenderParams||this.lastRenderParams.dataLength!==C.dataLength||this.lastRenderParams.width!==C.width,E=!this.lastRenderParams||this.lastRenderParams.height!==C.height,R=!this.colorLookupCache;this.lastRenderParams=C;let L=t.data;L.fill(0);let A=Math.min(Math.max(2,Math.ceil(d/m),Math.floor(d/50)),h.MAX_GAUSSIAN_RADIUS),S=A*A,_=c*d,P=Math.min(Math.max(A,Math.ceil(c/T)),h.MAX_GAUSSIAN_RADIUS);this.intensityMatrixCache&&this.intensityMatrixCache.length===_?this.intensityMatrixCache.fill(0):this.intensityMatrixCache=new Float32Array(_);let I=this.intensityMatrixCache;if(M||!this.gridCentersCache||this.gridCentersCache.length!==T){this.gridCentersCache=new Float32Array(T);let t=c/T;for(let e=0;e<T;e++){let a=Math.floor(t*e),r=Math.ceil(t*(e+1));this.gridCentersCache[e]=(a+r)/2}}let x=this.gridCentersCache,b=Math.ceil(10*A)+1;if(E||!this.weightLookupCache||this.weightLookupCache.length!==b){this.weightLookupCache=new Float32Array(b);for(let t=0;t<=10*A;t++){let e=t/10;this.weightLookupCache[t]=Math.exp(-(e*e)/(2*S))}}let w=this.weightLookupCache,y=0;for(let t=0;t<T;t++){let a=x[t],r=t*h.LEVEL_RANGE;for(let t=0;t<h.LEVEL_RANGE;t++){let i=e[r+t];if(i<=0)continue;let l=t+h.LEVEL_MIN;if(l<f||l>p)continue;let n=(l-f)/m*(d-1),o=Math.log(i+1)/Math.log(Math.max(s,1)+1),u=Math.max(0,Math.floor(a-P)),g=Math.min(c-1,Math.ceil(a+P)),T=Math.max(0,Math.floor(n-A)),C=Math.min(d-1,Math.ceil(n+A));for(let t=T;t<=C;t++){let e=t-n,r=e*e,i=t*c;for(let t=u;t<=g;t++){let e=(t-a)*A/P,l=e*e+r;if(l>S)continue;let s=Math.floor(10*Math.sqrt(l)),n=s<w.length?w[s]:0,h=i+t,u=I[h]+o*n;I[h]=u,u>y&&(y=u)}}}}let N=y>0?1/y:0;if(R||!this.colorLookupCache||256!==this.colorLookupCache.length){this.colorLookupCache=Array(256);for(let t=0;t<256;t++){let e=t/255;this.colorLookupCache[t]=this.interpolateColor(i,e)}}let v=this.colorLookupCache;for(let t=0;t<I.length;t++){let e=I[t];if(e<=.001)continue;let a=Math.min(e*N,1),r=v[Math.min(Math.floor(255*a),255)],i=4*t;L[i]=r.r,L[i+1]=r.g,L[i+2]=r.b,L[i+3]=Math.round(255*a)}r.putImageData(t,0,0)}}function m(t,e,a,r,i){if(!a)return;let l=a.length,s=e/l,n=0;for(let e=0;e<l;e++){let l=a[e],o=l.length;if(0===o)continue;0===n&&(n=t/o);let h=Math.floor(s*e),u=Math.ceil(s*(e+1));for(let e=0;e<o;e++){let a=l[e],s=Math.floor(n*e),o=Math.ceil(n*(e+1)),c=i(a);for(let e=h;e<u;e++){let a=e*t;for(let t=s;t<o;t++){let e=(a+t)*4;r[e]=c.r,r[e+1]=c.g,r[e+2]=c.b,r[e+3]=c.a}}}}}function T(t){if(!Array.isArray(t)||0===t.length)throw Error("Input must be a non-empty array.");let e=t[0],a=t[0];for(let r=1;r<t.length;r++)t[r]<e?e=t[r]:t[r]>a&&(a=t[r]);return[e,a]}function C(t){return"number"==typeof t&&Number.isFinite(t)}function M(t){return new Float64Array(t.flatMap(e=>0===e.length?Array(t[0].length).fill(Number.NaN):e))}let E=null;function R(){if(null!==E)return E;try{let t=document.createElement("canvas").getContext("webgl2");if(E=!!t,t){let e=t.getExtension("WEBGL_lose_context");e?.loseContext()}}catch{E=!1}return E}class L extends n{init(t){super.init(t),this.state.canvas.style.transform="scaleY(1)";let e=t.fillStyle??o.FILL_STYLE,a=t.fillStylePrimary??o.FILL_STYLE_PRIMARY,r=t.fillStyleTransparentBase??o.FILL_STYLE_TRANSPARENT_BASE;this.updateProps({fillStyle:e,fillStylePrimary:a,fillStyleTransparentBase:r,baseWidth:6,padding:t.padding??0,step:t.ticksStep??10,lineWidth:1,data:{value:0,limit:0}})}clear(){this.clearRect();let{ctx:t,BGCanvas:e}=this.state;e&&t.drawImage(e,0,0)}resize(){super.resize(),this.state.lineWidth&&this.drawBackground()}render(t){this.state.data={...this.state.data,...t},this.draw()}draw(){let{data:{value:t},range:[e,a],canvas:r,ctx:i,baseWidth:l,padding:s,BGCanvas:n,fillStylePrimary:o}=this.state;this.clearRect(),n&&i.drawImage(n,0,0);let h=3*l,u=r.height-2*s,c=(r.width-h)/2,d=(t-e)/(a-e)*u;i.fillStyle=o,i.fillRect(c,u-d+s,h,d),this.drawLimit()}drawLimit(){let{data:{limit:t},range:[e,a],canvas:r,ctx:i,baseWidth:l,padding:s,lineWidth:n,fillStylePrimary:o}=this.state;if(!C(t))return;let h=3*l,u=r.height-2*s,c=(r.width-h)/2,d=u*(a-t)/(a-e)+s;i.beginPath(),i.moveTo(c+h,d),i.lineTo(c+h+9,d-9),i.lineTo(c+h+9+30,d-9),i.lineTo(c+h+9+30,d+9),i.lineTo(c+h+9,d+9),i.lineTo(c+h,d),i.lineTo(c,d),i.lineWidth=n,i.strokeStyle=o,i.stroke(),i.fillStyle=o,i.font="12px Arial",i.textAlign="center",i.textBaseline="middle",i.fillText(t.toString(),c+h+9+15,d+1)}drawBackground(){let{canvas:t,baseWidth:e,padding:a,lineWidth:r,step:i,range:[l,s],fillStyle:n,fillStyleTransparentBase:o}=this.state,h=document.createElement("canvas");h.width=t.width,h.height=t.height;let u=h.getContext("2d");if(!u)return;let c=3*e,d=t.height-2*a,f=(t.width-c)/2,g=Array.from({length:11},(t,e)=>l+Math.round(e*(s-l)/10/i)*i);u.fillStyle=o,u.fillRect(f,a,c,d);for(let t=l;t<=s;t+=i){let i=g.includes(t),o=d*(s-t)/(s-l)+a;u.beginPath(),u.moveTo(f-(i?e:e/2),o),u.lineTo(f,o),u.strokeStyle=n,u.lineWidth=i?r:r/2,u.stroke(),i&&(u.fillStyle=n,u.font="12px Arial",u.textAlign="right",u.textBaseline="middle",u.fillText(t.toString(),f-1.2*e,o))}this.state.BGCanvas=h}}class A{state;constructor(t){this.state={id:t.id,container:void 0,canvas:null,gl:null,range:t.range??[-20,100]},this.init(t)}updateProps(t){this.state={...this.state,...t}}init(t){let{id:e}=this.state,a=document.getElementById(e),r=document.createElement("canvas"),i=r.getContext("webgl2",{alpha:!0,antialias:!1,premultipliedAlpha:!0,preserveDrawingBuffer:!1});if(!i){console.error("WebGL 2.0 not supported");return}r.style.transform="scaleY(-1)",this.updateProps({container:a??void 0,canvas:r,gl:i}),a?.appendChild(r),this.resize(!1)}compileShader(t,e){let{gl:a}=this.state,r=a.createShader(t);return r?(a.shaderSource(r,e),a.compileShader(r),a.getShaderParameter(r,a.COMPILE_STATUS))?r:(console.error("Shader compile error:",a.getShaderInfoLog(r)),a.deleteShader(r),null):null}createProgram(t){let{gl:e}=this.state,a=this.compileShader(e.VERTEX_SHADER,t.vertex),r=this.compileShader(e.FRAGMENT_SHADER,t.fragment);if(!a||!r)return null;let i=e.createProgram();return i?(e.attachShader(i,a),e.attachShader(i,r),e.linkProgram(i),e.getProgramParameter(i,e.LINK_STATUS))?(e.deleteShader(a),e.deleteShader(r),i):(console.error("Program link error:",e.getProgramInfoLog(i)),e.deleteProgram(i),null):null}createTexture(){let{gl:t}=this.state,e=t.createTexture();return e?(t.bindTexture(t.TEXTURE_2D,e),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),e):null}createQuadBuffer(){let{gl:t}=this.state,e=t.createBuffer();if(!e)return null;t.bindBuffer(t.ARRAY_BUFFER,e);let a=new Float32Array([-1,-1,1,-1,-1,1,-1,1,1,-1,1,1]);return t.bufferData(t.ARRAY_BUFFER,a,t.STATIC_DRAW),e}clearRect(){let{gl:t}=this.state;t.clearColor(0,0,0,0),t.clear(t.COLOR_BUFFER_BIT)}resize(t=!0){let{canvas:e,container:a,gl:r}=this.state;if(!a)return;let{clientWidth:i,clientHeight:l}=a;i&&l&&(e.width=i,e.height=l,r.viewport(0,0,i,l),t&&setTimeout(()=>{this.draw()}))}draw(){}dispose(){let{gl:t,canvas:e}=this.state;if(t){let e=t.getExtension("WEBGL_lose_context");e&&e.loseContext()}e?.remove()}}let S=`#version 300 es
|
|
2
2
|
in vec2 a_position;
|
|
3
3
|
out vec2 v_texCoord;
|
|
4
4
|
|
package/package.json
CHANGED