@tradecanvas/core 1.7.0 → 1.10.0
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/LICENSE +21 -21
- package/README.md +107 -107
- package/dist/WebGLSeriesRenderer-DQOPCwno.js +1643 -0
- package/dist/WebGLSeriesRenderer-DQOPCwno.js.map +1 -0
- package/dist/WebGLSeriesRenderer-DspCYR38.cjs +429 -0
- package/dist/WebGLSeriesRenderer-DspCYR38.cjs.map +1 -0
- package/dist/axis/GridRenderer.d.ts.map +1 -1
- package/dist/axis/PriceAxis.d.ts +3 -1
- package/dist/axis/PriceAxis.d.ts.map +1 -1
- package/dist/axis/TimeAxis.d.ts.map +1 -1
- package/dist/axis/gridLines.d.ts +9 -0
- package/dist/axis/gridLines.d.ts.map +1 -0
- package/dist/charts/BarRenderer.d.ts.map +1 -1
- package/dist/charts/CandlestickRenderer.d.ts.map +1 -1
- package/dist/charts/HollowCandleRenderer.d.ts.map +1 -1
- package/dist/charts/VolumeRenderer.d.ts +6 -3
- package/dist/charts/VolumeRenderer.d.ts.map +1 -1
- package/dist/charts/denseBars.d.ts.map +1 -1
- package/dist/charts/pixelGrid.d.ts +49 -0
- package/dist/charts/pixelGrid.d.ts.map +1 -0
- package/dist/drawings/DrawingBase.d.ts +4 -0
- package/dist/drawings/DrawingBase.d.ts.map +1 -1
- package/dist/drawings/DrawingRenderer.d.ts +2 -2
- package/dist/drawings/DrawingRenderer.d.ts.map +1 -1
- package/dist/drawings/tools/CrossLine.d.ts.map +1 -1
- package/dist/drawings/tools/DateRange.d.ts.map +1 -1
- package/dist/drawings/tools/ElliottWave.d.ts.map +1 -1
- package/dist/drawings/tools/FibChannel.d.ts.map +1 -1
- package/dist/drawings/tools/FibExtension.d.ts.map +1 -1
- package/dist/drawings/tools/FibRetracement.d.ts.map +1 -1
- package/dist/drawings/tools/FibSpeedResistanceFan.d.ts.map +1 -1
- package/dist/drawings/tools/FibTimeZones.d.ts.map +1 -1
- package/dist/drawings/tools/GannBox.d.ts.map +1 -1
- package/dist/drawings/tools/GannFan.d.ts.map +1 -1
- package/dist/drawings/tools/HorizontalLine.d.ts.map +1 -1
- package/dist/drawings/tools/HorizontalRay.d.ts.map +1 -1
- package/dist/drawings/tools/RiskReward.d.ts.map +1 -1
- package/dist/drawings/tools/TextAnnotation.d.ts.map +1 -1
- package/dist/drawings/tools/TrendAngle.d.ts.map +1 -1
- package/dist/drawings/tools/VerticalLine.d.ts.map +1 -1
- package/dist/drawings/tools/annotations.d.ts.map +1 -1
- package/dist/drawings/tools/fibGeometry.d.ts.map +1 -1
- package/dist/drawings/tools/labels.d.ts +26 -0
- package/dist/drawings/tools/labels.d.ts.map +1 -1
- package/dist/drawings/tools/options.d.ts +8 -0
- package/dist/drawings/tools/options.d.ts.map +1 -1
- package/dist/drawings/tools/priceLevels.d.ts.map +1 -1
- package/dist/drawings/tools/textBox.d.ts.map +1 -1
- package/dist/engine/LayerManager.d.ts +23 -0
- package/dist/engine/LayerManager.d.ts.map +1 -1
- package/dist/engine/RenderEngine.d.ts +32 -3
- package/dist/engine/RenderEngine.d.ts.map +1 -1
- package/dist/engine/gpu.d.ts +83 -0
- package/dist/engine/gpu.d.ts.map +1 -0
- package/dist/engine/index.d.ts +2 -0
- package/dist/engine/index.d.ts.map +1 -1
- package/dist/engine/loadWebGL.d.ts +9 -0
- package/dist/engine/loadWebGL.d.ts.map +1 -0
- package/dist/engine/plotSteps.d.ts +39 -0
- package/dist/engine/plotSteps.d.ts.map +1 -0
- package/dist/gridLines-J41F0DQ6.cjs +2 -0
- package/dist/gridLines-J41F0DQ6.cjs.map +1 -0
- package/dist/gridLines-kFhXyH-u.js +218 -0
- package/dist/gridLines-kFhXyH-u.js.map +1 -0
- package/dist/index.cjs +10 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2982 -2683
- package/dist/index.js.map +1 -1
- package/dist/indicators/IndicatorBase.d.ts.map +1 -1
- package/dist/indicators/IndicatorEngine.d.ts +2 -0
- package/dist/indicators/IndicatorEngine.d.ts.map +1 -1
- package/dist/indicators/linePen.d.ts +38 -0
- package/dist/indicators/linePen.d.ts.map +1 -0
- package/dist/indicators/overlay/Alligator.d.ts.map +1 -1
- package/dist/indicators/overlay/AnchoredVWAP.d.ts.map +1 -1
- package/dist/indicators/overlay/BollingerBands.d.ts.map +1 -1
- package/dist/indicators/overlay/EMA.d.ts.map +1 -1
- package/dist/indicators/overlay/HullMA.d.ts.map +1 -1
- package/dist/indicators/overlay/MTFMovingAverage.d.ts.map +1 -1
- package/dist/indicators/overlay/SMA.d.ts.map +1 -1
- package/dist/indicators/overlay/SessionVWAP.d.ts.map +1 -1
- package/dist/indicators/overlay/Supertrend.d.ts.map +1 -1
- package/dist/indicators/overlay/TEMA.d.ts.map +1 -1
- package/dist/indicators/overlay/VWAP.d.ts.map +1 -1
- package/dist/indicators/overlay/VWMA.d.ts.map +1 -1
- package/dist/indicators/overlay/WMA.d.ts.map +1 -1
- package/dist/indicators/plots.d.ts.map +1 -1
- package/dist/interaction/CrosshairHandler.d.ts.map +1 -1
- package/dist/interaction/InteractionManager.d.ts.map +1 -1
- package/dist/trading/PositionRenderer.d.ts.map +1 -1
- package/dist/trading/TradingDragHandler.d.ts.map +1 -1
- package/dist/trading/TradingManager.d.ts +3 -0
- package/dist/trading/TradingManager.d.ts.map +1 -1
- package/dist/trading/TradingRenderer.d.ts +2 -0
- package/dist/trading/TradingRenderer.d.ts.map +1 -1
- package/dist/trading/plot.d.ts +4 -0
- package/dist/trading/plot.d.ts.map +1 -0
- package/dist/ui/SessionBreaks.d.ts +10 -0
- package/dist/ui/SessionBreaks.d.ts.map +1 -1
- package/dist/ui/SessionShading.d.ts +3 -0
- package/dist/ui/SessionShading.d.ts.map +1 -1
- package/dist/ui/Watermark.d.ts +2 -0
- package/dist/ui/Watermark.d.ts.map +1 -1
- package/dist/ui/axisValueLabels.d.ts +17 -0
- package/dist/ui/axisValueLabels.d.ts.map +1 -1
- package/dist/ui/index.d.ts +2 -1
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/webgl/WebGLSeriesRenderer.d.ts +70 -0
- package/dist/webgl/WebGLSeriesRenderer.d.ts.map +1 -0
- package/dist/webgl/commandDrawer.d.ts +31 -0
- package/dist/webgl/commandDrawer.d.ts.map +1 -0
- package/dist/webgl/glColor.d.ts +13 -0
- package/dist/webgl/glColor.d.ts.map +1 -0
- package/dist/webgl/glKit.d.ts +26 -0
- package/dist/webgl/glKit.d.ts.map +1 -0
- package/dist/webgl/index.d.ts +5 -0
- package/dist/webgl/index.d.ts.map +1 -0
- package/dist/webgl/polygonSpans.d.ts +20 -0
- package/dist/webgl/polygonSpans.d.ts.map +1 -0
- package/dist/webgl/recordedCommands.d.ts +75 -0
- package/dist/webgl/recordedCommands.d.ts.map +1 -0
- package/dist/webgl/recordedPath.d.ts +51 -0
- package/dist/webgl/recordedPath.d.ts.map +1 -0
- package/dist/webgl/recordedShaders.d.ts +38 -0
- package/dist/webgl/recordedShaders.d.ts.map +1 -0
- package/dist/webgl/recorder.d.ts +67 -0
- package/dist/webgl/recorder.d.ts.map +1 -0
- package/dist/webgl/seriesUploads.d.ts +40 -0
- package/dist/webgl/seriesUploads.d.ts.map +1 -0
- package/dist/webgl/shaders.d.ts +39 -0
- package/dist/webgl/shaders.d.ts.map +1 -0
- package/dist/webgl/strokeGeometry.d.ts +28 -0
- package/dist/webgl/strokeGeometry.d.ts.map +1 -0
- package/dist/webgl/yMapping.d.ts +32 -0
- package/dist/webgl/yMapping.d.ts.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
const e=require(`./gridLines-J41F0DQ6.cjs`);let t=require(`@tradecanvas/commons`);var n=(e,t)=>e.time===t.time&&e.open===t.open&&e.high===t.high&&e.low===t.low&&e.close===t.close&&e.volume===t.volume,r=class{buffer=new Float32Array;count=0;basePrice=0;samples=[];last=null;source=null;get values(){return this.buffer}get length(){return this.count}get base(){return this.basePrice}sync(e){let t=e.length;if(t===0)return this.reset(),{full:!0,from:0,to:0};let r=this.count;if(!(e===this.source&&r>0&&t>=r&&this.samples.every(({index:t,bar:r})=>n(e[t],r))))return this.basePrice=e[t-1].close,this.ensure(t),this.write(e,0,t),this.remember(e),{full:!0,from:0,to:t};let i=this.last!==null&&n(e[r-1],this.last)?r:r-1;return t>this.buffer.length/6?(this.ensure(t),this.write(e,0,t),this.remember(e),{full:!0,from:0,to:t}):(this.write(e,i,t),this.remember(e),{full:!1,from:i,to:t})}reset(){this.count=0,this.samples=[],this.last=null,this.source=null}ensure(e){e*6<=this.buffer.length||(this.buffer=new Float32Array(Math.max(e+1024,Math.ceil(e*1.25))*6))}write(e,t,n){let r=this.buffer,i=this.basePrice;for(let a=t;a<n;a++){let t=e[a],n=a*6;r[n]=t.open-i,r[n+1]=t.high-i,r[n+2]=t.low-i,r[n+3]=t.close-i,r[n+4]=t.volume,r[n+5]=+(t.close>=t.open)}this.count=n}remember(e){let t=e.length,n=t-1,r=new Set;if(n>0)for(let e=0;e<16;e++)r.add(Math.min(n-1,Math.round(e*(n-1)/15)));this.samples=[...r].map(t=>({index:t,bar:{...e[t]}})),this.last={...e[t-1]},this.source=e}},i=new Map,a;function o(e,t){return e.endsWith(`%`)?parseFloat(e)/100:parseFloat(e)/t}function s(e){let t=e.trim();if(t.toLowerCase()===`transparent`)return[0,0,0,0];let n=/^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.exec(t);if(n){let e=n[1];e.length<=4&&(e=[...e].map(e=>e+e).join(``));let t=t=>parseInt(e.slice(t,t+2),16)/255;return[t(0),t(2),t(4),e.length===8?t(6):1]}let r=/^rgba?\(\s*([\d.]+%?)[\s,]+([\d.]+%?)[\s,]+([\d.]+%?)(?:\s*[,/]\s*([\d.]+%?))?\s*\)$/i.exec(t);return r?[o(r[1],255),o(r[2],255),o(r[3],255),r[4]===void 0?1:o(r[4],1)]:null}function c(){if(a!==void 0)return a;try{a=typeof OffscreenCanvas<`u`?new OffscreenCanvas(1,1).getContext(`2d`):typeof document<`u`?document.createElement(`canvas`).getContext(`2d`):null}catch{a=null}return a}function l(e){let t=c();if(!t)return null;t.fillStyle=`#000`,t.fillStyle=e;let n=String(t.fillStyle);if(t.fillStyle=`#fff`,t.fillStyle=e,String(t.fillStyle)!==n)return null;let r=s(n);if(r)return r;t.clearRect(0,0,1,1),t.fillRect(0,0,1,1);let i=t.getImageData(0,0,1,1).data;return[i[0]/255,i[1]/255,i[2]/255,i[3]/255]}var u=new Set;function d(e){let t=i.get(e);if(t)return t;if(u.has(e))return null;let n=s(e)??l(e);return i.size>256&&i.clear(),u.size>256&&u.clear(),n?i.set(e,n):u.add(e),n}function f(e){return d(e)??[0,0,0,0]}function p([e,t,n,r]){return[e*r,t*r,n*r,r]}function m(e,t){let{min:n,max:r}=e.priceRange,{y:i,height:a}=e.chartRect,o=+(e.invertScale===!0),s={log:0,invert:o,yA:i+a/2,yB:0,logOffset:0,min:1,logFloor:0,logK:0,top:i,bottom:i+a};if(e.logScale&&n>0&&r>0){let e=Math.log(r)-Math.log(n);return e===0?s:{...s,log:1,logOffset:t-n,min:n,logFloor:2**-52/n,logK:a/e}}let c=r-n;if(c===0)return s;let l=a/c;return o?{...s,yA:i+(t-n)*l,yB:l}:{...s,yA:i+(r-t)*l,yB:-l}}var h=class{constructor(e){this.gl=e}program(e,t,n){let r=this.gl,i=(e,t)=>{let n=r.createShader(e);if(!n)throw Error(`WebGL: no shader`);if(r.shaderSource(n,t),r.compileShader(n),!r.getShaderParameter(n,r.COMPILE_STATUS)){let e=r.getShaderInfoLog(n);throw r.deleteShader(n),Error(`WebGL shader: ${e}`)}return n},a=i(r.VERTEX_SHADER,e),o=i(r.FRAGMENT_SHADER,t),s=r.createProgram();if(!s)throw Error(`WebGL: no program`);if(r.attachShader(s,a),r.attachShader(s,o),r.linkProgram(s),r.deleteShader(a),r.deleteShader(o),!r.getProgramParameter(s,r.LINK_STATUS))throw Error(`WebGL program: ${r.getProgramInfoLog(s)}`);let c=r.createVertexArray();if(!c)throw Error(`WebGL: no vertex array`);let l=new Map;for(let e of n)l.set(e,r.getAttribLocation(s,e));return{program:s,vao:c,uniforms:new Map,attribs:l}}buffer(){let e=this.gl.createBuffer();if(!e)throw Error(`WebGL: no buffer`);return e}use(e){return this.gl.useProgram(e.program),this.gl.bindVertexArray(e.vao),e}attrib(e,t,n,r,i,a=1){let o=e.attribs.get(t);if(o===void 0||o<0)return;let s=this.gl;s.enableVertexAttribArray(o),s.vertexAttribPointer(o,n,s.FLOAT,!1,r,i),s.vertexAttribDivisor(o,a)}int(e,t,n){this.gl.uniform1i(this.loc(e,t),n)}float(e,t,n){this.gl.uniform1f(this.loc(e,t),n)}vec2(e,t,n,r){this.gl.uniform2f(this.loc(e,t),n,r)}vec4(e,t,n){this.gl.uniform4f(this.loc(e,t),n[0],n[1],n[2],n[3])}loc(e,t){return e.uniforms.has(t)||e.uniforms.set(t,this.gl.getUniformLocation(e.program,t)),e.uniforms.get(t)??null}deleteProgram(e){this.gl.deleteVertexArray(e.vao),this.gl.deleteProgram(e.program)}scissor(e,t,n,r,i,a){let o=Math.max(0,Math.floor(e)),s=Math.max(0,Math.floor(t)),c=Math.min(i,Math.ceil(n)),l=Math.min(a,Math.ceil(r));if(!(c>o&&l>s))return!1;let u=this.gl;return u.enable(u.SCISSOR_TEST),u.scissor(o,a-l,c-o,l-s),!0}};function g(e){let t=e.length/2;if(t<3)return[];let n=0,r=0;for(let i=1;i<t;i++)e[2*i]<e[2*n]&&(n=i),e[2*i]>e[2*r]&&(r=i);if(e[2*n]===e[2*r])return[];let i=v(e,n,r,1,t),a=v(e,n,r,-1,t);return!i||!a?null:ee(i,a)}function _(e){let t=0,n=e.length/2;for(let r=0;r<n;r++){let i=(r+1)%n;t+=e[2*r]*e[2*i+1]-e[2*i]*e[2*r+1]}return t/2}function v(e,t,n,r,i){let a=[e[2*t],e[2*t+1]];for(let o=t;o!==n;){if(o=(o+r+i)%i,e[2*o]<a[a.length-2])return null;a.push(e[2*o],e[2*o+1])}return a}var y=class{i=0;constructor(e){this.c=e}at(e,t){let n=this.c;for(;this.i+5<n.length&&(n[this.i+2]<t||n[this.i+2]===n[this.i]);)this.i+=2;let r=n[this.i],i=n[this.i+1],a=n[this.i+2],o=n[this.i+3],s=e=>a===r?i:i+(o-i)*(e-r)/(a-r);return[s(e),s(t)]}};function ee(e,t){let n=new Set;for(let t=0;t<e.length;t+=2)n.add(e[t]);for(let e=0;e<t.length;e+=2)n.add(t[e]);let r=[...n].sort((e,t)=>e-t),i=new y(e),a=new y(t),o=[],s=r.length-2;for(let e=0;e<=s;e++){let t=r[e],n=r[e+1],[c,l]=i.at(t,n),[u,d]=a.at(t,n);c===u&&l===d||o.push(t,n,c,l,u,d,+(e===0),+(e===s))}return o}var b=`#version 300 es
|
|
2
|
+
precision highp float;
|
|
3
|
+
uniform vec2 u_canvas;
|
|
4
|
+
uniform vec4 u_clip;
|
|
5
|
+
|
|
6
|
+
vec4 toClip(vec2 dev) {
|
|
7
|
+
return vec4(dev.x / u_canvas.x * 2.0 - 1.0, 1.0 - dev.y / u_canvas.y * 2.0, 0.0, 1.0);
|
|
8
|
+
}
|
|
9
|
+
`,x=`
|
|
10
|
+
vec2 corner(int k) {
|
|
11
|
+
if (k == 0) return vec2(0.0, 0.0);
|
|
12
|
+
if (k == 1 || k == 4) return vec2(1.0, 0.0);
|
|
13
|
+
if (k == 2 || k == 3) return vec2(0.0, 1.0);
|
|
14
|
+
return vec2(1.0, 1.0);
|
|
15
|
+
}
|
|
16
|
+
const vec4 NOWHERE = vec4(-2.0, -2.0, 0.0, 1.0);
|
|
17
|
+
`,S=`
|
|
18
|
+
// This fragment's pixel centre in device pixels, y down.
|
|
19
|
+
vec2 pixelCentre() { return vec2(gl_FragCoord.x, u_canvas.y - gl_FragCoord.y); }
|
|
20
|
+
|
|
21
|
+
// The share of the pixel centred at p inside the clip.
|
|
22
|
+
float clipCoverage(vec2 p) {
|
|
23
|
+
vec2 lo = p - 0.5;
|
|
24
|
+
vec2 c = clamp(min(lo + 1.0, u_clip.zw) - max(lo, u_clip.xy), 0.0, 1.0);
|
|
25
|
+
return c.x * c.y;
|
|
26
|
+
}
|
|
27
|
+
`,te=`${b}${x}
|
|
28
|
+
uniform float u_hw;
|
|
29
|
+
in vec4 a_p0;
|
|
30
|
+
in vec4 a_p1;
|
|
31
|
+
in vec4 a_p2;
|
|
32
|
+
in vec4 a_p3;
|
|
33
|
+
in vec4 a_p4;
|
|
34
|
+
in vec4 a_p5;
|
|
35
|
+
flat out vec4 v_p0;
|
|
36
|
+
flat out vec4 v_p1;
|
|
37
|
+
flat out vec4 v_p2;
|
|
38
|
+
flat out vec4 v_p3;
|
|
39
|
+
flat out vec4 v_p4;
|
|
40
|
+
flat out vec4 v_p5;
|
|
41
|
+
|
|
42
|
+
void main() {
|
|
43
|
+
v_p0 = a_p0; v_p1 = a_p1; v_p2 = a_p2; v_p3 = a_p3; v_p4 = a_p4; v_p5 = a_p5;
|
|
44
|
+
if (a_p2.z < 0.5 || a_p3.z < 0.5) { gl_Position = NOWHERE; return; }
|
|
45
|
+
vec2 a = a_p2.xy;
|
|
46
|
+
vec2 b = a_p3.xy;
|
|
47
|
+
vec2 d = b - a;
|
|
48
|
+
float len = length(d);
|
|
49
|
+
vec2 dir = len > 0.0 ? d / len : vec2(1.0, 0.0);
|
|
50
|
+
vec2 n = vec2(-dir.y, dir.x);
|
|
51
|
+
float m = u_hw + 1.0;
|
|
52
|
+
vec2 cr = corner(gl_VertexID % 6);
|
|
53
|
+
vec2 pos = mix(a - dir * m, b + dir * m, cr.x) + n * mix(-m, m, cr.y);
|
|
54
|
+
gl_Position = toClip(pos);
|
|
55
|
+
}
|
|
56
|
+
`,ne=`${b}${S}
|
|
57
|
+
uniform vec4 u_color;
|
|
58
|
+
uniform float u_hw;
|
|
59
|
+
uniform int u_cap;
|
|
60
|
+
uniform vec4 u_dash;
|
|
61
|
+
flat in vec4 v_p0;
|
|
62
|
+
flat in vec4 v_p1;
|
|
63
|
+
flat in vec4 v_p2;
|
|
64
|
+
flat in vec4 v_p3;
|
|
65
|
+
flat in vec4 v_p4;
|
|
66
|
+
flat in vec4 v_p5;
|
|
67
|
+
out vec4 outColor;
|
|
68
|
+
|
|
69
|
+
float segDist(vec2 p, vec2 a, vec2 b) {
|
|
70
|
+
vec2 ab = b - a;
|
|
71
|
+
float l2 = dot(ab, ab);
|
|
72
|
+
float t = l2 > 0.0 ? clamp(dot(p - a, ab) / l2, 0.0, 1.0) : 0.0;
|
|
73
|
+
return length(p - a - t * ab);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
bool joined(vec4 a, vec4 b) { return a.z > -0.5 && b.z > -0.5; }
|
|
77
|
+
|
|
78
|
+
// The share of a pixel at distance d from the centre line inside a line hw either side.
|
|
79
|
+
float across(float d) { return clamp(min(u_hw, d + 0.5) - max(-u_hw, d - 0.5), 0.0, 1.0); }
|
|
80
|
+
|
|
81
|
+
// The share of [s - 0.5, s + 0.5] inside [lo, hi].
|
|
82
|
+
float span(float s, float lo, float hi) { return clamp(min(s + 0.5, hi) - max(s - 0.5, lo), 0.0, 1.0); }
|
|
83
|
+
|
|
84
|
+
// The share of [s - 0.5, s + 0.5] on a dash.
|
|
85
|
+
float onDash(float s) {
|
|
86
|
+
float period = u_dash.x + u_dash.y + u_dash.z + u_dash.w;
|
|
87
|
+
float base = s - mod(s, period);
|
|
88
|
+
float on = 0.0;
|
|
89
|
+
for (int k = -1; k <= 1; k++) {
|
|
90
|
+
float p0 = base + float(k) * period;
|
|
91
|
+
on += span(s, p0, p0 + u_dash.x);
|
|
92
|
+
on += span(s, p0 + u_dash.x + u_dash.y, p0 + u_dash.x + u_dash.y + u_dash.z);
|
|
93
|
+
}
|
|
94
|
+
return min(on, 1.0);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
void main() {
|
|
98
|
+
vec2 p = pixelCentre();
|
|
99
|
+
float clipCov = clipCoverage(p);
|
|
100
|
+
if (clipCov <= 0.0) discard;
|
|
101
|
+
vec2 a = v_p2.xy;
|
|
102
|
+
vec2 b = v_p3.xy;
|
|
103
|
+
vec2 ab = b - a;
|
|
104
|
+
float len = length(ab);
|
|
105
|
+
vec2 dir = len > 0.0 ? ab / len : vec2(1.0, 0.0);
|
|
106
|
+
float along = dot(p - a, dir);
|
|
107
|
+
float perp = abs(dot(p - a, vec2(-dir.y, dir.x)));
|
|
108
|
+
bool startEnd = v_p1.z < -0.5;
|
|
109
|
+
bool finalEnd = v_p4.z < -0.5;
|
|
110
|
+
|
|
111
|
+
float cov;
|
|
112
|
+
if (u_dash.x + u_dash.y > 0.0) {
|
|
113
|
+
cov = across(perp) * onDash(v_p2.w + along) * span(along, 0.0, len);
|
|
114
|
+
} else {
|
|
115
|
+
float self = segDist(p, a, b);
|
|
116
|
+
float nearest = self;
|
|
117
|
+
if (joined(v_p0, v_p1)) { float d = segDist(p, v_p0.xy, v_p1.xy); if (d <= self) discard; nearest = min(nearest, d); }
|
|
118
|
+
if (joined(v_p1, v_p2)) { float d = segDist(p, v_p1.xy, v_p2.xy); if (d <= self) discard; nearest = min(nearest, d); }
|
|
119
|
+
if (joined(v_p3, v_p4)) { float d = segDist(p, v_p3.xy, v_p4.xy); if (d < self) discard; nearest = min(nearest, d); }
|
|
120
|
+
if (joined(v_p4, v_p5)) { float d = segDist(p, v_p4.xy, v_p5.xy); if (d < self) discard; nearest = min(nearest, d); }
|
|
121
|
+
cov = across(nearest);
|
|
122
|
+
// Past an end of the line: its cap, square-ended (butt or square) or round.
|
|
123
|
+
float before = startEnd ? -along : -1e9;
|
|
124
|
+
float after = finalEnd ? along - len : -1e9;
|
|
125
|
+
if (u_cap != 1 && (before > -0.5 || after > -0.5)) {
|
|
126
|
+
float reach = u_cap == 2 ? u_hw : 0.0;
|
|
127
|
+
float lo = startEnd ? -reach : -1e9;
|
|
128
|
+
float hi = finalEnd ? len + reach : 1e9;
|
|
129
|
+
cov = across(perp) * span(along, lo, hi);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (cov <= 0.0) discard;
|
|
133
|
+
outColor = u_color * (cov * clipCov);
|
|
134
|
+
}
|
|
135
|
+
`,re=`${b}${x}
|
|
136
|
+
in vec2 a_x;
|
|
137
|
+
in vec4 a_ab;
|
|
138
|
+
in vec2 a_ends;
|
|
139
|
+
flat out vec2 v_x;
|
|
140
|
+
flat out vec4 v_ab;
|
|
141
|
+
flat out vec2 v_ends;
|
|
142
|
+
|
|
143
|
+
void main() {
|
|
144
|
+
v_x = a_x;
|
|
145
|
+
v_ab = a_ab;
|
|
146
|
+
v_ends = a_ends;
|
|
147
|
+
float lo = min(min(a_ab.x, a_ab.y), min(a_ab.z, a_ab.w));
|
|
148
|
+
float hi = max(max(a_ab.x, a_ab.y), max(a_ab.z, a_ab.w));
|
|
149
|
+
vec2 cr = corner(gl_VertexID % 6);
|
|
150
|
+
gl_Position = toClip(mix(vec2(floor(a_x.x), floor(lo) - 1.0), vec2(ceil(a_x.y), ceil(hi) + 1.0), cr));
|
|
151
|
+
}
|
|
152
|
+
`,ie=`${b}${S}
|
|
153
|
+
uniform int u_kind;
|
|
154
|
+
uniform vec4 u_color;
|
|
155
|
+
uniform vec4 u_line;
|
|
156
|
+
uniform vec4 u_offsets;
|
|
157
|
+
uniform int u_stops;
|
|
158
|
+
uniform vec4 u_stop0;
|
|
159
|
+
uniform vec4 u_stop1;
|
|
160
|
+
uniform vec4 u_stop2;
|
|
161
|
+
uniform vec4 u_stop3;
|
|
162
|
+
flat in vec2 v_x;
|
|
163
|
+
flat in vec4 v_ab;
|
|
164
|
+
flat in vec2 v_ends;
|
|
165
|
+
out vec4 outColor;
|
|
166
|
+
|
|
167
|
+
vec4 stopColor(int i) {
|
|
168
|
+
if (i == 0) return u_stop0;
|
|
169
|
+
if (i == 1) return u_stop1;
|
|
170
|
+
if (i == 2) return u_stop2;
|
|
171
|
+
return u_stop3;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
vec4 gradient(vec2 p) {
|
|
175
|
+
vec2 g = u_line.zw - u_line.xy;
|
|
176
|
+
float l2 = dot(g, g);
|
|
177
|
+
// A gradient of no length paints nothing.
|
|
178
|
+
if (l2 <= 0.0) return vec4(0.0);
|
|
179
|
+
float t = dot(p - u_line.xy, g) / l2;
|
|
180
|
+
vec4 c = stopColor(0);
|
|
181
|
+
for (int i = 1; i < 4; i++) {
|
|
182
|
+
if (i >= u_stops) break;
|
|
183
|
+
float o0 = u_offsets[i - 1];
|
|
184
|
+
float o1 = u_offsets[i];
|
|
185
|
+
if (t >= o1) c = stopColor(i);
|
|
186
|
+
else if (t > o0) { c = mix(stopColor(i - 1), stopColor(i), (t - o0) / max(o1 - o0, 1e-6)); break; }
|
|
187
|
+
else break;
|
|
188
|
+
}
|
|
189
|
+
return vec4(c.rgb * c.a, c.a);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
void main() {
|
|
193
|
+
vec2 p = pixelCentre();
|
|
194
|
+
float x0 = v_x.x;
|
|
195
|
+
float x1 = v_x.y;
|
|
196
|
+
float left = v_ends.x > 0.5 ? clamp(p.x + 0.5 - x0, 0.0, 1.0) : (p.x >= x0 ? 1.0 : 0.0);
|
|
197
|
+
float right = v_ends.y > 0.5 ? clamp(x1 - (p.x - 0.5), 0.0, 1.0) : (p.x < x1 ? 1.0 : 0.0);
|
|
198
|
+
float along = v_ends.x > 0.5 && v_ends.y > 0.5
|
|
199
|
+
? clamp(min(p.x + 0.5, x1) - max(p.x - 0.5, x0), 0.0, 1.0)
|
|
200
|
+
: min(left, right);
|
|
201
|
+
float t = clamp((clamp(p.x, x0, x1) - x0) / max(x1 - x0, 1e-6), 0.0, 1.0);
|
|
202
|
+
float ya = mix(v_ab.x, v_ab.y, t);
|
|
203
|
+
float yb = mix(v_ab.z, v_ab.w, t);
|
|
204
|
+
float across = clamp(min(p.y + 0.5, max(ya, yb)) - max(p.y - 0.5, min(ya, yb)), 0.0, 1.0);
|
|
205
|
+
float cov = along * across * clipCoverage(p);
|
|
206
|
+
if (cov <= 0.0) discard;
|
|
207
|
+
vec4 color = u_kind == 1 ? gradient(p) : u_color;
|
|
208
|
+
outColor = color * cov;
|
|
209
|
+
}
|
|
210
|
+
`,ae=`${b}${x}
|
|
211
|
+
in vec3 a_disc;
|
|
212
|
+
in vec4 a_color;
|
|
213
|
+
flat out vec3 v_disc;
|
|
214
|
+
flat out vec4 v_color;
|
|
215
|
+
void main() {
|
|
216
|
+
v_disc = a_disc;
|
|
217
|
+
v_color = a_color;
|
|
218
|
+
float m = a_disc.z + 1.0;
|
|
219
|
+
gl_Position = toClip(mix(a_disc.xy - m, a_disc.xy + m, corner(gl_VertexID % 6)));
|
|
220
|
+
}
|
|
221
|
+
`,oe=`${b}${S}
|
|
222
|
+
flat in vec3 v_disc;
|
|
223
|
+
flat in vec4 v_color;
|
|
224
|
+
out vec4 outColor;
|
|
225
|
+
void main() {
|
|
226
|
+
vec2 p = pixelCentre();
|
|
227
|
+
float cov = clamp(v_disc.z + 0.5 - length(p - v_disc.xy), 0.0, 1.0) * clipCoverage(p);
|
|
228
|
+
if (cov <= 0.0) discard;
|
|
229
|
+
outColor = v_color * cov;
|
|
230
|
+
}
|
|
231
|
+
`,C=4,w=C*4,T=32,E=7,D=E*4,se=class{stroke;span;disc;buffer;constructor(e){this.kit=e,this.stroke=e.program(te,ne,[`a_p0`,`a_p1`,`a_p2`,`a_p3`,`a_p4`,`a_p5`]),this.span=e.program(re,ie,[`a_x`,`a_ab`,`a_ends`]),this.disc=e.program(ae,oe,[`a_disc`,`a_color`]),this.buffer=e.buffer()}draw(e,t,n,r){let i=this.kit.gl;i.enable(i.BLEND);for(let a of e)i.blendFunc(i.ONE,i.ONE_MINUS_SRC_ALPHA),i.disable(i.SCISSOR_TEST),a.type===`rects`?this.drawRects(a.values,r):a.type===`stroke`?this.drawStroke(a,t,n):a.type===`fill`?this.drawFill(a,t,n):this.drawDiscs(a.values,a.clip,t,n);i.disable(i.SCISSOR_TEST)}destroy(){for(let e of[this.stroke,this.span,this.disc])this.kit.deleteProgram(e);this.kit.gl.deleteBuffer(this.buffer)}upload(e){let t=this.kit.gl;t.bindBuffer(t.ARRAY_BUFFER,this.buffer),t.bufferData(t.ARRAY_BUFFER,e,t.STREAM_DRAW)}common(e,t,n,r){let i=this.kit;return i.scissor(t.x0,t.y0,t.x1,t.y1,n,r)?(i.use(e),i.vec2(e,`u_canvas`,n,r),i.vec4(e,`u_clip`,[t.x0,t.y0,Math.min(t.x1,n),Math.min(t.y1,r)]),!0):!1}drawRects(e,t){let n=e.length/8,r=new Float32Array(n*10);for(let t=0;t<n;t++)for(let n=0;n<8;n++)r[t*10+n]=e[t*8+n];t(r,n)}drawStroke(e,t,n){let r=this.stroke;if(!this.common(r,e.clip,t,n))return;let i=this.kit;i.vec4(r,`u_color`,e.color),i.float(r,`u_hw`,e.width/2),i.int(r,`u_cap`,e.cap),i.vec4(r,`u_dash`,e.dash??[0,0,0,0]),this.upload(new Float32Array(e.points));for(let e=0;e<6;e++)i.attrib(r,`a_p${e}`,4,w,e*w);let a=e.points.length/C-5;a>0&&i.gl.drawArraysInstanced(i.gl.TRIANGLES,0,6,a)}drawFill(e,t,n){let r=this.kit,i=e.bounds;if(!r.scissor(i.x0,i.y0,i.x1,i.y1,t,n))return;let a=r.use(this.span);r.vec2(a,`u_canvas`,t,n),r.vec4(a,`u_clip`,[e.clip.x0,e.clip.y0,Math.min(e.clip.x1,t),Math.min(e.clip.y1,n)]),this.upload(new Float32Array(e.spans)),r.attrib(a,`a_x`,2,T,0),r.attrib(a,`a_ab`,4,T,8),r.attrib(a,`a_ends`,2,T,24),this.paint(a,e.paint),r.gl.drawArraysInstanced(r.gl.TRIANGLES,0,6,e.spans.length/8)}paint(e,t){let n=this.kit;if(t.kind===`solid`){n.int(e,`u_kind`,0),n.vec4(e,`u_color`,t.color);return}n.int(e,`u_kind`,1),n.vec4(e,`u_line`,[t.x0,t.y0,t.x1,t.y1]);let r=[0,0,0,0];t.stops.forEach((e,t)=>{r[t]=e.offset}),n.vec4(e,`u_offsets`,r),n.int(e,`u_stops`,t.stops.length);for(let r=0;r<4;r++)n.vec4(e,`u_stop${r}`,(t.stops[r]??t.stops[t.stops.length-1]).color)}drawDiscs(e,t,n,r){let i=this.disc;this.common(i,t,n,r)&&(this.upload(new Float32Array(e)),this.kit.attrib(i,`a_disc`,3,D,0),this.kit.attrib(i,`a_color`,4,D,12),this.kit.gl.drawArraysInstanced(this.kit.gl.TRIANGLES,0,6,e.length/E))}},O=(e,t)=>({x0:Math.max(e.x0,t.x0),y0:Math.max(e.y0,t.y0),x1:Math.min(e.x1,t.x1),y1:Math.min(e.y1,t.y1)}),k=e=>!(e.x1>e.x0&&e.y1>e.y0);function A(e,t=0){let n=1/0,r=1/0,i=-1/0,a=-1/0;for(let t=0;t<e.length;t+=2){let o=e[t],s=e[t+1];o<n&&(n=o),o>i&&(i=o),s<r&&(r=s),s>a&&(a=s)}return{x0:n-t,y0:r-t,x1:i+t,y1:a+t}}function j(e){let t=[...e].sort((e,t)=>e.x0-t.x0),n=[];for(let e of t){for(let t=n.length-1;t>=0;t--)n[t].x1<=e.x0&&n.splice(t,1);for(let t of n)if(t.y0<e.y1&&e.y0<t.y1)return!0;n.push(e)}return!1}var M=class{stops=[];constructor(e,t,n,r){this.x0=e,this.y0=t,this.x1=n,this.y1=r}addColorStop(e,t){if(!(e>=0&&e<=1))throw RangeError(`offset out of range`);this.stops.push({offset:e,color:t})}},N=typeof Path2D==`function`?Path2D:class{},P=class e extends N{calls=[];unsupported=!1;constructor(t){super(t),t instanceof e?(this.calls.push(...t.calls),this.unsupported=t.unsupported):t!==void 0&&(this.unsupported=!0)}note(e,t,n=t){this.calls.push([e,t]),N.prototype[e]?.apply(this,n)}unfollowed(e,t){this.unsupported=!0,this.note(e,[],t)}moveTo(e,t){this.note(`moveTo`,[e,t])}lineTo(e,t){this.note(`lineTo`,[e,t])}closePath(){this.note(`closePath`,[])}rect(e,t,n,r){this.note(`rect`,[e,t,n,r])}arc(e,t,n,r,i,a){this.note(`arc`,[e,t,n,r,i,+!!a])}quadraticCurveTo(e,t,n,r){this.note(`quadraticCurveTo`,[e,t,n,r])}bezierCurveTo(e,t,n,r,i,a){this.note(`bezierCurveTo`,[e,t,n,r,i,a])}arcTo(...e){this.unfollowed(`arcTo`,e)}ellipse(...e){this.unfollowed(`ellipse`,e)}roundRect(...e){this.unfollowed(`roundRect`,e)}addPath(t,n){!(t instanceof e)||n!==void 0?this.unsupported=!0:(this.calls.push(...t.calls),this.unsupported||=t.unsupported),N.prototype.addPath?.call(this,t,n)}};function F(e){let t=globalThis,n=Object.prototype.hasOwnProperty.call(t,`Path2D`),r=t.Path2D;t.Path2D=P;try{e()}finally{n?t.Path2D=r:delete t.Path2D}}var I=.25;function L(e,t,n,r){if(n===`round`)return!1;let i=e.points,a=i.length/2,o=+!e.closed,s=e.closed?a:a-1;for(let e=o;e<s;e++){let o=(e-1+a)%a,s=(e+1)%a,c=i[2*e]-i[2*o],l=i[2*e+1]-i[2*o+1],u=i[2*s]-i[2*e],d=i[2*s+1]-i[2*e+1],f=Math.hypot(c,l),p=Math.hypot(u,d);if(f===0||p===0)continue;let m=Math.max(-1,Math.min(1,(c*u+l*d)/(f*p))),h=Math.sqrt((1+m)/2);if((n===`miter`&&h>0&&1/h<=r?t*(1/h-1):t*(1-h))>I)return!0}return!1}function ce(e,t){let n=e.points;for(let e=2;e<n.length;e+=2)if(Math.hypot(n[e]-n[e-2],n[e+1]-n[e-1])<t)return!0;return!1}function le(e){let t=[],n=()=>t.push(0,0,-1,0);n(),n();for(let{points:r,closed:i}of e){let e=r.length/2,a=i&&e>=3;a&&t.push(r[2*(e-2)],r[2*(e-2)+1],0,0,r[2*(e-1)],r[2*(e-1)+1],0,0);let o=0;for(let n=0;n<e;n++)n>0&&(o+=Math.hypot(r[2*n]-r[2*n-2],r[2*n+1]-r[2*n-1])),t.push(r[2*n],r[2*n+1],1,o);a&&(o+=Math.hypot(r[0]-r[2*(e-1)],r[1]-r[2*(e-1)+1]),t.push(r[0],r[1],1,o),t.push(r[2],r[3],0,0,r[4],r[5],0,0)),n()}return n(),t}var R=Math.PI*2;function z(e,t){let n=2*Math.sqrt(Math.max(.2/Math.max(e,.1),1e-6));return Math.min(512,Math.max(4,Math.ceil(Math.abs(t)/Math.min(n,Math.PI/4))))}var B=new Set([`fillStyle`,`strokeStyle`,`lineWidth`,`lineCap`,`lineJoin`,`miterLimit`,`globalAlpha`,`globalCompositeOperation`,`lineDashOffset`,`font`,`textAlign`,`textBaseline`,`direction`,`shadowBlur`,`shadowColor`,`shadowOffsetX`,`shadowOffsetY`,`filter`]),V=new Set([`fontKerning`,`fontStretch`,`fontVariantCaps`,`letterSpacing`,`wordSpacing`,`textRendering`]),H=new Set([`imageSmoothingEnabled`,`imageSmoothingQuality`]),U=e=>!!(e.rect||e.circle)||e.points.length>=6,ue=class{commands=[];ctx;texts=[];state;stack=[];path=[];ok=!0;constructor(e,t){this.dpr=e,this.measure=t,this.reset({x0:0,y0:0,x1:1/0,y1:1/0}),this.ctx=this.proxy()}region(e){let t=this.dpr,n={x0:e.x*t,y0:e.y*t,x1:(e.x+e.width)*t,y1:(e.y+e.height)*t},r=[];return{step:e=>{this.reset(n),this.texts=r;let t={commands:this.commands.length,texts:r.length};this.ok=!0;try{F(()=>e(this.ctx))}catch{this.ok=!1}return this.ok?!0:(this.commands.length=t.commands,r.length=t.texts,!1)},drawText:e=>de(e,r)}}reset(e){this.state={fillStyle:`#000000`,strokeStyle:`#000000`,lineWidth:1,lineCap:`butt`,lineJoin:`miter`,miterLimit:10,globalAlpha:1,globalCompositeOperation:`source-over`,lineDash:[],lineDashOffset:0,font:`10px sans-serif`,textAlign:`start`,textBaseline:`alphabetic`,direction:`inherit`,shadowBlur:0,shadowColor:`rgba(0, 0, 0, 0)`,shadowOffsetX:0,shadowOffsetY:0,filter:`none`,textExtras:{},transform:[this.dpr,0,0,this.dpr,0,0],clip:e},this.stack=[],this.path=[]}unsupported(){this.ok=!1}copyState(){let e=this.state;return{...e,lineDash:[...e.lineDash],textExtras:{...e.textExtras}}}axisAligned(){let e=this.state.transform;return e[1]===0&&e[2]===0}uniform(){let e=this.state.transform;return this.axisAligned()&&Math.abs(e[0])===Math.abs(e[3])}setMatrix(e){e.every(Number.isFinite)&&(this.state.transform=e)}multiply(e,t,n,r,i,a){let[o,s,c,l,u,d]=this.state.transform;this.setMatrix([o*e+c*t,s*e+l*t,o*n+c*r,s*n+l*r,o*i+c*a+u,s*i+l*a+d])}current(){return this.path[this.path.length-1]}moveTo(e,t){if(!Number.isFinite(e)||!Number.isFinite(t))return;let n=this.state.transform;this.path.push({points:[n[0]*e+n[2]*t+n[4],n[1]*e+n[3]*t+n[5]],closed:!1})}lineTo(e,t){if(!Number.isFinite(e)||!Number.isFinite(t))return;let n=this.current();if(!n||n.closed)return this.moveTo(e,t);let r=this.state.transform;n.points.push(r[0]*e+r[2]*t+r[4],r[1]*e+r[3]*t+r[5]),n.rect=void 0,n.circle=void 0}closePath(){let e=this.current();!e||e.closed||(e.closed=!0,this.path.push({points:[e.points[0],e.points[1]],closed:!1}))}rect(e,t,n,r){if(![e,t,n,r].every(Number.isFinite))return;let i=this.state.transform,a=i[0]*e+i[2]*t+i[4],o=i[1]*e+i[3]*t+i[5],s=i[0]*(e+n)+i[2]*t+i[4],c=i[1]*(e+n)+i[3]*t+i[5],l=i[0]*(e+n)+i[2]*(t+r)+i[4],u=i[1]*(e+n)+i[3]*(t+r)+i[5],d={points:[a,o,s,c,l,u,i[0]*e+i[2]*(t+r)+i[4],i[1]*e+i[3]*(t+r)+i[5]],closed:!0};this.axisAligned()&&(d.rect={x0:Math.min(a,l),y0:Math.min(o,u),x1:Math.max(a,l),y1:Math.max(o,u)}),this.path.push(d),this.path.push({points:[a,o],closed:!1})}arc(e,t,n,r,i,a=!1){if(![e,t,n,r,i].every(Number.isFinite))return;if(n<0)throw new DOMException(`negative radius`,`IndexSizeError`);let o=i-r;o=!a&&o>=R?R:a&&-o>=R?-R:a?-(((r-i)%R+R)%R):(o%R+R)%R;let s=this.current(),c=this.state.transform,l=e+n*Math.cos(r),u=t+n*Math.sin(r),d=!s||s.closed||s.points.length===2&&Math.abs(s.points[0]-(c[0]*l+c[2]*u+c[4]))<1e-6&&Math.abs(s.points[1]-(c[1]*l+c[3]*u+c[5]))<1e-6,f=z(n*Math.abs(c[0]),o);for(let i=0;i<=f;i++){let a=r+o*i/f;this.lineTo(e+n*Math.cos(a),t+n*Math.sin(a))}let p=this.current();Math.abs(o)>=R-1e-9&&d&&this.uniform()&&p&&(p.circle={x:c[0]*e+c[4],y:c[3]*t+c[5],r:n*Math.abs(c[0])})}curve(e,t){(!this.current()||this.current().closed)&&this.moveTo(e[0],e[1]);let n=this.current(),r=this.state.transform;if(!n||!this.axisAligned()||r[0]===0||r[3]===0)return this.unsupported();let i=[(n.points[n.points.length-2]-r[4])/r[0],(n.points[n.points.length-1]-r[5])/r[3],...e,...t],a=0;for(let e=2;e<i.length;e+=2)a+=Math.hypot((i[e]-i[e-2])*r[0],(i[e+1]-i[e-1])*r[3]);let o=Math.max(4,Math.min(64,Math.ceil(a/3)));for(let e=1;e<=o;e++){let t=e/o,n=i.length===6?[(1-t)**2,2*t*(1-t),t*t]:[(1-t)**3,3*t*(1-t)**2,3*t*t*(1-t),t**3],r=0,a=0;n.forEach((e,t)=>{r+=e*i[2*t],a+=e*i[2*t+1]}),this.lineTo(r,a)}}withPath(e,t){let n=this.path;this.path=[],e(),t(),this.path=n}onPath(e,t){if(!(e instanceof P)||e.unsupported)return this.unsupported();this.withPath(()=>{for(let[t,n]of e.calls)t===`moveTo`?this.moveTo(n[0],n[1]):t===`lineTo`?this.lineTo(n[0],n[1]):t===`closePath`?this.closePath():t===`rect`?this.rect(n[0],n[1],n[2],n[3]):t===`arc`?this.arc(n[0],n[1],n[2],n[3],n[4],!!n[5]):t===`quadraticCurveTo`?this.curve([n[0],n[1]],[n[2],n[3]]):t===`bezierCurveTo`&&this.curve([n[0],n[1],n[2],n[3]],[n[4],n[5]])},t)}paint(e){let t=Math.max(0,Math.min(1,this.state.globalAlpha));if(typeof e==`string`){let n=p(f(e));return{kind:`solid`,color:[n[0]*t,n[1]*t,n[2]*t,n[3]*t]}}if(!(e instanceof M))return null;if(e.stops.length===0)return{kind:`solid`,color:[0,0,0,0]};if(e.stops.length>4)return null;let n=this.state.transform,r=e.x0===e.x1||e.y0===e.y1;if(!this.axisAligned()||!this.uniform()&&!r)return null;let i=[...e.stops].sort((e,t)=>e.offset-t.offset).map(e=>{let n=f(e.color);return{offset:e.offset,color:[n[0],n[1],n[2],n[3]*t]}});return{kind:`linear`,x0:n[0]*e.x0+n[4],y0:n[3]*e.y0+n[5],x1:n[0]*e.x1+n[4],y1:n[3]*e.y1+n[5],stops:i}}plain(){let e=this.state;return e.globalCompositeOperation!==`source-over`||e.filter!==`none`?!1:!(f(e.shadowColor)[3]>0&&(e.shadowBlur>0||e.shadowOffsetX!==0||e.shadowOffsetY!==0))}fill(e=`nonzero`){if(!this.plain())return this.unsupported();let t=this.paint(this.state.fillStyle);if(!t)return this.unsupported();let n=this.path.filter(U);if(n.length===0||t.kind===`solid`&&t.color[3]===0)return;if(n.length>1&&j(n.map(e=>A(e.points)))){let r=t.kind===`solid`&&t.color[3]>=1,i=Math.sign(_(n[0].points));if(!r||e!==`nonzero`||n.some(e=>Math.sign(_(e.points))!==i))return this.unsupported()}if(t.kind===`solid`&&n.every(e=>e.rect))return this.fillRects(n,t.color);if(t.kind===`solid`&&n.every(e=>e.circle)){let e=[];for(let r of n)e.push(r.circle.x,r.circle.y,r.circle.r,...t.color);this.commands.push({type:`circles`,values:e,clip:this.state.clip});return}let r=[];for(let e of n){let t=g(e.points);if(!t)return this.unsupported();for(let e of t)r.push(e)}let i=A(n.flatMap(e=>e.points)),a=O({x0:Math.floor(i.x0),y0:Math.floor(i.y0),x1:Math.ceil(i.x1),y1:Math.ceil(i.y1)},this.state.clip);r.length>0&&!k(a)&&this.commands.push({type:`fill`,spans:r,bounds:a,paint:t,clip:this.state.clip})}fillRects(e,t){let n=[];for(let r of e){let e=O(r.rect,this.state.clip);k(e)||n.push(e.x0,e.y0,e.x1,e.y1,t[0],t[1],t[2],t[3])}n.length&&this.commands.push({type:`rects`,values:n})}stroke(){if(!this.plain())return this.unsupported();let e=this.paint(this.state.strokeStyle);if(!e||e.kind!==`solid`||!this.uniform())return this.unsupported();if(e.color[3]===0)return;let t=this.state,n=Math.abs(t.transform[0]),r=t.lineWidth*n,i=this.path.filter(e=>e.points.length>=4&&(t.lineCap!==`butt`||e.points.some((t,n)=>t!==e.points[n%2])));if(i.length===0)return;let a=this.dash(i,n);if(a===void 0||!this.drawsAlike(i,r,e.color[3]))return this.unsupported();let o=t.lineCap===`round`?1:t.lineCap===`square`?2:0;this.commands.push({type:`stroke`,points:le(i),color:e.color,width:r,cap:o,dash:a,clip:t.clip})}dash(e,t){let n=this.state;if(n.lineDash.length===0)return null;if(n.lineDash.length>4||n.lineDashOffset!==0||n.lineCap!==`butt`||e.some(e=>e.closed||e.points.length!==4))return;let r=n.lineDash.map(e=>e*t);for(;r.length<4;)r.push(...r.slice(0,4-r.length));return r}drawsAlike(e,t,n){let r=this.state,i=t/2;if(t>1&&e.some(e=>L(e,i,r.lineJoin,r.miterLimit)))return!1;let a=i+(r.lineCap===`butt`?0:i);return!(e.length>1&&j(e.map(e=>A(e.points,a)))||n<1&&e.some(e=>ce(e,t)))}clip(){let e=this.path.filter(U);if(e.length!==1||!e[0].rect)return this.unsupported();this.state.clip=O(this.state.clip,e[0].rect)}text(e,t,n,r,i){if(typeof(e?this.state.strokeStyle:this.state.fillStyle)!=`string`||!this.plain())return this.unsupported();this.texts.push({stroke:e,text:String(t),x:n,y:r,maxWidth:i,state:this.copyState()})}measureText(e){let t=this.measure;if(!t)return{width:String(e).length*6};let n=t.font;t.font=this.state.font;let r=t.measureText(e);return t.font=n,r}methods(){let e=()=>this.state,t=Object.create(null);return Object.assign(t,{save:()=>{this.stack.push(this.copyState())},restore:()=>{let e=this.stack.pop();e&&(this.state=e)},beginPath:()=>{this.path=[]},moveTo:(e,t)=>this.moveTo(e,t),lineTo:(e,t)=>this.lineTo(e,t),closePath:()=>this.closePath(),rect:(e,t,n,r)=>this.rect(e,t,n,r),arc:(e,t,n,r,i,a)=>this.arc(e,t,n,r,i,a),quadraticCurveTo:(e,t,n,r)=>this.curve([e,t],[n,r]),bezierCurveTo:(e,t,n,r,i,a)=>this.curve([e,t,n,r],[i,a]),fill:(e,t)=>typeof e==`object`?this.onPath(e,()=>this.fill(t)):this.fill(e),stroke:e=>e?this.onPath(e,()=>this.stroke()):this.stroke(),clip:e=>typeof e==`object`?this.onPath(e,()=>this.clip()):this.clip(),fillRect:(e,t,n,r)=>this.withPath(()=>this.rect(e,t,n,r),()=>this.fill()),strokeRect:(e,t,n,r)=>this.withPath(()=>this.rect(e,t,n,r),()=>this.stroke()),fillText:(e,t,n,r)=>this.text(!1,e,t,n,r),strokeText:(e,t,n,r)=>this.text(!0,e,t,n,r),measureText:e=>this.measureText(e),setLineDash:t=>{t.every(e=>Number.isFinite(e)&&e>=0)&&(e().lineDash=t.length%2?[...t,...t]:[...t])},getLineDash:()=>[...e().lineDash],translate:(e,t)=>this.multiply(1,0,0,1,e,t),scale:(e,t)=>this.multiply(e,0,0,t,0,0),rotate:e=>this.multiply(Math.cos(e),Math.sin(e),-Math.sin(e),Math.cos(e),0,0),transform:(e,t,n,r,i,a)=>this.multiply(e,t,n,r,i,a),setTransform:(e,t,n,r,i,a)=>typeof e==`number`?this.setMatrix([e,t??0,n??0,r??1,i??0,a??0]):this.unsupported(),resetTransform:()=>this.setMatrix([1,0,0,1,0,0]),getTransform:()=>{let[t,n,r,i,a,o]=e().transform;return{a:t,b:n,c:r,d:i,e:a,f:o,m11:t,m12:n,m21:r,m22:i,m41:a,m42:o,is2D:!0,isIdentity:t===1&&n===0&&r===0&&i===1&&a===0&&o===0}},createLinearGradient:(e,t,n,r)=>new M(e,t,n,r)}),t}proxy(){let e=this.methods();return new Proxy({},{get:(t,n)=>{if(typeof n==`string`){if(n in e)return e[n];if(B.has(n))return this.state[n];if(V.has(n))return this.state.textExtras[n];if(n===`canvas`)return this.measure?.canvas;if(!H.has(n))return this.unsupported(),()=>void 0}},set:(e,t,n)=>(typeof t==`string`&&this.setProp(t,n),!0)})}setProp(e,t){let n=this.state;e===`lineWidth`||e===`miterLimit`?typeof t==`number`&&Number.isFinite(t)&&t>0&&(n[e]=t):e===`globalAlpha`?typeof t==`number`&&Number.isFinite(t)&&t>=0&&t<=1&&(n.globalAlpha=t):e===`fillStyle`||e===`strokeStyle`?t instanceof M?n[e]=t:typeof t==`string`?d(t)&&(n[e]=t):this.unsupported():B.has(e)?n[e]=t:V.has(e)?this.state.textExtras[e]=t:H.has(e)||this.unsupported()}};function de(e,t){for(let n of t){let t=n.state;if(k(t.clip))continue;e.save(),e.setTransform(1,0,0,1,0,0),Number.isFinite(t.clip.x1)&&Number.isFinite(t.clip.y1)&&(e.beginPath(),e.rect(t.clip.x0,t.clip.y0,t.clip.x1-t.clip.x0,t.clip.y1-t.clip.y0),e.clip());let[r,i,a,o,s,c]=t.transform;e.setTransform(r,i,a,o,s,c),e.font=t.font,e.textAlign=t.textAlign,e.textBaseline=t.textBaseline,e.direction=t.direction,e.globalAlpha=t.globalAlpha,Object.assign(e,t.textExtras),n.stroke?(e.strokeStyle=t.strokeStyle,e.lineWidth=t.lineWidth,e.strokeText(n.text,n.x,n.y,n.maxWidth)):(e.fillStyle=t.fillStyle,e.fillText(n.text,n.x,n.y,n.maxWidth)),e.restore()}}function fe(e,t){return new ue(e,t)}var W=`#version 300 es
|
|
232
|
+
precision highp float;
|
|
233
|
+
uniform vec2 u_canvas;
|
|
234
|
+
uniform float u_dpr;
|
|
235
|
+
uniform int u_log;
|
|
236
|
+
uniform int u_invert;
|
|
237
|
+
uniform float u_yA;
|
|
238
|
+
uniform float u_yB;
|
|
239
|
+
uniform float u_logOffset;
|
|
240
|
+
uniform float u_min;
|
|
241
|
+
uniform float u_logFloor;
|
|
242
|
+
uniform float u_logK;
|
|
243
|
+
uniform float u_top;
|
|
244
|
+
uniform float u_bottom;
|
|
245
|
+
out vec4 v_color;
|
|
246
|
+
|
|
247
|
+
// A price (relative to the base price) to a CSS-pixel y, as priceToYMapper
|
|
248
|
+
// does; mappedY in yMapping.ts is the same steps in TypeScript.
|
|
249
|
+
float cssY(float rel) {
|
|
250
|
+
if (u_log == 1) {
|
|
251
|
+
float v = log(max(1.0 + (rel + u_logOffset) / u_min, u_logFloor)) * u_logK;
|
|
252
|
+
return u_invert == 1 ? u_top + v : u_bottom - v;
|
|
253
|
+
}
|
|
254
|
+
return u_yA + rel * u_yB;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
float snap(float v) { return floor(v + 0.5); }
|
|
258
|
+
|
|
259
|
+
vec4 toClip(vec2 dev) {
|
|
260
|
+
return vec4(dev.x / u_canvas.x * 2.0 - 1.0, 1.0 - dev.y / u_canvas.y * 2.0, 0.0, 1.0);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// The corners of a quad as two triangles.
|
|
264
|
+
vec2 corner(int k) {
|
|
265
|
+
if (k == 0) return vec2(0.0, 0.0);
|
|
266
|
+
if (k == 1 || k == 4) return vec2(1.0, 0.0);
|
|
267
|
+
if (k == 2 || k == 3) return vec2(0.0, 1.0);
|
|
268
|
+
return vec2(1.0, 1.0);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Nothing to draw: every vertex at one point off the canvas.
|
|
272
|
+
const vec4 NOWHERE = vec4(-2.0, -2.0, 0.0, 1.0);
|
|
273
|
+
`,pe=`${W}
|
|
274
|
+
in vec4 a_ohlc;
|
|
275
|
+
in vec2 a_vd;
|
|
276
|
+
uniform float u_x0;
|
|
277
|
+
uniform float u_unit;
|
|
278
|
+
uniform float u_wick;
|
|
279
|
+
uniform float u_body;
|
|
280
|
+
uniform vec4 u_upBody;
|
|
281
|
+
uniform vec4 u_downBody;
|
|
282
|
+
uniform vec4 u_upWick;
|
|
283
|
+
uniform vec4 u_downWick;
|
|
284
|
+
|
|
285
|
+
void main() {
|
|
286
|
+
int vid = gl_VertexID % 12;
|
|
287
|
+
vec2 cr = corner(vid % 6);
|
|
288
|
+
bool up = a_vd.y > 0.5;
|
|
289
|
+
float cx = (u_x0 + float(gl_InstanceID) * u_unit) * u_dpr;
|
|
290
|
+
float wickLeft = snap(cx - u_wick * 0.5);
|
|
291
|
+
float left;
|
|
292
|
+
float width;
|
|
293
|
+
float top;
|
|
294
|
+
float height;
|
|
295
|
+
if (vid < 6) {
|
|
296
|
+
float h = snap(cssY(a_ohlc.y) * u_dpr);
|
|
297
|
+
float l = snap(cssY(a_ohlc.z) * u_dpr);
|
|
298
|
+
left = wickLeft;
|
|
299
|
+
width = u_wick;
|
|
300
|
+
top = min(h, l);
|
|
301
|
+
height = max(abs(l - h), 1.0);
|
|
302
|
+
v_color = up ? u_upWick : u_downWick;
|
|
303
|
+
} else {
|
|
304
|
+
float o = snap(cssY(a_ohlc.x) * u_dpr);
|
|
305
|
+
float c = snap(cssY(a_ohlc.w) * u_dpr);
|
|
306
|
+
left = wickLeft - (u_body - u_wick) * 0.5;
|
|
307
|
+
width = u_body;
|
|
308
|
+
top = min(o, c);
|
|
309
|
+
height = max(abs(c - o), u_wick);
|
|
310
|
+
v_color = up ? u_upBody : u_downBody;
|
|
311
|
+
}
|
|
312
|
+
gl_Position = toClip(vec2(left + cr.x * width, top + cr.y * height));
|
|
313
|
+
}
|
|
314
|
+
`,me=`${W}
|
|
315
|
+
in vec4 a_ohlc;
|
|
316
|
+
in vec2 a_vd;
|
|
317
|
+
uniform float u_x0;
|
|
318
|
+
uniform float u_unit;
|
|
319
|
+
uniform float u_wick;
|
|
320
|
+
uniform float u_body;
|
|
321
|
+
uniform float u_volBottom;
|
|
322
|
+
uniform float u_volScale;
|
|
323
|
+
uniform vec4 u_volUp;
|
|
324
|
+
uniform vec4 u_volDown;
|
|
325
|
+
|
|
326
|
+
void main() {
|
|
327
|
+
vec2 cr = corner(gl_VertexID % 6);
|
|
328
|
+
float cx = (u_x0 + float(gl_InstanceID) * u_unit) * u_dpr;
|
|
329
|
+
float left = snap(cx - u_wick * 0.5) - (u_body - u_wick) * 0.5;
|
|
330
|
+
float bottom = snap(u_volBottom * u_dpr);
|
|
331
|
+
float top = snap((u_volBottom - a_vd.x * u_volScale) * u_dpr);
|
|
332
|
+
if (bottom - top < 1.0) { gl_Position = NOWHERE; v_color = vec4(0.0); return; }
|
|
333
|
+
v_color = a_vd.y > 0.5 ? u_volUp : u_volDown;
|
|
334
|
+
gl_Position = toClip(vec2(left + cr.x * u_body, top + cr.y * (bottom - top)));
|
|
335
|
+
}
|
|
336
|
+
`,he=`${W}
|
|
337
|
+
in vec4 a_col;
|
|
338
|
+
in float a_up;
|
|
339
|
+
uniform vec4 u_upBody;
|
|
340
|
+
uniform vec4 u_downBody;
|
|
341
|
+
|
|
342
|
+
void main() {
|
|
343
|
+
vec2 cr = corner(gl_VertexID % 6);
|
|
344
|
+
float left = snap(a_col.x * u_dpr);
|
|
345
|
+
float width = max(1.0, snap((a_col.x + 1.0) * u_dpr) - left);
|
|
346
|
+
float t = snap(cssY(a_col.y) * u_dpr);
|
|
347
|
+
float b = snap(cssY(a_col.z) * u_dpr);
|
|
348
|
+
v_color = a_up > 0.5 ? u_upBody : u_downBody;
|
|
349
|
+
gl_Position = toClip(vec2(left + cr.x * width, min(t, b) + cr.y * max(abs(b - t), 1.0)));
|
|
350
|
+
}
|
|
351
|
+
`,ge=`${W}
|
|
352
|
+
in vec4 a_col;
|
|
353
|
+
in float a_up;
|
|
354
|
+
uniform float u_volBottom;
|
|
355
|
+
uniform float u_volScale;
|
|
356
|
+
uniform vec4 u_volUp;
|
|
357
|
+
uniform vec4 u_volDown;
|
|
358
|
+
|
|
359
|
+
void main() {
|
|
360
|
+
vec2 cr = corner(gl_VertexID % 6);
|
|
361
|
+
float left = snap(a_col.x * u_dpr);
|
|
362
|
+
float width = max(1.0, snap((a_col.x + 1.0) * u_dpr) - left);
|
|
363
|
+
float bottom = snap(u_volBottom * u_dpr);
|
|
364
|
+
float top = snap((u_volBottom - a_col.w * u_volScale) * u_dpr);
|
|
365
|
+
if (bottom - top < 1.0) { gl_Position = NOWHERE; v_color = vec4(0.0); return; }
|
|
366
|
+
v_color = a_up > 0.5 ? u_volUp : u_volDown;
|
|
367
|
+
gl_Position = toClip(vec2(left + cr.x * width, top + cr.y * (bottom - top)));
|
|
368
|
+
}
|
|
369
|
+
`,_e=`${W}
|
|
370
|
+
in vec4 a_rect;
|
|
371
|
+
in vec4 a_color;
|
|
372
|
+
in vec2 a_dash;
|
|
373
|
+
flat out vec4 v_rect;
|
|
374
|
+
flat out vec2 v_dash;
|
|
375
|
+
|
|
376
|
+
void main() {
|
|
377
|
+
vec2 cr = corner(gl_VertexID % 6);
|
|
378
|
+
v_rect = a_rect * u_dpr;
|
|
379
|
+
v_dash = a_dash * u_dpr;
|
|
380
|
+
v_color = a_color;
|
|
381
|
+
gl_Position = toClip(mix(floor(v_rect.xy), ceil(v_rect.zw), cr));
|
|
382
|
+
}
|
|
383
|
+
`,ve=`#version 300 es
|
|
384
|
+
precision highp float;
|
|
385
|
+
uniform vec2 u_canvas;
|
|
386
|
+
uniform int u_union;
|
|
387
|
+
in vec4 v_color;
|
|
388
|
+
flat in vec4 v_rect;
|
|
389
|
+
flat in vec2 v_dash;
|
|
390
|
+
out vec4 outColor;
|
|
391
|
+
|
|
392
|
+
// The share of rows [y, y + 1] inside the rectangle and, dashed, on a dash.
|
|
393
|
+
float rows(float y) {
|
|
394
|
+
float lo = max(y, v_rect.y);
|
|
395
|
+
float hi = min(y + 1.0, v_rect.w);
|
|
396
|
+
if (hi <= lo) return 0.0;
|
|
397
|
+
if (v_dash.x <= 0.0) return hi - lo;
|
|
398
|
+
// A dash period is longer than a device pixel, so the row meets the dash
|
|
399
|
+
// of the period it starts in and the next (a third to spare).
|
|
400
|
+
float period = v_dash.x + v_dash.y;
|
|
401
|
+
float first = v_rect.y + floor((lo - v_rect.y) / period) * period;
|
|
402
|
+
float on = 0.0;
|
|
403
|
+
for (int i = 0; i < 3; i++) {
|
|
404
|
+
float start = first + float(i) * period;
|
|
405
|
+
on += max(0.0, min(hi, start + v_dash.x) - max(lo, start));
|
|
406
|
+
}
|
|
407
|
+
return on;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
void main() {
|
|
411
|
+
// This pixel's top-left corner in device pixels, y down.
|
|
412
|
+
vec2 p = vec2(floor(gl_FragCoord.x), u_canvas.y - floor(gl_FragCoord.y) - 1.0);
|
|
413
|
+
float coverage = clamp(min(p.x + 1.0, v_rect.z) - max(p.x, v_rect.x), 0.0, 1.0) * rows(p.y);
|
|
414
|
+
outColor = u_union == 1 ? vec4(v_color.rgb * coverage, coverage) : v_color * coverage;
|
|
415
|
+
}
|
|
416
|
+
`,G=`#version 300 es
|
|
417
|
+
precision highp float;
|
|
418
|
+
uniform vec2 u_canvas;
|
|
419
|
+
uniform vec4 u_clip;
|
|
420
|
+
in vec4 v_color;
|
|
421
|
+
out vec4 outColor;
|
|
422
|
+
|
|
423
|
+
void main() {
|
|
424
|
+
vec2 p = vec2(floor(gl_FragCoord.x), u_canvas.y - floor(gl_FragCoord.y) - 1.0);
|
|
425
|
+
vec2 c = clamp(min(p + 1.0, u_clip.zw) - max(p, u_clip.xy), 0.0, 1.0);
|
|
426
|
+
outColor = v_color * (c.x * c.y);
|
|
427
|
+
}
|
|
428
|
+
`,K=24,q=5,J=q*4,Y=10,X=Y*4,Z=[`a_ohlc`,`a_vd`,`a_col`,`a_up`,`a_rect`,`a_color`,`a_dash`],ye=class n{label;gl;kit;drawer;candleBars;volumeBars;candleColumns;volumeColumns;rects;seriesBuffer;columnBuffer;rectBuffer;uploads=new r;gpuFloats=0;columns=new Float32Array(4096*q);rectValues=new Float32Array(64*Y);clip=[0,0,0,0];lost=!1;lostCallback=null;static create(e={}){if(typeof document>`u`)return null;let t=document.createElement(`canvas`),r=null;try{r=t.getContext(`webgl2`,{alpha:!0,premultipliedAlpha:!0,antialias:!1,depth:!1,stencil:!1,preserveDrawingBuffer:!1,failIfMajorPerformanceCaveat:e.failIfMajorPerformanceCaveat??!1})}catch(e){return $(e),null}if(!r)return null;try{return new n(t,r)}catch(e){return $(e),Q(r),null}}constructor(e,t){this.canvas=e,this.gl=t,this.kit=new h(t);let n=t.getExtension(`WEBGL_debug_renderer_info`);this.label=String(n?t.getParameter(n.UNMASKED_RENDERER_WEBGL):t.getParameter(t.RENDERER));let r=this.kit;this.candleBars=r.program(pe,G,Z),this.volumeBars=r.program(me,G,Z),this.candleColumns=r.program(he,G,Z),this.volumeColumns=r.program(ge,G,Z),this.rects=r.program(_e,ve,Z),this.seriesBuffer=r.buffer(),this.columnBuffer=r.buffer(),this.rectBuffer=r.buffer(),this.drawer=new se(r),e.addEventListener(`webglcontextlost`,this.handleLost)}onLost(e){this.lostCallback=e,(this.lost||this.gl.isContextLost())&&(this.lost=!0,queueMicrotask(()=>{this.lostCallback===e&&e()}))}recorder(e,t){return fe(e,t)}render(e){let t=this.gl;if(this.lost||t.isContextLost())return{series:!1,volume:!1,background:!1,recorded:!1};let n=be(e.recorded)?e.recorded:null,r={series:e.candles,volume:e.volume!==null,background:e.background!==null,recorded:n!==null};return t.viewport(0,0,this.canvas.width,this.canvas.height),t.disable(t.SCISSOR_TEST),t.clearColor(0,0,0,0),t.clear(t.COLOR_BUFFER_BIT),t.enable(t.BLEND),e.background&&this.drawBackground(e,e.background),this.drawSeries(e),n&&n.commands.length>0&&this.drawer.draw(n.commands,this.canvas.width,this.canvas.height,(t,n)=>this.drawRecordedRects(e,t,n)),r}drawSeries(t){let n=this.gl,{data:r,viewport:i,dpr:a}=t;if(r.length===0||!t.candles&&!t.volume)return;this.syncSeries(t);let o=Math.max(0,i.visibleRange.from),s=Math.min(i.visibleRange.to,r.length-1);if(s<o)return;let{chartRect:c}=i;this.clip=[c.x*a,c.y*a,(c.x+c.width)*a,(c.y+c.height)*a];let l=Math.floor(this.clip[0]),u=Math.floor(this.clip[1]),d=Math.ceil(this.clip[2])-l,f=Math.ceil(this.clip[3])-u;n.enable(n.SCISSOR_TEST),n.scissor(l,this.canvas.height-u-f,Math.max(0,d),Math.max(0,f)),n.blendFunc(n.ONE,n.ONE_MINUS_SRC_ALPHA);let p=e.i(i),m=p?this.buildColumns(t,o,s):0;t.volume&&this.drawVolume(t,o,s,p,m);let{min:h,max:g}=i.priceRange;t.candles&&g-h!==0&&this.drawCandles(t,o,s,p,m),n.disable(n.SCISSOR_TEST)}drawRecordedRects(e,t,n){let r=this.gl,i=this.use(this.rects,e);this.kit.float(i,`u_dpr`,1),this.kit.int(i,`u_union`,0),r.bindBuffer(r.ARRAY_BUFFER,this.rectBuffer),r.bufferData(r.ARRAY_BUFFER,t,r.STREAM_DRAW),this.bindRects(i,0),r.drawArraysInstanced(r.TRIANGLES,0,6,n)}destroy(){this.canvas.removeEventListener(`webglcontextlost`,this.handleLost),this.lostCallback=null;let e=this.gl;if(!e.isContextLost()){for(let e of[this.candleBars,this.volumeBars,this.candleColumns,this.volumeColumns,this.rects])this.kit.deleteProgram(e);this.drawer.destroy(),e.deleteBuffer(this.seriesBuffer),e.deleteBuffer(this.columnBuffer),e.deleteBuffer(this.rectBuffer),Q(e)}this.canvas.remove()}handleLost=e=>{e.preventDefault(),!this.lost&&(this.lost=!0,this.lostCallback?.())};syncSeries(e){let t=this.gl,n=this.uploads.sync(e.data),r=this.uploads.values;t.bindBuffer(t.ARRAY_BUFFER,this.seriesBuffer),n.full||r.length!==this.gpuFloats?(t.bufferData(t.ARRAY_BUFFER,r,t.DYNAMIC_DRAW),this.gpuFloats=r.length):n.to>n.from&&t.bufferSubData(t.ARRAY_BUFFER,n.from*K,r,n.from*6,(n.to-n.from)*6)}buildColumns(t,n,r){let{viewport:i,data:a}=t,o=i.barWidth+i.barSpacing,s=-i.offset+i.chartRect.x+i.barWidth/2,c=this.uploads.base,l=0;e.r(a,n,r,e=>e*o+s,e=>{if((l+1)*q>this.columns.length){let e=new Float32Array(this.columns.length*2);e.set(this.columns),this.columns=e}let t=l*q;this.columns[t]=e.x,this.columns[t+1]=e.high-c,this.columns[t+2]=e.low-c,this.columns[t+3]=e.volume,this.columns[t+4]=+(e.close>=e.open),l++});let u=this.gl;return u.bindBuffer(u.ARRAY_BUFFER,this.columnBuffer),u.bufferData(u.ARRAY_BUFFER,this.columns.subarray(0,l*q),u.STREAM_DRAW),l}drawBackground(t,n){let{viewport:r,theme:i}=t,a=n.grid?e.t(r):{horizontal:[],vertical:[]},o=a.horizontal.length+a.vertical.length,s=o+n.rects.length;if(s===0)return;this.rectValues.length<s*Y&&(this.rectValues=new Float32Array(s*Y*2));let c=this.rectValues,l=0,u=(e,t,n,r,i,a,o)=>{c[l++]=e,c[l++]=t,c[l++]=n,c[l++]=r;for(let e=0;e<4;e++)c[l++]=i[e]*a;c[l++]=o?o[0]:0,c[l++]=o?o[1]:0},d=p(f(i.grid)),{chartRect:m}=r;for(let e of a.horizontal)u(m.x,e-.5,m.x+m.width,e+.5,d,1);for(let e of a.vertical)u(e-.5,m.y,e+.5,m.y+m.height,d,1);let h=``,g=d;for(let e of n.rects)e.color!==h&&(h=e.color,g=p(f(e.color))),u(e.x,e.y,e.x+e.width,e.y+e.height,g,e.alpha,e.dash);let _=this.gl,v=this.use(this.rects,t);_.bindBuffer(_.ARRAY_BUFFER,this.rectBuffer),_.bufferData(_.ARRAY_BUFFER,c.subarray(0,l),_.STREAM_DRAW),o>0&&(_.uniform1i(this.loc(v,`u_union`),1),_.blendColor(0,0,0,d[3]),_.blendFuncSeparate(_.ONE,_.ONE_MINUS_SRC_ALPHA,_.CONSTANT_ALPHA,_.ONE_MINUS_SRC_ALPHA),this.bindRects(v,0),_.drawArraysInstanced(_.TRIANGLES,0,6,o)),n.rects.length>0&&(_.uniform1i(this.loc(v,`u_union`),0),_.blendFunc(_.ONE,_.ONE_MINUS_SRC_ALPHA),this.bindRects(v,o),_.drawArraysInstanced(_.TRIANGLES,0,6,n.rects.length))}drawCandles(e,t,n,r,i){let{theme:a,viewport:o,dpr:s}=e,c=p(f(a.candleUp)),l=p(f(a.candleDown));if(r){let t=this.use(this.candleColumns,e);this.vec4(t,`u_upBody`,c),this.vec4(t,`u_downBody`,l),this.bindColumns(t),this.gl.drawArraysInstanced(this.gl.TRIANGLES,0,6,i);return}let u=this.use(this.candleBars,e);this.barUniforms(u,o,t,s),this.vec4(u,`u_upBody`,c),this.vec4(u,`u_downBody`,l),this.vec4(u,`u_upWick`,p(f(a.candleUpWick))),this.vec4(u,`u_downWick`,p(f(a.candleDownWick))),this.bindBars(u,t),this.gl.drawArraysInstanced(this.gl.TRIANGLES,0,12,n-t+1)}drawVolume(e,n,r,i,a){let{data:o,viewport:s,theme:c,dpr:l}=e,u=0;for(let e=n;e<=r;e++)o[e].volume>u&&(u=o[e].volume);if(u===0)return;let{chartRect:d}=s,m=(0,t.resolveVolumeColors)(c),h=this.use(i?this.volumeColumns:this.volumeBars,e);if(this.float(h,`u_volBottom`,d.y+d.height),this.float(h,`u_volScale`,d.height*(e.volume?.heightRatio??.15)/u),this.vec4(h,`u_volUp`,p(f(m.up))),this.vec4(h,`u_volDown`,p(f(m.down))),i){this.bindColumns(h),this.gl.drawArraysInstanced(this.gl.TRIANGLES,0,6,a);return}this.barUniforms(h,s,n,l),this.bindBars(h,n),this.gl.drawArraysInstanced(this.gl.TRIANGLES,0,6,r-n+1)}barUniforms(t,n,r,i){let a=n.barWidth+n.barSpacing,o=-n.offset+n.chartRect.x+n.barWidth/2,{body:s,wick:c}=e.o(n.barWidth,i);this.float(t,`u_x0`,r*a+o),this.float(t,`u_unit`,a),this.float(t,`u_wick`,c),this.float(t,`u_body`,s)}use(e,t){let n=this.gl;this.kit.use(e),n.uniform2f(this.loc(e,`u_canvas`),this.canvas.width,this.canvas.height),this.vec4(e,`u_clip`,this.clip),this.float(e,`u_dpr`,t.dpr);let r=m(t.viewport,this.uploads.base);return n.uniform1i(this.loc(e,`u_log`),r.log),n.uniform1i(this.loc(e,`u_invert`),r.invert),this.float(e,`u_yA`,r.yA),this.float(e,`u_yB`,r.yB),this.float(e,`u_logOffset`,r.logOffset),this.float(e,`u_min`,r.min),this.float(e,`u_logFloor`,r.logFloor),this.float(e,`u_logK`,r.logK),this.float(e,`u_top`,r.top),this.float(e,`u_bottom`,r.bottom),e}bindBars(e,t){let n=this.gl;n.bindBuffer(n.ARRAY_BUFFER,this.seriesBuffer),this.attrib(e,`a_ohlc`,4,K,t*K),this.attrib(e,`a_vd`,2,K,t*K+16)}bindRects(e,t){this.attrib(e,`a_rect`,4,X,t*X),this.attrib(e,`a_color`,4,X,t*X+16),this.attrib(e,`a_dash`,2,X,t*X+32)}bindColumns(e){let t=this.gl;t.bindBuffer(t.ARRAY_BUFFER,this.columnBuffer),this.attrib(e,`a_col`,4,J,0),this.attrib(e,`a_up`,1,J,16)}attrib(e,t,n,r,i){this.kit.attrib(e,t,n,r,i)}float(e,t,n){this.kit.float(e,t,n)}vec4(e,t,n){this.kit.vec4(e,t,n)}loc(e,t){return this.kit.loc(e,t)}};function be(e){return typeof e==`object`&&!!e&&Array.isArray(e.commands)}function Q(e){e.getExtension(`WEBGL_lose_context`)?.loseContext()}function $(e){console.warn(`TradeCanvas: WebGL renderer unavailable, drawing with Canvas 2D.`,e)}exports.WebGLSeriesRenderer=ye;
|
|
429
|
+
//# sourceMappingURL=WebGLSeriesRenderer-DspCYR38.cjs.map
|