chartforge 0.0.1 → 0.0.2
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/chartforge.js +1148 -0
- package/dist/chartforge.umd.cjs +1 -0
- package/dist/index-BCodEFNd.js +1060 -0
- package/dist/plugins.js +14 -0
- package/dist/themes.js +44 -0
- package/dist/types/ChartForge.d.ts +50 -0
- package/dist/types/ChartForge.d.ts.map +1 -0
- package/dist/types/adapters/PollingAdapter.d.ts +18 -0
- package/dist/types/adapters/PollingAdapter.d.ts.map +1 -0
- package/dist/types/adapters/RealTimeModule.d.ts +14 -0
- package/dist/types/adapters/RealTimeModule.d.ts.map +1 -0
- package/dist/types/adapters/WebSocketAdapter.d.ts +17 -0
- package/dist/types/adapters/WebSocketAdapter.d.ts.map +1 -0
- package/dist/types/adapters/index.d.ts +4 -0
- package/dist/types/adapters/index.d.ts.map +1 -0
- package/dist/types/core/AnimationEngine.d.ts +8 -0
- package/dist/types/core/AnimationEngine.d.ts.map +1 -0
- package/dist/types/core/DataPipeline.d.ts +10 -0
- package/dist/types/core/DataPipeline.d.ts.map +1 -0
- package/dist/types/core/EventBus.d.ts +10 -0
- package/dist/types/core/EventBus.d.ts.map +1 -0
- package/dist/types/core/MiddlewarePipeline.d.ts +7 -0
- package/dist/types/core/MiddlewarePipeline.d.ts.map +1 -0
- package/dist/types/core/PluginManager.d.ts +15 -0
- package/dist/types/core/PluginManager.d.ts.map +1 -0
- package/dist/types/core/ThemeManager.d.ts +11 -0
- package/dist/types/core/ThemeManager.d.ts.map +1 -0
- package/dist/types/core/VirtualRenderer.d.ts +18 -0
- package/dist/types/core/VirtualRenderer.d.ts.map +1 -0
- package/dist/types/core/index.d.ts +8 -0
- package/dist/types/core/index.d.ts.map +1 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/plugins/AnnotationPlugin.d.ts +42 -0
- package/dist/types/plugins/AnnotationPlugin.d.ts.map +1 -0
- package/dist/types/plugins/AxisPlugin.d.ts +27 -0
- package/dist/types/plugins/AxisPlugin.d.ts.map +1 -0
- package/dist/types/plugins/BasePlugin.d.ts +10 -0
- package/dist/types/plugins/BasePlugin.d.ts.map +1 -0
- package/dist/types/plugins/CrosshairPlugin.d.ts +29 -0
- package/dist/types/plugins/CrosshairPlugin.d.ts.map +1 -0
- package/dist/types/plugins/DataLabelsPlugin.d.ts +19 -0
- package/dist/types/plugins/DataLabelsPlugin.d.ts.map +1 -0
- package/dist/types/plugins/ExportPlugin.d.ts +20 -0
- package/dist/types/plugins/ExportPlugin.d.ts.map +1 -0
- package/dist/types/plugins/GridPlugin.d.ts +26 -0
- package/dist/types/plugins/GridPlugin.d.ts.map +1 -0
- package/dist/types/plugins/LegendPlugin.d.ts +26 -0
- package/dist/types/plugins/LegendPlugin.d.ts.map +1 -0
- package/dist/types/plugins/TooltipPlugin.d.ts +34 -0
- package/dist/types/plugins/TooltipPlugin.d.ts.map +1 -0
- package/dist/types/plugins/ZoomPlugin.d.ts +24 -0
- package/dist/types/plugins/ZoomPlugin.d.ts.map +1 -0
- package/dist/types/plugins/index.d.ts +37 -0
- package/dist/types/plugins/index.d.ts.map +1 -0
- package/dist/types/renderers/BarRenderer.d.ts +5 -0
- package/dist/types/renderers/BarRenderer.d.ts.map +1 -0
- package/dist/types/renderers/BaseRenderer.d.ts +31 -0
- package/dist/types/renderers/BaseRenderer.d.ts.map +1 -0
- package/dist/types/renderers/CandlestickRenderer.d.ts +5 -0
- package/dist/types/renderers/CandlestickRenderer.d.ts.map +1 -0
- package/dist/types/renderers/ColumnRenderer.d.ts +5 -0
- package/dist/types/renderers/ColumnRenderer.d.ts.map +1 -0
- package/dist/types/renderers/DonutRenderer.d.ts +5 -0
- package/dist/types/renderers/DonutRenderer.d.ts.map +1 -0
- package/dist/types/renderers/FunnelRenderer.d.ts +5 -0
- package/dist/types/renderers/FunnelRenderer.d.ts.map +1 -0
- package/dist/types/renderers/HeatmapRenderer.d.ts +5 -0
- package/dist/types/renderers/HeatmapRenderer.d.ts.map +1 -0
- package/dist/types/renderers/LineRenderer.d.ts +5 -0
- package/dist/types/renderers/LineRenderer.d.ts.map +1 -0
- package/dist/types/renderers/PieRenderer.d.ts +8 -0
- package/dist/types/renderers/PieRenderer.d.ts.map +1 -0
- package/dist/types/renderers/ScatterRenderer.d.ts +5 -0
- package/dist/types/renderers/ScatterRenderer.d.ts.map +1 -0
- package/dist/types/renderers/StackedBarRenderer.d.ts +5 -0
- package/dist/types/renderers/StackedBarRenderer.d.ts.map +1 -0
- package/dist/types/renderers/StackedColumnRenderer.d.ts +5 -0
- package/dist/types/renderers/StackedColumnRenderer.d.ts.map +1 -0
- package/dist/types/renderers/index.d.ts +17 -0
- package/dist/types/renderers/index.d.ts.map +1 -0
- package/dist/types/themes/builtins.d.ts +6 -0
- package/dist/types/themes/builtins.d.ts.map +1 -0
- package/dist/types/themes/index.d.ts +2 -0
- package/dist/types/themes/index.d.ts.map +1 -0
- package/dist/types/types.d.ts +97 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/utils/dom.d.ts +9 -0
- package/dist/types/utils/dom.d.ts.map +1 -0
- package/dist/types/utils/index.d.ts +3 -0
- package/dist/types/utils/index.d.ts.map +1 -0
- package/dist/types/utils/misc.d.ts +12 -0
- package/dist/types/utils/misc.d.ts.map +1 -0
- package/package.json +10 -8
|
@@ -0,0 +1 @@
|
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).ChartForge={})}(this,function(t){"use strict";class e{constructor(){this._events=new Map}on(t,e,i=0){this._events.has(t)||this._events.set(t,[]);const s=this._events.get(t);return s.push({handler:e,priority:i}),s.sort((t,e)=>e.priority-t.priority),()=>this.off(t,e)}off(t,e){const i=this._events.get(t);if(!i)return;const s=i.findIndex(t=>t.handler===e);-1!==s&&i.splice(s,1)}emit(t,e){this._events.get(t)?.forEach(({handler:t})=>t(e))}async emitAsync(t,e){const i=this._events.get(t);if(i)for(const{handler:s}of i)await s(e)}clear(t){t?this._events.delete(t):this._events.clear()}}class i{constructor(){this._fns=[]}use(t){return this._fns.push(t),this}async execute(t){let e=0;const i=async()=>{e>=this._fns.length||await this._fns[e++](t,i)};return await i(),t}}class s{constructor(){this._transformers=[]}addTransformer(t,e){return this._transformers.push({name:t,fn:e}),this}removeTransformer(t){const e=this._transformers.findIndex(e=>e.name===t);-1!==e&&this._transformers.splice(e,1)}async transform(t,e){let i=t;for(const s of this._transformers)i=await s.fn(i,e);return i}}const n={linear:t=>t,easeInQuad:t=>t*t,easeOutQuad:t=>t*(2-t),easeInOutQuad:t=>t<.5?2*t*t:(4-2*t)*t-1,easeInCubic:t=>t*t*t,easeOutCubic:t=>--t*t*t+1,easeInOutCubic:t=>t<.5?4*t*t*t:(t-1)*(2*t-2)*(2*t-2)+1,easeInElastic:t=>{const e=2*Math.PI/3;return 0===t?0:1===t?1:-Math.pow(2,10*t-10)*Math.sin((10*t-10.75)*e)},easeOutElastic:t=>{const e=2*Math.PI/3;return 0===t?0:1===t?1:Math.pow(2,-10*t)*Math.sin((10*t-.75)*e)+1},easeInBounce:t=>{const e=7.5625,i=2.75;return 1-((s=1-t)<1/i?e*s*s:s<2/i?e*(s-=1.5/i)*s+.75:s<2.5/i?e*(s-=2.25/i)*s+.9375:e*(s-=2.625/i)*s+.984375);var s},easeOutBounce:t=>{const e=7.5625,i=2.75;return t<1/i?e*t*t:t<2/i?e*(t-=1.5/i)*t+.75:t<2.5/i?e*(t-=2.25/i)*t+.9375:e*(t-=2.625/i)*t+.984375}};class a{constructor(){this._running=new Map}animate(t,e,i,s,a="easeOutQuad",r,o){this.stop(t);const h=n[a]??n.linear,d=performance.now(),l=n=>{const a=n-d,c=Math.min(a/s,1),p=h(c);if(r(e+(i-e)*p,c),c<1){const e=requestAnimationFrame(l);this._running.set(t,{rafId:e})}else this._running.delete(t),o?.()},c=requestAnimationFrame(l);this._running.set(t,{rafId:c})}stop(t){const e=this._running.get(t);e&&(cancelAnimationFrame(e.rafId),this._running.delete(t))}stopAll(){this._running.forEach(t=>cancelAnimationFrame(t.rafId)),this._running.clear()}}class r{constructor(){this._themes=new Map,this._current=null}register(t,e){this._themes.set(t,e)}get(t){return this._themes.get(t)}apply(t){const e=this._themes.get(t);return e?(this._current=t,e):(console.warn(`[ChartForge] Theme "${t}" not found`),null)}getCurrent(){return this._current?this._themes.get(this._current)??null:null}get currentName(){return this._current}}class o{constructor(t){this._chart=t,this._plugins=new Map,this._inited=new Set}register(t,e,i={}){if(this._plugins.has(t))return void console.warn(`[ChartForge] Plugin "${t}" already registered`);const s=new e(this._chart,i);this._plugins.set(t,{instance:s,config:i}),this._chart.initialized&&this._initOne(t,s)}get(t){return this._plugins.get(t)?.instance??null}has(t){return this._plugins.has(t)}remove(t){const e=this._plugins.get(t);e&&(e.instance.destroy?.(),this._plugins.delete(t),this._inited.delete(t))}initAll(){this._plugins.forEach((t,e)=>{this._inited.has(e)||this._initOne(e,t.instance)})}destroyAll(){this._plugins.forEach(t=>t.instance.destroy?.()),this._plugins.clear(),this._inited.clear()}_initOne(t,e){e.init?.(),this._inited.add(t)}}class h{constructor(t){this._chart=t,this._viewport={start:0,end:100},this._threshold=t.config.virtual?.threshold??1e4}updateViewport(t,e){this._viewport={start:t,end:e}}shouldVirtualize(){return this._chart.config.data.series.reduce((t,e)=>t+(Array.isArray(e.data)?e.data.length:0),0)>this._threshold}getVisibleData(){const{start:t,end:e}=this._viewport,i=this._chart.config.data;return{series:i.series.map(i=>({...i,data:i.data.slice(t,e)})),...i.labels&&{labels:i.labels.slice(t,e)}}}}class d{constructor(t){this._chart=t,this._registry=new Map,this._connections=new Map}registerAdapter(t,e){this._registry.set(t,e)}connect(t,e){const i=this._registry.get(t);if(!i)return void console.error(`[ChartForge] Real-time adapter "${t}" not registered`);const s=new i(e);s.on("data",t=>this._chart.updateData(t)),s.connect(),this._connections.set(t,s)}disconnect(t){const e=this._connections.get(t);e&&(e.disconnect(),this._connections.delete(t))}disconnectAll(){this._connections.forEach(t=>t.disconnect()),this._connections.clear()}}class l{constructor(t){this._config=t,this._ws=null,this._listeners=new Map}on(t,e){this._listeners.has(t)||this._listeners.set(t,[]),this._listeners.get(t).push(e)}_emit(t,e){this._listeners.get(t)?.forEach(t=>t(e))}connect(){this._ws=new WebSocket(this._config.url),this._ws.addEventListener("message",t=>{try{const e=JSON.parse(t.data);this._emit("data",e)}catch{console.warn("[ChartForge] WebSocketAdapter: invalid JSON",t.data)}}),this._ws.addEventListener("error",t=>this._emit("error",t))}disconnect(){this._ws?.close(),this._ws=null}send(t){this._ws?.readyState===WebSocket.OPEN&&this._ws.send(JSON.stringify(t))}}class c{constructor(t){this._config=t,this._timer=null,this._listeners=new Map}on(t,e){this._listeners.has(t)||this._listeners.set(t,[]),this._listeners.get(t).push(e)}_emit(t,e){this._listeners.get(t)?.forEach(t=>t(e))}async _poll(){try{const t=await fetch(this._config.url),e=await t.json();this._emit("data",e)}catch(t){this._emit("error",t)}}connect(){this._poll(),this._timer=setInterval(()=>{this._poll()},this._config.interval??5e3)}disconnect(){this._timer&&(clearInterval(this._timer),this._timer=null)}}const p={background:"#ffffff",foreground:"#000000",grid:"#e5e5e5",text:"#333333",textSecondary:"#666666",colors:["#3b82f6","#ef4444","#10b981","#f59e0b","#8b5cf6","#ec4899","#06b6d4","#84cc16"],tooltip:{background:"#ffffff",text:"#000000",border:"#e5e5e5",shadow:"rgba(0,0,0,0.1)"},legend:{text:"#333333",hover:"#000000"},axis:{line:"#d1d5db",text:"#6b7280",grid:"#f3f4f6"}},g={background:"#1a1a1a",foreground:"#ffffff",grid:"#333333",text:"#e5e5e5",textSecondary:"#999999",colors:["#60a5fa","#f87171","#34d399","#fbbf24","#a78bfa","#f472b6","#22d3ee","#a3e635"],tooltip:{background:"#2a2a2a",text:"#ffffff",border:"#444444",shadow:"rgba(0,0,0,0.3)"},legend:{text:"#e5e5e5",hover:"#ffffff"},axis:{line:"#404040",text:"#9ca3af",grid:"#262626"}},f={background:"#0a0a0a",foreground:"#00ffff",grid:"#1a1a2e",text:"#00ffff",textSecondary:"#ff00ff",colors:["#00ffff","#ff00ff","#ffff00","#00ff00","#ff0080","#8000ff","#ff8000","#0080ff"],tooltip:{background:"#1a1a2e",text:"#00ffff",border:"#00ffff",shadow:"rgba(0,255,255,0.3)"},legend:{text:"#00ffff",hover:"#ff00ff"},axis:{line:"#1a1a2e",text:"#00ffff",grid:"#16161f"}},u={light:p,dark:g,neon:f};function m(t,e={}){const i=document.createElementNS("http://www.w3.org/2000/svg",t);for(const[s,n]of Object.entries(e))"className"===s?i.setAttribute("class",String(n)):s.startsWith("on")&&"function"==typeof n?i.addEventListener(s.slice(2).toLowerCase(),n):i.setAttribute(s,String(n));return i}function _(t){for(;t.firstChild;)t.removeChild(t.firstChild)}function x(t,e,i,s){const n=(s-90)*Math.PI/180;return{x:t+i*Math.cos(n),y:e+i*Math.sin(n)}}class y{constructor(t,e){this.chart=t,this.data=e,this.theme=t.theme,this.config=t.config,this.group=t.mainGroup,this.padding={top:t.config.padding?.top??40,right:t.config.padding?.right??40,bottom:t.config.padding?.bottom??60,left:t.config.padding?.left??60}}dims(){const t=this.chart.svg.getAttribute("viewBox").split(" ").map(Number),e=t[2],i=t[3];return{width:e-this.padding.left-this.padding.right,height:i-this.padding.top-this.padding.bottom,totalWidth:e,totalHeight:i}}color(t){return this.theme.colors[t%this.theme.colors.length]}g(t){return m("g",{className:t})}}class b extends y{render(){const t=this.dims(),e=t.totalWidth/2,i=t.totalHeight/2,s=Math.min(t.width,t.height)/2-20,n=this.g("chartforge-pie");this.group.appendChild(n),this._drawSlices(n,e,i,s),this.config.animation?.enabled&&this._animate(n)}_drawSlices(t,e,i,s,n=0){const a=this.data.series[0].data,r=a.reduce((t,e)=>t+e,0);let o=0;a.forEach((a,h)=>{const d=a/r*360,l=o+d,c=this._slice(e,i,s,n,o,l,h);if(t.appendChild(c),0===n){const n=x(e,i,.7*s,o+d/2),h=m("text",{x:n.x,y:n.y,"text-anchor":"middle","dominant-baseline":"middle",fill:"#fff","font-size":"12","font-weight":"bold"});h.textContent=`${(a/r*100).toFixed(1)}%`,t.appendChild(h)}o=l})}_slice(t,e,i,s,n,a,r){const o=x(t,e,i,a),h=x(t,e,i,n),d=a-n<=180?"0":"1",l=this.data.series[0].data[r];let c;if(s>0){const r=x(t,e,s,a),l=x(t,e,s,n);c=[`M ${o.x} ${o.y}`,`A ${i} ${i} 0 ${d} 0 ${h.x} ${h.y}`,`L ${l.x} ${l.y}`,`A ${s} ${s} 0 ${d} 1 ${r.x} ${r.y}`,"Z"].join(" ")}else c=[`M ${t} ${e}`,`L ${o.x} ${o.y}`,`A ${i} ${i} 0 ${d} 0 ${h.x} ${h.y}`,"Z"].join(" ");const p=m("path",{d:c,fill:this.color(r),stroke:this.theme.background,"stroke-width":"2"});return p.addEventListener("mouseenter",()=>{p.setAttribute("opacity","0.8"),this.chart.emit("hover",{type:"pie",index:r,value:l})}),p.addEventListener("mouseleave",()=>p.setAttribute("opacity","1")),p.addEventListener("click",()=>this.chart.emit("click",{type:"pie",index:r,value:l})),p}_animate(t){t.querySelectorAll("path").forEach((t,e)=>{t.style.transformOrigin="center",t.style.transform="scale(0)",this.chart.animationEngine.animate(`pie-${e}`,0,1,this.config.animation?.duration??750,"easeOutElastic",e=>{t.style.transform=`scale(${e})`})})}}class v extends b{render(){const t=this.dims(),e=t.totalWidth/2,i=t.totalHeight/2,s=Math.min(t.width,t.height)/2-20,n=.6*s,a=this.g("chartforge-donut");this.group.appendChild(a),this._drawSlices(a,e,i,s,n);const r=m("text",{x:e,y:i,"text-anchor":"middle","dominant-baseline":"middle",fill:this.theme.text,"font-size":"24","font-weight":"bold"});r.textContent="Total",a.appendChild(r),this.config.animation?.enabled&&this._animate(a)}}class w extends y{render(){const t=this.dims(),e=this.data.series[0].data,i=Math.max(...e),s=t.width/e.length*.8,n=t.width/e.length*.2,a=this.g("chartforge-columns");this.group.appendChild(a),e.forEach((e,r)=>{const o=e/i*t.height,h=this.padding.left+r*(s+n),d=this.padding.top+t.height,l=m("rect",{x:h,y:d,width:s,height:0,fill:this.color(r)});a.appendChild(l),this.config.animation?.enabled?this.chart.animationEngine.animate(`col-${r}`,0,o,this.config.animation.duration??750,this.config.animation.easing??"easeOutQuad",t=>{l.setAttribute("height",String(t)),l.setAttribute("y",String(d-t))}):(l.setAttribute("height",String(o)),l.setAttribute("y",String(d-o))),l.addEventListener("mouseenter",()=>{l.setAttribute("opacity","0.8"),this.chart.emit("hover",{type:"column",index:r,value:e})}),l.addEventListener("mouseleave",()=>l.setAttribute("opacity","1")),l.addEventListener("click",()=>this.chart.emit("click",{type:"column",index:r,value:e}))})}}class k extends y{render(){const t=this.dims(),e=this.data.series[0].data,i=Math.max(...e),s=t.height/e.length*.8,n=t.height/e.length*.2,a=this.g("chartforge-bars");this.group.appendChild(a),e.forEach((e,r)=>{const o=e/i*t.width,h=this.padding.top+r*(s+n),d=m("rect",{x:this.padding.left,y:h,width:0,height:s,fill:this.color(r)});a.appendChild(d),this.config.animation?.enabled?this.chart.animationEngine.animate(`bar-${r}`,0,o,this.config.animation.duration??750,this.config.animation.easing??"easeOutQuad",t=>d.setAttribute("width",String(t))):d.setAttribute("width",String(o)),d.addEventListener("mouseenter",()=>{d.setAttribute("opacity","0.8"),this.chart.emit("hover",{type:"bar",index:r,value:e})}),d.addEventListener("mouseleave",()=>d.setAttribute("opacity","1")),d.addEventListener("click",()=>this.chart.emit("click",{type:"bar",index:r,value:e}));const l=m("text",{x:this.padding.left+6,y:h+s/2,fill:"#fff","font-size":"12","dominant-baseline":"middle"});l.textContent=String(this.data.labels?.[r]??`Item ${r+1}`),a.appendChild(l)})}}class C extends y{render(){const t=this.dims(),e=this.g("chartforge-lines");this.group.appendChild(e);const i=this.data.series.flatMap(t=>t.data),s=Math.max(...i),n=Math.min(...i),a=s-n||1;this.data.series.forEach((i,s)=>{const r=i.data,o=r.map((e,i)=>({x:this.padding.left+i/Math.max(r.length-1,1)*t.width,y:this.padding.top+t.height-(e-n)/a*t.height,value:e})),h=m("path",{d:o.map((t,e)=>`${0===e?"M":"L"} ${t.x} ${t.y}`).join(" "),fill:"none",stroke:this.color(s),"stroke-width":"2"});if(e.appendChild(h),o.forEach((t,i)=>{const n=m("circle",{cx:t.x,cy:t.y,r:4,fill:this.color(s)});n.addEventListener("mouseenter",()=>{n.setAttribute("r","6"),this.chart.emit("hover",{type:"line",seriesIndex:s,index:i,value:t.value})}),n.addEventListener("mouseleave",()=>n.setAttribute("r","4")),n.addEventListener("click",()=>this.chart.emit("click",{type:"line",seriesIndex:s,index:i,value:t.value})),e.appendChild(n)}),this.config.animation?.enabled){const t=h.getTotalLength();h.style.strokeDasharray=String(t),h.style.strokeDashoffset=String(t),this.chart.animationEngine.animate(`line-${s}`,t,0,this.config.animation.duration??750,this.config.animation.easing??"easeOutQuad",t=>{h.style.strokeDashoffset=String(t)})}})}}class S extends y{render(){const t=this.dims(),e=this.g("chartforge-scatter");this.group.appendChild(e),this.data.series.forEach((i,s)=>{const n=i.data,a=Math.max(...n.map(t=>t.x)),r=Math.max(...n.map(t=>t.y));n.forEach((i,n)=>{const o=this.padding.left+i.x/a*t.width,h=this.padding.top+t.height-i.y/r*t.height,d=i.r??5,l=m("circle",{cx:o,cy:h,r:this.config.animation?.enabled?0:d,fill:this.color(s),opacity:"0.7"});e.appendChild(l),this.config.animation?.enabled&&this.chart.animationEngine.animate(`scatter-${s}-${n}`,0,d,this.config.animation.duration??750,"easeOutElastic",t=>l.setAttribute("r",String(t))),l.addEventListener("mouseenter",()=>{l.setAttribute("r",String(1.5*d)),l.setAttribute("opacity","1"),this.chart.emit("hover",{type:"scatter",seriesIndex:s,index:n,point:i})}),l.addEventListener("mouseleave",()=>{l.setAttribute("r",String(d)),l.setAttribute("opacity","0.7")}),l.addEventListener("click",()=>this.chart.emit("click",{type:"scatter",seriesIndex:s,index:n,point:i}))})})}}class $ extends y{render(){const t=this.dims(),e=(this.data.labels??[]).length,i=t.width/e*.8,s=t.width/e*.2,n=Array.from({length:e},(t,e)=>this.data.series.reduce((t,i)=>t+(i.data[e]??0),0)),a=Math.max(...n),r=this.g("chartforge-stacked-columns");this.group.appendChild(r);for(let o=0;o<e;o++){let e=0;const n=this.padding.left+o*(i+s),h=this.padding.top+t.height;this.data.series.forEach((s,d)=>{const l=s.data[o]??0,c=l/a*t.height,p=m("rect",{x:n,y:h-e,width:i,height:0,fill:this.color(d)});r.appendChild(p);const g=e;this.config.animation?.enabled?this.chart.animationEngine.animate(`scol-${o}-${d}`,0,c,this.config.animation.duration??750,this.config.animation.easing??"easeOutQuad",t=>{p.setAttribute("height",String(t)),p.setAttribute("y",String(h-g-t))}):(p.setAttribute("height",String(c)),p.setAttribute("y",String(h-g-c))),p.addEventListener("mouseenter",()=>{p.setAttribute("opacity","0.8"),this.chart.emit("hover",{type:"stackedColumn",catIndex:o,seriesIndex:d,value:l})}),p.addEventListener("mouseleave",()=>p.setAttribute("opacity","1")),e+=c})}}}class A extends y{render(){const t=this.dims(),e=(this.data.labels??[]).length,i=t.height/e*.8,s=t.height/e*.2,n=Array.from({length:e},(t,e)=>this.data.series.reduce((t,i)=>t+(i.data[e]??0),0)),a=Math.max(...n),r=this.g("chartforge-stacked-bars");this.group.appendChild(r);for(let o=0;o<e;o++){let e=0;const n=this.padding.top+o*(i+s);this.data.series.forEach((s,h)=>{const d=s.data[o]??0,l=d/a*t.width,c=m("rect",{x:this.padding.left+e,y:n,width:0,height:i,fill:this.color(h)});r.appendChild(c);const p=e;this.config.animation?.enabled?this.chart.animationEngine.animate(`sbar-${o}-${h}`,0,l,this.config.animation.duration??750,this.config.animation.easing??"easeOutQuad",t=>{c.setAttribute("width",String(t)),c.setAttribute("x",String(this.padding.left+p))}):c.setAttribute("width",String(l)),c.addEventListener("mouseenter",()=>{c.setAttribute("opacity","0.8"),this.chart.emit("hover",{type:"stackedBar",catIndex:o,seriesIndex:h,value:d})}),c.addEventListener("mouseleave",()=>c.setAttribute("opacity","1")),e+=l})}}}class E extends y{render(){const t=this.dims(),e=this.data.series[0].data,i=Math.max(...e),s=t.height/e.length,n=this.g("chartforge-funnel");this.group.appendChild(n),e.forEach((a,r)=>{const o=e[r+1]??0,h=a/i*t.width,d=o/i*t.width,l=this.padding.top+r*s,c=this.padding.left+(t.width-h)/2,p=this.padding.left+(t.width-d)/2,g=m("polygon",{points:`${c},${l} ${c+h},${l} ${p+d},${l+s} ${p},${l+s}`,fill:this.color(r),stroke:this.theme.background,"stroke-width":"2"});n.appendChild(g);const f=m("text",{x:t.totalWidth/2,y:l+s/2,fill:"#fff","font-size":"14","text-anchor":"middle","dominant-baseline":"middle","font-weight":"bold"});f.textContent=`${this.data.labels?.[r]??`Stage ${r+1}`}: ${a}`,n.appendChild(f),g.addEventListener("mouseenter",()=>{g.setAttribute("opacity","0.8"),this.chart.emit("hover",{type:"funnel",index:r,value:a})}),g.addEventListener("mouseleave",()=>g.setAttribute("opacity","1"))})}}class L extends y{render(){const t=this.dims(),e=this.data.series[0].data,i=e.length,s=e[0]?.length??0,n=t.width/s,a=t.height/i,r=e.flat(),o=Math.min(...r),h=Math.max(...r)-o||1,d=this.g("chartforge-heatmap");this.group.appendChild(d),e.forEach((t,e)=>{t.forEach((t,i)=>{const s=(t-o)/h,r=`rgb(${Math.round(255*s)},100,${Math.round(255*(1-s))})`,l=m("rect",{x:this.padding.left+i*n,y:this.padding.top+e*a,width:n,height:a,fill:r,stroke:this.theme.background,"stroke-width":"1"});d.appendChild(l),l.addEventListener("mouseenter",()=>{l.setAttribute("stroke-width","2"),this.chart.emit("hover",{type:"heatmap",row:e,col:i,value:t})}),l.addEventListener("mouseleave",()=>l.setAttribute("stroke-width","1"))})})}}class M extends y{render(){const t=this.dims(),e=this.data.series[0].data,i=e.flatMap(t=>[t.open,t.high,t.low,t.close]),s=Math.min(...i),n=Math.max(...i)-s||1,a=t.width/e.length*.7,r=t.width/e.length*.3,o=this.g("chartforge-candlestick");this.group.appendChild(o);const h=e=>this.padding.top+t.height-(e-s)/n*t.height;e.forEach((t,e)=>{const i=this.padding.left+e*(a+r)+a/2,s=h(t.open),n=h(t.close),d=h(t.high),l=h(t.low),c=t.close>=t.open,p=c?"#10b981":"#ef4444",g=m("line",{x1:i,y1:d,x2:i,y2:l,stroke:p,"stroke-width":"1"});o.appendChild(g);const f=Math.min(s,n),u=Math.max(Math.abs(n-s),1),_=m("rect",{x:i-a/2,y:f,width:a,height:u,fill:c?p:"#ffffff",stroke:p,"stroke-width":"2"});o.appendChild(_),_.addEventListener("mouseenter",()=>{_.setAttribute("opacity","0.8"),this.chart.emit("hover",{type:"candlestick",index:e,candle:t})}),_.addEventListener("mouseleave",()=>_.setAttribute("opacity","1")),_.addEventListener("click",()=>this.chart.emit("click",{type:"candlestick",index:e,candle:t}))})}}const z={pie:b,donut:v,column:w,bar:k,row:k,line:C,scatter:S,stackedColumn:$,stackedBar:A,funnel:E,heatmap:L,candlestick:M};function R(){return`cf-${Date.now()}-${Math.random().toString(36).slice(2,9)}`}function B(t,e){let i;return(...s)=>{clearTimeout(i),i=setTimeout(()=>t(...s),e)}}function O(t,...e){for(const i of e)if(i)for(const e of Object.keys(i)){const s=i[e],n=t[e];s&&"object"==typeof s&&!Array.isArray(s)&&n&&"object"==typeof n&&!Array.isArray(n)?O(n,s):void 0!==s&&(t[e]=s)}return t}const T={width:"auto",height:400,responsive:!0,theme:"light",animation:{enabled:!0,duration:750,easing:"easeOutQuad"},plugins:{},middleware:[],virtual:{enabled:!1,threshold:1e4},padding:{top:40,right:40,bottom:60,left:60}},N=class t{constructor(t,n){if(this.initialized=!1,this._resizeObserver=null,this._rendering=!1,this.id=R(),this.container="string"==typeof t?document.querySelector(t):t,!this.container)throw new Error("[ChartForge] Container not found");this.config=O({...T},n),this.eventBus=new e,this.middleware=new i,this.dataPipeline=new s,this.animationEngine=new a,this.themeManager=new r,this.pluginManager=new o(this),this.virtualRenderer=new h(this),this.realTime=new d(this);for(const[e,i]of Object.entries(u))this.themeManager.register(e,i);this.realTime.registerAdapter("websocket",l),this.realTime.registerAdapter("polling",c),this._init()}_init(){const t=this.themeManager.apply(this.config.theme??"light");this.theme=t??u.light,this._createSVG(),this._setupMiddleware(),this.config.responsive&&(this._resizeObserver=new ResizeObserver(B(()=>this.resize(),150)),this._resizeObserver.observe(this.container)),this.initialized=!0,this.pluginManager.initAll(),this.render()}_createSVG(){const t="auto"===this.config.width?this.container.offsetWidth||600:this.config.width??600,e=this.config.height??400;this.svg=m("svg",{width:"100%",height:"100%",viewBox:`0 0 ${t} ${e}`,className:"chartforge-svg",role:"img"}),this.svg.appendChild(m("defs")),this.mainGroup=m("g",{className:"chartforge-main"}),this.svg.appendChild(this.mainGroup),this.svg.style.cssText=`\n display:block;\n font-family:'system-ui', sans-serif;\n background:${this.theme.background};\n border-radius:inherit;\n `,this.container.appendChild(this.svg)}_setupMiddleware(){this.middleware.use(async(t,e)=>{this.eventBus.emit("beforeRender",t),await e()});for(const t of this.config.middleware??[])this.middleware.use(t)}async render(){if(!this._rendering){this._rendering=!0;try{const t={data:this.config.data,theme:this.theme,svg:this.svg,mainGroup:this.mainGroup};await this.middleware.execute(t);const e=await this.dataPipeline.transform(this.config.data,this.config),i=this.config.virtual?.enabled&&this.virtualRenderer.shouldVirtualize();this._renderData(i?this.virtualRenderer.getVisibleData():e),this.eventBus.emit("afterRender",t)}finally{this._rendering=!1}}}_renderData(t){_(this.mainGroup);const e=z[this.config.type];e?new e(this,t).render():console.error(`[ChartForge] Unknown chart type: "${this.config.type}"`)}updateData(t){this.config.data=O({...this.config.data},t),this.render()}updateConfig(t){this.config=O({...this.config},t),this.render()}setTheme(t){const e=this.themeManager.apply(t);e&&(this.theme=e,this.svg.style.background=e.background,this.render())}use(t,e,i){return this.pluginManager.register(t,e,i),this}getPlugin(t){return this.pluginManager.get(t)}setViewport(t,e){this.virtualRenderer.updateViewport(t,e),this.render()}resize(){const t=this.container.offsetWidth||600,e=this.config.height??400;this.svg.setAttribute("viewBox",`0 0 ${t} ${e}`),this.render()}on(t,e,i){return this.eventBus.on(t,e,i)}off(t,e){this.eventBus.off(t,e)}emit(t,e){this.eventBus.emit(t,e)}destroy(){this.animationEngine.stopAll(),this.realTime.disconnectAll(),this.pluginManager.destroyAll(),this._resizeObserver?.disconnect(),this.eventBus.clear(),this.svg?.parentNode?.removeChild(this.svg)}static create(e,i){return new t(e,i)}static registerTheme(e,i){t._globalThemes.set(e,i)}};N._globalThemes=new Map;let I=N;class j{constructor(t,e){this._chart=t,this._cfg=e,this._els=[]}destroy(){this._els.forEach(t=>t.parentNode?.removeChild(t)),this._els.length=0}}const G={Tooltip:class extends j{constructor(t,e={}){super(t,e),this._mx=0,this._my=0,this._visible=!1;const i=t,{formatter:s,...n}=e;this._opts={...O({enabled:!0,backgroundColor:i.theme.tooltip.background,textColor:i.theme.tooltip.text,borderColor:i.theme.tooltip.border,borderRadius:6,padding:10,fontSize:13,shadow:!0,followCursor:!0,offset:{x:14,y:14}},n),formatter:s}}init(){this._opts.enabled&&(this._createTip(),this._attachEvents())}_createTip(){this._tip=document.createElement("div"),this._tip.className="cf-tooltip";const t=this._opts,e=t.shadow?"box-shadow:0 6px 20px rgba(0,0,0,.22)":"";this._tip.style.cssText=["position:fixed",`padding:${t.padding}px ${t.padding+4}px`,`background:${t.backgroundColor}`,`color:${t.textColor}`,`border:1px solid ${t.borderColor}`,`border-radius:${t.borderRadius}px`,`font-size:${t.fontSize}px`,"line-height:1.5","font-family:inherit","pointer-events:none","opacity:0","transform:scale(0.95)","transition:opacity .12s ease,transform .12s ease","z-index:99999","white-space:nowrap","max-width:260px",e,"top:0","left:0"].filter(Boolean).join(";"),document.body.appendChild(this._tip),this._els.push(this._tip)}_attachEvents(){const t=this._chart;t.svg.addEventListener("mousemove",t=>{const e=t;this._mx=e.clientX,this._my=e.clientY,this._visible&&this._position()}),t.on("hover",t=>{const e=t;this._buildContent(e),this._position(),this._show()}),t.svg.addEventListener("mouseleave",()=>this._hide())}_buildContent(t){const e=this._chart;if(this._opts.formatter)return void(this._tip.innerHTML=this._opts.formatter(t));const i=t=>e.config.data.labels?.[t]??`Item ${t+1}`,s=t=>e.config.data.series[t]?.name??`Series ${t+1}`,n=t=>"number"==typeof t?t.toLocaleString():String(t),a=(t,e)=>`<div style="display:flex;justify-content:space-between;gap:12px"><span style="opacity:.7">${t}</span><span style="font-weight:600">${n(e)}</span></div>`;let r="";switch(t.type){case"pie":case"donut":r=`<div style="font-weight:700;margin-bottom:4px">${i(t.index)}</div>${a("Value",t.value)}`;break;case"column":case"bar":r=`<div style="font-weight:700;margin-bottom:4px">${i(t.index)}</div>${a("Value",t.value)}`;break;case"line":{const e=t.seriesIndex,n=t.index;r=`<div style="font-weight:700;margin-bottom:4px">${s(e)}</div>${a(i(n),t.value)}`;break}case"scatter":{const e=t.point;r=`<div style="font-weight:700;margin-bottom:4px">${s(t.seriesIndex)}</div>${a("X",e.x)}${a("Y",e.y)}${void 0!==e.r?a("R",e.r):""}`;break}case"heatmap":r=`<div style="font-weight:700;margin-bottom:4px">Cell [${t.row}, ${t.col}]</div>${a("Value",t.value)}`;break;case"candlestick":{const e=t.candle,s=t.index,n=e.close-e.open,o=(n/e.open*100).toFixed(2),h=n>=0?"#10b981":"#ef4444";r=`<div style="font-weight:700;margin-bottom:4px">${i(s)}</div>`+a("Open",e.open)+a("High",e.high)+a("Low",e.low)+a("Close",e.close)+`<div style="color:${h};font-weight:700;margin-top:4px">${n>=0?"▲":"▼"} ${Math.abs(n).toLocaleString()} (${o}%)</div>`;break}case"stackedColumn":case"stackedBar":{const e=t.seriesIndex,n=t.catIndex;r=`<div style="font-weight:700;margin-bottom:4px">${s(e)}</div>${a(i(n),t.value)}`;break}case"funnel":r=`<div style="font-weight:700;margin-bottom:4px">${i(t.index)}</div>${a("Value",t.value)}`;break;default:r=`<div>${n(t.value??JSON.stringify(t))}</div>`}this._tip.innerHTML=r}_position(){const t=this._tip.getBoundingClientRect(),e=this._opts.offset.x,i=this._opts.offset.y;let s=this._mx+e,n=this._my+i;s+t.width>window.innerWidth-8&&(s=this._mx-t.width-e),n+t.height>window.innerHeight-8&&(n=this._my-t.height-i),s<8&&(s=8),n<8&&(n=8),this._tip.style.left=`${s}px`,this._tip.style.top=`${n}px`}_show(){this._visible=!0,this._tip.style.opacity="1",this._tip.style.transform="scale(1)"}_hide(){this._visible=!1,this._tip.style.opacity="0",this._tip.style.transform="scale(0.95)"}destroy(){this._tip?.parentNode?.removeChild(this._tip),this._els.length=0}},Legend:class extends j{constructor(t,e={}){super(t,e),this._hidden=new Set,this._origSeries=[];this._opts=O({enabled:!0,position:"bottom",align:"center",layout:"horizontal",fontSize:12,itemSpacing:12,markerSize:12,markerType:"square",clickable:!0},e)}init(){if(!this._opts.enabled)return;const t=this._chart;this._origSeries=[...t.config.data.series],this._group=m("g",{className:"cf-legend"}),t.svg.appendChild(this._group),this._els.push(this._group),this._draw(),t.on("afterRender",()=>{this._origSeries=[...t.config.data.series],this._draw()})}_draw(){const t=this._chart;_(this._group);const e=this._origSeries;if(!e.length)return;const i=t.svg.getAttribute("viewBox").split(" ").map(Number),s=i[2],n=i[3],a=this._opts;let r=0,o=0;"bottom"===a.position?(o=n-28,r=this._alignX(s,e.length,110)):"top"===a.position?(o=8,r=this._alignX(s,e.length,110)):"left"===a.position?(r=8,o=(n-e.length*(a.markerSize+a.itemSpacing))/2):(r=s-110,o=(n-e.length*(a.markerSize+a.itemSpacing))/2),e.forEach((t,e)=>{const i=this._item(t,e,r,o);this._group.appendChild(i),"horizontal"===a.layout?r+=110:o+=a.markerSize+a.itemSpacing})}_alignX(t,e,i){const s=e*i,n=this._opts;return"center"===n.align?(t-s)/2:"end"===n.align?t-s-20:20}_item(t,e,i,s){const n=this._chart,a=this._opts,r=this._hidden.has(e),o=n.theme.colors[e%n.theme.colors.length],h=r?.3:1,d=m("g");let l;l="circle"===a.markerType?m("circle",{cx:i+a.markerSize/2,cy:s+a.markerSize/2,r:a.markerSize/2,fill:o,opacity:h}):"line"===a.markerType?m("line",{x1:i,y1:s+a.markerSize/2,x2:i+a.markerSize,y2:s+a.markerSize/2,stroke:o,"stroke-width":3,opacity:h}):m("rect",{x:i,y:s,width:a.markerSize,height:a.markerSize,fill:o,opacity:h}),d.appendChild(l);const c=m("text",{x:i+a.markerSize+6,y:s+a.markerSize/2,fill:n.theme.legend.text,"font-size":a.fontSize,"dominant-baseline":"middle",opacity:h});return c.textContent=t.name??`Series ${e+1}`,d.appendChild(c),a.clickable&&(d.style.cursor="pointer",d.addEventListener("click",()=>this._toggle(e)),d.addEventListener("mouseenter",()=>c.setAttribute("fill",n.theme.legend.hover)),d.addEventListener("mouseleave",()=>c.setAttribute("fill",n.theme.legend.text))),d}_toggle(t){const e=this._chart;this._hidden.has(t)?this._hidden.delete(t):this._hidden.add(t),e.config.data.series=this._origSeries.filter((t,e)=>!this._hidden.has(e)),e.render(),e.config.data.series=this._origSeries,this._draw()}},Axis:class extends j{constructor(t,e={}){super(t,e),this._opts=O({x:{enabled:!0,label:"",fontSize:11,tickLength:5},y:{enabled:!0,label:"",fontSize:11,tickLength:5,ticks:5}},e)}init(){const t=this._chart;this._group=m("g",{className:"cf-axis"}),t.svg.appendChild(this._group),this._els.push(this._group),this._draw(),t.on("beforeRender",()=>this._draw())}_draw(){const t=this._chart;_(this._group);const e=t.svg.getAttribute("viewBox").split(" ").map(Number),i=e[2],s=e[3],n=t.config.padding??{},a={top:n.top??40,right:n.right??40,bottom:n.bottom??60,left:n.left??60};this._opts.x?.enabled&&this._drawX(i,s,a),this._opts.y?.enabled&&this._drawY(i,s,a)}_drawX(t,e,i){const s=this._chart,n=this._opts.x,a=e-i.bottom,r=i.left,o=t-i.right;this._group.appendChild(m("line",{x1:r,y1:a,x2:o,y2:a,stroke:s.theme.axis.line,"stroke-width":1}));const h=s.config.data.labels??[],d=(o-r)/(h.length||1);if(h.forEach((t,e)=>{const i=r+d*e+d/2;this._group.appendChild(m("line",{x1:i,y1:a,x2:i,y2:a+(n.tickLength??5),stroke:s.theme.axis.line,"stroke-width":1}));const o=m("text",{x:i,y:a+(n.tickLength??5)+13,fill:s.theme.axis.text,"font-size":n.fontSize??11,"text-anchor":"middle"});o.textContent=t,this._group.appendChild(o)}),n.label){const t=m("text",{x:(r+o)/2,y:e-8,fill:s.theme.text,"font-size":(n.fontSize??11)+2,"text-anchor":"middle","font-weight":"bold"});t.textContent=n.label,this._group.appendChild(t)}}_drawY(t,e,i){const s=this._chart,n=this._opts.y,a=i.left,r=i.top,o=e-i.bottom;this._group.appendChild(m("line",{x1:a,y1:r,x2:a,y2:o,stroke:s.theme.axis.line,"stroke-width":1}));const h=n.ticks??5,d=(o-r)/h,l=(s.config.data.series??[]).flatMap(t=>t.data),c=l.length?Math.max(...l):100;for(let p=0;p<=h;p++){const t=o-p*d,e=(c/h*p).toFixed(0);this._group.appendChild(m("line",{x1:a-(n.tickLength??5),y1:t,x2:a,y2:t,stroke:s.theme.axis.line,"stroke-width":1}));const i=m("text",{x:a-(n.tickLength??5)-5,y:t,fill:s.theme.axis.text,"font-size":n.fontSize??11,"text-anchor":"end","dominant-baseline":"middle"});i.textContent=e,this._group.appendChild(i)}if(n.label){const t=(r+o)/2,e=m("text",{x:15,y:t,fill:s.theme.text,"font-size":(n.fontSize??11)+2,"text-anchor":"middle","font-weight":"bold",transform:`rotate(-90,15,${t})`});e.textContent=n.label,this._group.appendChild(e)}}},Grid:class extends j{constructor(t,e={}){super(t,e);const i=t;this._opts=O({enabled:!0,x:{enabled:!0,color:i.theme.axis.grid,strokeWidth:1,dashArray:"2,2"},y:{enabled:!0,color:i.theme.axis.grid,strokeWidth:1,dashArray:"2,2",ticks:5}},e)}init(){if(!this._opts.enabled)return;const t=this._chart;this._group=m("g",{className:"cf-grid"}),t.mainGroup.insertBefore(this._group,t.mainGroup.firstChild),this._els.push(this._group),this._draw(),t.on("beforeRender",()=>this._draw())}_draw(){const t=this._chart;_(this._group);const e=t.svg.getAttribute("viewBox").split(" ").map(Number),i=e[2],s=e[3],n=t.config.padding??{},a={top:n.top??40,right:n.right??40,bottom:n.bottom??60,left:n.left??60},r=a.left,o=i-a.right,h=a.top,d=s-a.bottom;if(this._opts.y?.enabled){const t=this._opts.y.ticks??5,e=(d-h)/t;for(let i=0;i<=t;i++){const t=d-i*e;this._group.appendChild(m("line",{x1:r,y1:t,x2:o,y2:t,stroke:this._opts.y.color??"#ccc","stroke-width":this._opts.y.strokeWidth??1,"stroke-dasharray":this._opts.y.dashArray??"2,2",opacity:"0.5"}))}}if(this._opts.x?.enabled){const e=t.config.data.labels??[],i=(o-r)/(e.length||1);for(let t=0;t<=e.length;t++){const e=r+i*t;this._group.appendChild(m("line",{x1:e,y1:h,x2:e,y2:d,stroke:this._opts.x.color??"#ccc","stroke-width":this._opts.x.strokeWidth??1,"stroke-dasharray":this._opts.x.dashArray??"2,2",opacity:"0.5"}))}}}},Crosshair:class extends j{constructor(t,e={}){super(t,e);const i=t;this._opts={enabled:!0,x:{enabled:!0,color:i.theme.textSecondary,dashArray:"4,4",width:1,...e.x},y:{enabled:!0,color:i.theme.textSecondary,dashArray:"4,4",width:1,...e.y},snap:e.snap??!1}}init(){if(!this._opts.enabled)return;const t=this._chart;this._group=m("g",{className:"cf-crosshair",style:"pointer-events:none"}),this._xLine=m("line",{stroke:this._opts.x.color??"#888","stroke-width":this._opts.x.width??1,"stroke-dasharray":this._opts.x.dashArray??"4,4",opacity:0}),this._yLine=m("line",{stroke:this._opts.y.color??"#888","stroke-width":this._opts.y.width??1,"stroke-dasharray":this._opts.y.dashArray??"4,4",opacity:0}),this._opts.x.enabled&&this._group.appendChild(this._xLine),this._opts.y.enabled&&this._group.appendChild(this._yLine),t.mainGroup.appendChild(this._group),this._els.push(this._group),t.svg.addEventListener("mousemove",t=>this._onMove(t)),t.svg.addEventListener("mouseleave",()=>this._hide())}_onMove(t){const e=this._chart,i=e.svg.getAttribute("viewBox").split(" ").map(Number),s=i[2],n=i[3],a=e.config.padding??{},r=a.left??60,o=a.bottom??60,h=a.top??40,d=a.right??40,l=e.svg.getBoundingClientRect(),c=s/l.width,p=n/l.height,g=(t.clientX-l.left)*c,f=(t.clientY-l.top)*p;g<r||g>s-d||f<h||f>n-o?this._hide():(this._xLine.setAttribute("x1",String(g)),this._xLine.setAttribute("y1",String(h)),this._xLine.setAttribute("x2",String(g)),this._xLine.setAttribute("y2",String(n-o)),this._xLine.setAttribute("opacity","1"),this._yLine.setAttribute("x1",String(r)),this._yLine.setAttribute("y1",String(f)),this._yLine.setAttribute("x2",String(s-d)),this._yLine.setAttribute("y2",String(f)),this._yLine.setAttribute("opacity","1"))}_hide(){this._xLine.setAttribute("opacity","0"),this._yLine.setAttribute("opacity","0")}destroy(){this._group?.parentNode?.removeChild(this._group)}},DataLabels:class extends j{constructor(t,e={}){super(t,e);const i=t;this._opts={enabled:!0,fontSize:11,color:i.theme.text,anchor:"top",offset:5,formatter:t=>t.toLocaleString(),rotation:0,...e}}init(){if(!this._opts.enabled)return;const t=this._chart;this._group=m("g",{className:"cf-data-labels","pointer-events":"none"}),t.mainGroup.appendChild(this._group),this._els.push(this._group),t.on("afterRender",()=>this._draw())}_draw(){const t=this._chart;for(;this._group.firstChild;)this._group.removeChild(this._group.firstChild);const e=t.config.type,i=t.config.data,s=t.svg.getAttribute("viewBox").split(" ").map(Number),n=s[2],a=s[3],r=t.config.padding??{},o=r.left??60,h=r.right??40,d=r.top??40,l=r.bottom??60,c=n-o-h,p=a-d-l;if("column"===e){const t=i.series[0].data,e=Math.max(...t),s=c/t.length*.8,n=c/t.length*.2,a=d+p;t.forEach((t,i)=>{const r=o+i*(s+n)+s/2,h=a-t/e*p-this._opts.offset;this._addLabel(r,h,t,"middle")})}else if("bar"===e){const t=i.series[0].data,e=Math.max(...t),s=p/t.length*.8,n=p/t.length*.2;t.forEach((t,i)=>{const a=o+t/e*c+this._opts.offset,r=d+i*(s+n)+s/2;this._addLabel(a,r,t,"start","middle")})}}_addLabel(t,e,i,s="middle",n="auto"){const a=m("text",{x:t,y:e,fill:this._opts.color,"font-size":this._opts.fontSize,"text-anchor":s,"dominant-baseline":n});0!==this._opts.rotation&&a.setAttribute("transform",`rotate(${this._opts.rotation},${t},${e})`),a.textContent=this._opts.formatter(i),this._group.appendChild(a)}},Export:class extends j{constructor(t,e={}){super(t,e),this._opts={filename:e.filename??"chart",svgButton:e.svgButton??!0,pngButton:e.pngButton??!0,csvButton:e.csvButton??!0,buttonStyle:e.buttonStyle??""}}init(){const t=this._chart;this._toolbar=document.createElement("div"),this._toolbar.className="cf-export-toolbar",this._toolbar.style.cssText="display:flex;gap:6px;padding:4px 0;",this._opts.svgButton&&this._toolbar.appendChild(this._btn("SVG",()=>this.exportSVG())),this._opts.pngButton&&this._toolbar.appendChild(this._btn("PNG",()=>{this.exportPNG()})),this._opts.csvButton&&this._toolbar.appendChild(this._btn("CSV",()=>this.exportCSV())),t.container.insertBefore(this._toolbar,t.container.firstChild),this._els.push(this._toolbar)}_btn(t,e){const i=document.createElement("button");return i.textContent=`↓ ${t}`,i.style.cssText=["padding:3px 10px","font-size:11px","border-radius:4px","border:1px solid #888","background:transparent","cursor:pointer","opacity:.7","color: white",this._opts.buttonStyle].join(";"),i.addEventListener("mouseenter",()=>i.style.opacity="1"),i.addEventListener("mouseleave",()=>i.style.opacity=".7"),i.addEventListener("click",e),i}exportSVG(){const t=this._chart,e=(new XMLSerializer).serializeToString(t.svg),i=new Blob([e],{type:"image/svg+xml"});this._download(URL.createObjectURL(i),`${this._opts.filename}.svg`)}async exportPNG(t=2){const e=this._chart,i=(new XMLSerializer).serializeToString(e.svg),s=new Blob([i],{type:"image/svg+xml;charset=utf-8"}),n=URL.createObjectURL(s),a=new Image;await new Promise((t,e)=>{a.onload=()=>t(),a.onerror=e,a.src=n});const r=e.svg.getAttribute("viewBox")?.split(" ").map(Number)??[0,0,800,400],o=document.createElement("canvas");o.width=r[2]*t,o.height=r[3]*t;o.getContext("2d").drawImage(a,0,0,o.width,o.height),URL.revokeObjectURL(n),o.toBlob(t=>{t&&this._download(URL.createObjectURL(t),`${this._opts.filename}.png`)},"image/png")}exportCSV(){const t=this._chart.config.data,e=[],i=["Label",...t.series.map((t,e)=>t.name??`Series ${e+1}`)];e.push(i.join(","));const s=t.labels?.length??(t.series[0]?.data).length??0;for(let a=0;a<s;a++){const i=t.labels?.[a]??a,s=t.series.map(t=>t.data[a]??"");e.push([i,...s].join(","))}const n=new Blob([e.join("\n")],{type:"text/csv"});this._download(URL.createObjectURL(n),`${this._opts.filename}.csv`)}_download(t,e){const i=document.createElement("a");i.href=t,i.download=e,i.click(),setTimeout(()=>URL.revokeObjectURL(t),1e3)}},Zoom:class extends j{constructor(t,e={}){super(t,e),this._scale=1,this._tx=0,this._ty=0,this._dragging=!1,this._dragStart={x:0,y:0},this._opts={enabled:!0,type:"xy",minZoom:.5,maxZoom:10,resetOnDblClick:!0,...e}}init(){if(!this._opts.enabled)return;const t=this._chart.svg;t.style.userSelect="none",t.style.touchAction="none",t.addEventListener("wheel",t=>this._onWheel(t),{passive:!1}),t.addEventListener("mousedown",t=>this._onMouseDown(t)),t.addEventListener("mousemove",t=>this._onMouseMove(t)),t.addEventListener("mouseup",()=>{this._dragging=!1}),t.addEventListener("mouseleave",()=>{this._dragging=!1}),this._opts.resetOnDblClick&&t.addEventListener("dblclick",()=>this.reset())}_onWheel(t){t.preventDefault();const e=this._chart.svg.getBoundingClientRect(),i=t.clientX-e.left,s=t.clientY-e.top,n=t.deltaY>0?.85:1.15,a=Math.max(this._opts.minZoom,Math.min(this._opts.maxZoom,this._scale*n)),r=a/this._scale,o=this._opts.type;"x"!==o&&"xy"!==o||(this._tx=i-r*(i-this._tx)),"y"!==o&&"xy"!==o||(this._ty=s-r*(s-this._ty)),this._scale=a,this._apply()}_onMouseDown(t){0===t.button&&(this._dragging=!0,this._dragStart={x:t.clientX-this._tx,y:t.clientY-this._ty},this._chart.svg.style.cursor="grabbing")}_onMouseMove(t){if(!this._dragging)return;const e=this._opts.type;"x"!==e&&"xy"!==e||(this._tx=t.clientX-this._dragStart.x),"y"!==e&&"xy"!==e||(this._ty=t.clientY-this._dragStart.y),this._apply()}_apply(){const t=this._chart.mainGroup;t.style.transform=`translate(${this._tx}px, ${this._ty}px) scale(${this._scale})`,t.style.transformOrigin="0 0",this._chart.svg.style.cursor=this._dragging?"grabbing":"grab"}reset(){this._scale=1,this._tx=0,this._ty=0,this._apply(),this._chart.svg.style.cursor=""}},Annotation:class extends j{constructor(t,e={}){super(t,e),this._annCfg=e}init(){const t=this._chart;this._group=m("g",{className:"cf-annotations",style:"pointer-events:none"}),t.mainGroup.appendChild(this._group),this._els.push(this._group),this._draw(),t.on("afterRender",()=>this._draw())}addMarkLine(t){this._annCfg.markLines=[...this._annCfg.markLines??[],t],this._draw()}addMarkArea(t){this._annCfg.markAreas=[...this._annCfg.markAreas??[],t],this._draw()}addText(t){this._annCfg.texts=[...this._annCfg.texts??[],t],this._draw()}_draw(){for(;this._group.firstChild;)this._group.removeChild(this._group.firstChild);const t=this._chart,e=t.svg.getAttribute("viewBox").split(" ").map(Number),i=e[2],s=e[3],n=t.config.padding??{},a=n.left??60,r=n.right??40,o=n.top??40,h=n.bottom??60,d=i-a-r,l=s-o-h,c=(t.config.data.series??[]).flatMap(t=>t.data),p=c.length?Math.max(...c):100,g=c.length?Math.min(...c):0,f=p-g||1,u=(t,e)=>a+t/Math.max(e-1,1)*d,_=t=>o+l-(t-g)/f*l,x=t.config.data.labels?.length??1,y=t.theme.textSecondary;for(const b of this._annCfg.markLines??[]){const t=b.color??y;let e,n,d,l;if("horizontal"===b.type?(n=l=_(b.value),e=a,d=i-r):(e=d=u(b.value,x),n=o,l=s-h),this._group.appendChild(m("line",{x1:e,y1:n,x2:d,y2:l,stroke:t,"stroke-width":b.width??1.5,"stroke-dasharray":b.dashArray??"5,3"})),b.label){const i=m("text",{x:"horizontal"===b.type?d+4:e+4,y:"horizontal"===b.type?n-4:o-4,fill:t,"font-size":11});i.textContent=b.label,this._group.appendChild(i)}}for(const b of this._annCfg.markAreas??[]){const t=void 0!==b.xStart?u(b.xStart,x):a,e=void 0!==b.xEnd?u(b.xEnd,x):i-r,n=void 0!==b.yEnd?_(b.yEnd):o,d=void 0!==b.yStart?_(b.yStart):s-h;if(this._group.appendChild(m("rect",{x:t,y:n,width:e-t,height:d-n,fill:b.color??y,opacity:b.opacity??.12})),b.label){const e=m("text",{x:t+4,y:n+14,fill:b.color??y,"font-size":11});e.textContent=b.label,this._group.appendChild(e)}}for(const b of this._annCfg.texts??[]){const e=u(b.x,x),i=_(b.y),s=b.color??t.theme.text;if(b.background){const t=m("rect",{x:e-3,y:i-(b.fontSize??12),width:b.text.length*(.6*(b.fontSize??12))+6,height:(b.fontSize??12)+4,fill:b.background,rx:3});this._group.appendChild(t)}const n=m("text",{x:e,y:i,fill:s,"font-size":b.fontSize??12,"font-weight":"bold"});n.textContent=b.text,this._group.appendChild(n)}}}};t.AnimationEngine=a,t.BUILT_IN_THEMES=u,t.BarRenderer=k,t.BaseRenderer=y,t.CandlestickRenderer=M,t.ChartForge=I,t.ColumnRenderer=w,t.DataPipeline=s,t.DonutRenderer=v,t.EventBus=e,t.FunnelRenderer=E,t.HeatmapRenderer=L,t.LineRenderer=C,t.MiddlewarePipeline=i,t.PieRenderer=b,t.PluginManager=o,t.PollingAdapter=c,t.RENDERERS=z,t.RealTimeModule=d,t.ScatterRenderer=S,t.StackedBarRenderer=A,t.StackedColumnRenderer=$,t.ThemeManager=r,t.VirtualRenderer=h,t.WebSocketAdapter=l,t.clamp=function(t,e,i){return Math.min(Math.max(t,e),i)},t.createSVGElement=m,t.darkTheme=g,t.debounce=B,t.describeArc=function(t,e,i,s,n){const a=x(t,e,i,n),r=x(t,e,i,s),o=n-s<=180?"0":"1";return`M ${a.x} ${a.y} A ${i} ${i} 0 ${o} 0 ${r.x} ${r.y}`},t.flatMax=function(t){return Math.max(...t.flatMap(t=>t.data))},t.flatMin=function(t){return Math.min(...t.flatMap(t=>t.data))},t.lightTheme=p,t.merge=O,t.neonTheme=f,t.plugins=G,t.polarToCartesian=x,t.removeChildren=_,t.throttle=function(t,e){let i=!1;return(...s)=>{i||(t(...s),i=!0,setTimeout(()=>i=!1,e))}},t.uid=R,Object.defineProperty(t,Symbol.toStringTag,{value:"Module"})});
|