chartforge 0.0.2 → 0.0.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.
@@ -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).ChartForgePlugins={})}(this,function(t){"use strict";class e{constructor(t,e){this._chart=t,this._cfg=e,this._els=[]}destroy(){this._els.forEach(t=>t.parentNode?.removeChild(t)),this._els.length=0}}function i(t,...e){for(const s of e)if(s)for(const e of Object.keys(s)){const o=s[e],n=t[e];o&&"object"==typeof o&&!Array.isArray(o)&&n&&"object"==typeof n&&!Array.isArray(n)?i(n,o):void 0!==o&&(t[e]=o)}return t}class s extends e{constructor(t,e={}){super(t,e),this._mx=0,this._my=0,this._visible=!1;const s=t,{formatter:o,...n}=e;this._opts={...i({enabled:!0,backgroundColor:s.theme.tooltip.background,textColor:s.theme.tooltip.text,borderColor:s.theme.tooltip.border,borderRadius:6,padding:10,fontSize:13,shadow:!0,followCursor:!0,offset:{x:14,y:14}},n),formatter:o}}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}`,o=t=>"number"==typeof t?t.toLocaleString():String(t),n=(t,e)=>`<div style="display:flex;justify-content:space-between;gap:12px"><span style="opacity:.7">${t}</span><span style="font-weight:600">${o(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>${n("Value",t.value)}`;break;case"column":case"bar":r=`<div style="font-weight:700;margin-bottom:4px">${i(t.index)}</div>${n("Value",t.value)}`;break;case"line":{const e=t.seriesIndex,o=t.index;r=`<div style="font-weight:700;margin-bottom:4px">${s(e)}</div>${n(i(o),t.value)}`;break}case"scatter":{const e=t.point;r=`<div style="font-weight:700;margin-bottom:4px">${s(t.seriesIndex)}</div>${n("X",e.x)}${n("Y",e.y)}${void 0!==e.r?n("R",e.r):""}`;break}case"heatmap":r=`<div style="font-weight:700;margin-bottom:4px">Cell [${t.row}, ${t.col}]</div>${n("Value",t.value)}`;break;case"candlestick":{const e=t.candle,s=t.index,o=e.close-e.open,a=(o/e.open*100).toFixed(2),h=o>=0?"#10b981":"#ef4444";r=`<div style="font-weight:700;margin-bottom:4px">${i(s)}</div>`+n("Open",e.open)+n("High",e.high)+n("Low",e.low)+n("Close",e.close)+`<div style="color:${h};font-weight:700;margin-top:4px">${o>=0?"▲":"▼"} ${Math.abs(o).toLocaleString()} (${a}%)</div>`;break}case"stackedColumn":case"stackedBar":{const e=t.seriesIndex,o=t.catIndex;r=`<div style="font-weight:700;margin-bottom:4px">${s(e)}</div>${n(i(o),t.value)}`;break}case"funnel":r=`<div style="font-weight:700;margin-bottom:4px">${i(t.index)}</div>${n("Value",t.value)}`;break;default:r=`<div>${o(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,o=this._my+i;s+t.width>window.innerWidth-8&&(s=this._mx-t.width-e),o+t.height>window.innerHeight-8&&(o=this._my-t.height-i),s<8&&(s=8),o<8&&(o=8),this._tip.style.left=`${s}px`,this._tip.style.top=`${o}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}}function o(t,e={}){const i=document.createElementNS("http://www.w3.org/2000/svg",t);for(const[s,o]of Object.entries(e))"className"===s?i.setAttribute("class",String(o)):s.startsWith("on")&&"function"==typeof o?i.addEventListener(s.slice(2).toLowerCase(),o):i.setAttribute(s,String(o));return i}function n(t){for(;t.firstChild;)t.removeChild(t.firstChild)}class r extends e{constructor(t,e={}){super(t,e),this._hidden=new Set,this._origSeries=[];this._opts=i({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=o("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;n(this._group);const e=this._origSeries;if(!e.length)return;const i=t.svg.getAttribute("viewBox").split(" ").map(Number),s=i[2],o=i[3],r=this._opts;let a=0,h=0;"bottom"===r.position?(h=o-28,a=this._alignX(s,e.length,110)):"top"===r.position?(h=8,a=this._alignX(s,e.length,110)):"left"===r.position?(a=8,h=(o-e.length*(r.markerSize+r.itemSpacing))/2):(a=s-110,h=(o-e.length*(r.markerSize+r.itemSpacing))/2),e.forEach((t,e)=>{const i=this._item(t,e,a,h);this._group.appendChild(i),"horizontal"===r.layout?a+=110:h+=r.markerSize+r.itemSpacing})}_alignX(t,e,i){const s=e*i,o=this._opts;return"center"===o.align?(t-s)/2:"end"===o.align?t-s-20:20}_item(t,e,i,s){const n=this._chart,r=this._opts,a=this._hidden.has(e),h=n.theme.colors[e%n.theme.colors.length],l=a?.3:1,d=o("g");let p;p="circle"===r.markerType?o("circle",{cx:i+r.markerSize/2,cy:s+r.markerSize/2,r:r.markerSize/2,fill:h,opacity:l}):"line"===r.markerType?o("line",{x1:i,y1:s+r.markerSize/2,x2:i+r.markerSize,y2:s+r.markerSize/2,stroke:h,"stroke-width":3,opacity:l}):o("rect",{x:i,y:s,width:r.markerSize,height:r.markerSize,fill:h,opacity:l}),d.appendChild(p);const c=o("text",{x:i+r.markerSize+6,y:s+r.markerSize/2,fill:n.theme.legend.text,"font-size":r.fontSize,"dominant-baseline":"middle",opacity:l});return c.textContent=t.name??`Series ${e+1}`,d.appendChild(c),r.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()}}class a extends e{constructor(t,e={}){super(t,e),this._opts=i({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=o("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;n(this._group);const e=t.svg.getAttribute("viewBox").split(" ").map(Number),i=e[2],s=e[3],o=t.config.padding??{},r={top:o.top??40,right:o.right??40,bottom:o.bottom??60,left:o.left??60};this._opts.x?.enabled&&this._drawX(i,s,r),this._opts.y?.enabled&&this._drawY(i,s,r)}_drawX(t,e,i){const s=this._chart,n=this._opts.x,r=e-i.bottom,a=i.left,h=t-i.right;this._group.appendChild(o("line",{x1:a,y1:r,x2:h,y2:r,stroke:s.theme.axis.line,"stroke-width":1}));const l=s.config.data.labels??[],d=(h-a)/(l.length||1);if(l.forEach((t,e)=>{const i=a+d*e+d/2;this._group.appendChild(o("line",{x1:i,y1:r,x2:i,y2:r+(n.tickLength??5),stroke:s.theme.axis.line,"stroke-width":1}));const h=o("text",{x:i,y:r+(n.tickLength??5)+13,fill:s.theme.axis.text,"font-size":n.fontSize??11,"text-anchor":"middle"});h.textContent=t,this._group.appendChild(h)}),n.label){const t=o("text",{x:(a+h)/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,r=i.left,a=i.top,h=e-i.bottom;this._group.appendChild(o("line",{x1:r,y1:a,x2:r,y2:h,stroke:s.theme.axis.line,"stroke-width":1}));const l=n.ticks??5,d=(h-a)/l,p=(s.config.data.series??[]).flatMap(t=>t.data),c=p.length?Math.max(...p):100;for(let _=0;_<=l;_++){const t=h-_*d,e=(c/l*_).toFixed(0);this._group.appendChild(o("line",{x1:r-(n.tickLength??5),y1:t,x2:r,y2:t,stroke:s.theme.axis.line,"stroke-width":1}));const i=o("text",{x:r-(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=(a+h)/2,e=o("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)}}}class h extends e{constructor(t,e={}){super(t,e);const s=t;this._opts=i({enabled:!0,x:{enabled:!0,color:s.theme.axis.grid,strokeWidth:1,dashArray:"2,2"},y:{enabled:!0,color:s.theme.axis.grid,strokeWidth:1,dashArray:"2,2",ticks:5}},e)}init(){if(!this._opts.enabled)return;const t=this._chart;this._group=o("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;n(this._group);const e=t.svg.getAttribute("viewBox").split(" ").map(Number),i=e[2],s=e[3],r=t.config.padding??{},a={top:r.top??40,right:r.right??40,bottom:r.bottom??60,left:r.left??60},h=a.left,l=i-a.right,d=a.top,p=s-a.bottom;if(this._opts.y?.enabled){const t=this._opts.y.ticks??5,e=(p-d)/t;for(let i=0;i<=t;i++){const t=p-i*e;this._group.appendChild(o("line",{x1:h,y1:t,x2:l,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=(l-h)/(e.length||1);for(let t=0;t<=e.length;t++){const e=h+i*t;this._group.appendChild(o("line",{x1:e,y1:d,x2:e,y2:p,stroke:this._opts.x.color??"#ccc","stroke-width":this._opts.x.strokeWidth??1,"stroke-dasharray":this._opts.x.dashArray??"2,2",opacity:"0.5"}))}}}}class l extends e{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=o("g",{className:"cf-crosshair",style:"pointer-events:none"}),this._xLine=o("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=o("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],o=i[3],n=e.config.padding??{},r=n.left??60,a=n.bottom??60,h=n.top??40,l=n.right??40,d=e.svg.getBoundingClientRect(),p=s/d.width,c=o/d.height,_=(t.clientX-d.left)*p,g=(t.clientY-d.top)*c;_<r||_>s-l||g<h||g>o-a?this._hide():(this._xLine.setAttribute("x1",String(_)),this._xLine.setAttribute("y1",String(h)),this._xLine.setAttribute("x2",String(_)),this._xLine.setAttribute("y2",String(o-a)),this._xLine.setAttribute("opacity","1"),this._yLine.setAttribute("x1",String(r)),this._yLine.setAttribute("y1",String(g)),this._yLine.setAttribute("x2",String(s-l)),this._yLine.setAttribute("y2",String(g)),this._yLine.setAttribute("opacity","1"))}_hide(){this._xLine.setAttribute("opacity","0"),this._yLine.setAttribute("opacity","0")}destroy(){this._group?.parentNode?.removeChild(this._group)}}class d extends e{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=o("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),o=s[2],n=s[3],r=t.config.padding??{},a=r.left??60,h=r.right??40,l=r.top??40,d=r.bottom??60,p=o-a-h,c=n-l-d;if("column"===e){const t=i.series[0].data,e=Math.max(...t),s=p/t.length*.8,o=p/t.length*.2,n=l+c;t.forEach((t,i)=>{const r=a+i*(s+o)+s/2,h=n-t/e*c-this._opts.offset;this._addLabel(r,h,t,"middle")})}else if("bar"===e){const t=i.series[0].data,e=Math.max(...t),s=c/t.length*.8,o=c/t.length*.2;t.forEach((t,i)=>{const n=a+t/e*p+this._opts.offset,r=l+i*(s+o)+s/2;this._addLabel(n,r,t,"start","middle")})}}_addLabel(t,e,i,s="middle",n="auto"){const r=o("text",{x:t,y:e,fill:this._opts.color,"font-size":this._opts.fontSize,"text-anchor":s,"dominant-baseline":n});0!==this._opts.rotation&&r.setAttribute("transform",`rotate(${this._opts.rotation},${t},${e})`),r.textContent=this._opts.formatter(i),this._group.appendChild(r)}}class p extends e{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"}),o=URL.createObjectURL(s),n=new Image;await new Promise((t,e)=>{n.onload=()=>t(),n.onerror=e,n.src=o});const r=e.svg.getAttribute("viewBox")?.split(" ").map(Number)??[0,0,800,400],a=document.createElement("canvas");a.width=r[2]*t,a.height=r[3]*t;a.getContext("2d").drawImage(n,0,0,a.width,a.height),URL.revokeObjectURL(o),a.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 n=0;n<s;n++){const i=t.labels?.[n]??n,s=t.series.map(t=>t.data[n]??"");e.push([i,...s].join(","))}const o=new Blob([e.join("\n")],{type:"text/csv"});this._download(URL.createObjectURL(o),`${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)}}class c extends e{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,o=t.deltaY>0?.85:1.15,n=Math.max(this._opts.minZoom,Math.min(this._opts.maxZoom,this._scale*o)),r=n/this._scale,a=this._opts.type;"x"!==a&&"xy"!==a||(this._tx=i-r*(i-this._tx)),"y"!==a&&"xy"!==a||(this._ty=s-r*(s-this._ty)),this._scale=n,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=""}}class _ extends e{constructor(t,e={}){super(t,e),this._annCfg=e}init(){const t=this._chart;this._group=o("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??{},r=n.left??60,a=n.right??40,h=n.top??40,l=n.bottom??60,d=i-r-a,p=s-h-l,c=(t.config.data.series??[]).flatMap(t=>t.data),_=c.length?Math.max(...c):100,g=c.length?Math.min(...c):0,u=_-g||1,f=(t,e)=>r+t/Math.max(e-1,1)*d,x=t=>h+p-(t-g)/u*p,m=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,p;if("horizontal"===b.type?(n=p=x(b.value),e=r,d=i-a):(e=d=f(b.value,m),n=h,p=s-l),this._group.appendChild(o("line",{x1:e,y1:n,x2:d,y2:p,stroke:t,"stroke-width":b.width??1.5,"stroke-dasharray":b.dashArray??"5,3"})),b.label){const i=o("text",{x:"horizontal"===b.type?d+4:e+4,y:"horizontal"===b.type?n-4:h-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?f(b.xStart,m):r,e=void 0!==b.xEnd?f(b.xEnd,m):i-a,n=void 0!==b.yEnd?x(b.yEnd):h,d=void 0!==b.yStart?x(b.yStart):s-l;if(this._group.appendChild(o("rect",{x:t,y:n,width:e-t,height:d-n,fill:b.color??y,opacity:b.opacity??.12})),b.label){const e=o("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=f(b.x,m),i=x(b.y),s=b.color??t.theme.text;if(b.background){const t=o("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=o("text",{x:e,y:i,fill:s,"font-size":b.fontSize??12,"font-weight":"bold"});n.textContent=b.text,this._group.appendChild(n)}}}const g={Tooltip:s,Legend:r,Axis:a,Grid:h,Crosshair:l,DataLabels:d,Export:p,Zoom:c,Annotation:_};t.AnnotationPlugin=_,t.AxisPlugin=a,t.BasePlugin=e,t.CrosshairPlugin=l,t.DataLabelsPlugin=d,t.ExportPlugin=p,t.GridPlugin=h,t.LegendPlugin=r,t.TooltipPlugin=s,t.ZoomPlugin=c,t.plugins=g,Object.defineProperty(t,Symbol.toStringTag,{value:"Module"})});
@@ -0,0 +1 @@
1
+ !function(f,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((f="undefined"!=typeof globalThis?globalThis:f||self).ChartForgeThemes={})}(this,function(f){"use strict";const e={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"}},o={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"}},t={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"}},a={light:e,dark:o,neon:t};f.BUILT_IN_THEMES=a,f.darkTheme=o,f.lightTheme=e,f.neonTheme=t,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chartforge",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "Production-grade pluggable SVG charting library — zero dependencies",
5
5
  "type": "module",
6
6
  "main": "./dist/chartforge.umd.cjs",