@qfo/qfchart 0.6.2 → 0.6.3
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/dist/qfchart.min.browser.js +10 -10
- package/dist/qfchart.min.es.js +10 -10
- package/package.json +1 -1
- package/src/components/SeriesBuilder.ts +8 -2
|
@@ -14,25 +14,25 @@
|
|
|
14
14
|
* See the License for the specific language governing permissions and
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
|
-
(function(et,lt){typeof exports=="object"&&typeof module<"u"?lt(exports,require("echarts")):typeof define=="function"&&define.amd?define(["exports","echarts"],lt):(et=typeof globalThis<"u"?globalThis:et||self,lt(et.QFChart={},et.echarts))})(this,function(et,lt){"use strict";function yt(r){var e=Object.create(null);return r&&Object.keys(r).forEach(function(t){if(t!=="default"){var i=Object.getOwnPropertyDescriptor(r,t);Object.defineProperty(e,t,i.get?i:{enumerable:!0,get:function(){return r[t]}})}}),e.default=r,Object.freeze(e)}var j=yt(lt),xt=Object.defineProperty,mt=(r,e,t)=>e in r?xt(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,at=(r,e,t)=>(mt(r,typeof e!="symbol"?e+"":e,t),t);class bt{constructor(e,t,i,s={}){at(this,"id"),at(this,"plots"),at(this,"paneIndex"),at(this,"height"),at(this,"collapsed"),at(this,"titleColor"),at(this,"controls"),this.id=e,this.plots=t,this.paneIndex=i,this.height=s.height,this.collapsed=s.collapsed||!1,this.titleColor=s.titleColor,this.controls=s.controls}toggleCollapse(){this.collapsed=!this.collapsed}isVisible(){return!this.collapsed}updateData(e){Object.keys(e).forEach(t=>{if(!this.plots[t])this.plots[t]=e[t];else{const i=this.plots[t],s=e[t];s.options&&(i.options={...i.options,...s.options});const o=new Map;i.data.forEach(n=>{o.set(n.time,n)}),s.data.forEach(n=>{o.set(n.time,n)}),i.data=Array.from(o.values()).sort((n,p)=>n.time-p.time)}})}}class ft{static calculate(e,t,i,s=!1,o=null,n){let p=0;e>0&&(p=1/e*100);const d=i.yAxisPadding!==void 0?i.yAxisPadding:5,l=h=>C=>{const A=(C.max-C.min)*(h/100);return C.min-A},k=h=>C=>{const A=(C.max-C.min)*(h/100);return C.max+A},y=Array.from(t.values()).map(h=>h.paneIndex).filter(h=>h>0).sort((h,C)=>h-C).filter((h,C,A)=>A.indexOf(h)===C),b=y.length>0,P=i.dataZoom?.visible??!0,u=i.dataZoom?.position??"top",f=i.dataZoom?.height??6,v=i.dataZoom?.start??0,E=i.dataZoom?.end??100;let V=8,Z=92,x=-1;if(o)if(o==="main")x=0;else{const h=t.get(o);h&&(x=h.paneIndex)}if(x!==-1){const h=[],C=[],A=[],$=[],R=i.dataZoom?.start??50,D=i.dataZoom?.end??100;(i.dataZoom?.zoomOnTouch??!0)&&$.push({type:"inside",xAxisIndex:"all",start:R,end:D});const O=b?Math.max(...y):0,q=[];for(let W=0;W<=O;W++){const B=W===x;h.push({left:"10%",right:"10%",top:B?"5%":"0%",height:B?"90%":"0%",show:B,containLabel:!1}),C.push({type:"category",gridIndex:W,data:[],show:B,axisLabel:{show:B,color:"#94a3b8",fontFamily:i.fontFamily},axisLine:{show:B,lineStyle:{color:"#334155"}},splitLine:{show:B,lineStyle:{color:"#334155",opacity:.5}}});let tt,st;if(W===0&&x===0?(tt=i.yAxisMin!==void 0&&i.yAxisMin!=="auto"?i.yAxisMin:l(d),st=i.yAxisMax!==void 0&&i.yAxisMax!=="auto"?i.yAxisMax:k(d)):(tt=l(d),st=k(d)),A.push({position:"right",gridIndex:W,show:B,scale:!0,min:tt,max:st,axisLabel:{show:B,color:"#94a3b8",fontFamily:i.fontFamily,formatter:J=>{if(i.yAxisLabelFormatter)return i.yAxisLabelFormatter(J);const ot=i.yAxisDecimalPlaces!==void 0?i.yAxisDecimalPlaces:2;return typeof J=="number"?J.toFixed(ot):String(J)}},splitLine:{show:B,lineStyle:{color:"#334155",opacity:.5}}}),W>0){const J=Array.from(t.values()).find(ot=>ot.paneIndex===W);J&&q.push({index:W,height:B?90:0,top:B?5:0,isCollapsed:!1,indicatorId:J.id,titleColor:J.titleColor,controls:J.controls})}}return{grid:h,xAxis:C,yAxis:A,dataZoom:$,paneLayout:q,mainPaneHeight:x===0?90:0,mainPaneTop:x===0?5:0,pixelToPercent:p,overlayYAxisMap:new Map,separatePaneYAxisOffset:1}}P?u==="top"?(V=f+4,Z=95):(Z=100-f-2,V=8):(V=5,Z=95);let M=5;e>0&&(M=20/e*100);let w=75,T=[];if(b){const h=y.map(D=>{const O=Array.from(t.values()).find(q=>q.paneIndex===D);return{index:D,requestedHeight:O?.height,isCollapsed:O?.collapsed??!1,indicatorId:O?.id,titleColor:O?.titleColor,controls:O?.controls}}).map(D=>({...D,height:D.isCollapsed?3:D.requestedHeight!==void 0?D.requestedHeight:15})),C=h.reduce((D,O)=>D+O.height,0),A=h.length*M,$=C+A;w=Z-V-$,s?w=3:w<20&&(w=Math.max(w,10));let R=V+w+M;T=h.map(D=>{const O={index:D.index,height:D.height,top:R,isCollapsed:D.isCollapsed,indicatorId:D.indicatorId,titleColor:D.titleColor,controls:D.controls};return R+=D.height+M,O})}else w=Z-V,s&&(w=3);const I=[];I.push({left:"10%",right:"10%",top:V+"%",height:w+"%",containLabel:!1}),T.forEach(h=>{I.push({left:"10%",right:"10%",top:h.top+"%",height:h.height+"%",containLabel:!1})});const c=[0,...T.map((h,C)=>C+1)],a=[],g=T.length===0;a.push({type:"category",data:[],gridIndex:0,scale:!0,axisLine:{onZero:!1,show:!s,lineStyle:{color:"#334155"}},splitLine:{show:!s,lineStyle:{color:"#334155",opacity:.5}},axisLabel:{show:!s,color:"#94a3b8",fontFamily:i.fontFamily||"sans-serif",formatter:h=>{if(i.yAxisLabelFormatter)return i.yAxisLabelFormatter(h);const C=i.yAxisDecimalPlaces!==void 0?i.yAxisDecimalPlaces:2;return typeof h=="number"?h.toFixed(C):String(h)}},axisTick:{show:!s},axisPointer:{label:{show:g,fontSize:11,backgroundColor:"#475569"}}}),T.forEach((h,C)=>{const A=C===T.length-1;a.push({type:"category",gridIndex:C+1,data:[],axisLabel:{show:!1},axisLine:{show:!h.isCollapsed,lineStyle:{color:"#334155"}},axisTick:{show:!1},splitLine:{show:!1},axisPointer:{label:{show:A,fontSize:11,backgroundColor:"#475569"}}})});const m=[];let S,F;i.yAxisMin!==void 0&&i.yAxisMin!=="auto"?S=i.yAxisMin:S=l(d),i.yAxisMax!==void 0&&i.yAxisMax!=="auto"?F=i.yAxisMax:F=k(d),m.push({position:"right",scale:!0,min:S,max:F,gridIndex:0,splitLine:{show:!s,lineStyle:{color:"#334155",opacity:.5}},axisLine:{show:!s,lineStyle:{color:"#334155"}},axisLabel:{show:!s,color:"#94a3b8",fontFamily:i.fontFamily||"sans-serif",formatter:h=>{if(i.yAxisLabelFormatter)return i.yAxisLabelFormatter(h);const C=i.yAxisDecimalPlaces!==void 0?i.yAxisDecimalPlaces:2;return typeof h=="number"?h.toFixed(C):String(h)}}});let z=1,G=-1/0,N=1/0;n&&n.length>0&&(G=Math.min(...n.map(h=>h.low)),N=Math.max(...n.map(h=>h.high)));const H=new Map;t.forEach((h,C)=>{h.paneIndex===0&&!h.collapsed&&n&&n.length>0&&Object.entries(h.plots).forEach(([A,$])=>{const R=`${C}::${A}`,D=["background","barcolor","char"],O=$.options.style==="shape"&&($.options.location==="abovebar"||$.options.location==="belowbar");if(D.includes($.options.style)){H.has(R)||(H.set(R,z),z++);return}if($.options.style==="shape"&&!O){H.has(R)||(H.set(R,z),z++);return}const q=[];if(Object.values($.data).forEach(W=>{typeof W=="number"&&!isNaN(W)&&isFinite(W)&&q.push(W)}),q.length>0){const W=Math.min(...q),B=Math.max(...q),tt=B-W,st=N-G,J=W>=G*.5&&B<=N*1.5,ot=tt>st*.01;J&&ot||H.has(R)||(H.set(R,z),z++)}})});const X=H.size>0?z-1:0;for(let h=0;h<X;h++)m.push({position:"left",scale:!0,min:l(d),max:k(d),gridIndex:0,show:!1,splitLine:{show:!1},axisLine:{show:!1},axisLabel:{show:!1}});const _=z;T.forEach((h,C)=>{m.push({position:"right",scale:!0,min:l(d),max:k(d),gridIndex:C+1,splitLine:{show:!h.isCollapsed,lineStyle:{color:"#334155",opacity:.3}},axisLabel:{show:!h.isCollapsed,color:"#94a3b8",fontFamily:i.fontFamily||"sans-serif",fontSize:10,formatter:A=>{if(i.yAxisLabelFormatter)return i.yAxisLabelFormatter(A);const $=i.yAxisDecimalPlaces!==void 0?i.yAxisDecimalPlaces:2;return typeof A=="number"?A.toFixed($):String(A)}},axisLine:{show:!h.isCollapsed,lineStyle:{color:"#334155"}}})});const Y=[];return P&&((i.dataZoom?.zoomOnTouch??!0)&&Y.push({type:"inside",xAxisIndex:c,start:v,end:E}),u==="top"?Y.push({type:"slider",xAxisIndex:c,top:"1%",height:f+"%",start:v,end:E,borderColor:"#334155",textStyle:{color:"#cbd5e1"},brushSelect:!1}):Y.push({type:"slider",xAxisIndex:c,bottom:"1%",height:f+"%",start:v,end:E,borderColor:"#334155",textStyle:{color:"#cbd5e1"},brushSelect:!1})),{grid:I,xAxis:a,yAxis:m,dataZoom:Y,paneLayout:T,mainPaneHeight:w,mainPaneTop:V,pixelToPercent:p,overlayYAxisMap:H,separatePaneYAxisOffset:_}}static calculateMaximized(e,t,i){return{grid:[],xAxis:[],yAxis:[],dataZoom:[],paneLayout:[],mainPaneHeight:0,mainPaneTop:0,pixelToPercent:0}}}const pt=new Map;function vt(r,e="#00da3c",t="64px"){if(typeof document>"u")return"";const i=`${r}-${e}-${t}`;if(pt.has(i))return pt.get(i);const s=document.createElement("canvas"),o=s.getContext("2d");if(s.width=32,s.height=32,o){o.font="bold "+t+" Arial",o.fillStyle=e,o.textAlign="center",o.textBaseline="middle",o.fillText(r,16,16);const n=s.toDataURL("image/png");return pt.set(i,n),n}return""}class it{static buildCandlestickSeries(e,t,i){const s=t.upColor||"#00da3c",o=t.downColor||"#ec0000",n=e.map(d=>[d.open,d.close,d.low,d.high]);if(i&&i>n.length){const d=i-n.length;for(let l=0;l<d;l++)n.push(null)}let p;if(t.lastPriceLine?.visible!==!1&&e.length>0){const d=e[e.length-1],l=d.close,k=d.close>=d.open,y=t.lastPriceLine?.color||(k?s:o),b=t.lastPriceLine?.lineStyle||"dashed";p={symbol:["none","none"],data:[{yAxis:l,label:{show:!0,position:"end",formatter:P=>{if(t.yAxisLabelFormatter)return t.yAxisLabelFormatter(P.value);const u=t.yAxisDecimalPlaces!==void 0?t.yAxisDecimalPlaces:2;return typeof P.value=="number"?P.value.toFixed(u):P.value},color:"#fff",backgroundColor:y,padding:[2,4],borderRadius:2,fontSize:11,fontWeight:"bold"},lineStyle:{color:y,type:b,width:1,opacity:.8}}],animation:!1,silent:!0}}return{type:"candlestick",name:t.title||"Market",data:n,itemStyle:{color:s,color0:o,borderColor:s,borderColor0:o},markLine:p,xAxisIndex:0,yAxisIndex:0,z:5}}static getShapeSymbol(e){switch(e){case"arrowdown":return"path://M12 24l-12-12h8v-12h8v12h8z";case"arrowup":return"path://M12 0l12 12h-8v12h-8v-12h-8z";case"circle":return"circle";case"cross":return"path://M11 2h2v9h9v2h-9v9h-2v-9h-9v-2h9z";case"diamond":return"diamond";case"flag":return"path://M6 2v20h2v-8h12l-2-6 2-6h-12z";case"labeldown":return"path://M4 2h16a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-6l-2 4l-2 -4h-6a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2z";case"labelup":return"path://M12 2l2 4h6a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-16a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h6z";case"square":return"rect";case"triangledown":return"path://M12 21l-10-18h20z";case"triangleup":return"triangle";case"xcross":return"path://M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z";default:return"circle"}}static getShapeRotation(e){return 0}static getShapeSize(e,t,i){if(t!==void 0&&i!==void 0)return[t,i];let s;switch(e){case"tiny":s=8;break;case"small":s=12;break;case"normal":case"auto":s=16;break;case"large":s=24;break;case"huge":s=32;break;default:s=16}return t!==void 0?[t,t]:i!==void 0?[i,i]:s}static getLabelConfig(e,t){switch(t){case"abovebar":return{position:"top",distance:5};case"belowbar":return{position:"bottom",distance:5};case"top":return{position:"bottom",distance:5};case"bottom":return{position:"top",distance:5};case"absolute":default:return e==="labelup"||e==="labeldown"?{position:"inside",distance:0}:{position:"top",distance:5}}}static buildIndicatorSeries(e,t,i,s,o=0,n,p,d=1){const l=[],k=new Array(s).fill(null);return e.forEach((y,b)=>{y.collapsed||Object.keys(y.plots).forEach(P=>{const u=y.plots[P],f=`${b}::${P}`;let v=0,E=0;const V=u.options.overlay;if(V!==void 0?V:y.paneIndex===0)v=0,p&&p.has(f)?E=p.get(f):E=0;else{const w=i.findIndex(T=>T.index===y.paneIndex);w!==-1&&(v=w+1,E=d+w)}const Z=new Array(s).fill(null),x=new Array(s).fill(null),M=new Array(s).fill(null);switch(u.data.forEach(w=>{const T=t.get(w.time);if(T!==void 0){const I=w.options?.offset??u.options.offset??0,c=T+o+I;if(c>=0&&c<s){let a=w.value;const g=w.options?.color;(g===null||g==="na"||g==="NaN"||typeof g=="number"&&isNaN(g))&&(a=null),Z[c]=a,x[c]=g||u.options.color,M[c]=w.options||{}}}}),u.options.style){case"histogram":case"columns":l.push({name:f,type:"bar",xAxisIndex:v,yAxisIndex:E,data:Z.map((c,a)=>({value:c,itemStyle:x[a]?{color:x[a]}:void 0})),itemStyle:{color:u.options.color}});break;case"circles":case"cross":const w=Z.map((c,a)=>{if(c===null)return null;const g=x[a]||u.options.color,m={value:[a,c],itemStyle:{color:g}};return u.options.style==="cross"?(m.symbol=`image://${vt("+",g,"24px")}`,m.symbolSize=16):(m.symbol="circle",m.symbolSize=6),m}).filter(c=>c!==null);l.push({name:f,type:"scatter",xAxisIndex:v,yAxisIndex:E,data:w});break;case"bar":case"candle":const T=Z.map((c,a)=>{if(c===null||!Array.isArray(c)||c.length!==4)return null;const[g,m,S,F]=c,z=M[a]||{},G=z.color||x[a]||u.options.color,N=z.wickcolor||u.options.wickcolor||G,H=z.bordercolor||u.options.bordercolor||N;return[a,g,F,S,m,G,N,H]}).filter(c=>c!==null);l.push({name:f,type:"custom",xAxisIndex:v,yAxisIndex:E,renderItem:(c,a)=>{const g=a.value(0),m=a.value(1),S=a.value(2),F=a.value(3),z=a.value(4),G=a.value(5),N=a.value(6),H=a.value(7);if(isNaN(m)||isNaN(S)||isNaN(F)||isNaN(z))return null;const X=a.coord([g,0])[0],_=a.coord([g,m])[1],Y=a.coord([g,S])[1],h=a.coord([g,F])[1],C=a.coord([g,z])[1],A=a.size([1,0])[0]*.6;if(u.options.style==="candle"){const $=Math.min(_,Y),R=Math.max(_,Y),D=Math.abs(Y-_);return{type:"group",children:[{type:"line",shape:{x1:X,y1:C,x2:X,y2:$},style:{stroke:N,lineWidth:1}},{type:"line",shape:{x1:X,y1:R,x2:X,y2:h},style:{stroke:N,lineWidth:1}},{type:"rect",shape:{x:X-A/2,y:$,width:A,height:D||1},style:{fill:G,stroke:H,lineWidth:1}}]}}else{const $=A*.5;return{type:"group",children:[{type:"line",shape:{x1:X,y1:h,x2:X,y2:C},style:{stroke:G,lineWidth:1}},{type:"line",shape:{x1:X-$,y1:_,x2:X,y2:_},style:{stroke:G,lineWidth:1}},{type:"line",shape:{x1:X,y1:Y,x2:X+$,y2:Y},style:{stroke:G,lineWidth:1}}]}}},data:T});break;case"shape":const I=Z.map((c,a)=>{const g=M[a]||{},m=u.options,S=g.location||m.location||"absolute";if(S!=="absolute"&&!c||c==null)return null;const F=g.color||m.color||"blue",z=g.shape||m.shape||"circle",G=g.size||m.size||"normal",N=g.text||m.text,H=g.textcolor||m.textcolor||"white",X=g.width||m.width,_=g.height||m.height;let Y=c,h=[0,0];S==="abovebar"?(n&&n[a]&&(Y=n[a].high),h=[0,"-150%"]):S==="belowbar"?(n&&n[a]&&(Y=n[a].low),h=[0,"150%"]):S==="top"?(Y=c,h=[0,0]):S==="bottom"&&(Y=c,h=[0,0]);const C=it.getShapeSymbol(z),A=it.getShapeSize(G,X,_),$=it.getShapeRotation(z);let R=A;z.includes("label")&&(Array.isArray(A)?R=[A[0]*2.5,A[1]*2.5]:R=A*2.5);const D=it.getLabelConfig(z,S);return{value:[a,Y],symbol:C,symbolSize:R,symbolRotate:$,symbolOffset:h,itemStyle:{color:F},label:{show:!!N,position:D.position,distance:D.distance,formatter:N,color:H,fontSize:10,fontWeight:"bold"}}}).filter(c=>c!==null);l.push({name:f,type:"scatter",xAxisIndex:v,yAxisIndex:E,data:I});break;case"background":l.push({name:f,type:"custom",xAxisIndex:v,yAxisIndex:E,z:-10,renderItem:(c,a)=>{const g=a.value(0);if(isNaN(g))return;const m=a.coord([g,0]),S=a.size([1,0])[0],F=c.coordSys,z=m[0]-S/2,G=x[c.dataIndex],N=a.value(1);if(!(!G||N===null||N===void 0||isNaN(N)))return{type:"rect",shape:{x:z,y:F.y,width:S,height:F.height},style:{fill:G,opacity:.3},silent:!0}},data:Z.map((c,a)=>[a,c])});break;case"step":l.push({name:f,type:"custom",xAxisIndex:v,yAxisIndex:E,renderItem:(c,a)=>{const g=a.value(0),m=a.value(1);if(isNaN(m)||m===null)return;const S=a.coord([g,m]),F=a.size([1,0])[0];return{type:"line",shape:{x1:S[0]-F/2,y1:S[1],x2:S[0]+F/2,y2:S[1]},style:{stroke:x[c.dataIndex]||u.options.color,lineWidth:u.options.linewidth||1},silent:!0}},data:Z.map((c,a)=>[a,c])});break;case"barcolor":u.data.forEach(c=>{const a=t.get(c.time);if(a!==void 0){const g=c.options?.offset??u.options.offset??0,m=a+o+g;if(m>=0&&m<s){const S=c.options?.color||u.options.color;!(S===null||S==="na"||S==="NaN"||typeof S=="number"&&isNaN(S))&&c.value!==null&&c.value!==void 0&&(k[m]=S)}}});break;case"char":l.push({name:f,type:"scatter",xAxisIndex:v,yAxisIndex:E,symbolSize:0,data:Z.map((c,a)=>({value:[a,c],itemStyle:{opacity:0}})),silent:!0});break;case"line":default:l.push({name:f,type:"custom",xAxisIndex:v,yAxisIndex:E,renderItem:(c,a)=>{const g=c.dataIndex;if(g===0)return;const m=a.value(1),S=a.value(2);if(m===null||isNaN(m)||S===null||isNaN(S))return;const F=a.coord([g-1,S]),z=a.coord([g,m]);return{type:"line",shape:{x1:F[0],y1:F[1],x2:z[0],y2:z[1]},style:{stroke:x[g]||u.options.color,lineWidth:u.options.linewidth||1},silent:!0}},data:Z.map((c,a)=>[a,c,a>0?Z[a-1]:null])});break}})}),{series:l,barColors:k}}}class wt{static build(e,t,i,s=!1,o=null){const n=[],p=e.pixelToPercent,d=e.mainPaneTop;if(!o||o==="main"){const l=10*p;if(n.push({type:"text",left:"8.5%",top:d+l+"%",z:10,style:{text:t.title||"Market",fill:t.titleColor||"#fff",font:`bold 16px ${t.fontFamily||"sans-serif"}`,textVerticalAlign:"top"}}),t.watermark!==!1){const y=e.mainPaneTop+e.mainPaneHeight;n.push({type:"text",right:"11%",top:y-3+"%",z:10,style:{text:"QFChart",fill:t.fontColor||"#cbd5e1",font:"bold 16px sans-serif",opacity:.1},cursor:"pointer",onclick:()=>{window.open("https://quantforge.org","_blank")}})}const k=[];if(t.controls?.collapse&&k.push({type:"group",children:[{type:"rect",shape:{width:20,height:20,r:2},style:{fill:"#334155",stroke:"#475569",lineWidth:1},onclick:()=>i("main","collapse")},{type:"text",style:{text:s?"+":"\u2212",fill:"#cbd5e1",font:`bold 14px ${t.fontFamily}`,x:10,y:10,textAlign:"center",textVerticalAlign:"middle"},silent:!0}]}),t.controls?.maximize){const y=o==="main",b=t.controls?.collapse?25:0;k.push({type:"group",x:b,children:[{type:"rect",shape:{width:20,height:20,r:2},style:{fill:"#334155",stroke:"#475569",lineWidth:1},onclick:()=>i("main","maximize")},{type:"text",style:{text:y?"\u2750":"\u25A1",fill:"#cbd5e1",font:`14px ${t.fontFamily}`,x:10,y:10,textAlign:"center",textVerticalAlign:"middle"},silent:!0}]})}if(t.controls?.fullscreen){let y=0;t.controls?.collapse&&(y+=25),t.controls?.maximize&&(y+=25),k.push({type:"group",x:y,children:[{type:"rect",shape:{width:20,height:20,r:2},style:{fill:"#334155",stroke:"#475569",lineWidth:1},onclick:()=>i("main","fullscreen")},{type:"text",style:{text:"\u26F6",fill:"#cbd5e1",font:`14px ${t.fontFamily}`,x:10,y:10,textAlign:"center",textVerticalAlign:"middle"},silent:!0}]})}k.length>0&&n.push({type:"group",right:"10.5%",top:d+"%",children:k})}return e.paneLayout.forEach(l=>{if(o&&l.indicatorId!==o)return;n.push({type:"text",left:"8.5%",top:l.top+10*p+"%",z:10,style:{text:l.indicatorId||"",fill:l.titleColor||"#fff",font:`bold 12px ${t.fontFamily||"sans-serif"}`,textVerticalAlign:"top"}});const k=[];if(l.controls?.collapse&&k.push({type:"group",children:[{type:"rect",shape:{width:20,height:20,r:2},style:{fill:"#334155",stroke:"#475569",lineWidth:1},onclick:()=>l.indicatorId&&i(l.indicatorId,"collapse")},{type:"text",style:{text:l.isCollapsed?"+":"\u2212",fill:"#cbd5e1",font:`bold 14px ${t.fontFamily}`,x:10,y:10,textAlign:"center",textVerticalAlign:"middle"},silent:!0}]}),l.controls?.maximize){const y=o===l.indicatorId,b=l.controls?.collapse?25:0;k.push({type:"group",x:b,children:[{type:"rect",shape:{width:20,height:20,r:2},style:{fill:"#334155",stroke:"#475569",lineWidth:1},onclick:()=>l.indicatorId&&i(l.indicatorId,"maximize")},{type:"text",style:{text:y?"\u2750":"\u25A1",fill:"#cbd5e1",font:`14px ${t.fontFamily}`,x:10,y:10,textAlign:"center",textVerticalAlign:"middle"},silent:!0}]})}k.length>0&&n.push({type:"group",right:"10.5%",top:l.top+"%",children:k})}),n}}class Ct{static format(e,t){if(!e||e.length===0)return"";const i=t.title||"Market",s=t.upColor||"#00da3c",o=t.downColor||"#ec0000",n=t.fontFamily||"sans-serif",p=e[0].axisValue;let d=`<div style="font-weight: bold; margin-bottom: 5px; color: #cbd5e1; font-family: ${n};">${p}</div>`;const l=e.find(y=>y.seriesType==="candlestick"),k=e.filter(y=>y.seriesType!=="candlestick");if(l){const[y,b,P,u,f]=l.value,v=P>=b?s:o;d+=`
|
|
17
|
+
(function(et,lt){typeof exports=="object"&&typeof module<"u"?lt(exports,require("echarts")):typeof define=="function"&&define.amd?define(["exports","echarts"],lt):(et=typeof globalThis<"u"?globalThis:et||self,lt(et.QFChart={},et.echarts))})(this,function(et,lt){"use strict";function yt(r){var e=Object.create(null);return r&&Object.keys(r).forEach(function(t){if(t!=="default"){var i=Object.getOwnPropertyDescriptor(r,t);Object.defineProperty(e,t,i.get?i:{enumerable:!0,get:function(){return r[t]}})}}),e.default=r,Object.freeze(e)}var j=yt(lt),xt=Object.defineProperty,mt=(r,e,t)=>e in r?xt(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,at=(r,e,t)=>(mt(r,typeof e!="symbol"?e+"":e,t),t);class bt{constructor(e,t,i,s={}){at(this,"id"),at(this,"plots"),at(this,"paneIndex"),at(this,"height"),at(this,"collapsed"),at(this,"titleColor"),at(this,"controls"),this.id=e,this.plots=t,this.paneIndex=i,this.height=s.height,this.collapsed=s.collapsed||!1,this.titleColor=s.titleColor,this.controls=s.controls}toggleCollapse(){this.collapsed=!this.collapsed}isVisible(){return!this.collapsed}updateData(e){Object.keys(e).forEach(t=>{if(!this.plots[t])this.plots[t]=e[t];else{const i=this.plots[t],s=e[t];s.options&&(i.options={...i.options,...s.options});const o=new Map;i.data.forEach(n=>{o.set(n.time,n)}),s.data.forEach(n=>{o.set(n.time,n)}),i.data=Array.from(o.values()).sort((n,p)=>n.time-p.time)}})}}class ft{static calculate(e,t,i,s=!1,o=null,n){let p=0;e>0&&(p=1/e*100);const d=i.yAxisPadding!==void 0?i.yAxisPadding:5,l=h=>C=>{const M=(C.max-C.min)*(h/100);return C.min-M},k=h=>C=>{const M=(C.max-C.min)*(h/100);return C.max+M},y=Array.from(t.values()).map(h=>h.paneIndex).filter(h=>h>0).sort((h,C)=>h-C).filter((h,C,M)=>M.indexOf(h)===C),m=y.length>0,I=i.dataZoom?.visible??!0,u=i.dataZoom?.position??"top",f=i.dataZoom?.height??6,v=i.dataZoom?.start??0,E=i.dataZoom?.end??100;let V=8,Z=92,x=-1;if(o)if(o==="main")x=0;else{const h=t.get(o);h&&(x=h.paneIndex)}if(x!==-1){const h=[],C=[],M=[],$=[],R=i.dataZoom?.start??50,D=i.dataZoom?.end??100;(i.dataZoom?.zoomOnTouch??!0)&&$.push({type:"inside",xAxisIndex:"all",start:R,end:D});const W=m?Math.max(...y):0,q=[];for(let O=0;O<=W;O++){const B=O===x;h.push({left:"10%",right:"10%",top:B?"5%":"0%",height:B?"90%":"0%",show:B,containLabel:!1}),C.push({type:"category",gridIndex:O,data:[],show:B,axisLabel:{show:B,color:"#94a3b8",fontFamily:i.fontFamily},axisLine:{show:B,lineStyle:{color:"#334155"}},splitLine:{show:B,lineStyle:{color:"#334155",opacity:.5}}});let tt,st;if(O===0&&x===0?(tt=i.yAxisMin!==void 0&&i.yAxisMin!=="auto"?i.yAxisMin:l(d),st=i.yAxisMax!==void 0&&i.yAxisMax!=="auto"?i.yAxisMax:k(d)):(tt=l(d),st=k(d)),M.push({position:"right",gridIndex:O,show:B,scale:!0,min:tt,max:st,axisLabel:{show:B,color:"#94a3b8",fontFamily:i.fontFamily,formatter:J=>{if(i.yAxisLabelFormatter)return i.yAxisLabelFormatter(J);const ot=i.yAxisDecimalPlaces!==void 0?i.yAxisDecimalPlaces:2;return typeof J=="number"?J.toFixed(ot):String(J)}},splitLine:{show:B,lineStyle:{color:"#334155",opacity:.5}}}),O>0){const J=Array.from(t.values()).find(ot=>ot.paneIndex===O);J&&q.push({index:O,height:B?90:0,top:B?5:0,isCollapsed:!1,indicatorId:J.id,titleColor:J.titleColor,controls:J.controls})}}return{grid:h,xAxis:C,yAxis:M,dataZoom:$,paneLayout:q,mainPaneHeight:x===0?90:0,mainPaneTop:x===0?5:0,pixelToPercent:p,overlayYAxisMap:new Map,separatePaneYAxisOffset:1}}I?u==="top"?(V=f+4,Z=95):(Z=100-f-2,V=8):(V=5,Z=95);let A=5;e>0&&(A=20/e*100);let w=75,T=[];if(m){const h=y.map(D=>{const W=Array.from(t.values()).find(q=>q.paneIndex===D);return{index:D,requestedHeight:W?.height,isCollapsed:W?.collapsed??!1,indicatorId:W?.id,titleColor:W?.titleColor,controls:W?.controls}}).map(D=>({...D,height:D.isCollapsed?3:D.requestedHeight!==void 0?D.requestedHeight:15})),C=h.reduce((D,W)=>D+W.height,0),M=h.length*A,$=C+M;w=Z-V-$,s?w=3:w<20&&(w=Math.max(w,10));let R=V+w+A;T=h.map(D=>{const W={index:D.index,height:D.height,top:R,isCollapsed:D.isCollapsed,indicatorId:D.indicatorId,titleColor:D.titleColor,controls:D.controls};return R+=D.height+A,W})}else w=Z-V,s&&(w=3);const S=[];S.push({left:"10%",right:"10%",top:V+"%",height:w+"%",containLabel:!1}),T.forEach(h=>{S.push({left:"10%",right:"10%",top:h.top+"%",height:h.height+"%",containLabel:!1})});const c=[0,...T.map((h,C)=>C+1)],a=[],g=T.length===0;a.push({type:"category",data:[],gridIndex:0,scale:!0,axisLine:{onZero:!1,show:!s,lineStyle:{color:"#334155"}},splitLine:{show:!s,lineStyle:{color:"#334155",opacity:.5}},axisLabel:{show:!s,color:"#94a3b8",fontFamily:i.fontFamily||"sans-serif",formatter:h=>{if(i.yAxisLabelFormatter)return i.yAxisLabelFormatter(h);const C=i.yAxisDecimalPlaces!==void 0?i.yAxisDecimalPlaces:2;return typeof h=="number"?h.toFixed(C):String(h)}},axisTick:{show:!s},axisPointer:{label:{show:g,fontSize:11,backgroundColor:"#475569"}}}),T.forEach((h,C)=>{const M=C===T.length-1;a.push({type:"category",gridIndex:C+1,data:[],axisLabel:{show:!1},axisLine:{show:!h.isCollapsed,lineStyle:{color:"#334155"}},axisTick:{show:!1},splitLine:{show:!1},axisPointer:{label:{show:M,fontSize:11,backgroundColor:"#475569"}}})});const b=[];let P,F;i.yAxisMin!==void 0&&i.yAxisMin!=="auto"?P=i.yAxisMin:P=l(d),i.yAxisMax!==void 0&&i.yAxisMax!=="auto"?F=i.yAxisMax:F=k(d),b.push({position:"right",scale:!0,min:P,max:F,gridIndex:0,splitLine:{show:!s,lineStyle:{color:"#334155",opacity:.5}},axisLine:{show:!s,lineStyle:{color:"#334155"}},axisLabel:{show:!s,color:"#94a3b8",fontFamily:i.fontFamily||"sans-serif",formatter:h=>{if(i.yAxisLabelFormatter)return i.yAxisLabelFormatter(h);const C=i.yAxisDecimalPlaces!==void 0?i.yAxisDecimalPlaces:2;return typeof h=="number"?h.toFixed(C):String(h)}}});let z=1,G=-1/0,N=1/0;n&&n.length>0&&(G=Math.min(...n.map(h=>h.low)),N=Math.max(...n.map(h=>h.high)));const H=new Map;t.forEach((h,C)=>{h.paneIndex===0&&!h.collapsed&&n&&n.length>0&&Object.entries(h.plots).forEach(([M,$])=>{const R=`${C}::${M}`,D=["background","barcolor","char"],W=$.options.style==="shape"&&($.options.location==="abovebar"||$.options.location==="belowbar");if(D.includes($.options.style)){H.has(R)||(H.set(R,z),z++);return}if($.options.style==="shape"&&!W){H.has(R)||(H.set(R,z),z++);return}const q=[];if(Object.values($.data).forEach(O=>{typeof O=="number"&&!isNaN(O)&&isFinite(O)&&q.push(O)}),q.length>0){const O=Math.min(...q),B=Math.max(...q),tt=B-O,st=N-G,J=O>=G*.5&&B<=N*1.5,ot=tt>st*.01;J&&ot||H.has(R)||(H.set(R,z),z++)}})});const X=H.size>0?z-1:0;for(let h=0;h<X;h++)b.push({position:"left",scale:!0,min:l(d),max:k(d),gridIndex:0,show:!1,splitLine:{show:!1},axisLine:{show:!1},axisLabel:{show:!1}});const K=z;T.forEach((h,C)=>{b.push({position:"right",scale:!0,min:l(d),max:k(d),gridIndex:C+1,splitLine:{show:!h.isCollapsed,lineStyle:{color:"#334155",opacity:.3}},axisLabel:{show:!h.isCollapsed,color:"#94a3b8",fontFamily:i.fontFamily||"sans-serif",fontSize:10,formatter:M=>{if(i.yAxisLabelFormatter)return i.yAxisLabelFormatter(M);const $=i.yAxisDecimalPlaces!==void 0?i.yAxisDecimalPlaces:2;return typeof M=="number"?M.toFixed($):String(M)}},axisLine:{show:!h.isCollapsed,lineStyle:{color:"#334155"}}})});const Y=[];return I&&((i.dataZoom?.zoomOnTouch??!0)&&Y.push({type:"inside",xAxisIndex:c,start:v,end:E}),u==="top"?Y.push({type:"slider",xAxisIndex:c,top:"1%",height:f+"%",start:v,end:E,borderColor:"#334155",textStyle:{color:"#cbd5e1"},brushSelect:!1}):Y.push({type:"slider",xAxisIndex:c,bottom:"1%",height:f+"%",start:v,end:E,borderColor:"#334155",textStyle:{color:"#cbd5e1"},brushSelect:!1})),{grid:S,xAxis:a,yAxis:b,dataZoom:Y,paneLayout:T,mainPaneHeight:w,mainPaneTop:V,pixelToPercent:p,overlayYAxisMap:H,separatePaneYAxisOffset:K}}static calculateMaximized(e,t,i){return{grid:[],xAxis:[],yAxis:[],dataZoom:[],paneLayout:[],mainPaneHeight:0,mainPaneTop:0,pixelToPercent:0}}}const pt=new Map;function vt(r,e="#00da3c",t="64px"){if(typeof document>"u")return"";const i=`${r}-${e}-${t}`;if(pt.has(i))return pt.get(i);const s=document.createElement("canvas"),o=s.getContext("2d");if(s.width=32,s.height=32,o){o.font="bold "+t+" Arial",o.fillStyle=e,o.textAlign="center",o.textBaseline="middle",o.fillText(r,16,16);const n=s.toDataURL("image/png");return pt.set(i,n),n}return""}class it{static buildCandlestickSeries(e,t,i){const s=t.upColor||"#00da3c",o=t.downColor||"#ec0000",n=e.map(d=>[d.open,d.close,d.low,d.high]);if(i&&i>n.length){const d=i-n.length;for(let l=0;l<d;l++)n.push(null)}let p;if(t.lastPriceLine?.visible!==!1&&e.length>0){const d=e[e.length-1],l=d.close,k=d.close>=d.open,y=t.lastPriceLine?.color||(k?s:o);let m=t.lastPriceLine?.lineStyle||"dashed";m.startsWith("linestyle_")&&(m=m.replace("linestyle_","")),p={symbol:["none","none"],data:[{yAxis:l,label:{show:!0,position:"end",formatter:I=>{if(t.yAxisLabelFormatter)return t.yAxisLabelFormatter(I.value);const u=t.yAxisDecimalPlaces!==void 0?t.yAxisDecimalPlaces:2;return typeof I.value=="number"?I.value.toFixed(u):I.value},color:"#fff",backgroundColor:y,padding:[2,4],borderRadius:2,fontSize:11,fontWeight:"bold"},lineStyle:{color:y,type:m,width:1,opacity:.8}}],animation:!1,silent:!0}}return{type:"candlestick",name:t.title||"Market",data:n,itemStyle:{color:s,color0:o,borderColor:s,borderColor0:o},markLine:p,xAxisIndex:0,yAxisIndex:0,z:5}}static getShapeSymbol(e){switch(e){case"arrowdown":return"path://M12 24l-12-12h8v-12h8v12h8z";case"arrowup":return"path://M12 0l12 12h-8v12h-8v-12h-8z";case"circle":return"circle";case"cross":return"path://M11 2h2v9h9v2h-9v9h-2v-9h-9v-2h9z";case"diamond":return"diamond";case"flag":return"path://M6 2v20h2v-8h12l-2-6 2-6h-12z";case"labeldown":return"path://M4 2h16a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-6l-2 4l-2 -4h-6a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2z";case"labelup":return"path://M12 2l2 4h6a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-16a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h6z";case"square":return"rect";case"triangledown":return"path://M12 21l-10-18h20z";case"triangleup":return"triangle";case"xcross":return"path://M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z";default:return"circle"}}static getShapeRotation(e){return 0}static getShapeSize(e,t,i){if(t!==void 0&&i!==void 0)return[t,i];let s;switch(e){case"tiny":s=8;break;case"small":s=12;break;case"normal":case"auto":s=16;break;case"large":s=24;break;case"huge":s=32;break;default:s=16}return t!==void 0?[t,t]:i!==void 0?[i,i]:s}static getLabelConfig(e,t){switch(t){case"abovebar":return{position:"top",distance:5};case"belowbar":return{position:"bottom",distance:5};case"top":return{position:"bottom",distance:5};case"bottom":return{position:"top",distance:5};case"absolute":default:return e==="labelup"||e==="labeldown"?{position:"inside",distance:0}:{position:"top",distance:5}}}static buildIndicatorSeries(e,t,i,s,o=0,n,p,d=1){const l=[],k=new Array(s).fill(null);return e.forEach((y,m)=>{y.collapsed||Object.keys(y.plots).forEach(I=>{const u=y.plots[I],f=`${m}::${I}`;let v=0,E=0;const V=u.options.overlay;if(V!==void 0?V:y.paneIndex===0)v=0,p&&p.has(f)?E=p.get(f):E=0;else{const w=i.findIndex(T=>T.index===y.paneIndex);w!==-1&&(v=w+1,E=d+w)}const Z=new Array(s).fill(null),x=new Array(s).fill(null),A=new Array(s).fill(null);switch(u.data.forEach(w=>{const T=t.get(w.time);if(T!==void 0){const S=w.options?.offset??u.options.offset??0,c=T+o+S;if(c>=0&&c<s){let a=w.value;const g=w.options?.color;(g===null||g==="na"||g==="NaN"||typeof g=="number"&&isNaN(g))&&(a=null),Z[c]=a,x[c]=g||u.options.color,A[c]=w.options||{}}}}),u.options?.style?.startsWith("style_")&&(u.options.style=u.options.style.replace("style_","")),u.options.style){case"histogram":case"columns":l.push({name:f,type:"bar",xAxisIndex:v,yAxisIndex:E,data:Z.map((c,a)=>({value:c,itemStyle:x[a]?{color:x[a]}:void 0})),itemStyle:{color:u.options.color}});break;case"circles":case"cross":const w=Z.map((c,a)=>{if(c===null)return null;const g=x[a]||u.options.color,b={value:[a,c],itemStyle:{color:g}};return u.options.style==="cross"?(b.symbol=`image://${vt("+",g,"24px")}`,b.symbolSize=16):(b.symbol="circle",b.symbolSize=6),b}).filter(c=>c!==null);l.push({name:f,type:"scatter",xAxisIndex:v,yAxisIndex:E,data:w});break;case"bar":case"candle":const T=Z.map((c,a)=>{if(c===null||!Array.isArray(c)||c.length!==4)return null;const[g,b,P,F]=c,z=A[a]||{},G=z.color||x[a]||u.options.color,N=z.wickcolor||u.options.wickcolor||G,H=z.bordercolor||u.options.bordercolor||N;return[a,g,F,P,b,G,N,H]}).filter(c=>c!==null);l.push({name:f,type:"custom",xAxisIndex:v,yAxisIndex:E,renderItem:(c,a)=>{const g=a.value(0),b=a.value(1),P=a.value(2),F=a.value(3),z=a.value(4),G=a.value(5),N=a.value(6),H=a.value(7);if(isNaN(b)||isNaN(P)||isNaN(F)||isNaN(z))return null;const X=a.coord([g,0])[0],K=a.coord([g,b])[1],Y=a.coord([g,P])[1],h=a.coord([g,F])[1],C=a.coord([g,z])[1],M=a.size([1,0])[0]*.6;if(u.options.style==="candle"){const $=Math.min(K,Y),R=Math.max(K,Y),D=Math.abs(Y-K);return{type:"group",children:[{type:"line",shape:{x1:X,y1:C,x2:X,y2:$},style:{stroke:N,lineWidth:1}},{type:"line",shape:{x1:X,y1:R,x2:X,y2:h},style:{stroke:N,lineWidth:1}},{type:"rect",shape:{x:X-M/2,y:$,width:M,height:D||1},style:{fill:G,stroke:H,lineWidth:1}}]}}else{const $=M*.5;return{type:"group",children:[{type:"line",shape:{x1:X,y1:h,x2:X,y2:C},style:{stroke:G,lineWidth:1}},{type:"line",shape:{x1:X-$,y1:K,x2:X,y2:K},style:{stroke:G,lineWidth:1}},{type:"line",shape:{x1:X,y1:Y,x2:X+$,y2:Y},style:{stroke:G,lineWidth:1}}]}}},data:T});break;case"shape":const S=Z.map((c,a)=>{const g=A[a]||{},b=u.options,P=g.location||b.location||"absolute";if(P!=="absolute"&&!c||c==null)return null;const F=g.color||b.color||"blue",z=g.shape||b.shape||"circle",G=g.size||b.size||"normal",N=g.text||b.text,H=g.textcolor||b.textcolor||"white",X=g.width||b.width,K=g.height||b.height;let Y=c,h=[0,0];P==="abovebar"?(n&&n[a]&&(Y=n[a].high),h=[0,"-150%"]):P==="belowbar"?(n&&n[a]&&(Y=n[a].low),h=[0,"150%"]):P==="top"?(Y=c,h=[0,0]):P==="bottom"&&(Y=c,h=[0,0]);const C=it.getShapeSymbol(z),M=it.getShapeSize(G,X,K),$=it.getShapeRotation(z);let R=M;z.includes("label")&&(Array.isArray(M)?R=[M[0]*2.5,M[1]*2.5]:R=M*2.5);const D=it.getLabelConfig(z,P);return{value:[a,Y],symbol:C,symbolSize:R,symbolRotate:$,symbolOffset:h,itemStyle:{color:F},label:{show:!!N,position:D.position,distance:D.distance,formatter:N,color:H,fontSize:10,fontWeight:"bold"}}}).filter(c=>c!==null);l.push({name:f,type:"scatter",xAxisIndex:v,yAxisIndex:E,data:S});break;case"background":l.push({name:f,type:"custom",xAxisIndex:v,yAxisIndex:E,z:-10,renderItem:(c,a)=>{const g=a.value(0);if(isNaN(g))return;const b=a.coord([g,0]),P=a.size([1,0])[0],F=c.coordSys,z=b[0]-P/2,G=x[c.dataIndex],N=a.value(1);if(!(!G||N===null||N===void 0||isNaN(N)))return{type:"rect",shape:{x:z,y:F.y,width:P,height:F.height},style:{fill:G,opacity:.3},silent:!0}},data:Z.map((c,a)=>[a,c])});break;case"step":l.push({name:f,type:"custom",xAxisIndex:v,yAxisIndex:E,renderItem:(c,a)=>{const g=a.value(0),b=a.value(1);if(isNaN(b)||b===null)return;const P=a.coord([g,b]),F=a.size([1,0])[0];return{type:"line",shape:{x1:P[0]-F/2,y1:P[1],x2:P[0]+F/2,y2:P[1]},style:{stroke:x[c.dataIndex]||u.options.color,lineWidth:u.options.linewidth||1},silent:!0}},data:Z.map((c,a)=>[a,c])});break;case"barcolor":u.data.forEach(c=>{const a=t.get(c.time);if(a!==void 0){const g=c.options?.offset??u.options.offset??0,b=a+o+g;if(b>=0&&b<s){const P=c.options?.color||u.options.color;!(P===null||P==="na"||P==="NaN"||typeof P=="number"&&isNaN(P))&&c.value!==null&&c.value!==void 0&&(k[b]=P)}}});break;case"char":l.push({name:f,type:"scatter",xAxisIndex:v,yAxisIndex:E,symbolSize:0,data:Z.map((c,a)=>({value:[a,c],itemStyle:{opacity:0}})),silent:!0});break;case"line":default:l.push({name:f,type:"custom",xAxisIndex:v,yAxisIndex:E,renderItem:(c,a)=>{const g=c.dataIndex;if(g===0)return;const b=a.value(1),P=a.value(2);if(b===null||isNaN(b)||P===null||isNaN(P))return;const F=a.coord([g-1,P]),z=a.coord([g,b]);return{type:"line",shape:{x1:F[0],y1:F[1],x2:z[0],y2:z[1]},style:{stroke:x[g]||u.options.color,lineWidth:u.options.linewidth||1},silent:!0}},data:Z.map((c,a)=>[a,c,a>0?Z[a-1]:null])});break}})}),{series:l,barColors:k}}}class wt{static build(e,t,i,s=!1,o=null){const n=[],p=e.pixelToPercent,d=e.mainPaneTop;if(!o||o==="main"){const l=10*p;if(n.push({type:"text",left:"8.5%",top:d+l+"%",z:10,style:{text:t.title||"Market",fill:t.titleColor||"#fff",font:`bold 16px ${t.fontFamily||"sans-serif"}`,textVerticalAlign:"top"}}),t.watermark!==!1){const y=e.mainPaneTop+e.mainPaneHeight;n.push({type:"text",right:"11%",top:y-3+"%",z:10,style:{text:"QFChart",fill:t.fontColor||"#cbd5e1",font:"bold 16px sans-serif",opacity:.1},cursor:"pointer",onclick:()=>{window.open("https://quantforge.org","_blank")}})}const k=[];if(t.controls?.collapse&&k.push({type:"group",children:[{type:"rect",shape:{width:20,height:20,r:2},style:{fill:"#334155",stroke:"#475569",lineWidth:1},onclick:()=>i("main","collapse")},{type:"text",style:{text:s?"+":"\u2212",fill:"#cbd5e1",font:`bold 14px ${t.fontFamily}`,x:10,y:10,textAlign:"center",textVerticalAlign:"middle"},silent:!0}]}),t.controls?.maximize){const y=o==="main",m=t.controls?.collapse?25:0;k.push({type:"group",x:m,children:[{type:"rect",shape:{width:20,height:20,r:2},style:{fill:"#334155",stroke:"#475569",lineWidth:1},onclick:()=>i("main","maximize")},{type:"text",style:{text:y?"\u2750":"\u25A1",fill:"#cbd5e1",font:`14px ${t.fontFamily}`,x:10,y:10,textAlign:"center",textVerticalAlign:"middle"},silent:!0}]})}if(t.controls?.fullscreen){let y=0;t.controls?.collapse&&(y+=25),t.controls?.maximize&&(y+=25),k.push({type:"group",x:y,children:[{type:"rect",shape:{width:20,height:20,r:2},style:{fill:"#334155",stroke:"#475569",lineWidth:1},onclick:()=>i("main","fullscreen")},{type:"text",style:{text:"\u26F6",fill:"#cbd5e1",font:`14px ${t.fontFamily}`,x:10,y:10,textAlign:"center",textVerticalAlign:"middle"},silent:!0}]})}k.length>0&&n.push({type:"group",right:"10.5%",top:d+"%",children:k})}return e.paneLayout.forEach(l=>{if(o&&l.indicatorId!==o)return;n.push({type:"text",left:"8.5%",top:l.top+10*p+"%",z:10,style:{text:l.indicatorId||"",fill:l.titleColor||"#fff",font:`bold 12px ${t.fontFamily||"sans-serif"}`,textVerticalAlign:"top"}});const k=[];if(l.controls?.collapse&&k.push({type:"group",children:[{type:"rect",shape:{width:20,height:20,r:2},style:{fill:"#334155",stroke:"#475569",lineWidth:1},onclick:()=>l.indicatorId&&i(l.indicatorId,"collapse")},{type:"text",style:{text:l.isCollapsed?"+":"\u2212",fill:"#cbd5e1",font:`bold 14px ${t.fontFamily}`,x:10,y:10,textAlign:"center",textVerticalAlign:"middle"},silent:!0}]}),l.controls?.maximize){const y=o===l.indicatorId,m=l.controls?.collapse?25:0;k.push({type:"group",x:m,children:[{type:"rect",shape:{width:20,height:20,r:2},style:{fill:"#334155",stroke:"#475569",lineWidth:1},onclick:()=>l.indicatorId&&i(l.indicatorId,"maximize")},{type:"text",style:{text:y?"\u2750":"\u25A1",fill:"#cbd5e1",font:`14px ${t.fontFamily}`,x:10,y:10,textAlign:"center",textVerticalAlign:"middle"},silent:!0}]})}k.length>0&&n.push({type:"group",right:"10.5%",top:l.top+"%",children:k})}),n}}class Ct{static format(e,t){if(!e||e.length===0)return"";const i=t.title||"Market",s=t.upColor||"#00da3c",o=t.downColor||"#ec0000",n=t.fontFamily||"sans-serif",p=e[0].axisValue;let d=`<div style="font-weight: bold; margin-bottom: 5px; color: #cbd5e1; font-family: ${n};">${p}</div>`;const l=e.find(y=>y.seriesType==="candlestick"),k=e.filter(y=>y.seriesType!=="candlestick");if(l){const[y,m,I,u,f]=l.value,v=I>=m?s:o;d+=`
|
|
18
18
|
<div style="margin-bottom: 8px; font-family: ${n};">
|
|
19
19
|
<div style="display:flex; justify-content:space-between; color:${v}; font-weight:bold;">
|
|
20
20
|
<span>${i}</span>
|
|
21
21
|
</div>
|
|
22
22
|
<div style="display: grid; grid-template-columns: auto auto; gap: 2px 15px; font-size: 0.9em; color: #cbd5e1;">
|
|
23
|
-
<span>Open:</span> <span style="text-align: right; color: ${
|
|
23
|
+
<span>Open:</span> <span style="text-align: right; color: ${I>=m?s:o}">${m}</span>
|
|
24
24
|
<span>High:</span> <span style="text-align: right; color: ${s}">${f}</span>
|
|
25
25
|
<span>Low:</span> <span style="text-align: right; color: ${o}">${u}</span>
|
|
26
|
-
<span>Close:</span> <span style="text-align: right; color: ${
|
|
26
|
+
<span>Close:</span> <span style="text-align: right; color: ${I>=m?s:o}">${I}</span>
|
|
27
27
|
</div>
|
|
28
28
|
</div>
|
|
29
|
-
`}if(k.length>0){d+='<div style="border-top: 1px solid #334155; margin: 5px 0; padding-top: 5px;"></div>';const y={};k.forEach(
|
|
29
|
+
`}if(k.length>0){d+='<div style="border-top: 1px solid #334155; margin: 5px 0; padding-top: 5px;"></div>';const y={};k.forEach(m=>{const I=m.seriesName.split("::"),u=I.length>1?I[0]:"Unknown",f=I.length>1?I[1]:m.seriesName;y[u]||(y[u]=[]),y[u].push({...m,displayName:f})}),Object.keys(y).forEach(m=>{d+=`
|
|
30
30
|
<div style="margin-top: 8px; font-family: ${n};">
|
|
31
|
-
<div style="font-weight:bold; color: #fff; margin-bottom: 2px;">${
|
|
32
|
-
`,y[
|
|
31
|
+
<div style="font-weight:bold; color: #fff; margin-bottom: 2px;">${m}</div>
|
|
32
|
+
`,y[m].forEach(I=>{let u=I.value;if(Array.isArray(u)&&(u=u[1]),u==null)return;const f=typeof u=="number"?u.toLocaleString(void 0,{maximumFractionDigits:4}):u;d+=`
|
|
33
33
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 2px; padding-left: 8px;">
|
|
34
|
-
<div>${
|
|
34
|
+
<div>${I.marker} <span style="color: #cbd5e1;">${I.displayName}</span></div>
|
|
35
35
|
<div style="font-size: 10px; color: #fff;padding-left:10px;">${f}</div>
|
|
36
|
-
</div>`}),d+="</div>"})}return d}}var kt=Object.defineProperty,St=(r,e,t)=>e in r?kt(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,rt=(r,e,t)=>(St(r,typeof e!="symbol"?e+"":e,t),t);class Pt{constructor(e,t){rt(this,"plugins",new Map),rt(this,"activePluginId",null),rt(this,"context"),rt(this,"toolbarContainer"),rt(this,"tooltipElement",null),rt(this,"hideTimeout",null),this.context=e,this.toolbarContainer=t,this.createTooltip(),this.renderToolbar()}createTooltip(){this.tooltipElement=document.createElement("div"),Object.assign(this.tooltipElement.style,{position:"fixed",display:"none",backgroundColor:"#1e293b",color:"#e2e8f0",padding:"6px 10px",borderRadius:"6px",fontSize:"13px",lineHeight:"1.4",fontWeight:"500",border:"1px solid #334155",zIndex:"9999",pointerEvents:"none",whiteSpace:"nowrap",boxShadow:"0 4px 6px -1px rgba(0, 0, 0, 0.3), 0 2px 4px -1px rgba(0, 0, 0, 0.15)",fontFamily:this.context.getOptions().fontFamily||"sans-serif",transition:"opacity 0.15s ease-in-out, transform 0.15s ease-in-out",opacity:"0",transform:"translateX(-5px)"}),document.body.appendChild(this.tooltipElement)}destroy(){this.tooltipElement&&this.tooltipElement.parentNode&&this.tooltipElement.parentNode.removeChild(this.tooltipElement),this.tooltipElement=null}showTooltip(e,t){if(!this.tooltipElement)return;this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=null);const i=e.getBoundingClientRect();this.tooltipElement.textContent=t,this.tooltipElement.style.display="block";const s=this.tooltipElement.getBoundingClientRect(),o=i.top+(i.height-s.height)/2,n=i.right+10;this.tooltipElement.style.top=`${o}px`,this.tooltipElement.style.left=`${n}px`,requestAnimationFrame(()=>{this.tooltipElement&&(this.tooltipElement.style.opacity="1",this.tooltipElement.style.transform="translateX(0)")})}hideTooltip(){this.tooltipElement&&(this.tooltipElement.style.opacity="0",this.tooltipElement.style.transform="translateX(-5px)",this.hideTimeout&&clearTimeout(this.hideTimeout),this.hideTimeout=setTimeout(()=>{this.tooltipElement&&(this.tooltipElement.style.display="none"),this.hideTimeout=null},150))}register(e){if(this.plugins.has(e.id)){console.warn(`Plugin with id ${e.id} is already registered.`);return}this.plugins.set(e.id,e),e.init(this.context),this.addButton(e)}unregister(e){const t=this.plugins.get(e);t&&(this.activePluginId===e&&this.deactivatePlugin(),t.destroy?.(),this.plugins.delete(e),this.removeButton(e))}activatePlugin(e){if(this.activePluginId===e){this.deactivatePlugin();return}this.activePluginId&&this.deactivatePlugin();const t=this.plugins.get(e);t&&(this.activePluginId=e,this.setButtonActive(e,!0),t.activate?.())}deactivatePlugin(){this.activePluginId&&(this.plugins.get(this.activePluginId)?.deactivate?.(),this.setButtonActive(this.activePluginId,!1),this.activePluginId=null)}renderToolbar(){this.toolbarContainer.innerHTML="",this.toolbarContainer.classList.add("qfchart-toolbar"),this.toolbarContainer.style.display="flex",this.toolbarContainer.style.flexDirection="column",this.toolbarContainer.style.width="40px",this.toolbarContainer.style.backgroundColor=this.context.getOptions().backgroundColor||"#1e293b",this.toolbarContainer.style.borderRight="1px solid #334155",this.toolbarContainer.style.padding="5px",this.toolbarContainer.style.boxSizing="border-box",this.toolbarContainer.style.gap="5px",this.toolbarContainer.style.flexShrink="0"}addButton(e){const t=document.createElement("button");t.id=`qfchart-plugin-btn-${e.id}`,t.style.width="30px",t.style.height="30px",t.style.padding="4px",t.style.border="1px solid transparent",t.style.borderRadius="4px",t.style.backgroundColor="transparent",t.style.cursor="pointer",t.style.color=this.context.getOptions().fontColor||"#cbd5e1",t.style.display="flex",t.style.alignItems="center",t.style.justifyContent="center",e.icon?t.innerHTML=e.icon:t.innerText=(e.name||e.id).substring(0,2).toUpperCase(),t.addEventListener("mouseenter",()=>{this.activePluginId!==e.id&&(t.style.backgroundColor="rgba(255, 255, 255, 0.1)"),this.showTooltip(t,e.name||e.id)}),t.addEventListener("mouseleave",()=>{this.activePluginId!==e.id&&(t.style.backgroundColor="transparent"),this.hideTooltip()}),t.onclick=()=>this.activatePlugin(e.id),this.toolbarContainer.appendChild(t)}removeButton(e){const t=this.toolbarContainer.querySelector(`#qfchart-plugin-btn-${e}`);t&&t.remove()}setButtonActive(e,t){const i=this.toolbarContainer.querySelector(`#qfchart-plugin-btn-${e}`);i&&(t?(i.style.backgroundColor="#2563eb",i.style.color="#ffffff"):(i.style.backgroundColor="transparent",i.style.color=this.context.getOptions().fontColor||"#cbd5e1"))}}var It=Object.defineProperty,Mt=(r,e,t)=>e in r?It(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,U=(r,e,t)=>(Mt(r,typeof e!="symbol"?e+"":e,t),t);class At{constructor(e){U(this,"context"),U(this,"isEditing",!1),U(this,"currentDrawing",null),U(this,"editingPointIndex",null),U(this,"zr"),U(this,"editGroup",null),U(this,"editLine",null),U(this,"editStartPoint",null),U(this,"editEndPoint",null),U(this,"isMovingShape",!1),U(this,"dragStart",null),U(this,"initialPixelPoints",[]),U(this,"onDrawingMouseDown",t=>{if(this.isEditing)return;const i=this.context.getDrawing(t.id);i&&(this.isEditing=!0,this.isMovingShape=!0,this.currentDrawing=JSON.parse(JSON.stringify(i)),this.dragStart={x:t.x,y:t.y},this.initialPixelPoints=i.points.map(s=>{const o=this.context.coordinateConversion.dataToPixel(s);return o?{x:o.x,y:o.y}:{x:0,y:0}}),this.context.lockChart(),this.createEditGraphic(),this.zr.on("mousemove",this.onMouseMove),this.zr.on("mouseup",this.onMouseUp))}),U(this,"onPointMouseDown",t=>{if(this.isEditing)return;const i=this.context.getDrawing(t.id);i&&(this.isEditing=!0,this.currentDrawing=JSON.parse(JSON.stringify(i)),this.editingPointIndex=t.pointIndex,this.context.lockChart(),this.createEditGraphic(),this.zr.on("mousemove",this.onMouseMove),this.zr.on("mouseup",this.onMouseUp))}),U(this,"onMouseMove",t=>{if(!this.isEditing||!this.currentDrawing)return;const i=t.offsetX,s=t.offsetY;if(this.isMovingShape&&this.dragStart){const o=i-this.dragStart.x,n=s-this.dragStart.y,p={x:this.initialPixelPoints[0].x+o,y:this.initialPixelPoints[0].y+n},d={x:this.initialPixelPoints[1].x+o,y:this.initialPixelPoints[1].y+n};this.editLine.setShape({x1:p.x,y1:p.y,x2:d.x,y2:d.y}),this.editStartPoint.setShape({cx:p.x,cy:p.y}),this.editEndPoint.setShape({cx:d.x,cy:d.y})}else this.editingPointIndex!==null&&(this.editingPointIndex===0?(this.editLine.setShape({x1:i,y1:s}),this.editStartPoint.setShape({cx:i,cy:s})):(this.editLine.setShape({x2:i,y2:s}),this.editEndPoint.setShape({cx:i,cy:s})))}),U(this,"onMouseUp",t=>{this.isEditing&&this.finishEditing(t.offsetX,t.offsetY)}),this.context=e,this.zr=this.context.getChart().getZr(),this.bindEvents()}bindEvents(){this.context.events.on("drawing:point:mousedown",this.onPointMouseDown),this.context.events.on("drawing:mousedown",this.onDrawingMouseDown)}createEditGraphic(){if(!this.currentDrawing)return;this.editGroup=new j.graphic.Group;const e=this.currentDrawing.points[0],t=this.currentDrawing.points[1],i=this.context.coordinateConversion.dataToPixel(e),s=this.context.coordinateConversion.dataToPixel(t);!i||!s||(this.editLine=new j.graphic.Line({shape:{x1:i.x,y1:i.y,x2:s.x,y2:s.y},style:{stroke:this.currentDrawing.style?.color||"#3b82f6",lineWidth:this.currentDrawing.style?.lineWidth||2,lineDash:[4,4]},silent:!0}),this.editStartPoint=new j.graphic.Circle({shape:{cx:i.x,cy:i.y,r:5},style:{fill:"#fff",stroke:"#3b82f6",lineWidth:2},z:1e3}),this.editEndPoint=new j.graphic.Circle({shape:{cx:s.x,cy:s.y,r:5},style:{fill:"#fff",stroke:"#3b82f6",lineWidth:2},z:1e3}),this.editGroup.add(this.editLine),this.editGroup.add(this.editStartPoint),this.editGroup.add(this.editEndPoint),this.zr.add(this.editGroup))}finishEditing(e,t){if(this.currentDrawing){if(this.isMovingShape&&this.dragStart){const i=e-this.dragStart.x,s=t-this.dragStart.y,o=this.initialPixelPoints.map((n,p)=>{const d=n.x+i,l=n.y+s;return this.context.coordinateConversion.pixelToData({x:d,y:l})});o.every(n=>n!==null)&&o[0]&&o[1]&&(this.currentDrawing.points[0]=o[0],this.currentDrawing.points[1]=o[1],o[0].paneIndex!==void 0&&(this.currentDrawing.paneIndex=o[0].paneIndex),this.context.updateDrawing(this.currentDrawing))}else if(this.editingPointIndex!==null){const i=this.context.coordinateConversion.pixelToData({x:e,y:t});i&&(this.currentDrawing.points[this.editingPointIndex]=i,this.editingPointIndex===0&&i.paneIndex!==void 0&&(this.currentDrawing.paneIndex=i.paneIndex),this.context.updateDrawing(this.currentDrawing))}this.isEditing=!1,this.isMovingShape=!1,this.dragStart=null,this.initialPixelPoints=[],this.currentDrawing=null,this.editingPointIndex=null,this.editGroup&&(this.zr.remove(this.editGroup),this.editGroup=null),this.zr.off("mousemove",this.onMouseMove),this.zr.off("mouseup",this.onMouseUp),this.context.unlockChart()}}}var Dt=Object.defineProperty,Et=(r,e,t)=>e in r?Dt(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,zt=(r,e,t)=>(Et(r,typeof e!="symbol"?e+"":e,t),t);class Lt{constructor(){zt(this,"handlers",new Map)}on(e,t){this.handlers.has(e)||this.handlers.set(e,new Set),this.handlers.get(e).add(t)}off(e,t){const i=this.handlers.get(e);i&&i.delete(t)}emit(e,t){const i=this.handlers.get(e);i&&i.forEach(s=>{try{s(t)}catch(o){console.error(`Error in EventBus handler for ${e}:`,o)}})}clear(){this.handlers.clear()}}var Tt=Object.defineProperty,Ft=(r,e,t)=>e in r?Tt(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,L=(r,e,t)=>(Ft(r,typeof e!="symbol"?e+"":e,t),t);class Nt{constructor(e,t={}){L(this,"chart"),L(this,"options"),L(this,"marketData",[]),L(this,"indicators",new Map),L(this,"timeToIndex",new Map),L(this,"pluginManager"),L(this,"drawingEditor"),L(this,"events",new Lt),L(this,"isMainCollapsed",!1),L(this,"maximizedPaneId",null),L(this,"countdownInterval",null),L(this,"selectedDrawingId",null),L(this,"drawings",[]),L(this,"coordinateConversion",{pixelToData:o=>{const n=this.chart.getOption();if(!n||!n.grid)return null;const p=n.grid.length;for(let d=0;d<p;d++)if(this.chart.containPixel({gridIndex:d},[o.x,o.y])){this.chart.convertFromPixel({seriesIndex:d},[o.x,o.y]);const l=this.chart.convertFromPixel({gridIndex:d},[o.x,o.y]);if(l)return{timeIndex:Math.round(l[0]),value:l[1],paneIndex:d}}return null},dataToPixel:o=>{const n=o.paneIndex||0,p=this.chart.convertToPixel({gridIndex:n},[o.timeIndex,o.value]);return p?{x:p[0],y:p[1]}:null}}),L(this,"upColor","#00da3c"),L(this,"downColor","#ec0000"),L(this,"defaultPadding",0),L(this,"padding"),L(this,"dataIndexOffset",0),L(this,"rootContainer"),L(this,"layoutContainer"),L(this,"toolbarContainer"),L(this,"leftSidebar"),L(this,"rightSidebar"),L(this,"chartContainer"),L(this,"onKeyDown",o=>{(o.key==="Delete"||o.key==="Backspace")&&this.selectedDrawingId&&(this.removeDrawing(this.selectedDrawingId),this.selectedDrawingId=null,this.render())}),L(this,"onFullscreenChange",()=>{this.render()}),L(this,"isLocked",!1),L(this,"lockedState",null),this.rootContainer=e,this.options={title:"Market",height:"600px",backgroundColor:"#1e293b",upColor:"#00da3c",downColor:"#ec0000",fontColor:"#cbd5e1",fontFamily:"sans-serif",padding:.01,dataZoom:{visible:!0,position:"top",height:6},layout:{mainPaneHeight:"50%",gap:13},watermark:!0,...t},this.options.upColor&&(this.upColor=this.options.upColor),this.options.downColor&&(this.downColor=this.options.downColor),this.padding=this.options.padding!==void 0?this.options.padding:this.defaultPadding,this.options.height&&(typeof this.options.height=="number"?this.rootContainer.style.height=`${this.options.height}px`:this.rootContainer.style.height=this.options.height),this.rootContainer.innerHTML="",this.layoutContainer=document.createElement("div"),this.layoutContainer.style.display="flex",this.layoutContainer.style.width="100%",this.layoutContainer.style.height="100%",this.layoutContainer.style.overflow="hidden",this.rootContainer.appendChild(this.layoutContainer),this.leftSidebar=document.createElement("div"),this.leftSidebar.style.display="none",this.leftSidebar.style.width="250px",this.leftSidebar.style.flexShrink="0",this.leftSidebar.style.overflowY="auto",this.leftSidebar.style.backgroundColor=this.options.backgroundColor||"#1e293b",this.leftSidebar.style.borderRight="1px solid #334155",this.leftSidebar.style.padding="10px",this.leftSidebar.style.boxSizing="border-box",this.leftSidebar.style.color="#cbd5e1",this.leftSidebar.style.fontSize="12px",this.leftSidebar.style.fontFamily=this.options.fontFamily||"sans-serif",this.layoutContainer.appendChild(this.leftSidebar),this.toolbarContainer=document.createElement("div"),this.layoutContainer.appendChild(this.toolbarContainer),this.chartContainer=document.createElement("div"),this.chartContainer.style.flexGrow="1",this.chartContainer.style.height="100%",this.chartContainer.style.overflow="hidden",this.layoutContainer.appendChild(this.chartContainer),this.rightSidebar=document.createElement("div"),this.rightSidebar.style.display="none",this.rightSidebar.style.width="250px",this.rightSidebar.style.flexShrink="0",this.rightSidebar.style.overflowY="auto",this.rightSidebar.style.backgroundColor=this.options.backgroundColor||"#1e293b",this.rightSidebar.style.borderLeft="1px solid #334155",this.rightSidebar.style.padding="10px",this.rightSidebar.style.boxSizing="border-box",this.rightSidebar.style.color="#cbd5e1",this.rightSidebar.style.fontSize="12px",this.rightSidebar.style.fontFamily=this.options.fontFamily||"sans-serif",this.layoutContainer.appendChild(this.rightSidebar),this.chart=j.init(this.chartContainer),this.pluginManager=new Pt(this,this.toolbarContainer),this.drawingEditor=new At(this),this.chart.on("dataZoom",o=>{this.events.emit("chart:dataZoom",o);const n=this.options.databox?.triggerOn,p=this.options.databox?.position;n==="click"&&p==="floating"&&this.chart.dispatchAction({type:"hideTip"})}),this.chart.on("finished",o=>this.events.emit("chart:updated",o)),this.chart.getZr().on("mousedown",o=>this.events.emit("mouse:down",o)),this.chart.getZr().on("mousemove",o=>this.events.emit("mouse:move",o)),this.chart.getZr().on("mouseup",o=>this.events.emit("mouse:up",o)),this.chart.getZr().on("click",o=>this.events.emit("mouse:click",o));const i=this.chart.getZr(),s=i.setCursorStyle;i.setCursorStyle=function(o){o==="grab"&&(o="crosshair"),s.call(this,o)},this.bindDrawingEvents(),window.addEventListener("resize",this.resize.bind(this)),document.addEventListener("fullscreenchange",this.onFullscreenChange),document.addEventListener("keydown",this.onKeyDown)}bindDrawingEvents(){let e=null;const t=i=>{if(!i||i.componentType!=="series"||!i.seriesName?.startsWith("drawings"))return null;i.seriesIndex;const s=i.seriesName.match(/drawings-pane-(\d+)/);if(!s)return null;const o=parseInt(s[1]),n=this.drawings.filter(d=>(d.paneIndex||0)===o)[i.dataIndex];if(!n)return null;const p=i.event?.target?.name;return{drawing:n,targetName:p,paneIdx:o}};this.chart.on("mouseover",i=>{const s=t(i);if(!s)return;const o=i.event?.target?.parent;if(o){const n=s.drawing.id===this.selectedDrawingId;e&&(clearTimeout(e),e=null),n||o.children().forEach(p=>{p.name&&p.name.startsWith("point")&&p.attr("style",{opacity:1})})}if(s.targetName==="line")this.events.emit("drawing:hover",{id:s.drawing.id,type:s.drawing.type}),this.chart.getZr().setCursorStyle("move");else if(s.targetName?.startsWith("point")){const n=s.targetName==="point-start"?0:1;this.events.emit("drawing:point:hover",{id:s.drawing.id,pointIndex:n}),this.chart.getZr().setCursorStyle("pointer")}}),this.chart.on("mouseout",i=>{const s=t(i);if(!s)return;const o=i.event?.target?.parent;if(s.drawing.id!==this.selectedDrawingId){if(e=setTimeout(()=>{if(o){if(this.selectedDrawingId===s.drawing.id)return;o.children().forEach(n=>{n.name&&n.name.startsWith("point")&&n.attr("style",{opacity:0})})}},50),s.targetName==="line")this.events.emit("drawing:mouseout",{id:s.drawing.id});else if(s.targetName?.startsWith("point")){const n=s.targetName==="point-start"?0:1;this.events.emit("drawing:point:mouseout",{id:s.drawing.id,pointIndex:n})}this.chart.getZr().setCursorStyle("default")}}),this.chart.on("mousedown",i=>{const s=t(i);if(!s)return;const o=i.event?.event||i.event,n=o?.offsetX,p=o?.offsetY;if(s.targetName==="line")this.events.emit("drawing:mousedown",{id:s.drawing.id,x:n,y:p});else if(s.targetName?.startsWith("point")){const d=s.targetName==="point-start"?0:1;this.events.emit("drawing:point:mousedown",{id:s.drawing.id,pointIndex:d,x:n,y:p})}}),this.chart.on("click",i=>{const s=t(i);if(s){if(this.selectedDrawingId!==s.drawing.id&&(this.selectedDrawingId=s.drawing.id,this.events.emit("drawing:selected",{id:s.drawing.id}),this.render()),s.targetName==="line")this.events.emit("drawing:click",{id:s.drawing.id});else if(s.targetName?.startsWith("point")){const o=s.targetName==="point-start"?0:1;this.events.emit("drawing:point:click",{id:s.drawing.id,pointIndex:o})}}}),this.chart.getZr().on("click",i=>{i.target||this.selectedDrawingId&&(this.events.emit("drawing:deselected",{id:this.selectedDrawingId}),this.selectedDrawingId=null,this.render())})}getChart(){return this.chart}getMarketData(){return this.marketData}getTimeToIndex(){return this.timeToIndex}getOptions(){return this.options}disableTools(){this.pluginManager.deactivatePlugin()}registerPlugin(e){this.pluginManager.register(e)}addDrawing(e){this.drawings.push(e),this.render()}removeDrawing(e){const t=this.drawings.findIndex(i=>i.id===e);if(t!==-1){const i=this.drawings[t];this.drawings.splice(t,1),this.events.emit("drawing:deleted",{id:i.id}),this.render()}}getDrawing(e){return this.drawings.find(t=>t.id===e)}updateDrawing(e){const t=this.drawings.findIndex(i=>i.id===e.id);t!==-1&&(this.drawings[t]=e,this.render())}lockChart(){if(this.isLocked)return;this.isLocked=!0;const e=this.chart.getOption();this.chart.setOption({dataZoom:e.dataZoom.map(t=>({...t,disabled:!0})),tooltip:{show:!1}})}unlockChart(){if(!this.isLocked)return;this.isLocked=!1;const e=this.chart.getOption();(this.options.dataZoom||{}).visible,e.dataZoom&&this.chart.setOption({dataZoom:e.dataZoom.map(t=>({...t,disabled:!1})),tooltip:{show:!0}})}setZoom(e,t){this.chart.dispatchAction({type:"dataZoom",start:e,end:t})}setMarketData(e){this.marketData=e,this.rebuildTimeIndex(),this.render()}updateData(e){if(e.length===0)return;const t=new Map;this.marketData.forEach(f=>{t.set(f.time,f)}),e.forEach(f=>{t.has(f.time),t.set(f.time,f)}),this.marketData=Array.from(t.values()).sort((f,v)=>f.time-v.time),this.rebuildTimeIndex();const i=this.dataIndexOffset,s=it.buildCandlestickSeries(this.marketData,this.options),o={value:[NaN,NaN,NaN,NaN],itemStyle:{opacity:0}},n=[...Array(i).fill(o),...s.data,...Array(i).fill(o)],p=[...Array(i).fill(""),...this.marketData.map(f=>new Date(f.time).toLocaleString()),...Array(i).fill("")],d=this.chart.getOption(),l=ft.calculate(this.chart.getHeight(),this.indicators,this.options,this.isMainCollapsed,this.maximizedPaneId,this.marketData),k=[...Array(i).fill(null),...this.marketData,...Array(i).fill(null)],{series:y,barColors:b}=it.buildIndicatorSeries(this.indicators,this.timeToIndex,l.paneLayout,p.length,i,k,l.overlayYAxisMap,l.separatePaneYAxisOffset),P=n.map((f,v)=>b[v]?{value:f.value||f,itemStyle:{color:b[v],color0:b[v],borderColor:b[v],borderColor0:b[v]}}:f),u={xAxis:d.xAxis.map((f,v)=>({data:p})),series:[{data:P,markLine:s.markLine},...y.map(f=>{const v={data:f.data};return f.renderItem&&(v.renderItem=f.renderItem),v})]};this.chart.setOption(u,{notMerge:!1}),this.startCountdown()}startCountdown(){if(this.stopCountdown(),!this.options.lastPriceLine?.showCountdown||!this.options.interval||this.marketData.length===0)return;const e=()=>{if(this.marketData.length===0)return;const t=this.marketData[this.marketData.length-1].time+(this.options.interval||0),i=Date.now(),s=t-i;if(s<=0)return;const o=Math.abs(s),n=Math.floor(o/36e5),p=Math.floor(o%36e5/6e4),d=Math.floor(o%6e4/1e3),l=`${n>0?n.toString().padStart(2,"0")+":":""}${p.toString().padStart(2,"0")}:${d.toString().padStart(2,"0")}`,k=this.chart.getOption();if(!k||!k.series)return;const y=k.series.findIndex(E=>E.type==="candlestick");if(y===-1)return;const b=k.series[y];if(!b.markLine||!b.markLine.data||!b.markLine.data[0])return;const P=b.markLine.data[0];P.label.formatter;const u=P.yAxis;let f="";if(this.options.yAxisLabelFormatter)f=this.options.yAxisLabelFormatter(u);else{const E=this.options.yAxisDecimalPlaces!==void 0?this.options.yAxisDecimalPlaces:2;f=typeof u=="number"?u.toFixed(E):u}const v=`${f}
|
|
37
|
-
${l}`;this.chart.setOption({series:[{name:this.options.title||"Market",markLine:{data:[{...P,label:{...P.label,formatter:v}}]}}]})};e(),this.countdownInterval=setInterval(e,1e3)}stopCountdown(){this.countdownInterval&&(clearInterval(this.countdownInterval),this.countdownInterval=null)}addIndicator(e,t,i={}){const s=i.overlay!==void 0?i.overlay:i.isOverlay??!1;let o=0;if(!s){let p=0;this.indicators.forEach(d=>{d.paneIndex>p&&(p=d.paneIndex)}),o=p+1}const n=new bt(e,t,o,{height:i.height,collapsed:!1,titleColor:i.titleColor,controls:i.controls});return this.indicators.set(e,n),this.render(),n}setIndicator(e,t,i=!1){this.addIndicator(e,{[e]:t},{overlay:i})}removeIndicator(e){this.indicators.delete(e),this.render()}toggleIndicator(e,t="collapse"){if(t==="fullscreen"){document.fullscreenElement?document.exitFullscreen():this.rootContainer.requestFullscreen();return}if(t==="maximize"){this.maximizedPaneId===e?this.maximizedPaneId=null:this.maximizedPaneId=e,this.render();return}if(e==="main"){this.isMainCollapsed=!this.isMainCollapsed,this.render();return}const i=this.indicators.get(e);i&&(i.toggleCollapse(),this.render())}resize(){this.chart.resize()}destroy(){this.stopCountdown(),window.removeEventListener("resize",this.resize.bind(this)),document.removeEventListener("fullscreenchange",this.onFullscreenChange),document.removeEventListener("keydown",this.onKeyDown),this.pluginManager.deactivatePlugin(),this.pluginManager.destroy(),this.chart.dispose()}rebuildTimeIndex(){this.timeToIndex.clear(),this.marketData.forEach((i,s)=>{this.timeToIndex.set(i.time,s)});const e=this.marketData.length,t=Math.ceil(e*this.padding);this.dataIndexOffset=t}render(){if(this.marketData.length===0)return;let e=null;try{const x=this.chart.getOption();if(x&&x.dataZoom&&x.dataZoom.length>0){const M=x.dataZoom.find(w=>w.type==="slider"||w.type==="inside");M&&(e={start:M.start,end:M.end})}}catch{}const t=this.options.databox?.position,i=this.leftSidebar.style.display,s=this.rightSidebar.style.display,o=t==="left"?"block":"none",n=t==="right"?"block":"none";(i!==o||s!==n)&&(this.leftSidebar.style.display=o,this.rightSidebar.style.display=n,this.chart.resize());const p=this.dataIndexOffset,d=[...Array(p).fill(""),...this.marketData.map(x=>new Date(x.time).toLocaleString()),...Array(p).fill("")],l=ft.calculate(this.chart.getHeight(),this.indicators,this.options,this.isMainCollapsed,this.maximizedPaneId,this.marketData);if(!e&&l.dataZoom&&this.marketData.length>0){const x=this.marketData.length,M=d.length,w=p/M,T=x/M;l.dataZoom.forEach(I=>{if(I.start!==void 0){const c=I.start/100,a=w+c*T;I.start=a*100}if(I.end!==void 0){const c=I.end/100,a=w+c*T;I.end=a*100}})}e&&l.dataZoom&&l.dataZoom.forEach(x=>{x.start=e.start,x.end=e.end}),l.xAxis.forEach(x=>{x.data=d,x.boundaryGap=!1});const k=it.buildCandlestickSeries(this.marketData,this.options),y={value:[NaN,NaN,NaN,NaN],itemStyle:{opacity:0}};k.data=[...Array(p).fill(y),...k.data,...Array(p).fill(y)];const b=[...Array(p).fill(null),...this.marketData,...Array(p).fill(null)],{series:P,barColors:u}=it.buildIndicatorSeries(this.indicators,this.timeToIndex,l.paneLayout,d.length,p,b,l.overlayYAxisMap,l.separatePaneYAxisOffset);k.data=k.data.map((x,M)=>u[M]?{value:x.value||x,itemStyle:{color:u[M],color0:u[M],borderColor:u[M],borderColor0:u[M]}}:x);const f=wt.build(l,this.options,this.toggleIndicator.bind(this),this.isMainCollapsed,this.maximizedPaneId),v=new Map;this.drawings.forEach(x=>{const M=x.paneIndex||0;v.has(M)||v.set(M,[]),v.get(M).push(x)});const E=[];v.forEach((x,M)=>{E.push({type:"custom",name:`drawings-pane-${M}`,xAxisIndex:M,yAxisIndex:M,clip:!0,renderItem:(w,T)=>{const I=x[w.dataIndex];if(!I)return;const c=I.points[0],a=I.points[1];if(!c||!a)return;const g=T.coord([c.timeIndex,c.value]),m=T.coord([a.timeIndex,a.value]),S=I.id===this.selectedDrawingId;if(I.type==="line")return{type:"group",children:[{type:"line",name:"line",shape:{x1:g[0],y1:g[1],x2:m[0],y2:m[1]},style:{stroke:I.style?.color||"#3b82f6",lineWidth:I.style?.lineWidth||2}},{type:"circle",name:"point-start",shape:{cx:g[0],cy:g[1],r:4},style:{fill:"#fff",stroke:I.style?.color||"#3b82f6",lineWidth:1,opacity:S?1:0}},{type:"circle",name:"point-end",shape:{cx:m[0],cy:m[1],r:4},style:{fill:"#fff",stroke:I.style?.color||"#3b82f6",lineWidth:1,opacity:S?1:0}}]};if(I.type==="fibonacci"){const F=g[0],z=g[1],G=m[0],N=m[1],H=Math.min(F,G),X=Math.max(F,G),_=X-H,Y=N-z,h=[0,.236,.382,.5,.618,.786,1],C=["#787b86","#f44336","#ff9800","#4caf50","#2196f3","#00bcd4","#787b86"],A=[];A.push({type:"line",name:"line",shape:{x1:F,y1:z,x2:G,y2:N},style:{stroke:"#999",lineWidth:1,lineDash:[4,4]}}),A.push({type:"circle",name:"point-start",shape:{cx:F,cy:z,r:4},style:{fill:"#fff",stroke:I.style?.color||"#3b82f6",lineWidth:1,opacity:S?1:0},z:100}),A.push({type:"circle",name:"point-end",shape:{cx:G,cy:N,r:4},style:{fill:"#fff",stroke:I.style?.color||"#3b82f6",lineWidth:1,opacity:S?1:0},z:100}),h.forEach((D,O)=>{const q=N-Y*D,W=C[O%C.length];A.push({type:"line",name:"fib-line",shape:{x1:H,y1:q,x2:X,y2:q},style:{stroke:W,lineWidth:1},silent:!0});const B=I.points[0].value,tt=I.points[1].value,st=tt-B,J=tt-st*D;if(A.push({type:"text",style:{text:`${D} (${J.toFixed(2)})`,x:H+5,y:q-10,fill:W,fontSize:10},silent:!0}),O<h.length-1){const ot=h[O+1],dt=N-Y*ot,ut=Math.abs(dt-q),gt=Math.min(q,dt);A.push({type:"rect",shape:{x:H,y:gt,width:_,height:ut},style:{fill:C[(O+1)%C.length],opacity:.1},silent:!0})}});const $=[],R=[];return h.forEach((D,O)=>{const q=N-Y*D,W=C[O%C.length];R.push({type:"line",shape:{x1:H,y1:q,x2:X,y2:q},style:{stroke:W,lineWidth:1},silent:!0});const B=I.points[0].value,tt=I.points[1].value,st=tt-B,J=tt-st*D;if(R.push({type:"text",style:{text:`${D} (${J.toFixed(2)})`,x:H+5,y:q-10,fill:W,fontSize:10},silent:!0}),O<h.length-1){const ot=h[O+1],dt=N-Y*ot,ut=Math.abs(dt-q),gt=Math.min(q,dt);$.push({type:"rect",name:"line",shape:{x:H,y:gt,width:_,height:ut},style:{fill:C[(O+1)%C.length],opacity:.1}})}}),{type:"group",children:[...$,...R,{type:"line",name:"line",shape:{x1:F,y1:z,x2:G,y2:N},style:{stroke:"#999",lineWidth:1,lineDash:[4,4]}},{type:"circle",name:"point-start",shape:{cx:F,cy:z,r:4},style:{fill:"#fff",stroke:I.style?.color||"#3b82f6",lineWidth:1,opacity:S?1:0},z:100},{type:"circle",name:"point-end",shape:{cx:G,cy:N,r:4},style:{fill:"#fff",stroke:I.style?.color||"#3b82f6",lineWidth:1,opacity:S?1:0},z:100}]}}},data:x.map(w=>[w.points[0].timeIndex,w.points[0].value,w.points[1].timeIndex,w.points[1].value]),z:100,silent:!1})});const V=x=>{const M=Ct.format(x,this.options),w=this.options.databox?.position;return w==="left"?(this.leftSidebar.innerHTML=M,""):w==="right"?(this.rightSidebar.innerHTML=M,""):this.options.databox?`<div style="min-width: 200px;">${M}</div>`:""},Z={backgroundColor:this.options.backgroundColor,animation:!1,legend:{show:!1},tooltip:{show:!0,showContent:!!this.options.databox,trigger:"axis",triggerOn:this.options.databox?.triggerOn??"mousemove",axisPointer:{type:"cross",label:{backgroundColor:"#475569"}},backgroundColor:"rgba(30, 41, 59, 0.9)",borderWidth:1,borderColor:"#334155",padding:10,textStyle:{color:"#fff",fontFamily:this.options.fontFamily||"sans-serif"},formatter:V,extraCssText:t!=="floating"&&t!==void 0?"display: none !important;":void 0,position:(x,M,w,T,I)=>{if(this.options.databox?.position==="floating"){const c={top:10};return c[["left","right"][+(x[0]<I.viewSize[0]/2)]]=30,c}return null}},axisPointer:{link:{xAxisIndex:"all"},label:{backgroundColor:"#475569"}},graphic:f,grid:l.grid,xAxis:l.xAxis,yAxis:l.yAxis,dataZoom:l.dataZoom,series:[k,...P,...E]};this.chart.setOption(Z,!0)}}var Zt=Object.defineProperty,$t=(r,e,t)=>e in r?Zt(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,ht=(r,e,t)=>($t(r,typeof e!="symbol"?e+"":e,t),t);class ct{constructor(e){ht(this,"id"),ht(this,"name"),ht(this,"icon"),ht(this,"context"),ht(this,"eventListeners",[]),this.id=e.id,this.name=e.name,this.icon=e.icon}init(e){this.context=e,this.onInit()}onInit(){}activate(){this.onActivate(),this.context.events.emit("plugin:activated",this.id)}onActivate(){}deactivate(){this.onDeactivate(),this.context.events.emit("plugin:deactivated",this.id)}onDeactivate(){}destroy(){this.removeAllListeners(),this.onDestroy()}onDestroy(){}on(e,t){this.context.events.on(e,t),this.eventListeners.push({event:e,handler:t})}off(e,t){this.context.events.off(e,t),this.eventListeners=this.eventListeners.filter(i=>i.event!==e||i.handler!==t)}removeAllListeners(){this.eventListeners.forEach(({event:e,handler:t})=>{this.context.events.off(e,t)}),this.eventListeners=[]}get chart(){return this.context.getChart()}get marketData(){return this.context.getMarketData()}}var Gt=Object.defineProperty,Ot=(r,e,t)=>e in r?Gt(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,Q=(r,e,t)=>(Ot(r,typeof e!="symbol"?e+"":e,t),t);class Wt extends ct{constructor(e){super({id:"measure",name:e?.name||"Measure",icon:e?.icon||'<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M160-240q-33 0-56.5-23.5T80-320v-320q0-33 23.5-56.5T160-720h640q33 0 56.5 23.5T880-640v320q0 33-23.5 56.5T800-240H160Zm0-80h640v-320H680v160h-80v-160h-80v160h-80v-160h-80v160h-80v-160H160v320Zm120-160h80-80Zm160 0h80-80Zm160 0h80-80Zm-120 0Z"/></svg>'}),Q(this,"zr"),Q(this,"state","idle"),Q(this,"startPoint",null),Q(this,"endPoint",null),Q(this,"group",null),Q(this,"rect",null),Q(this,"labelRect",null),Q(this,"labelText",null),Q(this,"lineV",null),Q(this,"lineH",null),Q(this,"arrowStart",null),Q(this,"arrowEnd",null),Q(this,"onMouseDown",()=>{this.state==="finished"&&this.removeGraphic()}),Q(this,"onChartInteraction",()=>{this.group&&this.removeGraphic()}),Q(this,"onClick",t=>{this.state==="idle"?(this.state="drawing",this.startPoint=[t.offsetX,t.offsetY],this.endPoint=[t.offsetX,t.offsetY],this.initGraphic(),this.updateGraphic()):this.state==="drawing"&&(this.state="finished",this.endPoint=[t.offsetX,t.offsetY],this.updateGraphic(),this.context.disableTools(),this.enableClearListeners())}),Q(this,"clearHandlers",{}),Q(this,"onMouseMove",t=>{this.state==="drawing"&&(this.endPoint=[t.offsetX,t.offsetY],this.updateGraphic())})}onInit(){this.zr=this.chart.getZr()}onActivate(){this.state="idle",this.chart.getZr().setCursorStyle("crosshair"),this.zr.on("click",this.onClick),this.zr.on("mousemove",this.onMouseMove)}onDeactivate(){this.state="idle",this.chart.getZr().setCursorStyle("default"),this.zr.off("click",this.onClick),this.zr.off("mousemove",this.onMouseMove),this.disableClearListeners(),this.state==="drawing"&&this.removeGraphic()}onDestroy(){this.removeGraphic()}enableClearListeners(){const e=()=>{this.removeGraphic()};setTimeout(()=>{this.zr.on("click",e)},10),this.zr.on("mousedown",this.onMouseDown),this.context.events.on("chart:dataZoom",this.onChartInteraction),this.clearHandlers={click:e,mousedown:this.onMouseDown,dataZoom:this.onChartInteraction}}disableClearListeners(){this.clearHandlers.click&&this.zr.off("click",this.clearHandlers.click),this.clearHandlers.mousedown&&this.zr.off("mousedown",this.clearHandlers.mousedown),this.clearHandlers.dataZoom&&this.context.events.off("chart:dataZoom",this.clearHandlers.dataZoom),this.clearHandlers={}}initGraphic(){this.group||(this.group=new j.graphic.Group,this.rect=new j.graphic.Rect({shape:{x:0,y:0,width:0,height:0},style:{fill:"rgba(0,0,0,0)",stroke:"transparent",lineWidth:0},z:100}),this.lineV=new j.graphic.Line({shape:{x1:0,y1:0,x2:0,y2:0},style:{stroke:"#fff",lineWidth:1,lineDash:[4,4]},z:101}),this.lineH=new j.graphic.Line({shape:{x1:0,y1:0,x2:0,y2:0},style:{stroke:"#fff",lineWidth:1,lineDash:[4,4]},z:101}),this.arrowStart=new j.graphic.Polygon({shape:{points:[[0,0],[-5,10],[5,10]]},style:{fill:"#fff"},z:102}),this.arrowEnd=new j.graphic.Polygon({shape:{points:[[0,0],[-5,-10],[5,-10]]},style:{fill:"#fff"},z:102}),this.labelRect=new j.graphic.Rect({shape:{x:0,y:0,width:0,height:0,r:4},style:{fill:"transparent",stroke:"transparent",lineWidth:0,shadowBlur:5,shadowColor:"rgba(0,0,0,0.3)"},z:102}),this.labelText=new j.graphic.Text({style:{x:0,y:0,text:"",fill:"#fff",font:"12px sans-serif",align:"center",verticalAlign:"middle"},z:103}),this.group.add(this.rect),this.group.add(this.lineV),this.group.add(this.lineH),this.group.add(this.arrowStart),this.group.add(this.arrowEnd),this.group.add(this.labelRect),this.group.add(this.labelText),this.zr.add(this.group))}removeGraphic(){this.group&&(this.zr.remove(this.group),this.group=null,this.disableClearListeners())}updateGraphic(){if(!this.startPoint||!this.endPoint||!this.group)return;const[e,t]=this.startPoint,[i,s]=this.endPoint,o=this.context.coordinateConversion.pixelToData({x:e,y:t}),n=this.context.coordinateConversion.pixelToData({x:i,y:s});if(!o||!n)return;const p=Math.round(o.timeIndex),d=Math.round(n.timeIndex),l=o.value,k=n.value,y=d-p,b=k-l,P=b/l*100,u=b>=0,f=u?"rgba(33, 150, 243, 0.2)":"rgba(236, 0, 0, 0.2)",v=u?"#2196F3":"#ec0000";this.rect.setShape({x:Math.min(e,i),y:Math.min(t,s),width:Math.abs(i-e),height:Math.abs(s-t)}),this.rect.setStyle({fill:f});const E=(e+i)/2,V=(t+s)/2;this.lineV.setShape({x1:E,y1:t,x2:E,y2:s}),this.lineV.setStyle({stroke:v}),this.lineH.setShape({x1:e,y1:V,x2:i,y2:V}),this.lineH.setStyle({stroke:v});const Z=Math.min(t,s),x=Math.max(t,s);this.arrowStart.setStyle({fill:"none"}),this.arrowEnd.setStyle({fill:"none"}),u?(this.arrowStart.setShape({points:[[E,Z],[E-4,Z+6],[E+4,Z+6]]}),this.arrowStart.setStyle({fill:v})):(this.arrowEnd.setShape({points:[[E,x],[E-4,x-6],[E+4,x-6]]}),this.arrowEnd.setStyle({fill:v}));const M=[`${b.toFixed(2)} (${P.toFixed(2)}%)`,`${y} bars, ${(y*0).toFixed(0)}d`].join(`
|
|
38
|
-
`),w=140,T=40,
|
|
36
|
+
</div>`}),d+="</div>"})}return d}}var kt=Object.defineProperty,Pt=(r,e,t)=>e in r?kt(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,rt=(r,e,t)=>(Pt(r,typeof e!="symbol"?e+"":e,t),t);class It{constructor(e,t){rt(this,"plugins",new Map),rt(this,"activePluginId",null),rt(this,"context"),rt(this,"toolbarContainer"),rt(this,"tooltipElement",null),rt(this,"hideTimeout",null),this.context=e,this.toolbarContainer=t,this.createTooltip(),this.renderToolbar()}createTooltip(){this.tooltipElement=document.createElement("div"),Object.assign(this.tooltipElement.style,{position:"fixed",display:"none",backgroundColor:"#1e293b",color:"#e2e8f0",padding:"6px 10px",borderRadius:"6px",fontSize:"13px",lineHeight:"1.4",fontWeight:"500",border:"1px solid #334155",zIndex:"9999",pointerEvents:"none",whiteSpace:"nowrap",boxShadow:"0 4px 6px -1px rgba(0, 0, 0, 0.3), 0 2px 4px -1px rgba(0, 0, 0, 0.15)",fontFamily:this.context.getOptions().fontFamily||"sans-serif",transition:"opacity 0.15s ease-in-out, transform 0.15s ease-in-out",opacity:"0",transform:"translateX(-5px)"}),document.body.appendChild(this.tooltipElement)}destroy(){this.tooltipElement&&this.tooltipElement.parentNode&&this.tooltipElement.parentNode.removeChild(this.tooltipElement),this.tooltipElement=null}showTooltip(e,t){if(!this.tooltipElement)return;this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=null);const i=e.getBoundingClientRect();this.tooltipElement.textContent=t,this.tooltipElement.style.display="block";const s=this.tooltipElement.getBoundingClientRect(),o=i.top+(i.height-s.height)/2,n=i.right+10;this.tooltipElement.style.top=`${o}px`,this.tooltipElement.style.left=`${n}px`,requestAnimationFrame(()=>{this.tooltipElement&&(this.tooltipElement.style.opacity="1",this.tooltipElement.style.transform="translateX(0)")})}hideTooltip(){this.tooltipElement&&(this.tooltipElement.style.opacity="0",this.tooltipElement.style.transform="translateX(-5px)",this.hideTimeout&&clearTimeout(this.hideTimeout),this.hideTimeout=setTimeout(()=>{this.tooltipElement&&(this.tooltipElement.style.display="none"),this.hideTimeout=null},150))}register(e){if(this.plugins.has(e.id)){console.warn(`Plugin with id ${e.id} is already registered.`);return}this.plugins.set(e.id,e),e.init(this.context),this.addButton(e)}unregister(e){const t=this.plugins.get(e);t&&(this.activePluginId===e&&this.deactivatePlugin(),t.destroy?.(),this.plugins.delete(e),this.removeButton(e))}activatePlugin(e){if(this.activePluginId===e){this.deactivatePlugin();return}this.activePluginId&&this.deactivatePlugin();const t=this.plugins.get(e);t&&(this.activePluginId=e,this.setButtonActive(e,!0),t.activate?.())}deactivatePlugin(){this.activePluginId&&(this.plugins.get(this.activePluginId)?.deactivate?.(),this.setButtonActive(this.activePluginId,!1),this.activePluginId=null)}renderToolbar(){this.toolbarContainer.innerHTML="",this.toolbarContainer.classList.add("qfchart-toolbar"),this.toolbarContainer.style.display="flex",this.toolbarContainer.style.flexDirection="column",this.toolbarContainer.style.width="40px",this.toolbarContainer.style.backgroundColor=this.context.getOptions().backgroundColor||"#1e293b",this.toolbarContainer.style.borderRight="1px solid #334155",this.toolbarContainer.style.padding="5px",this.toolbarContainer.style.boxSizing="border-box",this.toolbarContainer.style.gap="5px",this.toolbarContainer.style.flexShrink="0"}addButton(e){const t=document.createElement("button");t.id=`qfchart-plugin-btn-${e.id}`,t.style.width="30px",t.style.height="30px",t.style.padding="4px",t.style.border="1px solid transparent",t.style.borderRadius="4px",t.style.backgroundColor="transparent",t.style.cursor="pointer",t.style.color=this.context.getOptions().fontColor||"#cbd5e1",t.style.display="flex",t.style.alignItems="center",t.style.justifyContent="center",e.icon?t.innerHTML=e.icon:t.innerText=(e.name||e.id).substring(0,2).toUpperCase(),t.addEventListener("mouseenter",()=>{this.activePluginId!==e.id&&(t.style.backgroundColor="rgba(255, 255, 255, 0.1)"),this.showTooltip(t,e.name||e.id)}),t.addEventListener("mouseleave",()=>{this.activePluginId!==e.id&&(t.style.backgroundColor="transparent"),this.hideTooltip()}),t.onclick=()=>this.activatePlugin(e.id),this.toolbarContainer.appendChild(t)}removeButton(e){const t=this.toolbarContainer.querySelector(`#qfchart-plugin-btn-${e}`);t&&t.remove()}setButtonActive(e,t){const i=this.toolbarContainer.querySelector(`#qfchart-plugin-btn-${e}`);i&&(t?(i.style.backgroundColor="#2563eb",i.style.color="#ffffff"):(i.style.backgroundColor="transparent",i.style.color=this.context.getOptions().fontColor||"#cbd5e1"))}}var St=Object.defineProperty,At=(r,e,t)=>e in r?St(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,U=(r,e,t)=>(At(r,typeof e!="symbol"?e+"":e,t),t);class Mt{constructor(e){U(this,"context"),U(this,"isEditing",!1),U(this,"currentDrawing",null),U(this,"editingPointIndex",null),U(this,"zr"),U(this,"editGroup",null),U(this,"editLine",null),U(this,"editStartPoint",null),U(this,"editEndPoint",null),U(this,"isMovingShape",!1),U(this,"dragStart",null),U(this,"initialPixelPoints",[]),U(this,"onDrawingMouseDown",t=>{if(this.isEditing)return;const i=this.context.getDrawing(t.id);i&&(this.isEditing=!0,this.isMovingShape=!0,this.currentDrawing=JSON.parse(JSON.stringify(i)),this.dragStart={x:t.x,y:t.y},this.initialPixelPoints=i.points.map(s=>{const o=this.context.coordinateConversion.dataToPixel(s);return o?{x:o.x,y:o.y}:{x:0,y:0}}),this.context.lockChart(),this.createEditGraphic(),this.zr.on("mousemove",this.onMouseMove),this.zr.on("mouseup",this.onMouseUp))}),U(this,"onPointMouseDown",t=>{if(this.isEditing)return;const i=this.context.getDrawing(t.id);i&&(this.isEditing=!0,this.currentDrawing=JSON.parse(JSON.stringify(i)),this.editingPointIndex=t.pointIndex,this.context.lockChart(),this.createEditGraphic(),this.zr.on("mousemove",this.onMouseMove),this.zr.on("mouseup",this.onMouseUp))}),U(this,"onMouseMove",t=>{if(!this.isEditing||!this.currentDrawing)return;const i=t.offsetX,s=t.offsetY;if(this.isMovingShape&&this.dragStart){const o=i-this.dragStart.x,n=s-this.dragStart.y,p={x:this.initialPixelPoints[0].x+o,y:this.initialPixelPoints[0].y+n},d={x:this.initialPixelPoints[1].x+o,y:this.initialPixelPoints[1].y+n};this.editLine.setShape({x1:p.x,y1:p.y,x2:d.x,y2:d.y}),this.editStartPoint.setShape({cx:p.x,cy:p.y}),this.editEndPoint.setShape({cx:d.x,cy:d.y})}else this.editingPointIndex!==null&&(this.editingPointIndex===0?(this.editLine.setShape({x1:i,y1:s}),this.editStartPoint.setShape({cx:i,cy:s})):(this.editLine.setShape({x2:i,y2:s}),this.editEndPoint.setShape({cx:i,cy:s})))}),U(this,"onMouseUp",t=>{this.isEditing&&this.finishEditing(t.offsetX,t.offsetY)}),this.context=e,this.zr=this.context.getChart().getZr(),this.bindEvents()}bindEvents(){this.context.events.on("drawing:point:mousedown",this.onPointMouseDown),this.context.events.on("drawing:mousedown",this.onDrawingMouseDown)}createEditGraphic(){if(!this.currentDrawing)return;this.editGroup=new j.graphic.Group;const e=this.currentDrawing.points[0],t=this.currentDrawing.points[1],i=this.context.coordinateConversion.dataToPixel(e),s=this.context.coordinateConversion.dataToPixel(t);!i||!s||(this.editLine=new j.graphic.Line({shape:{x1:i.x,y1:i.y,x2:s.x,y2:s.y},style:{stroke:this.currentDrawing.style?.color||"#3b82f6",lineWidth:this.currentDrawing.style?.lineWidth||2,lineDash:[4,4]},silent:!0}),this.editStartPoint=new j.graphic.Circle({shape:{cx:i.x,cy:i.y,r:5},style:{fill:"#fff",stroke:"#3b82f6",lineWidth:2},z:1e3}),this.editEndPoint=new j.graphic.Circle({shape:{cx:s.x,cy:s.y,r:5},style:{fill:"#fff",stroke:"#3b82f6",lineWidth:2},z:1e3}),this.editGroup.add(this.editLine),this.editGroup.add(this.editStartPoint),this.editGroup.add(this.editEndPoint),this.zr.add(this.editGroup))}finishEditing(e,t){if(this.currentDrawing){if(this.isMovingShape&&this.dragStart){const i=e-this.dragStart.x,s=t-this.dragStart.y,o=this.initialPixelPoints.map((n,p)=>{const d=n.x+i,l=n.y+s;return this.context.coordinateConversion.pixelToData({x:d,y:l})});o.every(n=>n!==null)&&o[0]&&o[1]&&(this.currentDrawing.points[0]=o[0],this.currentDrawing.points[1]=o[1],o[0].paneIndex!==void 0&&(this.currentDrawing.paneIndex=o[0].paneIndex),this.context.updateDrawing(this.currentDrawing))}else if(this.editingPointIndex!==null){const i=this.context.coordinateConversion.pixelToData({x:e,y:t});i&&(this.currentDrawing.points[this.editingPointIndex]=i,this.editingPointIndex===0&&i.paneIndex!==void 0&&(this.currentDrawing.paneIndex=i.paneIndex),this.context.updateDrawing(this.currentDrawing))}this.isEditing=!1,this.isMovingShape=!1,this.dragStart=null,this.initialPixelPoints=[],this.currentDrawing=null,this.editingPointIndex=null,this.editGroup&&(this.zr.remove(this.editGroup),this.editGroup=null),this.zr.off("mousemove",this.onMouseMove),this.zr.off("mouseup",this.onMouseUp),this.context.unlockChart()}}}var Dt=Object.defineProperty,Et=(r,e,t)=>e in r?Dt(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,zt=(r,e,t)=>(Et(r,typeof e!="symbol"?e+"":e,t),t);class Lt{constructor(){zt(this,"handlers",new Map)}on(e,t){this.handlers.has(e)||this.handlers.set(e,new Set),this.handlers.get(e).add(t)}off(e,t){const i=this.handlers.get(e);i&&i.delete(t)}emit(e,t){const i=this.handlers.get(e);i&&i.forEach(s=>{try{s(t)}catch(o){console.error(`Error in EventBus handler for ${e}:`,o)}})}clear(){this.handlers.clear()}}var Tt=Object.defineProperty,Ft=(r,e,t)=>e in r?Tt(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,L=(r,e,t)=>(Ft(r,typeof e!="symbol"?e+"":e,t),t);class Nt{constructor(e,t={}){L(this,"chart"),L(this,"options"),L(this,"marketData",[]),L(this,"indicators",new Map),L(this,"timeToIndex",new Map),L(this,"pluginManager"),L(this,"drawingEditor"),L(this,"events",new Lt),L(this,"isMainCollapsed",!1),L(this,"maximizedPaneId",null),L(this,"countdownInterval",null),L(this,"selectedDrawingId",null),L(this,"drawings",[]),L(this,"coordinateConversion",{pixelToData:o=>{const n=this.chart.getOption();if(!n||!n.grid)return null;const p=n.grid.length;for(let d=0;d<p;d++)if(this.chart.containPixel({gridIndex:d},[o.x,o.y])){this.chart.convertFromPixel({seriesIndex:d},[o.x,o.y]);const l=this.chart.convertFromPixel({gridIndex:d},[o.x,o.y]);if(l)return{timeIndex:Math.round(l[0]),value:l[1],paneIndex:d}}return null},dataToPixel:o=>{const n=o.paneIndex||0,p=this.chart.convertToPixel({gridIndex:n},[o.timeIndex,o.value]);return p?{x:p[0],y:p[1]}:null}}),L(this,"upColor","#00da3c"),L(this,"downColor","#ec0000"),L(this,"defaultPadding",0),L(this,"padding"),L(this,"dataIndexOffset",0),L(this,"rootContainer"),L(this,"layoutContainer"),L(this,"toolbarContainer"),L(this,"leftSidebar"),L(this,"rightSidebar"),L(this,"chartContainer"),L(this,"onKeyDown",o=>{(o.key==="Delete"||o.key==="Backspace")&&this.selectedDrawingId&&(this.removeDrawing(this.selectedDrawingId),this.selectedDrawingId=null,this.render())}),L(this,"onFullscreenChange",()=>{this.render()}),L(this,"isLocked",!1),L(this,"lockedState",null),this.rootContainer=e,this.options={title:"Market",height:"600px",backgroundColor:"#1e293b",upColor:"#00da3c",downColor:"#ec0000",fontColor:"#cbd5e1",fontFamily:"sans-serif",padding:.01,dataZoom:{visible:!0,position:"top",height:6},layout:{mainPaneHeight:"50%",gap:13},watermark:!0,...t},this.options.upColor&&(this.upColor=this.options.upColor),this.options.downColor&&(this.downColor=this.options.downColor),this.padding=this.options.padding!==void 0?this.options.padding:this.defaultPadding,this.options.height&&(typeof this.options.height=="number"?this.rootContainer.style.height=`${this.options.height}px`:this.rootContainer.style.height=this.options.height),this.rootContainer.innerHTML="",this.layoutContainer=document.createElement("div"),this.layoutContainer.style.display="flex",this.layoutContainer.style.width="100%",this.layoutContainer.style.height="100%",this.layoutContainer.style.overflow="hidden",this.rootContainer.appendChild(this.layoutContainer),this.leftSidebar=document.createElement("div"),this.leftSidebar.style.display="none",this.leftSidebar.style.width="250px",this.leftSidebar.style.flexShrink="0",this.leftSidebar.style.overflowY="auto",this.leftSidebar.style.backgroundColor=this.options.backgroundColor||"#1e293b",this.leftSidebar.style.borderRight="1px solid #334155",this.leftSidebar.style.padding="10px",this.leftSidebar.style.boxSizing="border-box",this.leftSidebar.style.color="#cbd5e1",this.leftSidebar.style.fontSize="12px",this.leftSidebar.style.fontFamily=this.options.fontFamily||"sans-serif",this.layoutContainer.appendChild(this.leftSidebar),this.toolbarContainer=document.createElement("div"),this.layoutContainer.appendChild(this.toolbarContainer),this.chartContainer=document.createElement("div"),this.chartContainer.style.flexGrow="1",this.chartContainer.style.height="100%",this.chartContainer.style.overflow="hidden",this.layoutContainer.appendChild(this.chartContainer),this.rightSidebar=document.createElement("div"),this.rightSidebar.style.display="none",this.rightSidebar.style.width="250px",this.rightSidebar.style.flexShrink="0",this.rightSidebar.style.overflowY="auto",this.rightSidebar.style.backgroundColor=this.options.backgroundColor||"#1e293b",this.rightSidebar.style.borderLeft="1px solid #334155",this.rightSidebar.style.padding="10px",this.rightSidebar.style.boxSizing="border-box",this.rightSidebar.style.color="#cbd5e1",this.rightSidebar.style.fontSize="12px",this.rightSidebar.style.fontFamily=this.options.fontFamily||"sans-serif",this.layoutContainer.appendChild(this.rightSidebar),this.chart=j.init(this.chartContainer),this.pluginManager=new It(this,this.toolbarContainer),this.drawingEditor=new Mt(this),this.chart.on("dataZoom",o=>{this.events.emit("chart:dataZoom",o);const n=this.options.databox?.triggerOn,p=this.options.databox?.position;n==="click"&&p==="floating"&&this.chart.dispatchAction({type:"hideTip"})}),this.chart.on("finished",o=>this.events.emit("chart:updated",o)),this.chart.getZr().on("mousedown",o=>this.events.emit("mouse:down",o)),this.chart.getZr().on("mousemove",o=>this.events.emit("mouse:move",o)),this.chart.getZr().on("mouseup",o=>this.events.emit("mouse:up",o)),this.chart.getZr().on("click",o=>this.events.emit("mouse:click",o));const i=this.chart.getZr(),s=i.setCursorStyle;i.setCursorStyle=function(o){o==="grab"&&(o="crosshair"),s.call(this,o)},this.bindDrawingEvents(),window.addEventListener("resize",this.resize.bind(this)),document.addEventListener("fullscreenchange",this.onFullscreenChange),document.addEventListener("keydown",this.onKeyDown)}bindDrawingEvents(){let e=null;const t=i=>{if(!i||i.componentType!=="series"||!i.seriesName?.startsWith("drawings"))return null;i.seriesIndex;const s=i.seriesName.match(/drawings-pane-(\d+)/);if(!s)return null;const o=parseInt(s[1]),n=this.drawings.filter(d=>(d.paneIndex||0)===o)[i.dataIndex];if(!n)return null;const p=i.event?.target?.name;return{drawing:n,targetName:p,paneIdx:o}};this.chart.on("mouseover",i=>{const s=t(i);if(!s)return;const o=i.event?.target?.parent;if(o){const n=s.drawing.id===this.selectedDrawingId;e&&(clearTimeout(e),e=null),n||o.children().forEach(p=>{p.name&&p.name.startsWith("point")&&p.attr("style",{opacity:1})})}if(s.targetName==="line")this.events.emit("drawing:hover",{id:s.drawing.id,type:s.drawing.type}),this.chart.getZr().setCursorStyle("move");else if(s.targetName?.startsWith("point")){const n=s.targetName==="point-start"?0:1;this.events.emit("drawing:point:hover",{id:s.drawing.id,pointIndex:n}),this.chart.getZr().setCursorStyle("pointer")}}),this.chart.on("mouseout",i=>{const s=t(i);if(!s)return;const o=i.event?.target?.parent;if(s.drawing.id!==this.selectedDrawingId){if(e=setTimeout(()=>{if(o){if(this.selectedDrawingId===s.drawing.id)return;o.children().forEach(n=>{n.name&&n.name.startsWith("point")&&n.attr("style",{opacity:0})})}},50),s.targetName==="line")this.events.emit("drawing:mouseout",{id:s.drawing.id});else if(s.targetName?.startsWith("point")){const n=s.targetName==="point-start"?0:1;this.events.emit("drawing:point:mouseout",{id:s.drawing.id,pointIndex:n})}this.chart.getZr().setCursorStyle("default")}}),this.chart.on("mousedown",i=>{const s=t(i);if(!s)return;const o=i.event?.event||i.event,n=o?.offsetX,p=o?.offsetY;if(s.targetName==="line")this.events.emit("drawing:mousedown",{id:s.drawing.id,x:n,y:p});else if(s.targetName?.startsWith("point")){const d=s.targetName==="point-start"?0:1;this.events.emit("drawing:point:mousedown",{id:s.drawing.id,pointIndex:d,x:n,y:p})}}),this.chart.on("click",i=>{const s=t(i);if(s){if(this.selectedDrawingId!==s.drawing.id&&(this.selectedDrawingId=s.drawing.id,this.events.emit("drawing:selected",{id:s.drawing.id}),this.render()),s.targetName==="line")this.events.emit("drawing:click",{id:s.drawing.id});else if(s.targetName?.startsWith("point")){const o=s.targetName==="point-start"?0:1;this.events.emit("drawing:point:click",{id:s.drawing.id,pointIndex:o})}}}),this.chart.getZr().on("click",i=>{i.target||this.selectedDrawingId&&(this.events.emit("drawing:deselected",{id:this.selectedDrawingId}),this.selectedDrawingId=null,this.render())})}getChart(){return this.chart}getMarketData(){return this.marketData}getTimeToIndex(){return this.timeToIndex}getOptions(){return this.options}disableTools(){this.pluginManager.deactivatePlugin()}registerPlugin(e){this.pluginManager.register(e)}addDrawing(e){this.drawings.push(e),this.render()}removeDrawing(e){const t=this.drawings.findIndex(i=>i.id===e);if(t!==-1){const i=this.drawings[t];this.drawings.splice(t,1),this.events.emit("drawing:deleted",{id:i.id}),this.render()}}getDrawing(e){return this.drawings.find(t=>t.id===e)}updateDrawing(e){const t=this.drawings.findIndex(i=>i.id===e.id);t!==-1&&(this.drawings[t]=e,this.render())}lockChart(){if(this.isLocked)return;this.isLocked=!0;const e=this.chart.getOption();this.chart.setOption({dataZoom:e.dataZoom.map(t=>({...t,disabled:!0})),tooltip:{show:!1}})}unlockChart(){if(!this.isLocked)return;this.isLocked=!1;const e=this.chart.getOption();(this.options.dataZoom||{}).visible,e.dataZoom&&this.chart.setOption({dataZoom:e.dataZoom.map(t=>({...t,disabled:!1})),tooltip:{show:!0}})}setZoom(e,t){this.chart.dispatchAction({type:"dataZoom",start:e,end:t})}setMarketData(e){this.marketData=e,this.rebuildTimeIndex(),this.render()}updateData(e){if(e.length===0)return;const t=new Map;this.marketData.forEach(f=>{t.set(f.time,f)}),e.forEach(f=>{t.has(f.time),t.set(f.time,f)}),this.marketData=Array.from(t.values()).sort((f,v)=>f.time-v.time),this.rebuildTimeIndex();const i=this.dataIndexOffset,s=it.buildCandlestickSeries(this.marketData,this.options),o={value:[NaN,NaN,NaN,NaN],itemStyle:{opacity:0}},n=[...Array(i).fill(o),...s.data,...Array(i).fill(o)],p=[...Array(i).fill(""),...this.marketData.map(f=>new Date(f.time).toLocaleString()),...Array(i).fill("")],d=this.chart.getOption(),l=ft.calculate(this.chart.getHeight(),this.indicators,this.options,this.isMainCollapsed,this.maximizedPaneId,this.marketData),k=[...Array(i).fill(null),...this.marketData,...Array(i).fill(null)],{series:y,barColors:m}=it.buildIndicatorSeries(this.indicators,this.timeToIndex,l.paneLayout,p.length,i,k,l.overlayYAxisMap,l.separatePaneYAxisOffset),I=n.map((f,v)=>m[v]?{value:f.value||f,itemStyle:{color:m[v],color0:m[v],borderColor:m[v],borderColor0:m[v]}}:f),u={xAxis:d.xAxis.map((f,v)=>({data:p})),series:[{data:I,markLine:s.markLine},...y.map(f=>{const v={data:f.data};return f.renderItem&&(v.renderItem=f.renderItem),v})]};this.chart.setOption(u,{notMerge:!1}),this.startCountdown()}startCountdown(){if(this.stopCountdown(),!this.options.lastPriceLine?.showCountdown||!this.options.interval||this.marketData.length===0)return;const e=()=>{if(this.marketData.length===0)return;const t=this.marketData[this.marketData.length-1].time+(this.options.interval||0),i=Date.now(),s=t-i;if(s<=0)return;const o=Math.abs(s),n=Math.floor(o/36e5),p=Math.floor(o%36e5/6e4),d=Math.floor(o%6e4/1e3),l=`${n>0?n.toString().padStart(2,"0")+":":""}${p.toString().padStart(2,"0")}:${d.toString().padStart(2,"0")}`,k=this.chart.getOption();if(!k||!k.series)return;const y=k.series.findIndex(E=>E.type==="candlestick");if(y===-1)return;const m=k.series[y];if(!m.markLine||!m.markLine.data||!m.markLine.data[0])return;const I=m.markLine.data[0];I.label.formatter;const u=I.yAxis;let f="";if(this.options.yAxisLabelFormatter)f=this.options.yAxisLabelFormatter(u);else{const E=this.options.yAxisDecimalPlaces!==void 0?this.options.yAxisDecimalPlaces:2;f=typeof u=="number"?u.toFixed(E):u}const v=`${f}
|
|
37
|
+
${l}`;this.chart.setOption({series:[{name:this.options.title||"Market",markLine:{data:[{...I,label:{...I.label,formatter:v}}]}}]})};e(),this.countdownInterval=setInterval(e,1e3)}stopCountdown(){this.countdownInterval&&(clearInterval(this.countdownInterval),this.countdownInterval=null)}addIndicator(e,t,i={}){const s=i.overlay!==void 0?i.overlay:i.isOverlay??!1;let o=0;if(!s){let p=0;this.indicators.forEach(d=>{d.paneIndex>p&&(p=d.paneIndex)}),o=p+1}const n=new bt(e,t,o,{height:i.height,collapsed:!1,titleColor:i.titleColor,controls:i.controls});return this.indicators.set(e,n),this.render(),n}setIndicator(e,t,i=!1){this.addIndicator(e,{[e]:t},{overlay:i})}removeIndicator(e){this.indicators.delete(e),this.render()}toggleIndicator(e,t="collapse"){if(t==="fullscreen"){document.fullscreenElement?document.exitFullscreen():this.rootContainer.requestFullscreen();return}if(t==="maximize"){this.maximizedPaneId===e?this.maximizedPaneId=null:this.maximizedPaneId=e,this.render();return}if(e==="main"){this.isMainCollapsed=!this.isMainCollapsed,this.render();return}const i=this.indicators.get(e);i&&(i.toggleCollapse(),this.render())}resize(){this.chart.resize()}destroy(){this.stopCountdown(),window.removeEventListener("resize",this.resize.bind(this)),document.removeEventListener("fullscreenchange",this.onFullscreenChange),document.removeEventListener("keydown",this.onKeyDown),this.pluginManager.deactivatePlugin(),this.pluginManager.destroy(),this.chart.dispose()}rebuildTimeIndex(){this.timeToIndex.clear(),this.marketData.forEach((i,s)=>{this.timeToIndex.set(i.time,s)});const e=this.marketData.length,t=Math.ceil(e*this.padding);this.dataIndexOffset=t}render(){if(this.marketData.length===0)return;let e=null;try{const x=this.chart.getOption();if(x&&x.dataZoom&&x.dataZoom.length>0){const A=x.dataZoom.find(w=>w.type==="slider"||w.type==="inside");A&&(e={start:A.start,end:A.end})}}catch{}const t=this.options.databox?.position,i=this.leftSidebar.style.display,s=this.rightSidebar.style.display,o=t==="left"?"block":"none",n=t==="right"?"block":"none";(i!==o||s!==n)&&(this.leftSidebar.style.display=o,this.rightSidebar.style.display=n,this.chart.resize());const p=this.dataIndexOffset,d=[...Array(p).fill(""),...this.marketData.map(x=>new Date(x.time).toLocaleString()),...Array(p).fill("")],l=ft.calculate(this.chart.getHeight(),this.indicators,this.options,this.isMainCollapsed,this.maximizedPaneId,this.marketData);if(!e&&l.dataZoom&&this.marketData.length>0){const x=this.marketData.length,A=d.length,w=p/A,T=x/A;l.dataZoom.forEach(S=>{if(S.start!==void 0){const c=S.start/100,a=w+c*T;S.start=a*100}if(S.end!==void 0){const c=S.end/100,a=w+c*T;S.end=a*100}})}e&&l.dataZoom&&l.dataZoom.forEach(x=>{x.start=e.start,x.end=e.end}),l.xAxis.forEach(x=>{x.data=d,x.boundaryGap=!1});const k=it.buildCandlestickSeries(this.marketData,this.options),y={value:[NaN,NaN,NaN,NaN],itemStyle:{opacity:0}};k.data=[...Array(p).fill(y),...k.data,...Array(p).fill(y)];const m=[...Array(p).fill(null),...this.marketData,...Array(p).fill(null)],{series:I,barColors:u}=it.buildIndicatorSeries(this.indicators,this.timeToIndex,l.paneLayout,d.length,p,m,l.overlayYAxisMap,l.separatePaneYAxisOffset);k.data=k.data.map((x,A)=>u[A]?{value:x.value||x,itemStyle:{color:u[A],color0:u[A],borderColor:u[A],borderColor0:u[A]}}:x);const f=wt.build(l,this.options,this.toggleIndicator.bind(this),this.isMainCollapsed,this.maximizedPaneId),v=new Map;this.drawings.forEach(x=>{const A=x.paneIndex||0;v.has(A)||v.set(A,[]),v.get(A).push(x)});const E=[];v.forEach((x,A)=>{E.push({type:"custom",name:`drawings-pane-${A}`,xAxisIndex:A,yAxisIndex:A,clip:!0,renderItem:(w,T)=>{const S=x[w.dataIndex];if(!S)return;const c=S.points[0],a=S.points[1];if(!c||!a)return;const g=T.coord([c.timeIndex,c.value]),b=T.coord([a.timeIndex,a.value]),P=S.id===this.selectedDrawingId;if(S.type==="line")return{type:"group",children:[{type:"line",name:"line",shape:{x1:g[0],y1:g[1],x2:b[0],y2:b[1]},style:{stroke:S.style?.color||"#3b82f6",lineWidth:S.style?.lineWidth||2}},{type:"circle",name:"point-start",shape:{cx:g[0],cy:g[1],r:4},style:{fill:"#fff",stroke:S.style?.color||"#3b82f6",lineWidth:1,opacity:P?1:0}},{type:"circle",name:"point-end",shape:{cx:b[0],cy:b[1],r:4},style:{fill:"#fff",stroke:S.style?.color||"#3b82f6",lineWidth:1,opacity:P?1:0}}]};if(S.type==="fibonacci"){const F=g[0],z=g[1],G=b[0],N=b[1],H=Math.min(F,G),X=Math.max(F,G),K=X-H,Y=N-z,h=[0,.236,.382,.5,.618,.786,1],C=["#787b86","#f44336","#ff9800","#4caf50","#2196f3","#00bcd4","#787b86"],M=[];M.push({type:"line",name:"line",shape:{x1:F,y1:z,x2:G,y2:N},style:{stroke:"#999",lineWidth:1,lineDash:[4,4]}}),M.push({type:"circle",name:"point-start",shape:{cx:F,cy:z,r:4},style:{fill:"#fff",stroke:S.style?.color||"#3b82f6",lineWidth:1,opacity:P?1:0},z:100}),M.push({type:"circle",name:"point-end",shape:{cx:G,cy:N,r:4},style:{fill:"#fff",stroke:S.style?.color||"#3b82f6",lineWidth:1,opacity:P?1:0},z:100}),h.forEach((D,W)=>{const q=N-Y*D,O=C[W%C.length];M.push({type:"line",name:"fib-line",shape:{x1:H,y1:q,x2:X,y2:q},style:{stroke:O,lineWidth:1},silent:!0});const B=S.points[0].value,tt=S.points[1].value,st=tt-B,J=tt-st*D;if(M.push({type:"text",style:{text:`${D} (${J.toFixed(2)})`,x:H+5,y:q-10,fill:O,fontSize:10},silent:!0}),W<h.length-1){const ot=h[W+1],dt=N-Y*ot,ut=Math.abs(dt-q),gt=Math.min(q,dt);M.push({type:"rect",shape:{x:H,y:gt,width:K,height:ut},style:{fill:C[(W+1)%C.length],opacity:.1},silent:!0})}});const $=[],R=[];return h.forEach((D,W)=>{const q=N-Y*D,O=C[W%C.length];R.push({type:"line",shape:{x1:H,y1:q,x2:X,y2:q},style:{stroke:O,lineWidth:1},silent:!0});const B=S.points[0].value,tt=S.points[1].value,st=tt-B,J=tt-st*D;if(R.push({type:"text",style:{text:`${D} (${J.toFixed(2)})`,x:H+5,y:q-10,fill:O,fontSize:10},silent:!0}),W<h.length-1){const ot=h[W+1],dt=N-Y*ot,ut=Math.abs(dt-q),gt=Math.min(q,dt);$.push({type:"rect",name:"line",shape:{x:H,y:gt,width:K,height:ut},style:{fill:C[(W+1)%C.length],opacity:.1}})}}),{type:"group",children:[...$,...R,{type:"line",name:"line",shape:{x1:F,y1:z,x2:G,y2:N},style:{stroke:"#999",lineWidth:1,lineDash:[4,4]}},{type:"circle",name:"point-start",shape:{cx:F,cy:z,r:4},style:{fill:"#fff",stroke:S.style?.color||"#3b82f6",lineWidth:1,opacity:P?1:0},z:100},{type:"circle",name:"point-end",shape:{cx:G,cy:N,r:4},style:{fill:"#fff",stroke:S.style?.color||"#3b82f6",lineWidth:1,opacity:P?1:0},z:100}]}}},data:x.map(w=>[w.points[0].timeIndex,w.points[0].value,w.points[1].timeIndex,w.points[1].value]),z:100,silent:!1})});const V=x=>{const A=Ct.format(x,this.options),w=this.options.databox?.position;return w==="left"?(this.leftSidebar.innerHTML=A,""):w==="right"?(this.rightSidebar.innerHTML=A,""):this.options.databox?`<div style="min-width: 200px;">${A}</div>`:""},Z={backgroundColor:this.options.backgroundColor,animation:!1,legend:{show:!1},tooltip:{show:!0,showContent:!!this.options.databox,trigger:"axis",triggerOn:this.options.databox?.triggerOn??"mousemove",axisPointer:{type:"cross",label:{backgroundColor:"#475569"}},backgroundColor:"rgba(30, 41, 59, 0.9)",borderWidth:1,borderColor:"#334155",padding:10,textStyle:{color:"#fff",fontFamily:this.options.fontFamily||"sans-serif"},formatter:V,extraCssText:t!=="floating"&&t!==void 0?"display: none !important;":void 0,position:(x,A,w,T,S)=>{if(this.options.databox?.position==="floating"){const c={top:10};return c[["left","right"][+(x[0]<S.viewSize[0]/2)]]=30,c}return null}},axisPointer:{link:{xAxisIndex:"all"},label:{backgroundColor:"#475569"}},graphic:f,grid:l.grid,xAxis:l.xAxis,yAxis:l.yAxis,dataZoom:l.dataZoom,series:[k,...I,...E]};this.chart.setOption(Z,!0)}}var Zt=Object.defineProperty,$t=(r,e,t)=>e in r?Zt(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,ht=(r,e,t)=>($t(r,typeof e!="symbol"?e+"":e,t),t);class ct{constructor(e){ht(this,"id"),ht(this,"name"),ht(this,"icon"),ht(this,"context"),ht(this,"eventListeners",[]),this.id=e.id,this.name=e.name,this.icon=e.icon}init(e){this.context=e,this.onInit()}onInit(){}activate(){this.onActivate(),this.context.events.emit("plugin:activated",this.id)}onActivate(){}deactivate(){this.onDeactivate(),this.context.events.emit("plugin:deactivated",this.id)}onDeactivate(){}destroy(){this.removeAllListeners(),this.onDestroy()}onDestroy(){}on(e,t){this.context.events.on(e,t),this.eventListeners.push({event:e,handler:t})}off(e,t){this.context.events.off(e,t),this.eventListeners=this.eventListeners.filter(i=>i.event!==e||i.handler!==t)}removeAllListeners(){this.eventListeners.forEach(({event:e,handler:t})=>{this.context.events.off(e,t)}),this.eventListeners=[]}get chart(){return this.context.getChart()}get marketData(){return this.context.getMarketData()}}var Gt=Object.defineProperty,Wt=(r,e,t)=>e in r?Gt(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,Q=(r,e,t)=>(Wt(r,typeof e!="symbol"?e+"":e,t),t);class Ot extends ct{constructor(e){super({id:"measure",name:e?.name||"Measure",icon:e?.icon||'<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M160-240q-33 0-56.5-23.5T80-320v-320q0-33 23.5-56.5T160-720h640q33 0 56.5 23.5T880-640v320q0 33-23.5 56.5T800-240H160Zm0-80h640v-320H680v160h-80v-160h-80v160h-80v-160h-80v160h-80v-160H160v320Zm120-160h80-80Zm160 0h80-80Zm160 0h80-80Zm-120 0Z"/></svg>'}),Q(this,"zr"),Q(this,"state","idle"),Q(this,"startPoint",null),Q(this,"endPoint",null),Q(this,"group",null),Q(this,"rect",null),Q(this,"labelRect",null),Q(this,"labelText",null),Q(this,"lineV",null),Q(this,"lineH",null),Q(this,"arrowStart",null),Q(this,"arrowEnd",null),Q(this,"onMouseDown",()=>{this.state==="finished"&&this.removeGraphic()}),Q(this,"onChartInteraction",()=>{this.group&&this.removeGraphic()}),Q(this,"onClick",t=>{this.state==="idle"?(this.state="drawing",this.startPoint=[t.offsetX,t.offsetY],this.endPoint=[t.offsetX,t.offsetY],this.initGraphic(),this.updateGraphic()):this.state==="drawing"&&(this.state="finished",this.endPoint=[t.offsetX,t.offsetY],this.updateGraphic(),this.context.disableTools(),this.enableClearListeners())}),Q(this,"clearHandlers",{}),Q(this,"onMouseMove",t=>{this.state==="drawing"&&(this.endPoint=[t.offsetX,t.offsetY],this.updateGraphic())})}onInit(){this.zr=this.chart.getZr()}onActivate(){this.state="idle",this.chart.getZr().setCursorStyle("crosshair"),this.zr.on("click",this.onClick),this.zr.on("mousemove",this.onMouseMove)}onDeactivate(){this.state="idle",this.chart.getZr().setCursorStyle("default"),this.zr.off("click",this.onClick),this.zr.off("mousemove",this.onMouseMove),this.disableClearListeners(),this.state==="drawing"&&this.removeGraphic()}onDestroy(){this.removeGraphic()}enableClearListeners(){const e=()=>{this.removeGraphic()};setTimeout(()=>{this.zr.on("click",e)},10),this.zr.on("mousedown",this.onMouseDown),this.context.events.on("chart:dataZoom",this.onChartInteraction),this.clearHandlers={click:e,mousedown:this.onMouseDown,dataZoom:this.onChartInteraction}}disableClearListeners(){this.clearHandlers.click&&this.zr.off("click",this.clearHandlers.click),this.clearHandlers.mousedown&&this.zr.off("mousedown",this.clearHandlers.mousedown),this.clearHandlers.dataZoom&&this.context.events.off("chart:dataZoom",this.clearHandlers.dataZoom),this.clearHandlers={}}initGraphic(){this.group||(this.group=new j.graphic.Group,this.rect=new j.graphic.Rect({shape:{x:0,y:0,width:0,height:0},style:{fill:"rgba(0,0,0,0)",stroke:"transparent",lineWidth:0},z:100}),this.lineV=new j.graphic.Line({shape:{x1:0,y1:0,x2:0,y2:0},style:{stroke:"#fff",lineWidth:1,lineDash:[4,4]},z:101}),this.lineH=new j.graphic.Line({shape:{x1:0,y1:0,x2:0,y2:0},style:{stroke:"#fff",lineWidth:1,lineDash:[4,4]},z:101}),this.arrowStart=new j.graphic.Polygon({shape:{points:[[0,0],[-5,10],[5,10]]},style:{fill:"#fff"},z:102}),this.arrowEnd=new j.graphic.Polygon({shape:{points:[[0,0],[-5,-10],[5,-10]]},style:{fill:"#fff"},z:102}),this.labelRect=new j.graphic.Rect({shape:{x:0,y:0,width:0,height:0,r:4},style:{fill:"transparent",stroke:"transparent",lineWidth:0,shadowBlur:5,shadowColor:"rgba(0,0,0,0.3)"},z:102}),this.labelText=new j.graphic.Text({style:{x:0,y:0,text:"",fill:"#fff",font:"12px sans-serif",align:"center",verticalAlign:"middle"},z:103}),this.group.add(this.rect),this.group.add(this.lineV),this.group.add(this.lineH),this.group.add(this.arrowStart),this.group.add(this.arrowEnd),this.group.add(this.labelRect),this.group.add(this.labelText),this.zr.add(this.group))}removeGraphic(){this.group&&(this.zr.remove(this.group),this.group=null,this.disableClearListeners())}updateGraphic(){if(!this.startPoint||!this.endPoint||!this.group)return;const[e,t]=this.startPoint,[i,s]=this.endPoint,o=this.context.coordinateConversion.pixelToData({x:e,y:t}),n=this.context.coordinateConversion.pixelToData({x:i,y:s});if(!o||!n)return;const p=Math.round(o.timeIndex),d=Math.round(n.timeIndex),l=o.value,k=n.value,y=d-p,m=k-l,I=m/l*100,u=m>=0,f=u?"rgba(33, 150, 243, 0.2)":"rgba(236, 0, 0, 0.2)",v=u?"#2196F3":"#ec0000";this.rect.setShape({x:Math.min(e,i),y:Math.min(t,s),width:Math.abs(i-e),height:Math.abs(s-t)}),this.rect.setStyle({fill:f});const E=(e+i)/2,V=(t+s)/2;this.lineV.setShape({x1:E,y1:t,x2:E,y2:s}),this.lineV.setStyle({stroke:v}),this.lineH.setShape({x1:e,y1:V,x2:i,y2:V}),this.lineH.setStyle({stroke:v});const Z=Math.min(t,s),x=Math.max(t,s);this.arrowStart.setStyle({fill:"none"}),this.arrowEnd.setStyle({fill:"none"}),u?(this.arrowStart.setShape({points:[[E,Z],[E-4,Z+6],[E+4,Z+6]]}),this.arrowStart.setStyle({fill:v})):(this.arrowEnd.setShape({points:[[E,x],[E-4,x-6],[E+4,x-6]]}),this.arrowEnd.setStyle({fill:v}));const A=[`${m.toFixed(2)} (${I.toFixed(2)}%)`,`${y} bars, ${(y*0).toFixed(0)}d`].join(`
|
|
38
|
+
`),w=140,T=40,S=Math.max(t,s),c=Math.min(t,s);let a=(e+i)/2-w/2,g=S+10;const b=this.chart.getHeight();g+T>b&&(g=c-T-10),this.labelRect.setShape({x:a,y:g,width:w,height:T}),this.labelRect.setStyle({fill:"#1e293b",stroke:v,lineWidth:1}),this.labelText.setStyle({x:a+w/2,y:g+T/2,text:A,fill:"#fff"})}}var Ht=Object.defineProperty,jt=(r,e,t)=>e in r?Ht(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,_=(r,e,t)=>(jt(r,typeof e!="symbol"?e+"":e,t),t);class Yt extends ct{constructor(e){super({id:"trend-line",name:e?.name||"Trend Line",icon:e?.icon||'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="2" y1="22" x2="22" y2="2" /></svg>'}),_(this,"zr"),_(this,"state","idle"),_(this,"startPoint",null),_(this,"endPoint",null),_(this,"group",null),_(this,"line",null),_(this,"startCircle",null),_(this,"endCircle",null),_(this,"onMouseDown",()=>{}),_(this,"onChartInteraction",()=>{}),_(this,"onClick",t=>{if(this.state==="idle")this.state="drawing",this.startPoint=[t.offsetX,t.offsetY],this.endPoint=[t.offsetX,t.offsetY],this.initGraphic(),this.updateGraphic();else if(this.state==="drawing"){if(this.state="finished",this.endPoint=[t.offsetX,t.offsetY],this.updateGraphic(),this.startPoint&&this.endPoint){const i=this.context.coordinateConversion.pixelToData({x:this.startPoint[0],y:this.startPoint[1]}),s=this.context.coordinateConversion.pixelToData({x:this.endPoint[0],y:this.endPoint[1]});if(i&&s){const o=i.paneIndex||0;this.context.addDrawing({id:`line-${Date.now()}`,type:"line",points:[i,s],paneIndex:o,style:{color:"#3b82f6",lineWidth:2}})}}this.removeGraphic(),this.context.disableTools()}}),_(this,"clearHandlers",{}),_(this,"onMouseMove",t=>{this.state==="drawing"&&(this.endPoint=[t.offsetX,t.offsetY],this.updateGraphic())})}onInit(){this.zr=this.chart.getZr()}onActivate(){this.state="idle",this.chart.getZr().setCursorStyle("crosshair"),this.zr.on("click",this.onClick),this.zr.on("mousemove",this.onMouseMove)}onDeactivate(){this.state="idle",this.chart.getZr().setCursorStyle("default"),this.zr.off("click",this.onClick),this.zr.off("mousemove",this.onMouseMove),this.disableClearListeners(),this.state==="drawing"&&this.removeGraphic()}onDestroy(){this.removeGraphic()}saveDataCoordinates(){}updateGraphicFromData(){}enableClearListeners(){}disableClearListeners(){}initGraphic(){this.group||(this.group=new j.graphic.Group,this.line=new j.graphic.Line({shape:{x1:0,y1:0,x2:0,y2:0},style:{stroke:"#3b82f6",lineWidth:2},z:100}),this.startCircle=new j.graphic.Circle({shape:{cx:0,cy:0,r:4},style:{fill:"#fff",stroke:"#3b82f6",lineWidth:1},z:101}),this.endCircle=new j.graphic.Circle({shape:{cx:0,cy:0,r:4},style:{fill:"#fff",stroke:"#3b82f6",lineWidth:1},z:101}),this.group.add(this.line),this.group.add(this.startCircle),this.group.add(this.endCircle),this.zr.add(this.group))}removeGraphic(){this.group&&(this.zr.remove(this.group),this.group=null,this.disableClearListeners())}updateGraphic(){if(!this.startPoint||!this.endPoint||!this.group)return;const[e,t]=this.startPoint,[i,s]=this.endPoint;this.line.setShape({x1:e,y1:t,x2:i,y2:s}),this.startCircle.setShape({cx:e,cy:t}),this.endCircle.setShape({cx:i,cy:s})}}var Rt=Object.defineProperty,qt=(r,e,t)=>e in r?Rt(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,nt=(r,e,t)=>(qt(r,typeof e!="symbol"?e+"":e,t),t);class Xt extends ct{constructor(e={}){super({id:"fibonacci-tool",name:e.name||"Fibonacci Retracement",icon:e.icon||'<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M120-80v-80h720v80H120Zm0-240v-80h720v80H120Zm0-240v-80h720v80H120Zm0-240v-80h720v80H120Z"/></svg>'}),nt(this,"startPoint",null),nt(this,"endPoint",null),nt(this,"state","idle"),nt(this,"graphicGroup",null),nt(this,"levels",[0,.236,.382,.5,.618,.786,1]),nt(this,"colors",["#787b86","#f44336","#ff9800","#4caf50","#2196f3","#00bcd4","#787b86"]),nt(this,"onClick",t=>{this.state==="idle"?(this.state="drawing",this.startPoint=[t.offsetX,t.offsetY],this.endPoint=[t.offsetX,t.offsetY],this.initGraphic(),this.updateGraphic()):this.state==="drawing"&&(this.state="finished",this.endPoint=[t.offsetX,t.offsetY],this.updateGraphic(),this.saveDrawing(),this.removeGraphic(),this.context.disableTools())}),nt(this,"onMouseMove",t=>{this.state==="drawing"&&(this.endPoint=[t.offsetX,t.offsetY],this.updateGraphic())})}onActivate(){this.state="idle",this.startPoint=null,this.endPoint=null,this.context.getChart().getZr().setCursorStyle("crosshair"),this.bindEvents()}onDeactivate(){this.state="idle",this.startPoint=null,this.endPoint=null,this.removeGraphic(),this.unbindEvents(),this.context.getChart().getZr().setCursorStyle("default")}bindEvents(){const e=this.context.getChart().getZr();e.on("click",this.onClick),e.on("mousemove",this.onMouseMove)}unbindEvents(){const e=this.context.getChart().getZr();e.off("click",this.onClick),e.off("mousemove",this.onMouseMove)}initGraphic(){this.graphicGroup=new j.graphic.Group,this.context.getChart().getZr().add(this.graphicGroup)}removeGraphic(){this.graphicGroup&&(this.context.getChart().getZr().remove(this.graphicGroup),this.graphicGroup=null)}updateGraphic(){if(!this.graphicGroup||!this.startPoint||!this.endPoint)return;this.graphicGroup.removeAll();const e=this.startPoint[0],t=this.startPoint[1],i=this.endPoint[0],s=this.endPoint[1],o=new j.graphic.Line({shape:{x1:e,y1:t,x2:i,y2:s},style:{stroke:"#999",lineWidth:1,lineDash:[4,4]},silent:!0});this.graphicGroup.add(o);const n=Math.min(e,i),p=Math.max(e,i),d=p-n,l=s-t;this.levels.forEach((k,y)=>{const m=s-l*k,I=this.colors[y%this.colors.length],u=new j.graphic.Line({shape:{x1:n,y1:m,x2:p,y2:m},style:{stroke:I,lineWidth:1},silent:!0});if(this.graphicGroup.add(u),y<this.levels.length-1){const f=this.levels[y+1],v=s-l*f,E=Math.abs(v-m),V=Math.min(m,v),Z=new j.graphic.Rect({shape:{x:n,y:V,width:d,height:E},style:{fill:this.colors[(y+1)%this.colors.length],opacity:.1},silent:!0});this.graphicGroup.add(Z)}})}saveDrawing(){if(!this.startPoint||!this.endPoint)return;const e=this.context.coordinateConversion.pixelToData({x:this.startPoint[0],y:this.startPoint[1]}),t=this.context.coordinateConversion.pixelToData({x:this.endPoint[0],y:this.endPoint[1]});if(e&&t){const i=e.paneIndex||0;this.context.addDrawing({id:`fib-${Date.now()}`,type:"fibonacci",points:[e,t],paneIndex:i,style:{color:"#3b82f6",lineWidth:1}})}}}et.AbstractPlugin=ct,et.FibonacciTool=Xt,et.LineTool=Yt,et.MeasureTool=Ot,et.QFChart=Nt});
|
package/dist/qfchart.min.es.js
CHANGED
|
@@ -14,25 +14,25 @@
|
|
|
14
14
|
* See the License for the specific language governing permissions and
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
|
-
import*as q from"echarts";var gt=Object.defineProperty,yt=(l,e,t)=>e in l?gt(l,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[e]=t,nt=(l,e,t)=>(yt(l,typeof e!="symbol"?e+"":e,t),t);class ft{constructor(e,t,i,s={}){nt(this,"id"),nt(this,"plots"),nt(this,"paneIndex"),nt(this,"height"),nt(this,"collapsed"),nt(this,"titleColor"),nt(this,"controls"),this.id=e,this.plots=t,this.paneIndex=i,this.height=s.height,this.collapsed=s.collapsed||!1,this.titleColor=s.titleColor,this.controls=s.controls}toggleCollapse(){this.collapsed=!this.collapsed}isVisible(){return!this.collapsed}updateData(e){Object.keys(e).forEach(t=>{if(!this.plots[t])this.plots[t]=e[t];else{const i=this.plots[t],s=e[t];s.options&&(i.options={...i.options,...s.options});const o=new Map;i.data.forEach(n=>{o.set(n.time,n)}),s.data.forEach(n=>{o.set(n.time,n)}),i.data=Array.from(o.values()).sort((n,p)=>n.time-p.time)}})}}class ut{static calculate(e,t,i,s=!1,o=null,n){let p=0;e>0&&(p=1/e*100);const d=i.yAxisPadding!==void 0?i.yAxisPadding:5,r=h=>C=>{const A=(C.max-C.min)*(h/100);return C.min-A},k=h=>C=>{const A=(C.max-C.min)*(h/100);return C.max+A},f=Array.from(t.values()).map(h=>h.paneIndex).filter(h=>h>0).sort((h,C)=>h-C).filter((h,C,A)=>A.indexOf(h)===C),b=f.length>0,I=i.dataZoom?.visible??!0,u=i.dataZoom?.position??"top",y=i.dataZoom?.height??6,v=i.dataZoom?.start??0,E=i.dataZoom?.end??100;let V=8,N=92,x=-1;if(o)if(o==="main")x=0;else{const h=t.get(o);h&&(x=h.paneIndex)}if(x!==-1){const h=[],C=[],A=[],$=[],R=i.dataZoom?.start??50,D=i.dataZoom?.end??100;(i.dataZoom?.zoomOnTouch??!0)&&$.push({type:"inside",xAxisIndex:"all",start:R,end:D});const W=b?Math.max(...f):0,j=[];for(let O=0;O<=W;O++){const B=O===x;h.push({left:"10%",right:"10%",top:B?"5%":"0%",height:B?"90%":"0%",show:B,containLabel:!1}),C.push({type:"category",gridIndex:O,data:[],show:B,axisLabel:{show:B,color:"#94a3b8",fontFamily:i.fontFamily},axisLine:{show:B,lineStyle:{color:"#334155"}},splitLine:{show:B,lineStyle:{color:"#334155",opacity:.5}}});let tt,et;if(O===0&&x===0?(tt=i.yAxisMin!==void 0&&i.yAxisMin!=="auto"?i.yAxisMin:r(d),et=i.yAxisMax!==void 0&&i.yAxisMax!=="auto"?i.yAxisMax:k(d)):(tt=r(d),et=k(d)),A.push({position:"right",gridIndex:O,show:B,scale:!0,min:tt,max:et,axisLabel:{show:B,color:"#94a3b8",fontFamily:i.fontFamily,formatter:Q=>{if(i.yAxisLabelFormatter)return i.yAxisLabelFormatter(Q);const it=i.yAxisDecimalPlaces!==void 0?i.yAxisDecimalPlaces:2;return typeof Q=="number"?Q.toFixed(it):String(Q)}},splitLine:{show:B,lineStyle:{color:"#334155",opacity:.5}}}),O>0){const Q=Array.from(t.values()).find(it=>it.paneIndex===O);Q&&j.push({index:O,height:B?90:0,top:B?5:0,isCollapsed:!1,indicatorId:Q.id,titleColor:Q.titleColor,controls:Q.controls})}}return{grid:h,xAxis:C,yAxis:A,dataZoom:$,paneLayout:j,mainPaneHeight:x===0?90:0,mainPaneTop:x===0?5:0,pixelToPercent:p,overlayYAxisMap:new Map,separatePaneYAxisOffset:1}}I?u==="top"?(V=y+4,N=95):(N=100-y-2,V=8):(V=5,N=95);let M=5;e>0&&(M=20/e*100);let w=75,T=[];if(b){const h=f.map(D=>{const W=Array.from(t.values()).find(j=>j.paneIndex===D);return{index:D,requestedHeight:W?.height,isCollapsed:W?.collapsed??!1,indicatorId:W?.id,titleColor:W?.titleColor,controls:W?.controls}}).map(D=>({...D,height:D.isCollapsed?3:D.requestedHeight!==void 0?D.requestedHeight:15})),C=h.reduce((D,W)=>D+W.height,0),A=h.length*M,$=C+A;w=N-V-$,s?w=3:w<20&&(w=Math.max(w,10));let R=V+w+M;T=h.map(D=>{const W={index:D.index,height:D.height,top:R,isCollapsed:D.isCollapsed,indicatorId:D.indicatorId,titleColor:D.titleColor,controls:D.controls};return R+=D.height+M,W})}else w=N-V,s&&(w=3);const P=[];P.push({left:"10%",right:"10%",top:V+"%",height:w+"%",containLabel:!1}),T.forEach(h=>{P.push({left:"10%",right:"10%",top:h.top+"%",height:h.height+"%",containLabel:!1})});const c=[0,...T.map((h,C)=>C+1)],a=[],g=T.length===0;a.push({type:"category",data:[],gridIndex:0,scale:!0,axisLine:{onZero:!1,show:!s,lineStyle:{color:"#334155"}},splitLine:{show:!s,lineStyle:{color:"#334155",opacity:.5}},axisLabel:{show:!s,color:"#94a3b8",fontFamily:i.fontFamily||"sans-serif",formatter:h=>{if(i.yAxisLabelFormatter)return i.yAxisLabelFormatter(h);const C=i.yAxisDecimalPlaces!==void 0?i.yAxisDecimalPlaces:2;return typeof h=="number"?h.toFixed(C):String(h)}},axisTick:{show:!s},axisPointer:{label:{show:g,fontSize:11,backgroundColor:"#475569"}}}),T.forEach((h,C)=>{const A=C===T.length-1;a.push({type:"category",gridIndex:C+1,data:[],axisLabel:{show:!1},axisLine:{show:!h.isCollapsed,lineStyle:{color:"#334155"}},axisTick:{show:!1},splitLine:{show:!1},axisPointer:{label:{show:A,fontSize:11,backgroundColor:"#475569"}}})});const m=[];let S,Z;i.yAxisMin!==void 0&&i.yAxisMin!=="auto"?S=i.yAxisMin:S=r(d),i.yAxisMax!==void 0&&i.yAxisMax!=="auto"?Z=i.yAxisMax:Z=k(d),m.push({position:"right",scale:!0,min:S,max:Z,gridIndex:0,splitLine:{show:!s,lineStyle:{color:"#334155",opacity:.5}},axisLine:{show:!s,lineStyle:{color:"#334155"}},axisLabel:{show:!s,color:"#94a3b8",fontFamily:i.fontFamily||"sans-serif",formatter:h=>{if(i.yAxisLabelFormatter)return i.yAxisLabelFormatter(h);const C=i.yAxisDecimalPlaces!==void 0?i.yAxisDecimalPlaces:2;return typeof h=="number"?h.toFixed(C):String(h)}}});let z=1,G=-1/0,F=1/0;n&&n.length>0&&(G=Math.min(...n.map(h=>h.low)),F=Math.max(...n.map(h=>h.high)));const H=new Map;t.forEach((h,C)=>{h.paneIndex===0&&!h.collapsed&&n&&n.length>0&&Object.entries(h.plots).forEach(([A,$])=>{const R=`${C}::${A}`,D=["background","barcolor","char"],W=$.options.style==="shape"&&($.options.location==="abovebar"||$.options.location==="belowbar");if(D.includes($.options.style)){H.has(R)||(H.set(R,z),z++);return}if($.options.style==="shape"&&!W){H.has(R)||(H.set(R,z),z++);return}const j=[];if(Object.values($.data).forEach(O=>{typeof O=="number"&&!isNaN(O)&&isFinite(O)&&j.push(O)}),j.length>0){const O=Math.min(...j),B=Math.max(...j),tt=B-O,et=F-G,Q=O>=G*.5&&B<=F*1.5,it=tt>et*.01;Q&&it||H.has(R)||(H.set(R,z),z++)}})});const X=H.size>0?z-1:0;for(let h=0;h<X;h++)m.push({position:"left",scale:!0,min:r(d),max:k(d),gridIndex:0,show:!1,splitLine:{show:!1},axisLine:{show:!1},axisLabel:{show:!1}});const _=z;T.forEach((h,C)=>{m.push({position:"right",scale:!0,min:r(d),max:k(d),gridIndex:C+1,splitLine:{show:!h.isCollapsed,lineStyle:{color:"#334155",opacity:.3}},axisLabel:{show:!h.isCollapsed,color:"#94a3b8",fontFamily:i.fontFamily||"sans-serif",fontSize:10,formatter:A=>{if(i.yAxisLabelFormatter)return i.yAxisLabelFormatter(A);const $=i.yAxisDecimalPlaces!==void 0?i.yAxisDecimalPlaces:2;return typeof A=="number"?A.toFixed($):String(A)}},axisLine:{show:!h.isCollapsed,lineStyle:{color:"#334155"}}})});const Y=[];return I&&((i.dataZoom?.zoomOnTouch??!0)&&Y.push({type:"inside",xAxisIndex:c,start:v,end:E}),u==="top"?Y.push({type:"slider",xAxisIndex:c,top:"1%",height:y+"%",start:v,end:E,borderColor:"#334155",textStyle:{color:"#cbd5e1"},brushSelect:!1}):Y.push({type:"slider",xAxisIndex:c,bottom:"1%",height:y+"%",start:v,end:E,borderColor:"#334155",textStyle:{color:"#cbd5e1"},brushSelect:!1})),{grid:P,xAxis:a,yAxis:m,dataZoom:Y,paneLayout:T,mainPaneHeight:w,mainPaneTop:V,pixelToPercent:p,overlayYAxisMap:H,separatePaneYAxisOffset:_}}static calculateMaximized(e,t,i){return{grid:[],xAxis:[],yAxis:[],dataZoom:[],paneLayout:[],mainPaneHeight:0,mainPaneTop:0,pixelToPercent:0}}}const pt=new Map;function xt(l,e="#00da3c",t="64px"){if(typeof document>"u")return"";const i=`${l}-${e}-${t}`;if(pt.has(i))return pt.get(i);const s=document.createElement("canvas"),o=s.getContext("2d");if(s.width=32,s.height=32,o){o.font="bold "+t+" Arial",o.fillStyle=e,o.textAlign="center",o.textBaseline="middle",o.fillText(l,16,16);const n=s.toDataURL("image/png");return pt.set(i,n),n}return""}class st{static buildCandlestickSeries(e,t,i){const s=t.upColor||"#00da3c",o=t.downColor||"#ec0000",n=e.map(d=>[d.open,d.close,d.low,d.high]);if(i&&i>n.length){const d=i-n.length;for(let r=0;r<d;r++)n.push(null)}let p;if(t.lastPriceLine?.visible!==!1&&e.length>0){const d=e[e.length-1],r=d.close,k=d.close>=d.open,f=t.lastPriceLine?.color||(k?s:o),b=t.lastPriceLine?.lineStyle||"dashed";p={symbol:["none","none"],data:[{yAxis:r,label:{show:!0,position:"end",formatter:I=>{if(t.yAxisLabelFormatter)return t.yAxisLabelFormatter(I.value);const u=t.yAxisDecimalPlaces!==void 0?t.yAxisDecimalPlaces:2;return typeof I.value=="number"?I.value.toFixed(u):I.value},color:"#fff",backgroundColor:f,padding:[2,4],borderRadius:2,fontSize:11,fontWeight:"bold"},lineStyle:{color:f,type:b,width:1,opacity:.8}}],animation:!1,silent:!0}}return{type:"candlestick",name:t.title||"Market",data:n,itemStyle:{color:s,color0:o,borderColor:s,borderColor0:o},markLine:p,xAxisIndex:0,yAxisIndex:0,z:5}}static getShapeSymbol(e){switch(e){case"arrowdown":return"path://M12 24l-12-12h8v-12h8v12h8z";case"arrowup":return"path://M12 0l12 12h-8v12h-8v-12h-8z";case"circle":return"circle";case"cross":return"path://M11 2h2v9h9v2h-9v9h-2v-9h-9v-2h9z";case"diamond":return"diamond";case"flag":return"path://M6 2v20h2v-8h12l-2-6 2-6h-12z";case"labeldown":return"path://M4 2h16a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-6l-2 4l-2 -4h-6a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2z";case"labelup":return"path://M12 2l2 4h6a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-16a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h6z";case"square":return"rect";case"triangledown":return"path://M12 21l-10-18h20z";case"triangleup":return"triangle";case"xcross":return"path://M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z";default:return"circle"}}static getShapeRotation(e){return 0}static getShapeSize(e,t,i){if(t!==void 0&&i!==void 0)return[t,i];let s;switch(e){case"tiny":s=8;break;case"small":s=12;break;case"normal":case"auto":s=16;break;case"large":s=24;break;case"huge":s=32;break;default:s=16}return t!==void 0?[t,t]:i!==void 0?[i,i]:s}static getLabelConfig(e,t){switch(t){case"abovebar":return{position:"top",distance:5};case"belowbar":return{position:"bottom",distance:5};case"top":return{position:"bottom",distance:5};case"bottom":return{position:"top",distance:5};case"absolute":default:return e==="labelup"||e==="labeldown"?{position:"inside",distance:0}:{position:"top",distance:5}}}static buildIndicatorSeries(e,t,i,s,o=0,n,p,d=1){const r=[],k=new Array(s).fill(null);return e.forEach((f,b)=>{f.collapsed||Object.keys(f.plots).forEach(I=>{const u=f.plots[I],y=`${b}::${I}`;let v=0,E=0;const V=u.options.overlay;if(V!==void 0?V:f.paneIndex===0)v=0,p&&p.has(y)?E=p.get(y):E=0;else{const w=i.findIndex(T=>T.index===f.paneIndex);w!==-1&&(v=w+1,E=d+w)}const N=new Array(s).fill(null),x=new Array(s).fill(null),M=new Array(s).fill(null);switch(u.data.forEach(w=>{const T=t.get(w.time);if(T!==void 0){const P=w.options?.offset??u.options.offset??0,c=T+o+P;if(c>=0&&c<s){let a=w.value;const g=w.options?.color;(g===null||g==="na"||g==="NaN"||typeof g=="number"&&isNaN(g))&&(a=null),N[c]=a,x[c]=g||u.options.color,M[c]=w.options||{}}}}),u.options.style){case"histogram":case"columns":r.push({name:y,type:"bar",xAxisIndex:v,yAxisIndex:E,data:N.map((c,a)=>({value:c,itemStyle:x[a]?{color:x[a]}:void 0})),itemStyle:{color:u.options.color}});break;case"circles":case"cross":const w=N.map((c,a)=>{if(c===null)return null;const g=x[a]||u.options.color,m={value:[a,c],itemStyle:{color:g}};return u.options.style==="cross"?(m.symbol=`image://${xt("+",g,"24px")}`,m.symbolSize=16):(m.symbol="circle",m.symbolSize=6),m}).filter(c=>c!==null);r.push({name:y,type:"scatter",xAxisIndex:v,yAxisIndex:E,data:w});break;case"bar":case"candle":const T=N.map((c,a)=>{if(c===null||!Array.isArray(c)||c.length!==4)return null;const[g,m,S,Z]=c,z=M[a]||{},G=z.color||x[a]||u.options.color,F=z.wickcolor||u.options.wickcolor||G,H=z.bordercolor||u.options.bordercolor||F;return[a,g,Z,S,m,G,F,H]}).filter(c=>c!==null);r.push({name:y,type:"custom",xAxisIndex:v,yAxisIndex:E,renderItem:(c,a)=>{const g=a.value(0),m=a.value(1),S=a.value(2),Z=a.value(3),z=a.value(4),G=a.value(5),F=a.value(6),H=a.value(7);if(isNaN(m)||isNaN(S)||isNaN(Z)||isNaN(z))return null;const X=a.coord([g,0])[0],_=a.coord([g,m])[1],Y=a.coord([g,S])[1],h=a.coord([g,Z])[1],C=a.coord([g,z])[1],A=a.size([1,0])[0]*.6;if(u.options.style==="candle"){const $=Math.min(_,Y),R=Math.max(_,Y),D=Math.abs(Y-_);return{type:"group",children:[{type:"line",shape:{x1:X,y1:C,x2:X,y2:$},style:{stroke:F,lineWidth:1}},{type:"line",shape:{x1:X,y1:R,x2:X,y2:h},style:{stroke:F,lineWidth:1}},{type:"rect",shape:{x:X-A/2,y:$,width:A,height:D||1},style:{fill:G,stroke:H,lineWidth:1}}]}}else{const $=A*.5;return{type:"group",children:[{type:"line",shape:{x1:X,y1:h,x2:X,y2:C},style:{stroke:G,lineWidth:1}},{type:"line",shape:{x1:X-$,y1:_,x2:X,y2:_},style:{stroke:G,lineWidth:1}},{type:"line",shape:{x1:X,y1:Y,x2:X+$,y2:Y},style:{stroke:G,lineWidth:1}}]}}},data:T});break;case"shape":const P=N.map((c,a)=>{const g=M[a]||{},m=u.options,S=g.location||m.location||"absolute";if(S!=="absolute"&&!c||c==null)return null;const Z=g.color||m.color||"blue",z=g.shape||m.shape||"circle",G=g.size||m.size||"normal",F=g.text||m.text,H=g.textcolor||m.textcolor||"white",X=g.width||m.width,_=g.height||m.height;let Y=c,h=[0,0];S==="abovebar"?(n&&n[a]&&(Y=n[a].high),h=[0,"-150%"]):S==="belowbar"?(n&&n[a]&&(Y=n[a].low),h=[0,"150%"]):S==="top"?(Y=c,h=[0,0]):S==="bottom"&&(Y=c,h=[0,0]);const C=st.getShapeSymbol(z),A=st.getShapeSize(G,X,_),$=st.getShapeRotation(z);let R=A;z.includes("label")&&(Array.isArray(A)?R=[A[0]*2.5,A[1]*2.5]:R=A*2.5);const D=st.getLabelConfig(z,S);return{value:[a,Y],symbol:C,symbolSize:R,symbolRotate:$,symbolOffset:h,itemStyle:{color:Z},label:{show:!!F,position:D.position,distance:D.distance,formatter:F,color:H,fontSize:10,fontWeight:"bold"}}}).filter(c=>c!==null);r.push({name:y,type:"scatter",xAxisIndex:v,yAxisIndex:E,data:P});break;case"background":r.push({name:y,type:"custom",xAxisIndex:v,yAxisIndex:E,z:-10,renderItem:(c,a)=>{const g=a.value(0);if(isNaN(g))return;const m=a.coord([g,0]),S=a.size([1,0])[0],Z=c.coordSys,z=m[0]-S/2,G=x[c.dataIndex],F=a.value(1);if(!(!G||F===null||F===void 0||isNaN(F)))return{type:"rect",shape:{x:z,y:Z.y,width:S,height:Z.height},style:{fill:G,opacity:.3},silent:!0}},data:N.map((c,a)=>[a,c])});break;case"step":r.push({name:y,type:"custom",xAxisIndex:v,yAxisIndex:E,renderItem:(c,a)=>{const g=a.value(0),m=a.value(1);if(isNaN(m)||m===null)return;const S=a.coord([g,m]),Z=a.size([1,0])[0];return{type:"line",shape:{x1:S[0]-Z/2,y1:S[1],x2:S[0]+Z/2,y2:S[1]},style:{stroke:x[c.dataIndex]||u.options.color,lineWidth:u.options.linewidth||1},silent:!0}},data:N.map((c,a)=>[a,c])});break;case"barcolor":u.data.forEach(c=>{const a=t.get(c.time);if(a!==void 0){const g=c.options?.offset??u.options.offset??0,m=a+o+g;if(m>=0&&m<s){const S=c.options?.color||u.options.color;!(S===null||S==="na"||S==="NaN"||typeof S=="number"&&isNaN(S))&&c.value!==null&&c.value!==void 0&&(k[m]=S)}}});break;case"char":r.push({name:y,type:"scatter",xAxisIndex:v,yAxisIndex:E,symbolSize:0,data:N.map((c,a)=>({value:[a,c],itemStyle:{opacity:0}})),silent:!0});break;case"line":default:r.push({name:y,type:"custom",xAxisIndex:v,yAxisIndex:E,renderItem:(c,a)=>{const g=c.dataIndex;if(g===0)return;const m=a.value(1),S=a.value(2);if(m===null||isNaN(m)||S===null||isNaN(S))return;const Z=a.coord([g-1,S]),z=a.coord([g,m]);return{type:"line",shape:{x1:Z[0],y1:Z[1],x2:z[0],y2:z[1]},style:{stroke:x[g]||u.options.color,lineWidth:u.options.linewidth||1},silent:!0}},data:N.map((c,a)=>[a,c,a>0?N[a-1]:null])});break}})}),{series:r,barColors:k}}}class mt{static build(e,t,i,s=!1,o=null){const n=[],p=e.pixelToPercent,d=e.mainPaneTop;if(!o||o==="main"){const r=10*p;if(n.push({type:"text",left:"8.5%",top:d+r+"%",z:10,style:{text:t.title||"Market",fill:t.titleColor||"#fff",font:`bold 16px ${t.fontFamily||"sans-serif"}`,textVerticalAlign:"top"}}),t.watermark!==!1){const f=e.mainPaneTop+e.mainPaneHeight;n.push({type:"text",right:"11%",top:f-3+"%",z:10,style:{text:"QFChart",fill:t.fontColor||"#cbd5e1",font:"bold 16px sans-serif",opacity:.1},cursor:"pointer",onclick:()=>{window.open("https://quantforge.org","_blank")}})}const k=[];if(t.controls?.collapse&&k.push({type:"group",children:[{type:"rect",shape:{width:20,height:20,r:2},style:{fill:"#334155",stroke:"#475569",lineWidth:1},onclick:()=>i("main","collapse")},{type:"text",style:{text:s?"+":"\u2212",fill:"#cbd5e1",font:`bold 14px ${t.fontFamily}`,x:10,y:10,textAlign:"center",textVerticalAlign:"middle"},silent:!0}]}),t.controls?.maximize){const f=o==="main",b=t.controls?.collapse?25:0;k.push({type:"group",x:b,children:[{type:"rect",shape:{width:20,height:20,r:2},style:{fill:"#334155",stroke:"#475569",lineWidth:1},onclick:()=>i("main","maximize")},{type:"text",style:{text:f?"\u2750":"\u25A1",fill:"#cbd5e1",font:`14px ${t.fontFamily}`,x:10,y:10,textAlign:"center",textVerticalAlign:"middle"},silent:!0}]})}if(t.controls?.fullscreen){let f=0;t.controls?.collapse&&(f+=25),t.controls?.maximize&&(f+=25),k.push({type:"group",x:f,children:[{type:"rect",shape:{width:20,height:20,r:2},style:{fill:"#334155",stroke:"#475569",lineWidth:1},onclick:()=>i("main","fullscreen")},{type:"text",style:{text:"\u26F6",fill:"#cbd5e1",font:`14px ${t.fontFamily}`,x:10,y:10,textAlign:"center",textVerticalAlign:"middle"},silent:!0}]})}k.length>0&&n.push({type:"group",right:"10.5%",top:d+"%",children:k})}return e.paneLayout.forEach(r=>{if(o&&r.indicatorId!==o)return;n.push({type:"text",left:"8.5%",top:r.top+10*p+"%",z:10,style:{text:r.indicatorId||"",fill:r.titleColor||"#fff",font:`bold 12px ${t.fontFamily||"sans-serif"}`,textVerticalAlign:"top"}});const k=[];if(r.controls?.collapse&&k.push({type:"group",children:[{type:"rect",shape:{width:20,height:20,r:2},style:{fill:"#334155",stroke:"#475569",lineWidth:1},onclick:()=>r.indicatorId&&i(r.indicatorId,"collapse")},{type:"text",style:{text:r.isCollapsed?"+":"\u2212",fill:"#cbd5e1",font:`bold 14px ${t.fontFamily}`,x:10,y:10,textAlign:"center",textVerticalAlign:"middle"},silent:!0}]}),r.controls?.maximize){const f=o===r.indicatorId,b=r.controls?.collapse?25:0;k.push({type:"group",x:b,children:[{type:"rect",shape:{width:20,height:20,r:2},style:{fill:"#334155",stroke:"#475569",lineWidth:1},onclick:()=>r.indicatorId&&i(r.indicatorId,"maximize")},{type:"text",style:{text:f?"\u2750":"\u25A1",fill:"#cbd5e1",font:`14px ${t.fontFamily}`,x:10,y:10,textAlign:"center",textVerticalAlign:"middle"},silent:!0}]})}k.length>0&&n.push({type:"group",right:"10.5%",top:r.top+"%",children:k})}),n}}class bt{static format(e,t){if(!e||e.length===0)return"";const i=t.title||"Market",s=t.upColor||"#00da3c",o=t.downColor||"#ec0000",n=t.fontFamily||"sans-serif",p=e[0].axisValue;let d=`<div style="font-weight: bold; margin-bottom: 5px; color: #cbd5e1; font-family: ${n};">${p}</div>`;const r=e.find(f=>f.seriesType==="candlestick"),k=e.filter(f=>f.seriesType!=="candlestick");if(r){const[f,b,I,u,y]=r.value,v=I>=b?s:o;d+=`
|
|
17
|
+
import*as q from"echarts";var gt=Object.defineProperty,yt=(l,e,t)=>e in l?gt(l,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[e]=t,nt=(l,e,t)=>(yt(l,typeof e!="symbol"?e+"":e,t),t);class ft{constructor(e,t,i,s={}){nt(this,"id"),nt(this,"plots"),nt(this,"paneIndex"),nt(this,"height"),nt(this,"collapsed"),nt(this,"titleColor"),nt(this,"controls"),this.id=e,this.plots=t,this.paneIndex=i,this.height=s.height,this.collapsed=s.collapsed||!1,this.titleColor=s.titleColor,this.controls=s.controls}toggleCollapse(){this.collapsed=!this.collapsed}isVisible(){return!this.collapsed}updateData(e){Object.keys(e).forEach(t=>{if(!this.plots[t])this.plots[t]=e[t];else{const i=this.plots[t],s=e[t];s.options&&(i.options={...i.options,...s.options});const o=new Map;i.data.forEach(n=>{o.set(n.time,n)}),s.data.forEach(n=>{o.set(n.time,n)}),i.data=Array.from(o.values()).sort((n,p)=>n.time-p.time)}})}}class ut{static calculate(e,t,i,s=!1,o=null,n){let p=0;e>0&&(p=1/e*100);const d=i.yAxisPadding!==void 0?i.yAxisPadding:5,r=h=>C=>{const M=(C.max-C.min)*(h/100);return C.min-M},k=h=>C=>{const M=(C.max-C.min)*(h/100);return C.max+M},f=Array.from(t.values()).map(h=>h.paneIndex).filter(h=>h>0).sort((h,C)=>h-C).filter((h,C,M)=>M.indexOf(h)===C),m=f.length>0,S=i.dataZoom?.visible??!0,u=i.dataZoom?.position??"top",y=i.dataZoom?.height??6,v=i.dataZoom?.start??0,E=i.dataZoom?.end??100;let V=8,N=92,x=-1;if(o)if(o==="main")x=0;else{const h=t.get(o);h&&(x=h.paneIndex)}if(x!==-1){const h=[],C=[],M=[],$=[],R=i.dataZoom?.start??50,D=i.dataZoom?.end??100;(i.dataZoom?.zoomOnTouch??!0)&&$.push({type:"inside",xAxisIndex:"all",start:R,end:D});const W=m?Math.max(...f):0,j=[];for(let O=0;O<=W;O++){const B=O===x;h.push({left:"10%",right:"10%",top:B?"5%":"0%",height:B?"90%":"0%",show:B,containLabel:!1}),C.push({type:"category",gridIndex:O,data:[],show:B,axisLabel:{show:B,color:"#94a3b8",fontFamily:i.fontFamily},axisLine:{show:B,lineStyle:{color:"#334155"}},splitLine:{show:B,lineStyle:{color:"#334155",opacity:.5}}});let tt,et;if(O===0&&x===0?(tt=i.yAxisMin!==void 0&&i.yAxisMin!=="auto"?i.yAxisMin:r(d),et=i.yAxisMax!==void 0&&i.yAxisMax!=="auto"?i.yAxisMax:k(d)):(tt=r(d),et=k(d)),M.push({position:"right",gridIndex:O,show:B,scale:!0,min:tt,max:et,axisLabel:{show:B,color:"#94a3b8",fontFamily:i.fontFamily,formatter:Q=>{if(i.yAxisLabelFormatter)return i.yAxisLabelFormatter(Q);const it=i.yAxisDecimalPlaces!==void 0?i.yAxisDecimalPlaces:2;return typeof Q=="number"?Q.toFixed(it):String(Q)}},splitLine:{show:B,lineStyle:{color:"#334155",opacity:.5}}}),O>0){const Q=Array.from(t.values()).find(it=>it.paneIndex===O);Q&&j.push({index:O,height:B?90:0,top:B?5:0,isCollapsed:!1,indicatorId:Q.id,titleColor:Q.titleColor,controls:Q.controls})}}return{grid:h,xAxis:C,yAxis:M,dataZoom:$,paneLayout:j,mainPaneHeight:x===0?90:0,mainPaneTop:x===0?5:0,pixelToPercent:p,overlayYAxisMap:new Map,separatePaneYAxisOffset:1}}S?u==="top"?(V=y+4,N=95):(N=100-y-2,V=8):(V=5,N=95);let A=5;e>0&&(A=20/e*100);let w=75,T=[];if(m){const h=f.map(D=>{const W=Array.from(t.values()).find(j=>j.paneIndex===D);return{index:D,requestedHeight:W?.height,isCollapsed:W?.collapsed??!1,indicatorId:W?.id,titleColor:W?.titleColor,controls:W?.controls}}).map(D=>({...D,height:D.isCollapsed?3:D.requestedHeight!==void 0?D.requestedHeight:15})),C=h.reduce((D,W)=>D+W.height,0),M=h.length*A,$=C+M;w=N-V-$,s?w=3:w<20&&(w=Math.max(w,10));let R=V+w+A;T=h.map(D=>{const W={index:D.index,height:D.height,top:R,isCollapsed:D.isCollapsed,indicatorId:D.indicatorId,titleColor:D.titleColor,controls:D.controls};return R+=D.height+A,W})}else w=N-V,s&&(w=3);const P=[];P.push({left:"10%",right:"10%",top:V+"%",height:w+"%",containLabel:!1}),T.forEach(h=>{P.push({left:"10%",right:"10%",top:h.top+"%",height:h.height+"%",containLabel:!1})});const c=[0,...T.map((h,C)=>C+1)],a=[],g=T.length===0;a.push({type:"category",data:[],gridIndex:0,scale:!0,axisLine:{onZero:!1,show:!s,lineStyle:{color:"#334155"}},splitLine:{show:!s,lineStyle:{color:"#334155",opacity:.5}},axisLabel:{show:!s,color:"#94a3b8",fontFamily:i.fontFamily||"sans-serif",formatter:h=>{if(i.yAxisLabelFormatter)return i.yAxisLabelFormatter(h);const C=i.yAxisDecimalPlaces!==void 0?i.yAxisDecimalPlaces:2;return typeof h=="number"?h.toFixed(C):String(h)}},axisTick:{show:!s},axisPointer:{label:{show:g,fontSize:11,backgroundColor:"#475569"}}}),T.forEach((h,C)=>{const M=C===T.length-1;a.push({type:"category",gridIndex:C+1,data:[],axisLabel:{show:!1},axisLine:{show:!h.isCollapsed,lineStyle:{color:"#334155"}},axisTick:{show:!1},splitLine:{show:!1},axisPointer:{label:{show:M,fontSize:11,backgroundColor:"#475569"}}})});const b=[];let I,Z;i.yAxisMin!==void 0&&i.yAxisMin!=="auto"?I=i.yAxisMin:I=r(d),i.yAxisMax!==void 0&&i.yAxisMax!=="auto"?Z=i.yAxisMax:Z=k(d),b.push({position:"right",scale:!0,min:I,max:Z,gridIndex:0,splitLine:{show:!s,lineStyle:{color:"#334155",opacity:.5}},axisLine:{show:!s,lineStyle:{color:"#334155"}},axisLabel:{show:!s,color:"#94a3b8",fontFamily:i.fontFamily||"sans-serif",formatter:h=>{if(i.yAxisLabelFormatter)return i.yAxisLabelFormatter(h);const C=i.yAxisDecimalPlaces!==void 0?i.yAxisDecimalPlaces:2;return typeof h=="number"?h.toFixed(C):String(h)}}});let z=1,G=-1/0,F=1/0;n&&n.length>0&&(G=Math.min(...n.map(h=>h.low)),F=Math.max(...n.map(h=>h.high)));const H=new Map;t.forEach((h,C)=>{h.paneIndex===0&&!h.collapsed&&n&&n.length>0&&Object.entries(h.plots).forEach(([M,$])=>{const R=`${C}::${M}`,D=["background","barcolor","char"],W=$.options.style==="shape"&&($.options.location==="abovebar"||$.options.location==="belowbar");if(D.includes($.options.style)){H.has(R)||(H.set(R,z),z++);return}if($.options.style==="shape"&&!W){H.has(R)||(H.set(R,z),z++);return}const j=[];if(Object.values($.data).forEach(O=>{typeof O=="number"&&!isNaN(O)&&isFinite(O)&&j.push(O)}),j.length>0){const O=Math.min(...j),B=Math.max(...j),tt=B-O,et=F-G,Q=O>=G*.5&&B<=F*1.5,it=tt>et*.01;Q&&it||H.has(R)||(H.set(R,z),z++)}})});const X=H.size>0?z-1:0;for(let h=0;h<X;h++)b.push({position:"left",scale:!0,min:r(d),max:k(d),gridIndex:0,show:!1,splitLine:{show:!1},axisLine:{show:!1},axisLabel:{show:!1}});const _=z;T.forEach((h,C)=>{b.push({position:"right",scale:!0,min:r(d),max:k(d),gridIndex:C+1,splitLine:{show:!h.isCollapsed,lineStyle:{color:"#334155",opacity:.3}},axisLabel:{show:!h.isCollapsed,color:"#94a3b8",fontFamily:i.fontFamily||"sans-serif",fontSize:10,formatter:M=>{if(i.yAxisLabelFormatter)return i.yAxisLabelFormatter(M);const $=i.yAxisDecimalPlaces!==void 0?i.yAxisDecimalPlaces:2;return typeof M=="number"?M.toFixed($):String(M)}},axisLine:{show:!h.isCollapsed,lineStyle:{color:"#334155"}}})});const Y=[];return S&&((i.dataZoom?.zoomOnTouch??!0)&&Y.push({type:"inside",xAxisIndex:c,start:v,end:E}),u==="top"?Y.push({type:"slider",xAxisIndex:c,top:"1%",height:y+"%",start:v,end:E,borderColor:"#334155",textStyle:{color:"#cbd5e1"},brushSelect:!1}):Y.push({type:"slider",xAxisIndex:c,bottom:"1%",height:y+"%",start:v,end:E,borderColor:"#334155",textStyle:{color:"#cbd5e1"},brushSelect:!1})),{grid:P,xAxis:a,yAxis:b,dataZoom:Y,paneLayout:T,mainPaneHeight:w,mainPaneTop:V,pixelToPercent:p,overlayYAxisMap:H,separatePaneYAxisOffset:_}}static calculateMaximized(e,t,i){return{grid:[],xAxis:[],yAxis:[],dataZoom:[],paneLayout:[],mainPaneHeight:0,mainPaneTop:0,pixelToPercent:0}}}const pt=new Map;function xt(l,e="#00da3c",t="64px"){if(typeof document>"u")return"";const i=`${l}-${e}-${t}`;if(pt.has(i))return pt.get(i);const s=document.createElement("canvas"),o=s.getContext("2d");if(s.width=32,s.height=32,o){o.font="bold "+t+" Arial",o.fillStyle=e,o.textAlign="center",o.textBaseline="middle",o.fillText(l,16,16);const n=s.toDataURL("image/png");return pt.set(i,n),n}return""}class st{static buildCandlestickSeries(e,t,i){const s=t.upColor||"#00da3c",o=t.downColor||"#ec0000",n=e.map(d=>[d.open,d.close,d.low,d.high]);if(i&&i>n.length){const d=i-n.length;for(let r=0;r<d;r++)n.push(null)}let p;if(t.lastPriceLine?.visible!==!1&&e.length>0){const d=e[e.length-1],r=d.close,k=d.close>=d.open,f=t.lastPriceLine?.color||(k?s:o);let m=t.lastPriceLine?.lineStyle||"dashed";m.startsWith("linestyle_")&&(m=m.replace("linestyle_","")),p={symbol:["none","none"],data:[{yAxis:r,label:{show:!0,position:"end",formatter:S=>{if(t.yAxisLabelFormatter)return t.yAxisLabelFormatter(S.value);const u=t.yAxisDecimalPlaces!==void 0?t.yAxisDecimalPlaces:2;return typeof S.value=="number"?S.value.toFixed(u):S.value},color:"#fff",backgroundColor:f,padding:[2,4],borderRadius:2,fontSize:11,fontWeight:"bold"},lineStyle:{color:f,type:m,width:1,opacity:.8}}],animation:!1,silent:!0}}return{type:"candlestick",name:t.title||"Market",data:n,itemStyle:{color:s,color0:o,borderColor:s,borderColor0:o},markLine:p,xAxisIndex:0,yAxisIndex:0,z:5}}static getShapeSymbol(e){switch(e){case"arrowdown":return"path://M12 24l-12-12h8v-12h8v12h8z";case"arrowup":return"path://M12 0l12 12h-8v12h-8v-12h-8z";case"circle":return"circle";case"cross":return"path://M11 2h2v9h9v2h-9v9h-2v-9h-9v-2h9z";case"diamond":return"diamond";case"flag":return"path://M6 2v20h2v-8h12l-2-6 2-6h-12z";case"labeldown":return"path://M4 2h16a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-6l-2 4l-2 -4h-6a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2z";case"labelup":return"path://M12 2l2 4h6a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-16a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h6z";case"square":return"rect";case"triangledown":return"path://M12 21l-10-18h20z";case"triangleup":return"triangle";case"xcross":return"path://M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z";default:return"circle"}}static getShapeRotation(e){return 0}static getShapeSize(e,t,i){if(t!==void 0&&i!==void 0)return[t,i];let s;switch(e){case"tiny":s=8;break;case"small":s=12;break;case"normal":case"auto":s=16;break;case"large":s=24;break;case"huge":s=32;break;default:s=16}return t!==void 0?[t,t]:i!==void 0?[i,i]:s}static getLabelConfig(e,t){switch(t){case"abovebar":return{position:"top",distance:5};case"belowbar":return{position:"bottom",distance:5};case"top":return{position:"bottom",distance:5};case"bottom":return{position:"top",distance:5};case"absolute":default:return e==="labelup"||e==="labeldown"?{position:"inside",distance:0}:{position:"top",distance:5}}}static buildIndicatorSeries(e,t,i,s,o=0,n,p,d=1){const r=[],k=new Array(s).fill(null);return e.forEach((f,m)=>{f.collapsed||Object.keys(f.plots).forEach(S=>{const u=f.plots[S],y=`${m}::${S}`;let v=0,E=0;const V=u.options.overlay;if(V!==void 0?V:f.paneIndex===0)v=0,p&&p.has(y)?E=p.get(y):E=0;else{const w=i.findIndex(T=>T.index===f.paneIndex);w!==-1&&(v=w+1,E=d+w)}const N=new Array(s).fill(null),x=new Array(s).fill(null),A=new Array(s).fill(null);switch(u.data.forEach(w=>{const T=t.get(w.time);if(T!==void 0){const P=w.options?.offset??u.options.offset??0,c=T+o+P;if(c>=0&&c<s){let a=w.value;const g=w.options?.color;(g===null||g==="na"||g==="NaN"||typeof g=="number"&&isNaN(g))&&(a=null),N[c]=a,x[c]=g||u.options.color,A[c]=w.options||{}}}}),u.options?.style?.startsWith("style_")&&(u.options.style=u.options.style.replace("style_","")),u.options.style){case"histogram":case"columns":r.push({name:y,type:"bar",xAxisIndex:v,yAxisIndex:E,data:N.map((c,a)=>({value:c,itemStyle:x[a]?{color:x[a]}:void 0})),itemStyle:{color:u.options.color}});break;case"circles":case"cross":const w=N.map((c,a)=>{if(c===null)return null;const g=x[a]||u.options.color,b={value:[a,c],itemStyle:{color:g}};return u.options.style==="cross"?(b.symbol=`image://${xt("+",g,"24px")}`,b.symbolSize=16):(b.symbol="circle",b.symbolSize=6),b}).filter(c=>c!==null);r.push({name:y,type:"scatter",xAxisIndex:v,yAxisIndex:E,data:w});break;case"bar":case"candle":const T=N.map((c,a)=>{if(c===null||!Array.isArray(c)||c.length!==4)return null;const[g,b,I,Z]=c,z=A[a]||{},G=z.color||x[a]||u.options.color,F=z.wickcolor||u.options.wickcolor||G,H=z.bordercolor||u.options.bordercolor||F;return[a,g,Z,I,b,G,F,H]}).filter(c=>c!==null);r.push({name:y,type:"custom",xAxisIndex:v,yAxisIndex:E,renderItem:(c,a)=>{const g=a.value(0),b=a.value(1),I=a.value(2),Z=a.value(3),z=a.value(4),G=a.value(5),F=a.value(6),H=a.value(7);if(isNaN(b)||isNaN(I)||isNaN(Z)||isNaN(z))return null;const X=a.coord([g,0])[0],_=a.coord([g,b])[1],Y=a.coord([g,I])[1],h=a.coord([g,Z])[1],C=a.coord([g,z])[1],M=a.size([1,0])[0]*.6;if(u.options.style==="candle"){const $=Math.min(_,Y),R=Math.max(_,Y),D=Math.abs(Y-_);return{type:"group",children:[{type:"line",shape:{x1:X,y1:C,x2:X,y2:$},style:{stroke:F,lineWidth:1}},{type:"line",shape:{x1:X,y1:R,x2:X,y2:h},style:{stroke:F,lineWidth:1}},{type:"rect",shape:{x:X-M/2,y:$,width:M,height:D||1},style:{fill:G,stroke:H,lineWidth:1}}]}}else{const $=M*.5;return{type:"group",children:[{type:"line",shape:{x1:X,y1:h,x2:X,y2:C},style:{stroke:G,lineWidth:1}},{type:"line",shape:{x1:X-$,y1:_,x2:X,y2:_},style:{stroke:G,lineWidth:1}},{type:"line",shape:{x1:X,y1:Y,x2:X+$,y2:Y},style:{stroke:G,lineWidth:1}}]}}},data:T});break;case"shape":const P=N.map((c,a)=>{const g=A[a]||{},b=u.options,I=g.location||b.location||"absolute";if(I!=="absolute"&&!c||c==null)return null;const Z=g.color||b.color||"blue",z=g.shape||b.shape||"circle",G=g.size||b.size||"normal",F=g.text||b.text,H=g.textcolor||b.textcolor||"white",X=g.width||b.width,_=g.height||b.height;let Y=c,h=[0,0];I==="abovebar"?(n&&n[a]&&(Y=n[a].high),h=[0,"-150%"]):I==="belowbar"?(n&&n[a]&&(Y=n[a].low),h=[0,"150%"]):I==="top"?(Y=c,h=[0,0]):I==="bottom"&&(Y=c,h=[0,0]);const C=st.getShapeSymbol(z),M=st.getShapeSize(G,X,_),$=st.getShapeRotation(z);let R=M;z.includes("label")&&(Array.isArray(M)?R=[M[0]*2.5,M[1]*2.5]:R=M*2.5);const D=st.getLabelConfig(z,I);return{value:[a,Y],symbol:C,symbolSize:R,symbolRotate:$,symbolOffset:h,itemStyle:{color:Z},label:{show:!!F,position:D.position,distance:D.distance,formatter:F,color:H,fontSize:10,fontWeight:"bold"}}}).filter(c=>c!==null);r.push({name:y,type:"scatter",xAxisIndex:v,yAxisIndex:E,data:P});break;case"background":r.push({name:y,type:"custom",xAxisIndex:v,yAxisIndex:E,z:-10,renderItem:(c,a)=>{const g=a.value(0);if(isNaN(g))return;const b=a.coord([g,0]),I=a.size([1,0])[0],Z=c.coordSys,z=b[0]-I/2,G=x[c.dataIndex],F=a.value(1);if(!(!G||F===null||F===void 0||isNaN(F)))return{type:"rect",shape:{x:z,y:Z.y,width:I,height:Z.height},style:{fill:G,opacity:.3},silent:!0}},data:N.map((c,a)=>[a,c])});break;case"step":r.push({name:y,type:"custom",xAxisIndex:v,yAxisIndex:E,renderItem:(c,a)=>{const g=a.value(0),b=a.value(1);if(isNaN(b)||b===null)return;const I=a.coord([g,b]),Z=a.size([1,0])[0];return{type:"line",shape:{x1:I[0]-Z/2,y1:I[1],x2:I[0]+Z/2,y2:I[1]},style:{stroke:x[c.dataIndex]||u.options.color,lineWidth:u.options.linewidth||1},silent:!0}},data:N.map((c,a)=>[a,c])});break;case"barcolor":u.data.forEach(c=>{const a=t.get(c.time);if(a!==void 0){const g=c.options?.offset??u.options.offset??0,b=a+o+g;if(b>=0&&b<s){const I=c.options?.color||u.options.color;!(I===null||I==="na"||I==="NaN"||typeof I=="number"&&isNaN(I))&&c.value!==null&&c.value!==void 0&&(k[b]=I)}}});break;case"char":r.push({name:y,type:"scatter",xAxisIndex:v,yAxisIndex:E,symbolSize:0,data:N.map((c,a)=>({value:[a,c],itemStyle:{opacity:0}})),silent:!0});break;case"line":default:r.push({name:y,type:"custom",xAxisIndex:v,yAxisIndex:E,renderItem:(c,a)=>{const g=c.dataIndex;if(g===0)return;const b=a.value(1),I=a.value(2);if(b===null||isNaN(b)||I===null||isNaN(I))return;const Z=a.coord([g-1,I]),z=a.coord([g,b]);return{type:"line",shape:{x1:Z[0],y1:Z[1],x2:z[0],y2:z[1]},style:{stroke:x[g]||u.options.color,lineWidth:u.options.linewidth||1},silent:!0}},data:N.map((c,a)=>[a,c,a>0?N[a-1]:null])});break}})}),{series:r,barColors:k}}}class mt{static build(e,t,i,s=!1,o=null){const n=[],p=e.pixelToPercent,d=e.mainPaneTop;if(!o||o==="main"){const r=10*p;if(n.push({type:"text",left:"8.5%",top:d+r+"%",z:10,style:{text:t.title||"Market",fill:t.titleColor||"#fff",font:`bold 16px ${t.fontFamily||"sans-serif"}`,textVerticalAlign:"top"}}),t.watermark!==!1){const f=e.mainPaneTop+e.mainPaneHeight;n.push({type:"text",right:"11%",top:f-3+"%",z:10,style:{text:"QFChart",fill:t.fontColor||"#cbd5e1",font:"bold 16px sans-serif",opacity:.1},cursor:"pointer",onclick:()=>{window.open("https://quantforge.org","_blank")}})}const k=[];if(t.controls?.collapse&&k.push({type:"group",children:[{type:"rect",shape:{width:20,height:20,r:2},style:{fill:"#334155",stroke:"#475569",lineWidth:1},onclick:()=>i("main","collapse")},{type:"text",style:{text:s?"+":"\u2212",fill:"#cbd5e1",font:`bold 14px ${t.fontFamily}`,x:10,y:10,textAlign:"center",textVerticalAlign:"middle"},silent:!0}]}),t.controls?.maximize){const f=o==="main",m=t.controls?.collapse?25:0;k.push({type:"group",x:m,children:[{type:"rect",shape:{width:20,height:20,r:2},style:{fill:"#334155",stroke:"#475569",lineWidth:1},onclick:()=>i("main","maximize")},{type:"text",style:{text:f?"\u2750":"\u25A1",fill:"#cbd5e1",font:`14px ${t.fontFamily}`,x:10,y:10,textAlign:"center",textVerticalAlign:"middle"},silent:!0}]})}if(t.controls?.fullscreen){let f=0;t.controls?.collapse&&(f+=25),t.controls?.maximize&&(f+=25),k.push({type:"group",x:f,children:[{type:"rect",shape:{width:20,height:20,r:2},style:{fill:"#334155",stroke:"#475569",lineWidth:1},onclick:()=>i("main","fullscreen")},{type:"text",style:{text:"\u26F6",fill:"#cbd5e1",font:`14px ${t.fontFamily}`,x:10,y:10,textAlign:"center",textVerticalAlign:"middle"},silent:!0}]})}k.length>0&&n.push({type:"group",right:"10.5%",top:d+"%",children:k})}return e.paneLayout.forEach(r=>{if(o&&r.indicatorId!==o)return;n.push({type:"text",left:"8.5%",top:r.top+10*p+"%",z:10,style:{text:r.indicatorId||"",fill:r.titleColor||"#fff",font:`bold 12px ${t.fontFamily||"sans-serif"}`,textVerticalAlign:"top"}});const k=[];if(r.controls?.collapse&&k.push({type:"group",children:[{type:"rect",shape:{width:20,height:20,r:2},style:{fill:"#334155",stroke:"#475569",lineWidth:1},onclick:()=>r.indicatorId&&i(r.indicatorId,"collapse")},{type:"text",style:{text:r.isCollapsed?"+":"\u2212",fill:"#cbd5e1",font:`bold 14px ${t.fontFamily}`,x:10,y:10,textAlign:"center",textVerticalAlign:"middle"},silent:!0}]}),r.controls?.maximize){const f=o===r.indicatorId,m=r.controls?.collapse?25:0;k.push({type:"group",x:m,children:[{type:"rect",shape:{width:20,height:20,r:2},style:{fill:"#334155",stroke:"#475569",lineWidth:1},onclick:()=>r.indicatorId&&i(r.indicatorId,"maximize")},{type:"text",style:{text:f?"\u2750":"\u25A1",fill:"#cbd5e1",font:`14px ${t.fontFamily}`,x:10,y:10,textAlign:"center",textVerticalAlign:"middle"},silent:!0}]})}k.length>0&&n.push({type:"group",right:"10.5%",top:r.top+"%",children:k})}),n}}class bt{static format(e,t){if(!e||e.length===0)return"";const i=t.title||"Market",s=t.upColor||"#00da3c",o=t.downColor||"#ec0000",n=t.fontFamily||"sans-serif",p=e[0].axisValue;let d=`<div style="font-weight: bold; margin-bottom: 5px; color: #cbd5e1; font-family: ${n};">${p}</div>`;const r=e.find(f=>f.seriesType==="candlestick"),k=e.filter(f=>f.seriesType!=="candlestick");if(r){const[f,m,S,u,y]=r.value,v=S>=m?s:o;d+=`
|
|
18
18
|
<div style="margin-bottom: 8px; font-family: ${n};">
|
|
19
19
|
<div style="display:flex; justify-content:space-between; color:${v}; font-weight:bold;">
|
|
20
20
|
<span>${i}</span>
|
|
21
21
|
</div>
|
|
22
22
|
<div style="display: grid; grid-template-columns: auto auto; gap: 2px 15px; font-size: 0.9em; color: #cbd5e1;">
|
|
23
|
-
<span>Open:</span> <span style="text-align: right; color: ${
|
|
23
|
+
<span>Open:</span> <span style="text-align: right; color: ${S>=m?s:o}">${m}</span>
|
|
24
24
|
<span>High:</span> <span style="text-align: right; color: ${s}">${y}</span>
|
|
25
25
|
<span>Low:</span> <span style="text-align: right; color: ${o}">${u}</span>
|
|
26
|
-
<span>Close:</span> <span style="text-align: right; color: ${
|
|
26
|
+
<span>Close:</span> <span style="text-align: right; color: ${S>=m?s:o}">${S}</span>
|
|
27
27
|
</div>
|
|
28
28
|
</div>
|
|
29
|
-
`}if(k.length>0){d+='<div style="border-top: 1px solid #334155; margin: 5px 0; padding-top: 5px;"></div>';const f={};k.forEach(
|
|
29
|
+
`}if(k.length>0){d+='<div style="border-top: 1px solid #334155; margin: 5px 0; padding-top: 5px;"></div>';const f={};k.forEach(m=>{const S=m.seriesName.split("::"),u=S.length>1?S[0]:"Unknown",y=S.length>1?S[1]:m.seriesName;f[u]||(f[u]=[]),f[u].push({...m,displayName:y})}),Object.keys(f).forEach(m=>{d+=`
|
|
30
30
|
<div style="margin-top: 8px; font-family: ${n};">
|
|
31
|
-
<div style="font-weight:bold; color: #fff; margin-bottom: 2px;">${
|
|
32
|
-
`,f[
|
|
31
|
+
<div style="font-weight:bold; color: #fff; margin-bottom: 2px;">${m}</div>
|
|
32
|
+
`,f[m].forEach(S=>{let u=S.value;if(Array.isArray(u)&&(u=u[1]),u==null)return;const y=typeof u=="number"?u.toLocaleString(void 0,{maximumFractionDigits:4}):u;d+=`
|
|
33
33
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 2px; padding-left: 8px;">
|
|
34
|
-
<div>${
|
|
34
|
+
<div>${S.marker} <span style="color: #cbd5e1;">${S.displayName}</span></div>
|
|
35
35
|
<div style="font-size: 10px; color: #fff;padding-left:10px;">${y}</div>
|
|
36
|
-
</div>`}),d+="</div>"})}return d}}var vt=Object.defineProperty,wt=(l,e,t)=>e in l?vt(l,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[e]=t,at=(l,e,t)=>(wt(l,typeof e!="symbol"?e+"":e,t),t);class Ct{constructor(e,t){at(this,"plugins",new Map),at(this,"activePluginId",null),at(this,"context"),at(this,"toolbarContainer"),at(this,"tooltipElement",null),at(this,"hideTimeout",null),this.context=e,this.toolbarContainer=t,this.createTooltip(),this.renderToolbar()}createTooltip(){this.tooltipElement=document.createElement("div"),Object.assign(this.tooltipElement.style,{position:"fixed",display:"none",backgroundColor:"#1e293b",color:"#e2e8f0",padding:"6px 10px",borderRadius:"6px",fontSize:"13px",lineHeight:"1.4",fontWeight:"500",border:"1px solid #334155",zIndex:"9999",pointerEvents:"none",whiteSpace:"nowrap",boxShadow:"0 4px 6px -1px rgba(0, 0, 0, 0.3), 0 2px 4px -1px rgba(0, 0, 0, 0.15)",fontFamily:this.context.getOptions().fontFamily||"sans-serif",transition:"opacity 0.15s ease-in-out, transform 0.15s ease-in-out",opacity:"0",transform:"translateX(-5px)"}),document.body.appendChild(this.tooltipElement)}destroy(){this.tooltipElement&&this.tooltipElement.parentNode&&this.tooltipElement.parentNode.removeChild(this.tooltipElement),this.tooltipElement=null}showTooltip(e,t){if(!this.tooltipElement)return;this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=null);const i=e.getBoundingClientRect();this.tooltipElement.textContent=t,this.tooltipElement.style.display="block";const s=this.tooltipElement.getBoundingClientRect(),o=i.top+(i.height-s.height)/2,n=i.right+10;this.tooltipElement.style.top=`${o}px`,this.tooltipElement.style.left=`${n}px`,requestAnimationFrame(()=>{this.tooltipElement&&(this.tooltipElement.style.opacity="1",this.tooltipElement.style.transform="translateX(0)")})}hideTooltip(){this.tooltipElement&&(this.tooltipElement.style.opacity="0",this.tooltipElement.style.transform="translateX(-5px)",this.hideTimeout&&clearTimeout(this.hideTimeout),this.hideTimeout=setTimeout(()=>{this.tooltipElement&&(this.tooltipElement.style.display="none"),this.hideTimeout=null},150))}register(e){if(this.plugins.has(e.id)){console.warn(`Plugin with id ${e.id} is already registered.`);return}this.plugins.set(e.id,e),e.init(this.context),this.addButton(e)}unregister(e){const t=this.plugins.get(e);t&&(this.activePluginId===e&&this.deactivatePlugin(),t.destroy?.(),this.plugins.delete(e),this.removeButton(e))}activatePlugin(e){if(this.activePluginId===e){this.deactivatePlugin();return}this.activePluginId&&this.deactivatePlugin();const t=this.plugins.get(e);t&&(this.activePluginId=e,this.setButtonActive(e,!0),t.activate?.())}deactivatePlugin(){this.activePluginId&&(this.plugins.get(this.activePluginId)?.deactivate?.(),this.setButtonActive(this.activePluginId,!1),this.activePluginId=null)}renderToolbar(){this.toolbarContainer.innerHTML="",this.toolbarContainer.classList.add("qfchart-toolbar"),this.toolbarContainer.style.display="flex",this.toolbarContainer.style.flexDirection="column",this.toolbarContainer.style.width="40px",this.toolbarContainer.style.backgroundColor=this.context.getOptions().backgroundColor||"#1e293b",this.toolbarContainer.style.borderRight="1px solid #334155",this.toolbarContainer.style.padding="5px",this.toolbarContainer.style.boxSizing="border-box",this.toolbarContainer.style.gap="5px",this.toolbarContainer.style.flexShrink="0"}addButton(e){const t=document.createElement("button");t.id=`qfchart-plugin-btn-${e.id}`,t.style.width="30px",t.style.height="30px",t.style.padding="4px",t.style.border="1px solid transparent",t.style.borderRadius="4px",t.style.backgroundColor="transparent",t.style.cursor="pointer",t.style.color=this.context.getOptions().fontColor||"#cbd5e1",t.style.display="flex",t.style.alignItems="center",t.style.justifyContent="center",e.icon?t.innerHTML=e.icon:t.innerText=(e.name||e.id).substring(0,2).toUpperCase(),t.addEventListener("mouseenter",()=>{this.activePluginId!==e.id&&(t.style.backgroundColor="rgba(255, 255, 255, 0.1)"),this.showTooltip(t,e.name||e.id)}),t.addEventListener("mouseleave",()=>{this.activePluginId!==e.id&&(t.style.backgroundColor="transparent"),this.hideTooltip()}),t.onclick=()=>this.activatePlugin(e.id),this.toolbarContainer.appendChild(t)}removeButton(e){const t=this.toolbarContainer.querySelector(`#qfchart-plugin-btn-${e}`);t&&t.remove()}setButtonActive(e,t){const i=this.toolbarContainer.querySelector(`#qfchart-plugin-btn-${e}`);i&&(t?(i.style.backgroundColor="#2563eb",i.style.color="#ffffff"):(i.style.backgroundColor="transparent",i.style.color=this.context.getOptions().fontColor||"#cbd5e1"))}}var kt=Object.defineProperty,St=(l,e,t)=>e in l?kt(l,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[e]=t,J=(l,e,t)=>(St(l,typeof e!="symbol"?e+"":e,t),t);class It{constructor(e){J(this,"context"),J(this,"isEditing",!1),J(this,"currentDrawing",null),J(this,"editingPointIndex",null),J(this,"zr"),J(this,"editGroup",null),J(this,"editLine",null),J(this,"editStartPoint",null),J(this,"editEndPoint",null),J(this,"isMovingShape",!1),J(this,"dragStart",null),J(this,"initialPixelPoints",[]),J(this,"onDrawingMouseDown",t=>{if(this.isEditing)return;const i=this.context.getDrawing(t.id);i&&(this.isEditing=!0,this.isMovingShape=!0,this.currentDrawing=JSON.parse(JSON.stringify(i)),this.dragStart={x:t.x,y:t.y},this.initialPixelPoints=i.points.map(s=>{const o=this.context.coordinateConversion.dataToPixel(s);return o?{x:o.x,y:o.y}:{x:0,y:0}}),this.context.lockChart(),this.createEditGraphic(),this.zr.on("mousemove",this.onMouseMove),this.zr.on("mouseup",this.onMouseUp))}),J(this,"onPointMouseDown",t=>{if(this.isEditing)return;const i=this.context.getDrawing(t.id);i&&(this.isEditing=!0,this.currentDrawing=JSON.parse(JSON.stringify(i)),this.editingPointIndex=t.pointIndex,this.context.lockChart(),this.createEditGraphic(),this.zr.on("mousemove",this.onMouseMove),this.zr.on("mouseup",this.onMouseUp))}),J(this,"onMouseMove",t=>{if(!this.isEditing||!this.currentDrawing)return;const i=t.offsetX,s=t.offsetY;if(this.isMovingShape&&this.dragStart){const o=i-this.dragStart.x,n=s-this.dragStart.y,p={x:this.initialPixelPoints[0].x+o,y:this.initialPixelPoints[0].y+n},d={x:this.initialPixelPoints[1].x+o,y:this.initialPixelPoints[1].y+n};this.editLine.setShape({x1:p.x,y1:p.y,x2:d.x,y2:d.y}),this.editStartPoint.setShape({cx:p.x,cy:p.y}),this.editEndPoint.setShape({cx:d.x,cy:d.y})}else this.editingPointIndex!==null&&(this.editingPointIndex===0?(this.editLine.setShape({x1:i,y1:s}),this.editStartPoint.setShape({cx:i,cy:s})):(this.editLine.setShape({x2:i,y2:s}),this.editEndPoint.setShape({cx:i,cy:s})))}),J(this,"onMouseUp",t=>{this.isEditing&&this.finishEditing(t.offsetX,t.offsetY)}),this.context=e,this.zr=this.context.getChart().getZr(),this.bindEvents()}bindEvents(){this.context.events.on("drawing:point:mousedown",this.onPointMouseDown),this.context.events.on("drawing:mousedown",this.onDrawingMouseDown)}createEditGraphic(){if(!this.currentDrawing)return;this.editGroup=new q.graphic.Group;const e=this.currentDrawing.points[0],t=this.currentDrawing.points[1],i=this.context.coordinateConversion.dataToPixel(e),s=this.context.coordinateConversion.dataToPixel(t);!i||!s||(this.editLine=new q.graphic.Line({shape:{x1:i.x,y1:i.y,x2:s.x,y2:s.y},style:{stroke:this.currentDrawing.style?.color||"#3b82f6",lineWidth:this.currentDrawing.style?.lineWidth||2,lineDash:[4,4]},silent:!0}),this.editStartPoint=new q.graphic.Circle({shape:{cx:i.x,cy:i.y,r:5},style:{fill:"#fff",stroke:"#3b82f6",lineWidth:2},z:1e3}),this.editEndPoint=new q.graphic.Circle({shape:{cx:s.x,cy:s.y,r:5},style:{fill:"#fff",stroke:"#3b82f6",lineWidth:2},z:1e3}),this.editGroup.add(this.editLine),this.editGroup.add(this.editStartPoint),this.editGroup.add(this.editEndPoint),this.zr.add(this.editGroup))}finishEditing(e,t){if(this.currentDrawing){if(this.isMovingShape&&this.dragStart){const i=e-this.dragStart.x,s=t-this.dragStart.y,o=this.initialPixelPoints.map((n,p)=>{const d=n.x+i,r=n.y+s;return this.context.coordinateConversion.pixelToData({x:d,y:r})});o.every(n=>n!==null)&&o[0]&&o[1]&&(this.currentDrawing.points[0]=o[0],this.currentDrawing.points[1]=o[1],o[0].paneIndex!==void 0&&(this.currentDrawing.paneIndex=o[0].paneIndex),this.context.updateDrawing(this.currentDrawing))}else if(this.editingPointIndex!==null){const i=this.context.coordinateConversion.pixelToData({x:e,y:t});i&&(this.currentDrawing.points[this.editingPointIndex]=i,this.editingPointIndex===0&&i.paneIndex!==void 0&&(this.currentDrawing.paneIndex=i.paneIndex),this.context.updateDrawing(this.currentDrawing))}this.isEditing=!1,this.isMovingShape=!1,this.dragStart=null,this.initialPixelPoints=[],this.currentDrawing=null,this.editingPointIndex=null,this.editGroup&&(this.zr.remove(this.editGroup),this.editGroup=null),this.zr.off("mousemove",this.onMouseMove),this.zr.off("mouseup",this.onMouseUp),this.context.unlockChart()}}}var Pt=Object.defineProperty,Mt=(l,e,t)=>e in l?Pt(l,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[e]=t,At=(l,e,t)=>(Mt(l,typeof e!="symbol"?e+"":e,t),t);class Dt{constructor(){At(this,"handlers",new Map)}on(e,t){this.handlers.has(e)||this.handlers.set(e,new Set),this.handlers.get(e).add(t)}off(e,t){const i=this.handlers.get(e);i&&i.delete(t)}emit(e,t){const i=this.handlers.get(e);i&&i.forEach(s=>{try{s(t)}catch(o){console.error(`Error in EventBus handler for ${e}:`,o)}})}clear(){this.handlers.clear()}}var Et=Object.defineProperty,zt=(l,e,t)=>e in l?Et(l,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[e]=t,L=(l,e,t)=>(zt(l,typeof e!="symbol"?e+"":e,t),t);class Lt{constructor(e,t={}){L(this,"chart"),L(this,"options"),L(this,"marketData",[]),L(this,"indicators",new Map),L(this,"timeToIndex",new Map),L(this,"pluginManager"),L(this,"drawingEditor"),L(this,"events",new Dt),L(this,"isMainCollapsed",!1),L(this,"maximizedPaneId",null),L(this,"countdownInterval",null),L(this,"selectedDrawingId",null),L(this,"drawings",[]),L(this,"coordinateConversion",{pixelToData:o=>{const n=this.chart.getOption();if(!n||!n.grid)return null;const p=n.grid.length;for(let d=0;d<p;d++)if(this.chart.containPixel({gridIndex:d},[o.x,o.y])){this.chart.convertFromPixel({seriesIndex:d},[o.x,o.y]);const r=this.chart.convertFromPixel({gridIndex:d},[o.x,o.y]);if(r)return{timeIndex:Math.round(r[0]),value:r[1],paneIndex:d}}return null},dataToPixel:o=>{const n=o.paneIndex||0,p=this.chart.convertToPixel({gridIndex:n},[o.timeIndex,o.value]);return p?{x:p[0],y:p[1]}:null}}),L(this,"upColor","#00da3c"),L(this,"downColor","#ec0000"),L(this,"defaultPadding",0),L(this,"padding"),L(this,"dataIndexOffset",0),L(this,"rootContainer"),L(this,"layoutContainer"),L(this,"toolbarContainer"),L(this,"leftSidebar"),L(this,"rightSidebar"),L(this,"chartContainer"),L(this,"onKeyDown",o=>{(o.key==="Delete"||o.key==="Backspace")&&this.selectedDrawingId&&(this.removeDrawing(this.selectedDrawingId),this.selectedDrawingId=null,this.render())}),L(this,"onFullscreenChange",()=>{this.render()}),L(this,"isLocked",!1),L(this,"lockedState",null),this.rootContainer=e,this.options={title:"Market",height:"600px",backgroundColor:"#1e293b",upColor:"#00da3c",downColor:"#ec0000",fontColor:"#cbd5e1",fontFamily:"sans-serif",padding:.01,dataZoom:{visible:!0,position:"top",height:6},layout:{mainPaneHeight:"50%",gap:13},watermark:!0,...t},this.options.upColor&&(this.upColor=this.options.upColor),this.options.downColor&&(this.downColor=this.options.downColor),this.padding=this.options.padding!==void 0?this.options.padding:this.defaultPadding,this.options.height&&(typeof this.options.height=="number"?this.rootContainer.style.height=`${this.options.height}px`:this.rootContainer.style.height=this.options.height),this.rootContainer.innerHTML="",this.layoutContainer=document.createElement("div"),this.layoutContainer.style.display="flex",this.layoutContainer.style.width="100%",this.layoutContainer.style.height="100%",this.layoutContainer.style.overflow="hidden",this.rootContainer.appendChild(this.layoutContainer),this.leftSidebar=document.createElement("div"),this.leftSidebar.style.display="none",this.leftSidebar.style.width="250px",this.leftSidebar.style.flexShrink="0",this.leftSidebar.style.overflowY="auto",this.leftSidebar.style.backgroundColor=this.options.backgroundColor||"#1e293b",this.leftSidebar.style.borderRight="1px solid #334155",this.leftSidebar.style.padding="10px",this.leftSidebar.style.boxSizing="border-box",this.leftSidebar.style.color="#cbd5e1",this.leftSidebar.style.fontSize="12px",this.leftSidebar.style.fontFamily=this.options.fontFamily||"sans-serif",this.layoutContainer.appendChild(this.leftSidebar),this.toolbarContainer=document.createElement("div"),this.layoutContainer.appendChild(this.toolbarContainer),this.chartContainer=document.createElement("div"),this.chartContainer.style.flexGrow="1",this.chartContainer.style.height="100%",this.chartContainer.style.overflow="hidden",this.layoutContainer.appendChild(this.chartContainer),this.rightSidebar=document.createElement("div"),this.rightSidebar.style.display="none",this.rightSidebar.style.width="250px",this.rightSidebar.style.flexShrink="0",this.rightSidebar.style.overflowY="auto",this.rightSidebar.style.backgroundColor=this.options.backgroundColor||"#1e293b",this.rightSidebar.style.borderLeft="1px solid #334155",this.rightSidebar.style.padding="10px",this.rightSidebar.style.boxSizing="border-box",this.rightSidebar.style.color="#cbd5e1",this.rightSidebar.style.fontSize="12px",this.rightSidebar.style.fontFamily=this.options.fontFamily||"sans-serif",this.layoutContainer.appendChild(this.rightSidebar),this.chart=q.init(this.chartContainer),this.pluginManager=new Ct(this,this.toolbarContainer),this.drawingEditor=new It(this),this.chart.on("dataZoom",o=>{this.events.emit("chart:dataZoom",o);const n=this.options.databox?.triggerOn,p=this.options.databox?.position;n==="click"&&p==="floating"&&this.chart.dispatchAction({type:"hideTip"})}),this.chart.on("finished",o=>this.events.emit("chart:updated",o)),this.chart.getZr().on("mousedown",o=>this.events.emit("mouse:down",o)),this.chart.getZr().on("mousemove",o=>this.events.emit("mouse:move",o)),this.chart.getZr().on("mouseup",o=>this.events.emit("mouse:up",o)),this.chart.getZr().on("click",o=>this.events.emit("mouse:click",o));const i=this.chart.getZr(),s=i.setCursorStyle;i.setCursorStyle=function(o){o==="grab"&&(o="crosshair"),s.call(this,o)},this.bindDrawingEvents(),window.addEventListener("resize",this.resize.bind(this)),document.addEventListener("fullscreenchange",this.onFullscreenChange),document.addEventListener("keydown",this.onKeyDown)}bindDrawingEvents(){let e=null;const t=i=>{if(!i||i.componentType!=="series"||!i.seriesName?.startsWith("drawings"))return null;i.seriesIndex;const s=i.seriesName.match(/drawings-pane-(\d+)/);if(!s)return null;const o=parseInt(s[1]),n=this.drawings.filter(d=>(d.paneIndex||0)===o)[i.dataIndex];if(!n)return null;const p=i.event?.target?.name;return{drawing:n,targetName:p,paneIdx:o}};this.chart.on("mouseover",i=>{const s=t(i);if(!s)return;const o=i.event?.target?.parent;if(o){const n=s.drawing.id===this.selectedDrawingId;e&&(clearTimeout(e),e=null),n||o.children().forEach(p=>{p.name&&p.name.startsWith("point")&&p.attr("style",{opacity:1})})}if(s.targetName==="line")this.events.emit("drawing:hover",{id:s.drawing.id,type:s.drawing.type}),this.chart.getZr().setCursorStyle("move");else if(s.targetName?.startsWith("point")){const n=s.targetName==="point-start"?0:1;this.events.emit("drawing:point:hover",{id:s.drawing.id,pointIndex:n}),this.chart.getZr().setCursorStyle("pointer")}}),this.chart.on("mouseout",i=>{const s=t(i);if(!s)return;const o=i.event?.target?.parent;if(s.drawing.id!==this.selectedDrawingId){if(e=setTimeout(()=>{if(o){if(this.selectedDrawingId===s.drawing.id)return;o.children().forEach(n=>{n.name&&n.name.startsWith("point")&&n.attr("style",{opacity:0})})}},50),s.targetName==="line")this.events.emit("drawing:mouseout",{id:s.drawing.id});else if(s.targetName?.startsWith("point")){const n=s.targetName==="point-start"?0:1;this.events.emit("drawing:point:mouseout",{id:s.drawing.id,pointIndex:n})}this.chart.getZr().setCursorStyle("default")}}),this.chart.on("mousedown",i=>{const s=t(i);if(!s)return;const o=i.event?.event||i.event,n=o?.offsetX,p=o?.offsetY;if(s.targetName==="line")this.events.emit("drawing:mousedown",{id:s.drawing.id,x:n,y:p});else if(s.targetName?.startsWith("point")){const d=s.targetName==="point-start"?0:1;this.events.emit("drawing:point:mousedown",{id:s.drawing.id,pointIndex:d,x:n,y:p})}}),this.chart.on("click",i=>{const s=t(i);if(s){if(this.selectedDrawingId!==s.drawing.id&&(this.selectedDrawingId=s.drawing.id,this.events.emit("drawing:selected",{id:s.drawing.id}),this.render()),s.targetName==="line")this.events.emit("drawing:click",{id:s.drawing.id});else if(s.targetName?.startsWith("point")){const o=s.targetName==="point-start"?0:1;this.events.emit("drawing:point:click",{id:s.drawing.id,pointIndex:o})}}}),this.chart.getZr().on("click",i=>{i.target||this.selectedDrawingId&&(this.events.emit("drawing:deselected",{id:this.selectedDrawingId}),this.selectedDrawingId=null,this.render())})}getChart(){return this.chart}getMarketData(){return this.marketData}getTimeToIndex(){return this.timeToIndex}getOptions(){return this.options}disableTools(){this.pluginManager.deactivatePlugin()}registerPlugin(e){this.pluginManager.register(e)}addDrawing(e){this.drawings.push(e),this.render()}removeDrawing(e){const t=this.drawings.findIndex(i=>i.id===e);if(t!==-1){const i=this.drawings[t];this.drawings.splice(t,1),this.events.emit("drawing:deleted",{id:i.id}),this.render()}}getDrawing(e){return this.drawings.find(t=>t.id===e)}updateDrawing(e){const t=this.drawings.findIndex(i=>i.id===e.id);t!==-1&&(this.drawings[t]=e,this.render())}lockChart(){if(this.isLocked)return;this.isLocked=!0;const e=this.chart.getOption();this.chart.setOption({dataZoom:e.dataZoom.map(t=>({...t,disabled:!0})),tooltip:{show:!1}})}unlockChart(){if(!this.isLocked)return;this.isLocked=!1;const e=this.chart.getOption();(this.options.dataZoom||{}).visible,e.dataZoom&&this.chart.setOption({dataZoom:e.dataZoom.map(t=>({...t,disabled:!1})),tooltip:{show:!0}})}setZoom(e,t){this.chart.dispatchAction({type:"dataZoom",start:e,end:t})}setMarketData(e){this.marketData=e,this.rebuildTimeIndex(),this.render()}updateData(e){if(e.length===0)return;const t=new Map;this.marketData.forEach(y=>{t.set(y.time,y)}),e.forEach(y=>{t.has(y.time),t.set(y.time,y)}),this.marketData=Array.from(t.values()).sort((y,v)=>y.time-v.time),this.rebuildTimeIndex();const i=this.dataIndexOffset,s=st.buildCandlestickSeries(this.marketData,this.options),o={value:[NaN,NaN,NaN,NaN],itemStyle:{opacity:0}},n=[...Array(i).fill(o),...s.data,...Array(i).fill(o)],p=[...Array(i).fill(""),...this.marketData.map(y=>new Date(y.time).toLocaleString()),...Array(i).fill("")],d=this.chart.getOption(),r=ut.calculate(this.chart.getHeight(),this.indicators,this.options,this.isMainCollapsed,this.maximizedPaneId,this.marketData),k=[...Array(i).fill(null),...this.marketData,...Array(i).fill(null)],{series:f,barColors:b}=st.buildIndicatorSeries(this.indicators,this.timeToIndex,r.paneLayout,p.length,i,k,r.overlayYAxisMap,r.separatePaneYAxisOffset),I=n.map((y,v)=>b[v]?{value:y.value||y,itemStyle:{color:b[v],color0:b[v],borderColor:b[v],borderColor0:b[v]}}:y),u={xAxis:d.xAxis.map((y,v)=>({data:p})),series:[{data:I,markLine:s.markLine},...f.map(y=>{const v={data:y.data};return y.renderItem&&(v.renderItem=y.renderItem),v})]};this.chart.setOption(u,{notMerge:!1}),this.startCountdown()}startCountdown(){if(this.stopCountdown(),!this.options.lastPriceLine?.showCountdown||!this.options.interval||this.marketData.length===0)return;const e=()=>{if(this.marketData.length===0)return;const t=this.marketData[this.marketData.length-1].time+(this.options.interval||0),i=Date.now(),s=t-i;if(s<=0)return;const o=Math.abs(s),n=Math.floor(o/36e5),p=Math.floor(o%36e5/6e4),d=Math.floor(o%6e4/1e3),r=`${n>0?n.toString().padStart(2,"0")+":":""}${p.toString().padStart(2,"0")}:${d.toString().padStart(2,"0")}`,k=this.chart.getOption();if(!k||!k.series)return;const f=k.series.findIndex(E=>E.type==="candlestick");if(f===-1)return;const b=k.series[f];if(!b.markLine||!b.markLine.data||!b.markLine.data[0])return;const I=b.markLine.data[0];I.label.formatter;const u=I.yAxis;let y="";if(this.options.yAxisLabelFormatter)y=this.options.yAxisLabelFormatter(u);else{const E=this.options.yAxisDecimalPlaces!==void 0?this.options.yAxisDecimalPlaces:2;y=typeof u=="number"?u.toFixed(E):u}const v=`${y}
|
|
37
|
-
${r}`;this.chart.setOption({series:[{name:this.options.title||"Market",markLine:{data:[{...I,label:{...I.label,formatter:v}}]}}]})};e(),this.countdownInterval=setInterval(e,1e3)}stopCountdown(){this.countdownInterval&&(clearInterval(this.countdownInterval),this.countdownInterval=null)}addIndicator(e,t,i={}){const s=i.overlay!==void 0?i.overlay:i.isOverlay??!1;let o=0;if(!s){let p=0;this.indicators.forEach(d=>{d.paneIndex>p&&(p=d.paneIndex)}),o=p+1}const n=new ft(e,t,o,{height:i.height,collapsed:!1,titleColor:i.titleColor,controls:i.controls});return this.indicators.set(e,n),this.render(),n}setIndicator(e,t,i=!1){this.addIndicator(e,{[e]:t},{overlay:i})}removeIndicator(e){this.indicators.delete(e),this.render()}toggleIndicator(e,t="collapse"){if(t==="fullscreen"){document.fullscreenElement?document.exitFullscreen():this.rootContainer.requestFullscreen();return}if(t==="maximize"){this.maximizedPaneId===e?this.maximizedPaneId=null:this.maximizedPaneId=e,this.render();return}if(e==="main"){this.isMainCollapsed=!this.isMainCollapsed,this.render();return}const i=this.indicators.get(e);i&&(i.toggleCollapse(),this.render())}resize(){this.chart.resize()}destroy(){this.stopCountdown(),window.removeEventListener("resize",this.resize.bind(this)),document.removeEventListener("fullscreenchange",this.onFullscreenChange),document.removeEventListener("keydown",this.onKeyDown),this.pluginManager.deactivatePlugin(),this.pluginManager.destroy(),this.chart.dispose()}rebuildTimeIndex(){this.timeToIndex.clear(),this.marketData.forEach((i,s)=>{this.timeToIndex.set(i.time,s)});const e=this.marketData.length,t=Math.ceil(e*this.padding);this.dataIndexOffset=t}render(){if(this.marketData.length===0)return;let e=null;try{const x=this.chart.getOption();if(x&&x.dataZoom&&x.dataZoom.length>0){const M=x.dataZoom.find(w=>w.type==="slider"||w.type==="inside");M&&(e={start:M.start,end:M.end})}}catch{}const t=this.options.databox?.position,i=this.leftSidebar.style.display,s=this.rightSidebar.style.display,o=t==="left"?"block":"none",n=t==="right"?"block":"none";(i!==o||s!==n)&&(this.leftSidebar.style.display=o,this.rightSidebar.style.display=n,this.chart.resize());const p=this.dataIndexOffset,d=[...Array(p).fill(""),...this.marketData.map(x=>new Date(x.time).toLocaleString()),...Array(p).fill("")],r=ut.calculate(this.chart.getHeight(),this.indicators,this.options,this.isMainCollapsed,this.maximizedPaneId,this.marketData);if(!e&&r.dataZoom&&this.marketData.length>0){const x=this.marketData.length,M=d.length,w=p/M,T=x/M;r.dataZoom.forEach(P=>{if(P.start!==void 0){const c=P.start/100,a=w+c*T;P.start=a*100}if(P.end!==void 0){const c=P.end/100,a=w+c*T;P.end=a*100}})}e&&r.dataZoom&&r.dataZoom.forEach(x=>{x.start=e.start,x.end=e.end}),r.xAxis.forEach(x=>{x.data=d,x.boundaryGap=!1});const k=st.buildCandlestickSeries(this.marketData,this.options),f={value:[NaN,NaN,NaN,NaN],itemStyle:{opacity:0}};k.data=[...Array(p).fill(f),...k.data,...Array(p).fill(f)];const b=[...Array(p).fill(null),...this.marketData,...Array(p).fill(null)],{series:I,barColors:u}=st.buildIndicatorSeries(this.indicators,this.timeToIndex,r.paneLayout,d.length,p,b,r.overlayYAxisMap,r.separatePaneYAxisOffset);k.data=k.data.map((x,M)=>u[M]?{value:x.value||x,itemStyle:{color:u[M],color0:u[M],borderColor:u[M],borderColor0:u[M]}}:x);const y=mt.build(r,this.options,this.toggleIndicator.bind(this),this.isMainCollapsed,this.maximizedPaneId),v=new Map;this.drawings.forEach(x=>{const M=x.paneIndex||0;v.has(M)||v.set(M,[]),v.get(M).push(x)});const E=[];v.forEach((x,M)=>{E.push({type:"custom",name:`drawings-pane-${M}`,xAxisIndex:M,yAxisIndex:M,clip:!0,renderItem:(w,T)=>{const P=x[w.dataIndex];if(!P)return;const c=P.points[0],a=P.points[1];if(!c||!a)return;const g=T.coord([c.timeIndex,c.value]),m=T.coord([a.timeIndex,a.value]),S=P.id===this.selectedDrawingId;if(P.type==="line")return{type:"group",children:[{type:"line",name:"line",shape:{x1:g[0],y1:g[1],x2:m[0],y2:m[1]},style:{stroke:P.style?.color||"#3b82f6",lineWidth:P.style?.lineWidth||2}},{type:"circle",name:"point-start",shape:{cx:g[0],cy:g[1],r:4},style:{fill:"#fff",stroke:P.style?.color||"#3b82f6",lineWidth:1,opacity:S?1:0}},{type:"circle",name:"point-end",shape:{cx:m[0],cy:m[1],r:4},style:{fill:"#fff",stroke:P.style?.color||"#3b82f6",lineWidth:1,opacity:S?1:0}}]};if(P.type==="fibonacci"){const Z=g[0],z=g[1],G=m[0],F=m[1],H=Math.min(Z,G),X=Math.max(Z,G),_=X-H,Y=F-z,h=[0,.236,.382,.5,.618,.786,1],C=["#787b86","#f44336","#ff9800","#4caf50","#2196f3","#00bcd4","#787b86"],A=[];A.push({type:"line",name:"line",shape:{x1:Z,y1:z,x2:G,y2:F},style:{stroke:"#999",lineWidth:1,lineDash:[4,4]}}),A.push({type:"circle",name:"point-start",shape:{cx:Z,cy:z,r:4},style:{fill:"#fff",stroke:P.style?.color||"#3b82f6",lineWidth:1,opacity:S?1:0},z:100}),A.push({type:"circle",name:"point-end",shape:{cx:G,cy:F,r:4},style:{fill:"#fff",stroke:P.style?.color||"#3b82f6",lineWidth:1,opacity:S?1:0},z:100}),h.forEach((D,W)=>{const j=F-Y*D,O=C[W%C.length];A.push({type:"line",name:"fib-line",shape:{x1:H,y1:j,x2:X,y2:j},style:{stroke:O,lineWidth:1},silent:!0});const B=P.points[0].value,tt=P.points[1].value,et=tt-B,Q=tt-et*D;if(A.push({type:"text",style:{text:`${D} (${Q.toFixed(2)})`,x:H+5,y:j-10,fill:O,fontSize:10},silent:!0}),W<h.length-1){const it=h[W+1],rt=F-Y*it,dt=Math.abs(rt-j),ct=Math.min(j,rt);A.push({type:"rect",shape:{x:H,y:ct,width:_,height:dt},style:{fill:C[(W+1)%C.length],opacity:.1},silent:!0})}});const $=[],R=[];return h.forEach((D,W)=>{const j=F-Y*D,O=C[W%C.length];R.push({type:"line",shape:{x1:H,y1:j,x2:X,y2:j},style:{stroke:O,lineWidth:1},silent:!0});const B=P.points[0].value,tt=P.points[1].value,et=tt-B,Q=tt-et*D;if(R.push({type:"text",style:{text:`${D} (${Q.toFixed(2)})`,x:H+5,y:j-10,fill:O,fontSize:10},silent:!0}),W<h.length-1){const it=h[W+1],rt=F-Y*it,dt=Math.abs(rt-j),ct=Math.min(j,rt);$.push({type:"rect",name:"line",shape:{x:H,y:ct,width:_,height:dt},style:{fill:C[(W+1)%C.length],opacity:.1}})}}),{type:"group",children:[...$,...R,{type:"line",name:"line",shape:{x1:Z,y1:z,x2:G,y2:F},style:{stroke:"#999",lineWidth:1,lineDash:[4,4]}},{type:"circle",name:"point-start",shape:{cx:Z,cy:z,r:4},style:{fill:"#fff",stroke:P.style?.color||"#3b82f6",lineWidth:1,opacity:S?1:0},z:100},{type:"circle",name:"point-end",shape:{cx:G,cy:F,r:4},style:{fill:"#fff",stroke:P.style?.color||"#3b82f6",lineWidth:1,opacity:S?1:0},z:100}]}}},data:x.map(w=>[w.points[0].timeIndex,w.points[0].value,w.points[1].timeIndex,w.points[1].value]),z:100,silent:!1})});const V=x=>{const M=bt.format(x,this.options),w=this.options.databox?.position;return w==="left"?(this.leftSidebar.innerHTML=M,""):w==="right"?(this.rightSidebar.innerHTML=M,""):this.options.databox?`<div style="min-width: 200px;">${M}</div>`:""},N={backgroundColor:this.options.backgroundColor,animation:!1,legend:{show:!1},tooltip:{show:!0,showContent:!!this.options.databox,trigger:"axis",triggerOn:this.options.databox?.triggerOn??"mousemove",axisPointer:{type:"cross",label:{backgroundColor:"#475569"}},backgroundColor:"rgba(30, 41, 59, 0.9)",borderWidth:1,borderColor:"#334155",padding:10,textStyle:{color:"#fff",fontFamily:this.options.fontFamily||"sans-serif"},formatter:V,extraCssText:t!=="floating"&&t!==void 0?"display: none !important;":void 0,position:(x,M,w,T,P)=>{if(this.options.databox?.position==="floating"){const c={top:10};return c[["left","right"][+(x[0]<P.viewSize[0]/2)]]=30,c}return null}},axisPointer:{link:{xAxisIndex:"all"},label:{backgroundColor:"#475569"}},graphic:y,grid:r.grid,xAxis:r.xAxis,yAxis:r.yAxis,dataZoom:r.dataZoom,series:[k,...I,...E]};this.chart.setOption(N,!0)}}var Tt=Object.defineProperty,Zt=(l,e,t)=>e in l?Tt(l,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[e]=t,lt=(l,e,t)=>(Zt(l,typeof e!="symbol"?e+"":e,t),t);class ht{constructor(e){lt(this,"id"),lt(this,"name"),lt(this,"icon"),lt(this,"context"),lt(this,"eventListeners",[]),this.id=e.id,this.name=e.name,this.icon=e.icon}init(e){this.context=e,this.onInit()}onInit(){}activate(){this.onActivate(),this.context.events.emit("plugin:activated",this.id)}onActivate(){}deactivate(){this.onDeactivate(),this.context.events.emit("plugin:deactivated",this.id)}onDeactivate(){}destroy(){this.removeAllListeners(),this.onDestroy()}onDestroy(){}on(e,t){this.context.events.on(e,t),this.eventListeners.push({event:e,handler:t})}off(e,t){this.context.events.off(e,t),this.eventListeners=this.eventListeners.filter(i=>i.event!==e||i.handler!==t)}removeAllListeners(){this.eventListeners.forEach(({event:e,handler:t})=>{this.context.events.off(e,t)}),this.eventListeners=[]}get chart(){return this.context.getChart()}get marketData(){return this.context.getMarketData()}}var Ft=Object.defineProperty,Nt=(l,e,t)=>e in l?Ft(l,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[e]=t,U=(l,e,t)=>(Nt(l,typeof e!="symbol"?e+"":e,t),t);class $t extends ht{constructor(e){super({id:"measure",name:e?.name||"Measure",icon:e?.icon||'<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M160-240q-33 0-56.5-23.5T80-320v-320q0-33 23.5-56.5T160-720h640q33 0 56.5 23.5T880-640v320q0 33-23.5 56.5T800-240H160Zm0-80h640v-320H680v160h-80v-160h-80v160h-80v-160h-80v160h-80v-160H160v320Zm120-160h80-80Zm160 0h80-80Zm160 0h80-80Zm-120 0Z"/></svg>'}),U(this,"zr"),U(this,"state","idle"),U(this,"startPoint",null),U(this,"endPoint",null),U(this,"group",null),U(this,"rect",null),U(this,"labelRect",null),U(this,"labelText",null),U(this,"lineV",null),U(this,"lineH",null),U(this,"arrowStart",null),U(this,"arrowEnd",null),U(this,"onMouseDown",()=>{this.state==="finished"&&this.removeGraphic()}),U(this,"onChartInteraction",()=>{this.group&&this.removeGraphic()}),U(this,"onClick",t=>{this.state==="idle"?(this.state="drawing",this.startPoint=[t.offsetX,t.offsetY],this.endPoint=[t.offsetX,t.offsetY],this.initGraphic(),this.updateGraphic()):this.state==="drawing"&&(this.state="finished",this.endPoint=[t.offsetX,t.offsetY],this.updateGraphic(),this.context.disableTools(),this.enableClearListeners())}),U(this,"clearHandlers",{}),U(this,"onMouseMove",t=>{this.state==="drawing"&&(this.endPoint=[t.offsetX,t.offsetY],this.updateGraphic())})}onInit(){this.zr=this.chart.getZr()}onActivate(){this.state="idle",this.chart.getZr().setCursorStyle("crosshair"),this.zr.on("click",this.onClick),this.zr.on("mousemove",this.onMouseMove)}onDeactivate(){this.state="idle",this.chart.getZr().setCursorStyle("default"),this.zr.off("click",this.onClick),this.zr.off("mousemove",this.onMouseMove),this.disableClearListeners(),this.state==="drawing"&&this.removeGraphic()}onDestroy(){this.removeGraphic()}enableClearListeners(){const e=()=>{this.removeGraphic()};setTimeout(()=>{this.zr.on("click",e)},10),this.zr.on("mousedown",this.onMouseDown),this.context.events.on("chart:dataZoom",this.onChartInteraction),this.clearHandlers={click:e,mousedown:this.onMouseDown,dataZoom:this.onChartInteraction}}disableClearListeners(){this.clearHandlers.click&&this.zr.off("click",this.clearHandlers.click),this.clearHandlers.mousedown&&this.zr.off("mousedown",this.clearHandlers.mousedown),this.clearHandlers.dataZoom&&this.context.events.off("chart:dataZoom",this.clearHandlers.dataZoom),this.clearHandlers={}}initGraphic(){this.group||(this.group=new q.graphic.Group,this.rect=new q.graphic.Rect({shape:{x:0,y:0,width:0,height:0},style:{fill:"rgba(0,0,0,0)",stroke:"transparent",lineWidth:0},z:100}),this.lineV=new q.graphic.Line({shape:{x1:0,y1:0,x2:0,y2:0},style:{stroke:"#fff",lineWidth:1,lineDash:[4,4]},z:101}),this.lineH=new q.graphic.Line({shape:{x1:0,y1:0,x2:0,y2:0},style:{stroke:"#fff",lineWidth:1,lineDash:[4,4]},z:101}),this.arrowStart=new q.graphic.Polygon({shape:{points:[[0,0],[-5,10],[5,10]]},style:{fill:"#fff"},z:102}),this.arrowEnd=new q.graphic.Polygon({shape:{points:[[0,0],[-5,-10],[5,-10]]},style:{fill:"#fff"},z:102}),this.labelRect=new q.graphic.Rect({shape:{x:0,y:0,width:0,height:0,r:4},style:{fill:"transparent",stroke:"transparent",lineWidth:0,shadowBlur:5,shadowColor:"rgba(0,0,0,0.3)"},z:102}),this.labelText=new q.graphic.Text({style:{x:0,y:0,text:"",fill:"#fff",font:"12px sans-serif",align:"center",verticalAlign:"middle"},z:103}),this.group.add(this.rect),this.group.add(this.lineV),this.group.add(this.lineH),this.group.add(this.arrowStart),this.group.add(this.arrowEnd),this.group.add(this.labelRect),this.group.add(this.labelText),this.zr.add(this.group))}removeGraphic(){this.group&&(this.zr.remove(this.group),this.group=null,this.disableClearListeners())}updateGraphic(){if(!this.startPoint||!this.endPoint||!this.group)return;const[e,t]=this.startPoint,[i,s]=this.endPoint,o=this.context.coordinateConversion.pixelToData({x:e,y:t}),n=this.context.coordinateConversion.pixelToData({x:i,y:s});if(!o||!n)return;const p=Math.round(o.timeIndex),d=Math.round(n.timeIndex),r=o.value,k=n.value,f=d-p,b=k-r,I=b/r*100,u=b>=0,y=u?"rgba(33, 150, 243, 0.2)":"rgba(236, 0, 0, 0.2)",v=u?"#2196F3":"#ec0000";this.rect.setShape({x:Math.min(e,i),y:Math.min(t,s),width:Math.abs(i-e),height:Math.abs(s-t)}),this.rect.setStyle({fill:y});const E=(e+i)/2,V=(t+s)/2;this.lineV.setShape({x1:E,y1:t,x2:E,y2:s}),this.lineV.setStyle({stroke:v}),this.lineH.setShape({x1:e,y1:V,x2:i,y2:V}),this.lineH.setStyle({stroke:v});const N=Math.min(t,s),x=Math.max(t,s);this.arrowStart.setStyle({fill:"none"}),this.arrowEnd.setStyle({fill:"none"}),u?(this.arrowStart.setShape({points:[[E,N],[E-4,N+6],[E+4,N+6]]}),this.arrowStart.setStyle({fill:v})):(this.arrowEnd.setShape({points:[[E,x],[E-4,x-6],[E+4,x-6]]}),this.arrowEnd.setStyle({fill:v}));const M=[`${b.toFixed(2)} (${I.toFixed(2)}%)`,`${f} bars, ${(f*0).toFixed(0)}d`].join(`
|
|
38
|
-
`),w=140,T=40,P=Math.max(t,s),c=Math.min(t,s);let a=(e+i)/2-w/2,g=P+10;const
|
|
36
|
+
</div>`}),d+="</div>"})}return d}}var vt=Object.defineProperty,wt=(l,e,t)=>e in l?vt(l,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[e]=t,at=(l,e,t)=>(wt(l,typeof e!="symbol"?e+"":e,t),t);class Ct{constructor(e,t){at(this,"plugins",new Map),at(this,"activePluginId",null),at(this,"context"),at(this,"toolbarContainer"),at(this,"tooltipElement",null),at(this,"hideTimeout",null),this.context=e,this.toolbarContainer=t,this.createTooltip(),this.renderToolbar()}createTooltip(){this.tooltipElement=document.createElement("div"),Object.assign(this.tooltipElement.style,{position:"fixed",display:"none",backgroundColor:"#1e293b",color:"#e2e8f0",padding:"6px 10px",borderRadius:"6px",fontSize:"13px",lineHeight:"1.4",fontWeight:"500",border:"1px solid #334155",zIndex:"9999",pointerEvents:"none",whiteSpace:"nowrap",boxShadow:"0 4px 6px -1px rgba(0, 0, 0, 0.3), 0 2px 4px -1px rgba(0, 0, 0, 0.15)",fontFamily:this.context.getOptions().fontFamily||"sans-serif",transition:"opacity 0.15s ease-in-out, transform 0.15s ease-in-out",opacity:"0",transform:"translateX(-5px)"}),document.body.appendChild(this.tooltipElement)}destroy(){this.tooltipElement&&this.tooltipElement.parentNode&&this.tooltipElement.parentNode.removeChild(this.tooltipElement),this.tooltipElement=null}showTooltip(e,t){if(!this.tooltipElement)return;this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=null);const i=e.getBoundingClientRect();this.tooltipElement.textContent=t,this.tooltipElement.style.display="block";const s=this.tooltipElement.getBoundingClientRect(),o=i.top+(i.height-s.height)/2,n=i.right+10;this.tooltipElement.style.top=`${o}px`,this.tooltipElement.style.left=`${n}px`,requestAnimationFrame(()=>{this.tooltipElement&&(this.tooltipElement.style.opacity="1",this.tooltipElement.style.transform="translateX(0)")})}hideTooltip(){this.tooltipElement&&(this.tooltipElement.style.opacity="0",this.tooltipElement.style.transform="translateX(-5px)",this.hideTimeout&&clearTimeout(this.hideTimeout),this.hideTimeout=setTimeout(()=>{this.tooltipElement&&(this.tooltipElement.style.display="none"),this.hideTimeout=null},150))}register(e){if(this.plugins.has(e.id)){console.warn(`Plugin with id ${e.id} is already registered.`);return}this.plugins.set(e.id,e),e.init(this.context),this.addButton(e)}unregister(e){const t=this.plugins.get(e);t&&(this.activePluginId===e&&this.deactivatePlugin(),t.destroy?.(),this.plugins.delete(e),this.removeButton(e))}activatePlugin(e){if(this.activePluginId===e){this.deactivatePlugin();return}this.activePluginId&&this.deactivatePlugin();const t=this.plugins.get(e);t&&(this.activePluginId=e,this.setButtonActive(e,!0),t.activate?.())}deactivatePlugin(){this.activePluginId&&(this.plugins.get(this.activePluginId)?.deactivate?.(),this.setButtonActive(this.activePluginId,!1),this.activePluginId=null)}renderToolbar(){this.toolbarContainer.innerHTML="",this.toolbarContainer.classList.add("qfchart-toolbar"),this.toolbarContainer.style.display="flex",this.toolbarContainer.style.flexDirection="column",this.toolbarContainer.style.width="40px",this.toolbarContainer.style.backgroundColor=this.context.getOptions().backgroundColor||"#1e293b",this.toolbarContainer.style.borderRight="1px solid #334155",this.toolbarContainer.style.padding="5px",this.toolbarContainer.style.boxSizing="border-box",this.toolbarContainer.style.gap="5px",this.toolbarContainer.style.flexShrink="0"}addButton(e){const t=document.createElement("button");t.id=`qfchart-plugin-btn-${e.id}`,t.style.width="30px",t.style.height="30px",t.style.padding="4px",t.style.border="1px solid transparent",t.style.borderRadius="4px",t.style.backgroundColor="transparent",t.style.cursor="pointer",t.style.color=this.context.getOptions().fontColor||"#cbd5e1",t.style.display="flex",t.style.alignItems="center",t.style.justifyContent="center",e.icon?t.innerHTML=e.icon:t.innerText=(e.name||e.id).substring(0,2).toUpperCase(),t.addEventListener("mouseenter",()=>{this.activePluginId!==e.id&&(t.style.backgroundColor="rgba(255, 255, 255, 0.1)"),this.showTooltip(t,e.name||e.id)}),t.addEventListener("mouseleave",()=>{this.activePluginId!==e.id&&(t.style.backgroundColor="transparent"),this.hideTooltip()}),t.onclick=()=>this.activatePlugin(e.id),this.toolbarContainer.appendChild(t)}removeButton(e){const t=this.toolbarContainer.querySelector(`#qfchart-plugin-btn-${e}`);t&&t.remove()}setButtonActive(e,t){const i=this.toolbarContainer.querySelector(`#qfchart-plugin-btn-${e}`);i&&(t?(i.style.backgroundColor="#2563eb",i.style.color="#ffffff"):(i.style.backgroundColor="transparent",i.style.color=this.context.getOptions().fontColor||"#cbd5e1"))}}var kt=Object.defineProperty,It=(l,e,t)=>e in l?kt(l,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[e]=t,J=(l,e,t)=>(It(l,typeof e!="symbol"?e+"":e,t),t);class St{constructor(e){J(this,"context"),J(this,"isEditing",!1),J(this,"currentDrawing",null),J(this,"editingPointIndex",null),J(this,"zr"),J(this,"editGroup",null),J(this,"editLine",null),J(this,"editStartPoint",null),J(this,"editEndPoint",null),J(this,"isMovingShape",!1),J(this,"dragStart",null),J(this,"initialPixelPoints",[]),J(this,"onDrawingMouseDown",t=>{if(this.isEditing)return;const i=this.context.getDrawing(t.id);i&&(this.isEditing=!0,this.isMovingShape=!0,this.currentDrawing=JSON.parse(JSON.stringify(i)),this.dragStart={x:t.x,y:t.y},this.initialPixelPoints=i.points.map(s=>{const o=this.context.coordinateConversion.dataToPixel(s);return o?{x:o.x,y:o.y}:{x:0,y:0}}),this.context.lockChart(),this.createEditGraphic(),this.zr.on("mousemove",this.onMouseMove),this.zr.on("mouseup",this.onMouseUp))}),J(this,"onPointMouseDown",t=>{if(this.isEditing)return;const i=this.context.getDrawing(t.id);i&&(this.isEditing=!0,this.currentDrawing=JSON.parse(JSON.stringify(i)),this.editingPointIndex=t.pointIndex,this.context.lockChart(),this.createEditGraphic(),this.zr.on("mousemove",this.onMouseMove),this.zr.on("mouseup",this.onMouseUp))}),J(this,"onMouseMove",t=>{if(!this.isEditing||!this.currentDrawing)return;const i=t.offsetX,s=t.offsetY;if(this.isMovingShape&&this.dragStart){const o=i-this.dragStart.x,n=s-this.dragStart.y,p={x:this.initialPixelPoints[0].x+o,y:this.initialPixelPoints[0].y+n},d={x:this.initialPixelPoints[1].x+o,y:this.initialPixelPoints[1].y+n};this.editLine.setShape({x1:p.x,y1:p.y,x2:d.x,y2:d.y}),this.editStartPoint.setShape({cx:p.x,cy:p.y}),this.editEndPoint.setShape({cx:d.x,cy:d.y})}else this.editingPointIndex!==null&&(this.editingPointIndex===0?(this.editLine.setShape({x1:i,y1:s}),this.editStartPoint.setShape({cx:i,cy:s})):(this.editLine.setShape({x2:i,y2:s}),this.editEndPoint.setShape({cx:i,cy:s})))}),J(this,"onMouseUp",t=>{this.isEditing&&this.finishEditing(t.offsetX,t.offsetY)}),this.context=e,this.zr=this.context.getChart().getZr(),this.bindEvents()}bindEvents(){this.context.events.on("drawing:point:mousedown",this.onPointMouseDown),this.context.events.on("drawing:mousedown",this.onDrawingMouseDown)}createEditGraphic(){if(!this.currentDrawing)return;this.editGroup=new q.graphic.Group;const e=this.currentDrawing.points[0],t=this.currentDrawing.points[1],i=this.context.coordinateConversion.dataToPixel(e),s=this.context.coordinateConversion.dataToPixel(t);!i||!s||(this.editLine=new q.graphic.Line({shape:{x1:i.x,y1:i.y,x2:s.x,y2:s.y},style:{stroke:this.currentDrawing.style?.color||"#3b82f6",lineWidth:this.currentDrawing.style?.lineWidth||2,lineDash:[4,4]},silent:!0}),this.editStartPoint=new q.graphic.Circle({shape:{cx:i.x,cy:i.y,r:5},style:{fill:"#fff",stroke:"#3b82f6",lineWidth:2},z:1e3}),this.editEndPoint=new q.graphic.Circle({shape:{cx:s.x,cy:s.y,r:5},style:{fill:"#fff",stroke:"#3b82f6",lineWidth:2},z:1e3}),this.editGroup.add(this.editLine),this.editGroup.add(this.editStartPoint),this.editGroup.add(this.editEndPoint),this.zr.add(this.editGroup))}finishEditing(e,t){if(this.currentDrawing){if(this.isMovingShape&&this.dragStart){const i=e-this.dragStart.x,s=t-this.dragStart.y,o=this.initialPixelPoints.map((n,p)=>{const d=n.x+i,r=n.y+s;return this.context.coordinateConversion.pixelToData({x:d,y:r})});o.every(n=>n!==null)&&o[0]&&o[1]&&(this.currentDrawing.points[0]=o[0],this.currentDrawing.points[1]=o[1],o[0].paneIndex!==void 0&&(this.currentDrawing.paneIndex=o[0].paneIndex),this.context.updateDrawing(this.currentDrawing))}else if(this.editingPointIndex!==null){const i=this.context.coordinateConversion.pixelToData({x:e,y:t});i&&(this.currentDrawing.points[this.editingPointIndex]=i,this.editingPointIndex===0&&i.paneIndex!==void 0&&(this.currentDrawing.paneIndex=i.paneIndex),this.context.updateDrawing(this.currentDrawing))}this.isEditing=!1,this.isMovingShape=!1,this.dragStart=null,this.initialPixelPoints=[],this.currentDrawing=null,this.editingPointIndex=null,this.editGroup&&(this.zr.remove(this.editGroup),this.editGroup=null),this.zr.off("mousemove",this.onMouseMove),this.zr.off("mouseup",this.onMouseUp),this.context.unlockChart()}}}var Pt=Object.defineProperty,At=(l,e,t)=>e in l?Pt(l,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[e]=t,Mt=(l,e,t)=>(At(l,typeof e!="symbol"?e+"":e,t),t);class Dt{constructor(){Mt(this,"handlers",new Map)}on(e,t){this.handlers.has(e)||this.handlers.set(e,new Set),this.handlers.get(e).add(t)}off(e,t){const i=this.handlers.get(e);i&&i.delete(t)}emit(e,t){const i=this.handlers.get(e);i&&i.forEach(s=>{try{s(t)}catch(o){console.error(`Error in EventBus handler for ${e}:`,o)}})}clear(){this.handlers.clear()}}var Et=Object.defineProperty,zt=(l,e,t)=>e in l?Et(l,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[e]=t,L=(l,e,t)=>(zt(l,typeof e!="symbol"?e+"":e,t),t);class Lt{constructor(e,t={}){L(this,"chart"),L(this,"options"),L(this,"marketData",[]),L(this,"indicators",new Map),L(this,"timeToIndex",new Map),L(this,"pluginManager"),L(this,"drawingEditor"),L(this,"events",new Dt),L(this,"isMainCollapsed",!1),L(this,"maximizedPaneId",null),L(this,"countdownInterval",null),L(this,"selectedDrawingId",null),L(this,"drawings",[]),L(this,"coordinateConversion",{pixelToData:o=>{const n=this.chart.getOption();if(!n||!n.grid)return null;const p=n.grid.length;for(let d=0;d<p;d++)if(this.chart.containPixel({gridIndex:d},[o.x,o.y])){this.chart.convertFromPixel({seriesIndex:d},[o.x,o.y]);const r=this.chart.convertFromPixel({gridIndex:d},[o.x,o.y]);if(r)return{timeIndex:Math.round(r[0]),value:r[1],paneIndex:d}}return null},dataToPixel:o=>{const n=o.paneIndex||0,p=this.chart.convertToPixel({gridIndex:n},[o.timeIndex,o.value]);return p?{x:p[0],y:p[1]}:null}}),L(this,"upColor","#00da3c"),L(this,"downColor","#ec0000"),L(this,"defaultPadding",0),L(this,"padding"),L(this,"dataIndexOffset",0),L(this,"rootContainer"),L(this,"layoutContainer"),L(this,"toolbarContainer"),L(this,"leftSidebar"),L(this,"rightSidebar"),L(this,"chartContainer"),L(this,"onKeyDown",o=>{(o.key==="Delete"||o.key==="Backspace")&&this.selectedDrawingId&&(this.removeDrawing(this.selectedDrawingId),this.selectedDrawingId=null,this.render())}),L(this,"onFullscreenChange",()=>{this.render()}),L(this,"isLocked",!1),L(this,"lockedState",null),this.rootContainer=e,this.options={title:"Market",height:"600px",backgroundColor:"#1e293b",upColor:"#00da3c",downColor:"#ec0000",fontColor:"#cbd5e1",fontFamily:"sans-serif",padding:.01,dataZoom:{visible:!0,position:"top",height:6},layout:{mainPaneHeight:"50%",gap:13},watermark:!0,...t},this.options.upColor&&(this.upColor=this.options.upColor),this.options.downColor&&(this.downColor=this.options.downColor),this.padding=this.options.padding!==void 0?this.options.padding:this.defaultPadding,this.options.height&&(typeof this.options.height=="number"?this.rootContainer.style.height=`${this.options.height}px`:this.rootContainer.style.height=this.options.height),this.rootContainer.innerHTML="",this.layoutContainer=document.createElement("div"),this.layoutContainer.style.display="flex",this.layoutContainer.style.width="100%",this.layoutContainer.style.height="100%",this.layoutContainer.style.overflow="hidden",this.rootContainer.appendChild(this.layoutContainer),this.leftSidebar=document.createElement("div"),this.leftSidebar.style.display="none",this.leftSidebar.style.width="250px",this.leftSidebar.style.flexShrink="0",this.leftSidebar.style.overflowY="auto",this.leftSidebar.style.backgroundColor=this.options.backgroundColor||"#1e293b",this.leftSidebar.style.borderRight="1px solid #334155",this.leftSidebar.style.padding="10px",this.leftSidebar.style.boxSizing="border-box",this.leftSidebar.style.color="#cbd5e1",this.leftSidebar.style.fontSize="12px",this.leftSidebar.style.fontFamily=this.options.fontFamily||"sans-serif",this.layoutContainer.appendChild(this.leftSidebar),this.toolbarContainer=document.createElement("div"),this.layoutContainer.appendChild(this.toolbarContainer),this.chartContainer=document.createElement("div"),this.chartContainer.style.flexGrow="1",this.chartContainer.style.height="100%",this.chartContainer.style.overflow="hidden",this.layoutContainer.appendChild(this.chartContainer),this.rightSidebar=document.createElement("div"),this.rightSidebar.style.display="none",this.rightSidebar.style.width="250px",this.rightSidebar.style.flexShrink="0",this.rightSidebar.style.overflowY="auto",this.rightSidebar.style.backgroundColor=this.options.backgroundColor||"#1e293b",this.rightSidebar.style.borderLeft="1px solid #334155",this.rightSidebar.style.padding="10px",this.rightSidebar.style.boxSizing="border-box",this.rightSidebar.style.color="#cbd5e1",this.rightSidebar.style.fontSize="12px",this.rightSidebar.style.fontFamily=this.options.fontFamily||"sans-serif",this.layoutContainer.appendChild(this.rightSidebar),this.chart=q.init(this.chartContainer),this.pluginManager=new Ct(this,this.toolbarContainer),this.drawingEditor=new St(this),this.chart.on("dataZoom",o=>{this.events.emit("chart:dataZoom",o);const n=this.options.databox?.triggerOn,p=this.options.databox?.position;n==="click"&&p==="floating"&&this.chart.dispatchAction({type:"hideTip"})}),this.chart.on("finished",o=>this.events.emit("chart:updated",o)),this.chart.getZr().on("mousedown",o=>this.events.emit("mouse:down",o)),this.chart.getZr().on("mousemove",o=>this.events.emit("mouse:move",o)),this.chart.getZr().on("mouseup",o=>this.events.emit("mouse:up",o)),this.chart.getZr().on("click",o=>this.events.emit("mouse:click",o));const i=this.chart.getZr(),s=i.setCursorStyle;i.setCursorStyle=function(o){o==="grab"&&(o="crosshair"),s.call(this,o)},this.bindDrawingEvents(),window.addEventListener("resize",this.resize.bind(this)),document.addEventListener("fullscreenchange",this.onFullscreenChange),document.addEventListener("keydown",this.onKeyDown)}bindDrawingEvents(){let e=null;const t=i=>{if(!i||i.componentType!=="series"||!i.seriesName?.startsWith("drawings"))return null;i.seriesIndex;const s=i.seriesName.match(/drawings-pane-(\d+)/);if(!s)return null;const o=parseInt(s[1]),n=this.drawings.filter(d=>(d.paneIndex||0)===o)[i.dataIndex];if(!n)return null;const p=i.event?.target?.name;return{drawing:n,targetName:p,paneIdx:o}};this.chart.on("mouseover",i=>{const s=t(i);if(!s)return;const o=i.event?.target?.parent;if(o){const n=s.drawing.id===this.selectedDrawingId;e&&(clearTimeout(e),e=null),n||o.children().forEach(p=>{p.name&&p.name.startsWith("point")&&p.attr("style",{opacity:1})})}if(s.targetName==="line")this.events.emit("drawing:hover",{id:s.drawing.id,type:s.drawing.type}),this.chart.getZr().setCursorStyle("move");else if(s.targetName?.startsWith("point")){const n=s.targetName==="point-start"?0:1;this.events.emit("drawing:point:hover",{id:s.drawing.id,pointIndex:n}),this.chart.getZr().setCursorStyle("pointer")}}),this.chart.on("mouseout",i=>{const s=t(i);if(!s)return;const o=i.event?.target?.parent;if(s.drawing.id!==this.selectedDrawingId){if(e=setTimeout(()=>{if(o){if(this.selectedDrawingId===s.drawing.id)return;o.children().forEach(n=>{n.name&&n.name.startsWith("point")&&n.attr("style",{opacity:0})})}},50),s.targetName==="line")this.events.emit("drawing:mouseout",{id:s.drawing.id});else if(s.targetName?.startsWith("point")){const n=s.targetName==="point-start"?0:1;this.events.emit("drawing:point:mouseout",{id:s.drawing.id,pointIndex:n})}this.chart.getZr().setCursorStyle("default")}}),this.chart.on("mousedown",i=>{const s=t(i);if(!s)return;const o=i.event?.event||i.event,n=o?.offsetX,p=o?.offsetY;if(s.targetName==="line")this.events.emit("drawing:mousedown",{id:s.drawing.id,x:n,y:p});else if(s.targetName?.startsWith("point")){const d=s.targetName==="point-start"?0:1;this.events.emit("drawing:point:mousedown",{id:s.drawing.id,pointIndex:d,x:n,y:p})}}),this.chart.on("click",i=>{const s=t(i);if(s){if(this.selectedDrawingId!==s.drawing.id&&(this.selectedDrawingId=s.drawing.id,this.events.emit("drawing:selected",{id:s.drawing.id}),this.render()),s.targetName==="line")this.events.emit("drawing:click",{id:s.drawing.id});else if(s.targetName?.startsWith("point")){const o=s.targetName==="point-start"?0:1;this.events.emit("drawing:point:click",{id:s.drawing.id,pointIndex:o})}}}),this.chart.getZr().on("click",i=>{i.target||this.selectedDrawingId&&(this.events.emit("drawing:deselected",{id:this.selectedDrawingId}),this.selectedDrawingId=null,this.render())})}getChart(){return this.chart}getMarketData(){return this.marketData}getTimeToIndex(){return this.timeToIndex}getOptions(){return this.options}disableTools(){this.pluginManager.deactivatePlugin()}registerPlugin(e){this.pluginManager.register(e)}addDrawing(e){this.drawings.push(e),this.render()}removeDrawing(e){const t=this.drawings.findIndex(i=>i.id===e);if(t!==-1){const i=this.drawings[t];this.drawings.splice(t,1),this.events.emit("drawing:deleted",{id:i.id}),this.render()}}getDrawing(e){return this.drawings.find(t=>t.id===e)}updateDrawing(e){const t=this.drawings.findIndex(i=>i.id===e.id);t!==-1&&(this.drawings[t]=e,this.render())}lockChart(){if(this.isLocked)return;this.isLocked=!0;const e=this.chart.getOption();this.chart.setOption({dataZoom:e.dataZoom.map(t=>({...t,disabled:!0})),tooltip:{show:!1}})}unlockChart(){if(!this.isLocked)return;this.isLocked=!1;const e=this.chart.getOption();(this.options.dataZoom||{}).visible,e.dataZoom&&this.chart.setOption({dataZoom:e.dataZoom.map(t=>({...t,disabled:!1})),tooltip:{show:!0}})}setZoom(e,t){this.chart.dispatchAction({type:"dataZoom",start:e,end:t})}setMarketData(e){this.marketData=e,this.rebuildTimeIndex(),this.render()}updateData(e){if(e.length===0)return;const t=new Map;this.marketData.forEach(y=>{t.set(y.time,y)}),e.forEach(y=>{t.has(y.time),t.set(y.time,y)}),this.marketData=Array.from(t.values()).sort((y,v)=>y.time-v.time),this.rebuildTimeIndex();const i=this.dataIndexOffset,s=st.buildCandlestickSeries(this.marketData,this.options),o={value:[NaN,NaN,NaN,NaN],itemStyle:{opacity:0}},n=[...Array(i).fill(o),...s.data,...Array(i).fill(o)],p=[...Array(i).fill(""),...this.marketData.map(y=>new Date(y.time).toLocaleString()),...Array(i).fill("")],d=this.chart.getOption(),r=ut.calculate(this.chart.getHeight(),this.indicators,this.options,this.isMainCollapsed,this.maximizedPaneId,this.marketData),k=[...Array(i).fill(null),...this.marketData,...Array(i).fill(null)],{series:f,barColors:m}=st.buildIndicatorSeries(this.indicators,this.timeToIndex,r.paneLayout,p.length,i,k,r.overlayYAxisMap,r.separatePaneYAxisOffset),S=n.map((y,v)=>m[v]?{value:y.value||y,itemStyle:{color:m[v],color0:m[v],borderColor:m[v],borderColor0:m[v]}}:y),u={xAxis:d.xAxis.map((y,v)=>({data:p})),series:[{data:S,markLine:s.markLine},...f.map(y=>{const v={data:y.data};return y.renderItem&&(v.renderItem=y.renderItem),v})]};this.chart.setOption(u,{notMerge:!1}),this.startCountdown()}startCountdown(){if(this.stopCountdown(),!this.options.lastPriceLine?.showCountdown||!this.options.interval||this.marketData.length===0)return;const e=()=>{if(this.marketData.length===0)return;const t=this.marketData[this.marketData.length-1].time+(this.options.interval||0),i=Date.now(),s=t-i;if(s<=0)return;const o=Math.abs(s),n=Math.floor(o/36e5),p=Math.floor(o%36e5/6e4),d=Math.floor(o%6e4/1e3),r=`${n>0?n.toString().padStart(2,"0")+":":""}${p.toString().padStart(2,"0")}:${d.toString().padStart(2,"0")}`,k=this.chart.getOption();if(!k||!k.series)return;const f=k.series.findIndex(E=>E.type==="candlestick");if(f===-1)return;const m=k.series[f];if(!m.markLine||!m.markLine.data||!m.markLine.data[0])return;const S=m.markLine.data[0];S.label.formatter;const u=S.yAxis;let y="";if(this.options.yAxisLabelFormatter)y=this.options.yAxisLabelFormatter(u);else{const E=this.options.yAxisDecimalPlaces!==void 0?this.options.yAxisDecimalPlaces:2;y=typeof u=="number"?u.toFixed(E):u}const v=`${y}
|
|
37
|
+
${r}`;this.chart.setOption({series:[{name:this.options.title||"Market",markLine:{data:[{...S,label:{...S.label,formatter:v}}]}}]})};e(),this.countdownInterval=setInterval(e,1e3)}stopCountdown(){this.countdownInterval&&(clearInterval(this.countdownInterval),this.countdownInterval=null)}addIndicator(e,t,i={}){const s=i.overlay!==void 0?i.overlay:i.isOverlay??!1;let o=0;if(!s){let p=0;this.indicators.forEach(d=>{d.paneIndex>p&&(p=d.paneIndex)}),o=p+1}const n=new ft(e,t,o,{height:i.height,collapsed:!1,titleColor:i.titleColor,controls:i.controls});return this.indicators.set(e,n),this.render(),n}setIndicator(e,t,i=!1){this.addIndicator(e,{[e]:t},{overlay:i})}removeIndicator(e){this.indicators.delete(e),this.render()}toggleIndicator(e,t="collapse"){if(t==="fullscreen"){document.fullscreenElement?document.exitFullscreen():this.rootContainer.requestFullscreen();return}if(t==="maximize"){this.maximizedPaneId===e?this.maximizedPaneId=null:this.maximizedPaneId=e,this.render();return}if(e==="main"){this.isMainCollapsed=!this.isMainCollapsed,this.render();return}const i=this.indicators.get(e);i&&(i.toggleCollapse(),this.render())}resize(){this.chart.resize()}destroy(){this.stopCountdown(),window.removeEventListener("resize",this.resize.bind(this)),document.removeEventListener("fullscreenchange",this.onFullscreenChange),document.removeEventListener("keydown",this.onKeyDown),this.pluginManager.deactivatePlugin(),this.pluginManager.destroy(),this.chart.dispose()}rebuildTimeIndex(){this.timeToIndex.clear(),this.marketData.forEach((i,s)=>{this.timeToIndex.set(i.time,s)});const e=this.marketData.length,t=Math.ceil(e*this.padding);this.dataIndexOffset=t}render(){if(this.marketData.length===0)return;let e=null;try{const x=this.chart.getOption();if(x&&x.dataZoom&&x.dataZoom.length>0){const A=x.dataZoom.find(w=>w.type==="slider"||w.type==="inside");A&&(e={start:A.start,end:A.end})}}catch{}const t=this.options.databox?.position,i=this.leftSidebar.style.display,s=this.rightSidebar.style.display,o=t==="left"?"block":"none",n=t==="right"?"block":"none";(i!==o||s!==n)&&(this.leftSidebar.style.display=o,this.rightSidebar.style.display=n,this.chart.resize());const p=this.dataIndexOffset,d=[...Array(p).fill(""),...this.marketData.map(x=>new Date(x.time).toLocaleString()),...Array(p).fill("")],r=ut.calculate(this.chart.getHeight(),this.indicators,this.options,this.isMainCollapsed,this.maximizedPaneId,this.marketData);if(!e&&r.dataZoom&&this.marketData.length>0){const x=this.marketData.length,A=d.length,w=p/A,T=x/A;r.dataZoom.forEach(P=>{if(P.start!==void 0){const c=P.start/100,a=w+c*T;P.start=a*100}if(P.end!==void 0){const c=P.end/100,a=w+c*T;P.end=a*100}})}e&&r.dataZoom&&r.dataZoom.forEach(x=>{x.start=e.start,x.end=e.end}),r.xAxis.forEach(x=>{x.data=d,x.boundaryGap=!1});const k=st.buildCandlestickSeries(this.marketData,this.options),f={value:[NaN,NaN,NaN,NaN],itemStyle:{opacity:0}};k.data=[...Array(p).fill(f),...k.data,...Array(p).fill(f)];const m=[...Array(p).fill(null),...this.marketData,...Array(p).fill(null)],{series:S,barColors:u}=st.buildIndicatorSeries(this.indicators,this.timeToIndex,r.paneLayout,d.length,p,m,r.overlayYAxisMap,r.separatePaneYAxisOffset);k.data=k.data.map((x,A)=>u[A]?{value:x.value||x,itemStyle:{color:u[A],color0:u[A],borderColor:u[A],borderColor0:u[A]}}:x);const y=mt.build(r,this.options,this.toggleIndicator.bind(this),this.isMainCollapsed,this.maximizedPaneId),v=new Map;this.drawings.forEach(x=>{const A=x.paneIndex||0;v.has(A)||v.set(A,[]),v.get(A).push(x)});const E=[];v.forEach((x,A)=>{E.push({type:"custom",name:`drawings-pane-${A}`,xAxisIndex:A,yAxisIndex:A,clip:!0,renderItem:(w,T)=>{const P=x[w.dataIndex];if(!P)return;const c=P.points[0],a=P.points[1];if(!c||!a)return;const g=T.coord([c.timeIndex,c.value]),b=T.coord([a.timeIndex,a.value]),I=P.id===this.selectedDrawingId;if(P.type==="line")return{type:"group",children:[{type:"line",name:"line",shape:{x1:g[0],y1:g[1],x2:b[0],y2:b[1]},style:{stroke:P.style?.color||"#3b82f6",lineWidth:P.style?.lineWidth||2}},{type:"circle",name:"point-start",shape:{cx:g[0],cy:g[1],r:4},style:{fill:"#fff",stroke:P.style?.color||"#3b82f6",lineWidth:1,opacity:I?1:0}},{type:"circle",name:"point-end",shape:{cx:b[0],cy:b[1],r:4},style:{fill:"#fff",stroke:P.style?.color||"#3b82f6",lineWidth:1,opacity:I?1:0}}]};if(P.type==="fibonacci"){const Z=g[0],z=g[1],G=b[0],F=b[1],H=Math.min(Z,G),X=Math.max(Z,G),_=X-H,Y=F-z,h=[0,.236,.382,.5,.618,.786,1],C=["#787b86","#f44336","#ff9800","#4caf50","#2196f3","#00bcd4","#787b86"],M=[];M.push({type:"line",name:"line",shape:{x1:Z,y1:z,x2:G,y2:F},style:{stroke:"#999",lineWidth:1,lineDash:[4,4]}}),M.push({type:"circle",name:"point-start",shape:{cx:Z,cy:z,r:4},style:{fill:"#fff",stroke:P.style?.color||"#3b82f6",lineWidth:1,opacity:I?1:0},z:100}),M.push({type:"circle",name:"point-end",shape:{cx:G,cy:F,r:4},style:{fill:"#fff",stroke:P.style?.color||"#3b82f6",lineWidth:1,opacity:I?1:0},z:100}),h.forEach((D,W)=>{const j=F-Y*D,O=C[W%C.length];M.push({type:"line",name:"fib-line",shape:{x1:H,y1:j,x2:X,y2:j},style:{stroke:O,lineWidth:1},silent:!0});const B=P.points[0].value,tt=P.points[1].value,et=tt-B,Q=tt-et*D;if(M.push({type:"text",style:{text:`${D} (${Q.toFixed(2)})`,x:H+5,y:j-10,fill:O,fontSize:10},silent:!0}),W<h.length-1){const it=h[W+1],rt=F-Y*it,dt=Math.abs(rt-j),ct=Math.min(j,rt);M.push({type:"rect",shape:{x:H,y:ct,width:_,height:dt},style:{fill:C[(W+1)%C.length],opacity:.1},silent:!0})}});const $=[],R=[];return h.forEach((D,W)=>{const j=F-Y*D,O=C[W%C.length];R.push({type:"line",shape:{x1:H,y1:j,x2:X,y2:j},style:{stroke:O,lineWidth:1},silent:!0});const B=P.points[0].value,tt=P.points[1].value,et=tt-B,Q=tt-et*D;if(R.push({type:"text",style:{text:`${D} (${Q.toFixed(2)})`,x:H+5,y:j-10,fill:O,fontSize:10},silent:!0}),W<h.length-1){const it=h[W+1],rt=F-Y*it,dt=Math.abs(rt-j),ct=Math.min(j,rt);$.push({type:"rect",name:"line",shape:{x:H,y:ct,width:_,height:dt},style:{fill:C[(W+1)%C.length],opacity:.1}})}}),{type:"group",children:[...$,...R,{type:"line",name:"line",shape:{x1:Z,y1:z,x2:G,y2:F},style:{stroke:"#999",lineWidth:1,lineDash:[4,4]}},{type:"circle",name:"point-start",shape:{cx:Z,cy:z,r:4},style:{fill:"#fff",stroke:P.style?.color||"#3b82f6",lineWidth:1,opacity:I?1:0},z:100},{type:"circle",name:"point-end",shape:{cx:G,cy:F,r:4},style:{fill:"#fff",stroke:P.style?.color||"#3b82f6",lineWidth:1,opacity:I?1:0},z:100}]}}},data:x.map(w=>[w.points[0].timeIndex,w.points[0].value,w.points[1].timeIndex,w.points[1].value]),z:100,silent:!1})});const V=x=>{const A=bt.format(x,this.options),w=this.options.databox?.position;return w==="left"?(this.leftSidebar.innerHTML=A,""):w==="right"?(this.rightSidebar.innerHTML=A,""):this.options.databox?`<div style="min-width: 200px;">${A}</div>`:""},N={backgroundColor:this.options.backgroundColor,animation:!1,legend:{show:!1},tooltip:{show:!0,showContent:!!this.options.databox,trigger:"axis",triggerOn:this.options.databox?.triggerOn??"mousemove",axisPointer:{type:"cross",label:{backgroundColor:"#475569"}},backgroundColor:"rgba(30, 41, 59, 0.9)",borderWidth:1,borderColor:"#334155",padding:10,textStyle:{color:"#fff",fontFamily:this.options.fontFamily||"sans-serif"},formatter:V,extraCssText:t!=="floating"&&t!==void 0?"display: none !important;":void 0,position:(x,A,w,T,P)=>{if(this.options.databox?.position==="floating"){const c={top:10};return c[["left","right"][+(x[0]<P.viewSize[0]/2)]]=30,c}return null}},axisPointer:{link:{xAxisIndex:"all"},label:{backgroundColor:"#475569"}},graphic:y,grid:r.grid,xAxis:r.xAxis,yAxis:r.yAxis,dataZoom:r.dataZoom,series:[k,...S,...E]};this.chart.setOption(N,!0)}}var Tt=Object.defineProperty,Zt=(l,e,t)=>e in l?Tt(l,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[e]=t,lt=(l,e,t)=>(Zt(l,typeof e!="symbol"?e+"":e,t),t);class ht{constructor(e){lt(this,"id"),lt(this,"name"),lt(this,"icon"),lt(this,"context"),lt(this,"eventListeners",[]),this.id=e.id,this.name=e.name,this.icon=e.icon}init(e){this.context=e,this.onInit()}onInit(){}activate(){this.onActivate(),this.context.events.emit("plugin:activated",this.id)}onActivate(){}deactivate(){this.onDeactivate(),this.context.events.emit("plugin:deactivated",this.id)}onDeactivate(){}destroy(){this.removeAllListeners(),this.onDestroy()}onDestroy(){}on(e,t){this.context.events.on(e,t),this.eventListeners.push({event:e,handler:t})}off(e,t){this.context.events.off(e,t),this.eventListeners=this.eventListeners.filter(i=>i.event!==e||i.handler!==t)}removeAllListeners(){this.eventListeners.forEach(({event:e,handler:t})=>{this.context.events.off(e,t)}),this.eventListeners=[]}get chart(){return this.context.getChart()}get marketData(){return this.context.getMarketData()}}var Ft=Object.defineProperty,Nt=(l,e,t)=>e in l?Ft(l,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[e]=t,U=(l,e,t)=>(Nt(l,typeof e!="symbol"?e+"":e,t),t);class $t extends ht{constructor(e){super({id:"measure",name:e?.name||"Measure",icon:e?.icon||'<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M160-240q-33 0-56.5-23.5T80-320v-320q0-33 23.5-56.5T160-720h640q33 0 56.5 23.5T880-640v320q0 33-23.5 56.5T800-240H160Zm0-80h640v-320H680v160h-80v-160h-80v160h-80v-160h-80v160h-80v-160H160v320Zm120-160h80-80Zm160 0h80-80Zm160 0h80-80Zm-120 0Z"/></svg>'}),U(this,"zr"),U(this,"state","idle"),U(this,"startPoint",null),U(this,"endPoint",null),U(this,"group",null),U(this,"rect",null),U(this,"labelRect",null),U(this,"labelText",null),U(this,"lineV",null),U(this,"lineH",null),U(this,"arrowStart",null),U(this,"arrowEnd",null),U(this,"onMouseDown",()=>{this.state==="finished"&&this.removeGraphic()}),U(this,"onChartInteraction",()=>{this.group&&this.removeGraphic()}),U(this,"onClick",t=>{this.state==="idle"?(this.state="drawing",this.startPoint=[t.offsetX,t.offsetY],this.endPoint=[t.offsetX,t.offsetY],this.initGraphic(),this.updateGraphic()):this.state==="drawing"&&(this.state="finished",this.endPoint=[t.offsetX,t.offsetY],this.updateGraphic(),this.context.disableTools(),this.enableClearListeners())}),U(this,"clearHandlers",{}),U(this,"onMouseMove",t=>{this.state==="drawing"&&(this.endPoint=[t.offsetX,t.offsetY],this.updateGraphic())})}onInit(){this.zr=this.chart.getZr()}onActivate(){this.state="idle",this.chart.getZr().setCursorStyle("crosshair"),this.zr.on("click",this.onClick),this.zr.on("mousemove",this.onMouseMove)}onDeactivate(){this.state="idle",this.chart.getZr().setCursorStyle("default"),this.zr.off("click",this.onClick),this.zr.off("mousemove",this.onMouseMove),this.disableClearListeners(),this.state==="drawing"&&this.removeGraphic()}onDestroy(){this.removeGraphic()}enableClearListeners(){const e=()=>{this.removeGraphic()};setTimeout(()=>{this.zr.on("click",e)},10),this.zr.on("mousedown",this.onMouseDown),this.context.events.on("chart:dataZoom",this.onChartInteraction),this.clearHandlers={click:e,mousedown:this.onMouseDown,dataZoom:this.onChartInteraction}}disableClearListeners(){this.clearHandlers.click&&this.zr.off("click",this.clearHandlers.click),this.clearHandlers.mousedown&&this.zr.off("mousedown",this.clearHandlers.mousedown),this.clearHandlers.dataZoom&&this.context.events.off("chart:dataZoom",this.clearHandlers.dataZoom),this.clearHandlers={}}initGraphic(){this.group||(this.group=new q.graphic.Group,this.rect=new q.graphic.Rect({shape:{x:0,y:0,width:0,height:0},style:{fill:"rgba(0,0,0,0)",stroke:"transparent",lineWidth:0},z:100}),this.lineV=new q.graphic.Line({shape:{x1:0,y1:0,x2:0,y2:0},style:{stroke:"#fff",lineWidth:1,lineDash:[4,4]},z:101}),this.lineH=new q.graphic.Line({shape:{x1:0,y1:0,x2:0,y2:0},style:{stroke:"#fff",lineWidth:1,lineDash:[4,4]},z:101}),this.arrowStart=new q.graphic.Polygon({shape:{points:[[0,0],[-5,10],[5,10]]},style:{fill:"#fff"},z:102}),this.arrowEnd=new q.graphic.Polygon({shape:{points:[[0,0],[-5,-10],[5,-10]]},style:{fill:"#fff"},z:102}),this.labelRect=new q.graphic.Rect({shape:{x:0,y:0,width:0,height:0,r:4},style:{fill:"transparent",stroke:"transparent",lineWidth:0,shadowBlur:5,shadowColor:"rgba(0,0,0,0.3)"},z:102}),this.labelText=new q.graphic.Text({style:{x:0,y:0,text:"",fill:"#fff",font:"12px sans-serif",align:"center",verticalAlign:"middle"},z:103}),this.group.add(this.rect),this.group.add(this.lineV),this.group.add(this.lineH),this.group.add(this.arrowStart),this.group.add(this.arrowEnd),this.group.add(this.labelRect),this.group.add(this.labelText),this.zr.add(this.group))}removeGraphic(){this.group&&(this.zr.remove(this.group),this.group=null,this.disableClearListeners())}updateGraphic(){if(!this.startPoint||!this.endPoint||!this.group)return;const[e,t]=this.startPoint,[i,s]=this.endPoint,o=this.context.coordinateConversion.pixelToData({x:e,y:t}),n=this.context.coordinateConversion.pixelToData({x:i,y:s});if(!o||!n)return;const p=Math.round(o.timeIndex),d=Math.round(n.timeIndex),r=o.value,k=n.value,f=d-p,m=k-r,S=m/r*100,u=m>=0,y=u?"rgba(33, 150, 243, 0.2)":"rgba(236, 0, 0, 0.2)",v=u?"#2196F3":"#ec0000";this.rect.setShape({x:Math.min(e,i),y:Math.min(t,s),width:Math.abs(i-e),height:Math.abs(s-t)}),this.rect.setStyle({fill:y});const E=(e+i)/2,V=(t+s)/2;this.lineV.setShape({x1:E,y1:t,x2:E,y2:s}),this.lineV.setStyle({stroke:v}),this.lineH.setShape({x1:e,y1:V,x2:i,y2:V}),this.lineH.setStyle({stroke:v});const N=Math.min(t,s),x=Math.max(t,s);this.arrowStart.setStyle({fill:"none"}),this.arrowEnd.setStyle({fill:"none"}),u?(this.arrowStart.setShape({points:[[E,N],[E-4,N+6],[E+4,N+6]]}),this.arrowStart.setStyle({fill:v})):(this.arrowEnd.setShape({points:[[E,x],[E-4,x-6],[E+4,x-6]]}),this.arrowEnd.setStyle({fill:v}));const A=[`${m.toFixed(2)} (${S.toFixed(2)}%)`,`${f} bars, ${(f*0).toFixed(0)}d`].join(`
|
|
38
|
+
`),w=140,T=40,P=Math.max(t,s),c=Math.min(t,s);let a=(e+i)/2-w/2,g=P+10;const b=this.chart.getHeight();g+T>b&&(g=c-T-10),this.labelRect.setShape({x:a,y:g,width:w,height:T}),this.labelRect.setStyle({fill:"#1e293b",stroke:v,lineWidth:1}),this.labelText.setStyle({x:a+w/2,y:g+T/2,text:A,fill:"#fff"})}}var Gt=Object.defineProperty,Wt=(l,e,t)=>e in l?Gt(l,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[e]=t,K=(l,e,t)=>(Wt(l,typeof e!="symbol"?e+"":e,t),t);class Ot extends ht{constructor(e){super({id:"trend-line",name:e?.name||"Trend Line",icon:e?.icon||'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="2" y1="22" x2="22" y2="2" /></svg>'}),K(this,"zr"),K(this,"state","idle"),K(this,"startPoint",null),K(this,"endPoint",null),K(this,"group",null),K(this,"line",null),K(this,"startCircle",null),K(this,"endCircle",null),K(this,"onMouseDown",()=>{}),K(this,"onChartInteraction",()=>{}),K(this,"onClick",t=>{if(this.state==="idle")this.state="drawing",this.startPoint=[t.offsetX,t.offsetY],this.endPoint=[t.offsetX,t.offsetY],this.initGraphic(),this.updateGraphic();else if(this.state==="drawing"){if(this.state="finished",this.endPoint=[t.offsetX,t.offsetY],this.updateGraphic(),this.startPoint&&this.endPoint){const i=this.context.coordinateConversion.pixelToData({x:this.startPoint[0],y:this.startPoint[1]}),s=this.context.coordinateConversion.pixelToData({x:this.endPoint[0],y:this.endPoint[1]});if(i&&s){const o=i.paneIndex||0;this.context.addDrawing({id:`line-${Date.now()}`,type:"line",points:[i,s],paneIndex:o,style:{color:"#3b82f6",lineWidth:2}})}}this.removeGraphic(),this.context.disableTools()}}),K(this,"clearHandlers",{}),K(this,"onMouseMove",t=>{this.state==="drawing"&&(this.endPoint=[t.offsetX,t.offsetY],this.updateGraphic())})}onInit(){this.zr=this.chart.getZr()}onActivate(){this.state="idle",this.chart.getZr().setCursorStyle("crosshair"),this.zr.on("click",this.onClick),this.zr.on("mousemove",this.onMouseMove)}onDeactivate(){this.state="idle",this.chart.getZr().setCursorStyle("default"),this.zr.off("click",this.onClick),this.zr.off("mousemove",this.onMouseMove),this.disableClearListeners(),this.state==="drawing"&&this.removeGraphic()}onDestroy(){this.removeGraphic()}saveDataCoordinates(){}updateGraphicFromData(){}enableClearListeners(){}disableClearListeners(){}initGraphic(){this.group||(this.group=new q.graphic.Group,this.line=new q.graphic.Line({shape:{x1:0,y1:0,x2:0,y2:0},style:{stroke:"#3b82f6",lineWidth:2},z:100}),this.startCircle=new q.graphic.Circle({shape:{cx:0,cy:0,r:4},style:{fill:"#fff",stroke:"#3b82f6",lineWidth:1},z:101}),this.endCircle=new q.graphic.Circle({shape:{cx:0,cy:0,r:4},style:{fill:"#fff",stroke:"#3b82f6",lineWidth:1},z:101}),this.group.add(this.line),this.group.add(this.startCircle),this.group.add(this.endCircle),this.zr.add(this.group))}removeGraphic(){this.group&&(this.zr.remove(this.group),this.group=null,this.disableClearListeners())}updateGraphic(){if(!this.startPoint||!this.endPoint||!this.group)return;const[e,t]=this.startPoint,[i,s]=this.endPoint;this.line.setShape({x1:e,y1:t,x2:i,y2:s}),this.startCircle.setShape({cx:e,cy:t}),this.endCircle.setShape({cx:i,cy:s})}}var Ht=Object.defineProperty,Yt=(l,e,t)=>e in l?Ht(l,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[e]=t,ot=(l,e,t)=>(Yt(l,typeof e!="symbol"?e+"":e,t),t);class Rt extends ht{constructor(e={}){super({id:"fibonacci-tool",name:e.name||"Fibonacci Retracement",icon:e.icon||'<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M120-80v-80h720v80H120Zm0-240v-80h720v80H120Zm0-240v-80h720v80H120Zm0-240v-80h720v80H120Z"/></svg>'}),ot(this,"startPoint",null),ot(this,"endPoint",null),ot(this,"state","idle"),ot(this,"graphicGroup",null),ot(this,"levels",[0,.236,.382,.5,.618,.786,1]),ot(this,"colors",["#787b86","#f44336","#ff9800","#4caf50","#2196f3","#00bcd4","#787b86"]),ot(this,"onClick",t=>{this.state==="idle"?(this.state="drawing",this.startPoint=[t.offsetX,t.offsetY],this.endPoint=[t.offsetX,t.offsetY],this.initGraphic(),this.updateGraphic()):this.state==="drawing"&&(this.state="finished",this.endPoint=[t.offsetX,t.offsetY],this.updateGraphic(),this.saveDrawing(),this.removeGraphic(),this.context.disableTools())}),ot(this,"onMouseMove",t=>{this.state==="drawing"&&(this.endPoint=[t.offsetX,t.offsetY],this.updateGraphic())})}onActivate(){this.state="idle",this.startPoint=null,this.endPoint=null,this.context.getChart().getZr().setCursorStyle("crosshair"),this.bindEvents()}onDeactivate(){this.state="idle",this.startPoint=null,this.endPoint=null,this.removeGraphic(),this.unbindEvents(),this.context.getChart().getZr().setCursorStyle("default")}bindEvents(){const e=this.context.getChart().getZr();e.on("click",this.onClick),e.on("mousemove",this.onMouseMove)}unbindEvents(){const e=this.context.getChart().getZr();e.off("click",this.onClick),e.off("mousemove",this.onMouseMove)}initGraphic(){this.graphicGroup=new q.graphic.Group,this.context.getChart().getZr().add(this.graphicGroup)}removeGraphic(){this.graphicGroup&&(this.context.getChart().getZr().remove(this.graphicGroup),this.graphicGroup=null)}updateGraphic(){if(!this.graphicGroup||!this.startPoint||!this.endPoint)return;this.graphicGroup.removeAll();const e=this.startPoint[0],t=this.startPoint[1],i=this.endPoint[0],s=this.endPoint[1],o=new q.graphic.Line({shape:{x1:e,y1:t,x2:i,y2:s},style:{stroke:"#999",lineWidth:1,lineDash:[4,4]},silent:!0});this.graphicGroup.add(o);const n=Math.min(e,i),p=Math.max(e,i),d=p-n,r=s-t;this.levels.forEach((k,f)=>{const m=s-r*k,S=this.colors[f%this.colors.length],u=new q.graphic.Line({shape:{x1:n,y1:m,x2:p,y2:m},style:{stroke:S,lineWidth:1},silent:!0});if(this.graphicGroup.add(u),f<this.levels.length-1){const y=this.levels[f+1],v=s-r*y,E=Math.abs(v-m),V=Math.min(m,v),N=new q.graphic.Rect({shape:{x:n,y:V,width:d,height:E},style:{fill:this.colors[(f+1)%this.colors.length],opacity:.1},silent:!0});this.graphicGroup.add(N)}})}saveDrawing(){if(!this.startPoint||!this.endPoint)return;const e=this.context.coordinateConversion.pixelToData({x:this.startPoint[0],y:this.startPoint[1]}),t=this.context.coordinateConversion.pixelToData({x:this.endPoint[0],y:this.endPoint[1]});if(e&&t){const i=e.paneIndex||0;this.context.addDrawing({id:`fib-${Date.now()}`,type:"fibonacci",points:[e,t],paneIndex:i,style:{color:"#3b82f6",lineWidth:1}})}}}export{ht as AbstractPlugin,Rt as FibonacciTool,Ot as LineTool,$t as MeasureTool,Lt as QFChart};
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { OHLCV, Indicator as IndicatorType, QFChartOptions, IndicatorPlot } from '../types';
|
|
1
|
+
import { OHLCV, Indicator as IndicatorType, QFChartOptions, IndicatorPlot, IndicatorStyle } from '../types';
|
|
2
2
|
import { PaneConfiguration } from './LayoutManager';
|
|
3
3
|
import { textToBase64Image } from '../Utils';
|
|
4
4
|
|
|
@@ -25,8 +25,11 @@ export class SeriesBuilder {
|
|
|
25
25
|
const isUp = lastBar.close >= lastBar.open;
|
|
26
26
|
// Use configured color, or dynamic color based on candle direction
|
|
27
27
|
const lineColor = options.lastPriceLine?.color || (isUp ? upColor : downColor);
|
|
28
|
-
|
|
28
|
+
let lineStyleType = options.lastPriceLine?.lineStyle || 'dashed';
|
|
29
29
|
|
|
30
|
+
if (lineStyleType.startsWith('linestyle_')) {
|
|
31
|
+
lineStyleType = lineStyleType.replace('linestyle_', '') as any;
|
|
32
|
+
}
|
|
30
33
|
markLine = {
|
|
31
34
|
symbol: ['none', 'none'],
|
|
32
35
|
data: [
|
|
@@ -298,6 +301,9 @@ export class SeriesBuilder {
|
|
|
298
301
|
}
|
|
299
302
|
});
|
|
300
303
|
|
|
304
|
+
if (plot.options?.style?.startsWith('style_')) {
|
|
305
|
+
plot.options.style = plot.options.style.replace('style_', '') as IndicatorStyle;
|
|
306
|
+
}
|
|
301
307
|
switch (plot.options.style) {
|
|
302
308
|
case 'histogram':
|
|
303
309
|
case 'columns':
|