chartifypdf 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,13 +1,19 @@
1
1
  # ChartifyPDF
2
2
 
3
- A zero-dependency React line chart component built with pure SVG. Supports zoom, tooltips, responsive sizing, and customizable styling.
3
+ A zero-dependency React line chart component built with pure SVG. Supports semantic zoom, smooth curves, hover highlight, peak markers, context menu, export to PDF/PNG/SVG, and more.
4
4
 
5
5
  ## Features
6
6
 
7
7
  - **Pure SVG** — no external charting libraries
8
8
  - **TypeScript** — fully typed props and exports
9
9
  - **Responsive** — auto-resizes via ResizeObserver, or set fixed dimensions
10
- - **Zoom & Pan** — scroll to zoom, drag to pan, with configurable controls
10
+ - **Semantic Zoom** — domain-based zoom with Shift+scroll, labels auto-update granularity
11
+ - **Smooth Curves** — monotone cubic (Fritsch-Carlson) and natural cubic spline
12
+ - **Hover Highlight** — hovered series stays bright, others dim with smooth transition
13
+ - **Peak Markers** — configurable icons (arrow/diamond/star) at peak data points
14
+ - **Right-Click Context Menu** — data table popover showing all series values
15
+ - **Export** — export chart as PDF, PNG, or SVG with one click
16
+ - **Click to Zoom** — click a data point to zoom in, double-click to reset
11
17
  - **Tooltips** — hover to see data values, with custom formatters and renderers
12
18
  - **Multi-series** — plot multiple data lines on one chart
13
19
  - **Customizable** — colors, axes, grid lines, fonts, margins, and more
@@ -67,6 +73,10 @@ function App() {
67
73
  | `className` | `string` | — | CSS class for container div |
68
74
  | `onPointClick` | `(point, series) => void` | — | Click handler for data points |
69
75
  | `ariaLabel` | `string` | `"Line chart"` | Accessibility label |
76
+ | `curveType` | `CurveType` | `"linear"` | Global curve type: `"linear"` \| `"monotone"` \| `"natural"` |
77
+ | `peaks` | `PeakConfig[]` | — | Peak date markers |
78
+ | `contextMenu` | `ContextMenuConfig` | — | Right-click context menu config |
79
+ | `export` | `ExportConfig` | — | Export button config |
70
80
 
71
81
  ### `DataSeries`
72
82
 
@@ -80,6 +90,7 @@ function App() {
80
90
  | `strokeDasharray` | `string` | — | SVG dash pattern (e.g. `"5 3"`) |
81
91
  | `showDots` | `boolean` | `false` | Show circles at data points |
82
92
  | `dotRadius` | `number` | `3.5` | Dot circle radius |
93
+ | `curveType` | `CurveType` | — | Per-series curve override |
83
94
 
84
95
  ### `AxisConfig`
85
96
 
@@ -92,6 +103,7 @@ function App() {
92
103
  | `max` | `number` | auto | Override axis maximum |
93
104
  | `gridLines` | `boolean` | Y: `true`, X: `false` | Show grid lines |
94
105
  | `gridLineColor` | `string` | `"#e0e0e0"` | Grid line color |
106
+ | `integerTicks` | `boolean` | `false` | Force integer-only ticks (useful for date timelines) |
95
107
 
96
108
  ### `TooltipConfig`
97
109
 
@@ -115,6 +127,36 @@ function App() {
115
127
  | `controlsPosition` | `string` | `"top-right"` | `"top-left"` \| `"top-right"` \| `"bottom-left"` \| `"bottom-right"` |
116
128
  | `enableWheel` | `boolean` | `true` | Zoom with mouse wheel |
117
129
  | `enablePan` | `boolean` | `true` | Pan by dragging |
130
+ | `requireModifierKey` | `boolean` | `true` | Require a modifier key for wheel zoom (prevents accidental page scroll) |
131
+ | `modifierKey` | `string` | `"shift"` | Which modifier key: `"shift"` (default, no browser conflict) \| `"ctrl"` \| `"alt"` |
132
+ | `enableClickZoom` | `boolean` | `false` | Click to zoom into a data point, double-click to reset |
133
+
134
+ ### `PeakConfig`
135
+
136
+ | Field | Type | Default | Description |
137
+ |-------|------|---------|-------------|
138
+ | `x` | `number` | *required* | X position of the peak |
139
+ | `label` | `string` | — | Label text above the marker |
140
+ | `color` | `string` | `"#ef4444"` | Marker color |
141
+ | `icon` | `string` | `"arrow"` | `"arrow"` \| `"diamond"` \| `"star"` |
142
+
143
+ ### `ContextMenuConfig`
144
+
145
+ | Field | Type | Default | Description |
146
+ |-------|------|---------|-------------|
147
+ | `enabled` | `boolean` | `false` | Enable right-click context menu |
148
+ | `backgroundColor` | `string` | `"#ffffff"` | Menu background color |
149
+ | `textColor` | `string` | `"#1f2937"` | Menu text color |
150
+ | `borderColor` | `string` | `"#e5e7eb"` | Menu border color |
151
+
152
+ ### `ExportConfig`
153
+
154
+ | Field | Type | Default | Description |
155
+ |-------|------|---------|-------------|
156
+ | `enabled` | `boolean` | `false` | Show export button |
157
+ | `buttonPosition` | `string` | `"top-right"` | `"top-left"` \| `"top-right"` \| `"bottom-left"` \| `"bottom-right"` |
158
+ | `fileName` | `string` | `"chart"` | Exported file name (without extension) |
159
+ | `format` | `string` | `"pdf"` | `"pdf"` \| `"png"` \| `"svg"` |
118
160
 
119
161
  ### `ChartStyle`
120
162
 
@@ -144,6 +186,31 @@ function App() {
144
186
 
145
187
  The chart fills its parent container's width and updates on resize.
146
188
 
189
+ ### Smooth Curved Lines
190
+
191
+ ```tsx
192
+ <LineChart
193
+ data={data}
194
+ curveType="monotone"
195
+ width={800}
196
+ height={400}
197
+ />
198
+ ```
199
+
200
+ Available curve types:
201
+ - `"linear"` — straight lines (default)
202
+ - `"monotone"` — Fritsch-Carlson monotone cubic, no overshoot (best for data)
203
+ - `"natural"` — natural cubic spline, smoother but may overshoot
204
+
205
+ Per-series override:
206
+
207
+ ```tsx
208
+ const data = [
209
+ { id: "a", name: "Smooth", data: [...], curveType: "monotone" },
210
+ { id: "b", name: "Linear", data: [...], curveType: "linear" },
211
+ ];
212
+ ```
213
+
147
214
  ### Multi-series with Custom Colors
148
215
 
149
216
  ```tsx
@@ -167,19 +234,91 @@ const data = [
167
234
  <LineChart data={data} width={800} height={400} />
168
235
  ```
169
236
 
170
- ### With Zoom and Custom Axes
237
+ Hover over any line to highlight it — the hovered series stays at full opacity while others dim to 20%.
238
+
239
+ ### Semantic Zoom with Integer Timeline
171
240
 
172
241
  ```tsx
173
242
  <LineChart
174
243
  data={data}
175
244
  width={800}
176
245
  height={400}
177
- xAxis={{ label: "Month", tickCount: 12, gridLines: true }}
178
- yAxis={{ label: "Revenue ($)", tickFormat: (v) => `$${v}` }}
179
- zoom={{ enabled: true, maxScale: 5, controlsPosition: "top-left" }}
246
+ xAxis={{
247
+ label: "Day",
248
+ integerTicks: true,
249
+ tickFormat: (v) => `Day ${v}`,
250
+ }}
251
+ zoom={{
252
+ enabled: true,
253
+ maxScale: 5,
254
+ requireModifierKey: true,
255
+ enableClickZoom: true,
256
+ }}
180
257
  />
181
258
  ```
182
259
 
260
+ - **Shift + scroll** to zoom — page scrolls normally without Shift (no browser zoom conflict)
261
+ - **Click** a data point to zoom 2x centered at that point
262
+ - **Double-click** to reset zoom
263
+ - X-axis labels automatically update granularity when zoomed
264
+ - `integerTicks: true` prevents decimal values on date timelines
265
+
266
+ ### Peak Markers
267
+
268
+ ```tsx
269
+ <LineChart
270
+ data={data}
271
+ peaks={[
272
+ { x: 3, label: "Peak", icon: "star", color: "#ef4444" },
273
+ { x: 7, label: "ATH", icon: "arrow" },
274
+ ]}
275
+ />
276
+ ```
277
+
278
+ ### Right-Click Context Menu
279
+
280
+ ```tsx
281
+ <LineChart
282
+ data={data}
283
+ contextMenu={{
284
+ enabled: true,
285
+ backgroundColor: "#1a1a2e",
286
+ textColor: "#eee",
287
+ borderColor: "#333",
288
+ }}
289
+ />
290
+ ```
291
+
292
+ Right-click anywhere on the chart to see a data table showing all series values at the nearest X position. Press Escape or click outside to close.
293
+
294
+ ### Export to PDF/PNG/SVG
295
+
296
+ ```tsx
297
+ <LineChart
298
+ data={data}
299
+ export={{
300
+ enabled: true,
301
+ format: "png",
302
+ fileName: "my-chart",
303
+ buttonPosition: "top-right",
304
+ }}
305
+ />
306
+ ```
307
+
308
+ A download button appears in the chart. Click to export.
309
+
310
+ For programmatic export:
311
+
312
+ ```tsx
313
+ import { exportChart, exportChartAsPdf, exportChartAsPng, exportChartAsSvg } from "chartifypdf";
314
+
315
+ // Using a ref to the SVG element
316
+ const svgElement = document.querySelector("svg");
317
+ await exportChart(svgElement, "pdf", "my-chart");
318
+ await exportChartAsPng(svgElement, "my-chart");
319
+ await exportChartAsSvg(svgElement, "my-chart");
320
+ ```
321
+
183
322
  ### Custom Tooltip
184
323
 
185
324
  ```tsx
@@ -231,20 +370,63 @@ const data = [
231
370
 
232
371
  Note: Set `showDots: true` on the series to make points clickable.
233
372
 
373
+ ### Full-featured Example
374
+
375
+ ```tsx
376
+ <LineChart
377
+ data={data}
378
+ width={900}
379
+ height={500}
380
+ curveType="monotone"
381
+ xAxis={{ label: "Date", integerTicks: true, gridLines: true }}
382
+ yAxis={{ label: "Value ($)", tickFormat: (v) => `$${v}` }}
383
+ zoom={{
384
+ enabled: true,
385
+ maxScale: 8,
386
+ requireModifierKey: true,
387
+ enableClickZoom: true,
388
+ }}
389
+ peaks={[{ x: 15, label: "Peak", icon: "star" }]}
390
+ contextMenu={{ enabled: true }}
391
+ export={{ enabled: true, format: "png", fileName: "report" }}
392
+ animation={{ enabled: true }}
393
+ />
394
+ ```
395
+
234
396
  ## Exported Hooks
235
397
 
236
398
  For advanced usage, you can import the hooks directly:
237
399
 
238
400
  ```tsx
239
- import { useChartDimensions, useScales, useZoom, useTooltip } from "chartifypdf";
401
+ import {
402
+ useChartDimensions,
403
+ useDataDomain,
404
+ useScales,
405
+ useZoom,
406
+ useTooltip,
407
+ } from "chartifypdf";
240
408
  ```
241
409
 
242
410
  | Hook | Purpose |
243
411
  |------|---------|
244
412
  | `useChartDimensions` | Responsive container measurement via ResizeObserver |
245
- | `useScales` | Compute linear scales, ticks, and domains from data |
246
- | `useZoom` | Manage zoom/pan state and event handlers |
247
- | `useTooltip` | Track mouse position and find nearest data point |
413
+ | `useDataDomain` | Extract full X/Y domain from data series |
414
+ | `useScales` | Compute linear scales, ticks, and domains (supports view domain override) |
415
+ | `useZoom` | Domain-based semantic zoom/pan state and event handlers |
416
+ | `useTooltip` | Track mouse position and find nearest data point with Y-proximity detection |
417
+
418
+ ## Exported Utilities
419
+
420
+ ```tsx
421
+ import { exportChart, exportChartAsPdf, exportChartAsPng, exportChartAsSvg } from "chartifypdf";
422
+ ```
423
+
424
+ | Utility | Description |
425
+ |---------|-------------|
426
+ | `exportChart(svg, format, fileName)` | Export SVG element as PDF, PNG, or SVG |
427
+ | `exportChartAsPdf(svg, fileName)` | Export as PDF (opens print dialog) |
428
+ | `exportChartAsPng(svg, fileName)` | Export as PNG (2x resolution) |
429
+ | `exportChartAsSvg(svg, fileName)` | Export as SVG file |
248
430
 
249
431
  ## Browser Support
250
432
 
@@ -252,6 +434,7 @@ Works in all modern browsers that support:
252
434
  - SVG
253
435
  - ResizeObserver
254
436
  - CSS transitions (for animation)
437
+ - Canvas API (for PNG/PDF export)
255
438
 
256
439
  ## License
257
440
 
package/dist/index.d.ts CHANGED
@@ -43,7 +43,8 @@ interface ZoomConfig {
43
43
  controlsPosition?: "top-left" | "top-right" | "bottom-left" | "bottom-right";
44
44
  enableWheel?: boolean;
45
45
  enablePan?: boolean;
46
- requireCtrlKey?: boolean;
46
+ requireModifierKey?: boolean;
47
+ modifierKey?: "shift" | "ctrl" | "alt";
47
48
  enableClickZoom?: boolean;
48
49
  }
49
50
  interface ChartMargin {
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var e=require("react/jsx-runtime"),t=require("react");const n=["#4e79a7","#f28e2b","#e15759","#76b7b2","#59a14f","#edc948","#b07aa1","#ff9da7","#9c755f","#bab0ac"];function o(e,n,o){const[i,r]=t.useState({width:n??0,height:o??0}),s=void 0!==n&&void 0!==o;return t.useLayoutEffect(()=>{if(s)return void r({width:n,height:o});const t=e.current;if(!t)return;const i=()=>{const e=t.getBoundingClientRect();r({width:e.width,height:e.height})};i();const a=new ResizeObserver(()=>{i()});return a.observe(t),()=>a.disconnect()},[e,s,n,o]),i}function i(e,t,n){return Math.min(Math.max(e,t),n)}function r(e,t,n){return e+(t-e)*n}function s(e,t){const n=Math.floor(Math.log10(e)),o=e/Math.pow(10,n);let i;return i=t?o<1.5?1:o<3?2:o<7?5:10:o<=1?1:o<=2?2:o<=5?5:10,i*Math.pow(10,n)}function a(e,t,n){if(e===t){const n=0===e?1:.1*Math.abs(e);e-=n,t+=n}const o=s(t-e,!1),i=s(o/(n-1),!0);return{niceMin:Math.floor(e/i)*i,niceMax:Math.ceil(t/i)*i,tickStep:i}}function l(e,t,n,o){return i=>{if(t===e)return(n+o)/2;const s=function(e,t,n){return e===t?0:(n-e)/(t-e)}(e,t,i);return r(n,o,s)}}function c(e,t,n){const o=[];for(let i=e;i<=t+.5*n;i+=n)o.push(parseFloat(i.toPrecision(12)));return o}function d(e,n,o){return t.useMemo(()=>{let t=1/0,i=-1/0,r=1/0,s=-1/0;for(const n of e)for(const e of n.data)e.x<t&&(t=e.x),e.x>i&&(i=e.x),e.y<r&&(r=e.y),e.y>s&&(s=e.y);isFinite(t)||(t=0,i=1,r=0,s=1),void 0!==n?.min&&(t=n.min),void 0!==n?.max&&(i=n.max),void 0!==o?.min&&(r=o.min),void 0!==o?.max&&(s=o.max);const l=n?.tickCount??6,c=o?.tickCount??6,d=a(t,i,l),u=a(r,s,c);return{fullXDomain:[d.niceMin,d.niceMax],fullYDomain:[u.niceMin,u.niceMax]}},[e,n,o])}function u(e,n,o,i,r,s,d){return t.useMemo(()=>{let t=1/0,u=-1/0,h=1/0,f=-1/0;for(const n of e)for(const e of n.data)e.x<t&&(t=e.x),e.x>u&&(u=e.x),e.y<h&&(h=e.y),e.y>f&&(f=e.y);isFinite(t)||(t=0,u=1,h=0,f=1),void 0!==i?.min&&(t=i.min),void 0!==i?.max&&(u=i.max),void 0!==r?.min&&(h=r.min),void 0!==r?.max&&(f=r.max);const x=i?.tickCount??6,m=r?.tickCount??6;let p,g,y,b;if(s)p=s[0],g=s[1];else{const e=a(t,u,x);p=e.niceMin,g=e.niceMax}if(d)y=d[0],b=d[1];else{const e=a(h,f,m);y=e.niceMin,b=e.niceMax}const k=a(p,g,x),v=a(y,b,m),w=l(p,g,0,n),C=l(y,b,o,0);let M=k.tickStep,S=k.niceMin,j=k.niceMax;i?.integerTicks&&(M=Math.max(1,Math.ceil(M)),S=Math.ceil(p),j=Math.floor(g));let $=v.tickStep,L=v.niceMin,P=v.niceMax;r?.integerTicks&&($=Math.max(1,Math.ceil($)),L=Math.ceil(y),P=Math.floor(b));return{xScale:w,yScale:C,xTicks:c(S,j,M).filter(e=>e>=p&&e<=g).filter(e=>!i?.integerTicks||Number.isInteger(e)),yTicks:c(L,P,$).filter(e=>e>=y&&e<=b).filter(e=>!r?.integerTicks||Number.isInteger(e)),xDomain:[p,g],yDomain:[y,b]}},[e,n,o,i,r,s,d])}function h(e,n,o,s,a){const l=e?.enabled??!1,c=e?.maxScale??10,d=e?.step??.5,u=e?.enableWheel??!0,h=e?.enablePan??!0,f=e?.requireCtrlKey??!0,[x,m]=t.useState(n),[p,g]=t.useState(o),[y,b]=t.useState(!1),[k,v]=t.useState(!1),w=t.useRef({x:0,y:0,xDomain:n,yDomain:o}),C=t.useRef(null),M=t.useRef({x:n,y:o});n[0]===M.current.x[0]&&n[1]===M.current.x[1]&&o[0]===M.current.y[0]&&o[1]===M.current.y[1]||(M.current={x:n,y:o},m(n),g(o));const S=n[1]-n[0],j=x[1]-x[0],$=S>0&&j>0?S/j:1,L=t.useCallback((e,t)=>{const n=e[1]-e[0];if(n>=t[1]-t[0])return t;let o=e[0],i=e[1];return o<t[0]&&(o=t[0],i=o+n),i>t[1]&&(i=t[1],o=i-n),[o,i]},[]),P=t.useCallback(()=>{C.current&&clearTimeout(C.current),v(!0),C.current=setTimeout(()=>v(!1),2e3)},[]),D=t.useCallback((e,t,i)=>{if(!l)return;const s=t??.5,a=i??.5;m(t=>{const o=(t[1]-t[0])/e,i=S/c,a=Math.max(o,i),l=Math.min(a,S),d=r(t[0],t[1],s)-l*s;return L([d,d+l],n)}),g(t=>{const n=t[1]-t[0],i=o[1]-o[0],s=n/e,l=i/c,d=Math.max(s,l),u=Math.min(d,i),h=r(t[0],t[1],a)-u*a;return L([h,h+u],o)})},[l,n,o,S,c,L]),T=t.useCallback(()=>{D(1+d)},[d,D]),R=t.useCallback(()=>{D(1/(1+d))},[d,D]),W=t.useCallback(()=>{m(n),g(o)},[n,o]),A=t.useCallback((e,t)=>{if(!l)return;m(t=>{const o=(t[1]-t[0])/2,i=S/c,r=Math.max(o,i),s=Math.min(r,S),a=e-s/2;return L([a,a+s],n)}),g(e=>{const n=e[1]-e[0],i=o[1]-o[0],r=n/2,s=i/c,a=Math.max(r,s),l=Math.min(a,i),d=t-l/2;return L([d,d+l],o)})},[l,n,o,S,c,L]),z=t.useCallback(e=>{if(!l||!u)return;if(f&&!e.ctrlKey&&!e.metaKey)return void P();e.preventDefault();const t=e.currentTarget.getBoundingClientRect(),n=e.clientX-t.left,o=e.clientY-t.top,r=i(n/(t.width||1),0,1),s=i(o/(t.height||1),0,1),a=e.deltaY<0?1+d:1/(1+d);D(a,r,s)},[l,u,f,d,P,D]),N=t.useCallback(e=>{!l||!h||$<=1||0===e.button&&(b(!0),w.current={x:e.clientX,y:e.clientY,xDomain:x,yDomain:p})},[l,h,$,x,p]),X=t.useCallback(e=>{if(!y)return;const t=e.clientX-w.current.x,i=e.clientY-w.current.y,r=w.current.xDomain,l=w.current.yDomain,c=r[1]-r[0],d=l[1]-l[0],u=-t/s*c,h=i/a*d,f=[r[0]+u,r[1]+u],x=[l[0]+h,l[1]+h];m(L(f,n)),g(L(x,o))},[y,s,a,n,o,L]),E=t.useCallback(()=>{b(!1)},[]);return{viewXDomain:x,viewYDomain:p,scale:$,isPanning:y,showZoomHint:k,zoomIn:T,zoomOut:R,resetZoom:W,zoomToPoint:A,handleWheel:z,handlePanStart:N,handlePanMove:X,handlePanEnd:E}}function f(e,t,n){if(0===e.length)return null;let o=0,i=e.length-1;for(;o<i;){const r=Math.floor((o+i)/2);n(e[r].x)<t?o=r+1:i=r}let r=e[o],s=Math.abs(n(r.x)-t);if(o>0){const i=Math.abs(n(e[o-1].x)-t);i<s&&(s=i,r=e[o-1])}return r}function x(e,n,o,i,r,s,a,l){const[c,d]=t.useState(!1),[u,h]=t.useState(0),[x,m]=t.useState(0),[p,g]=t.useState(null),[y,b]=t.useState(null),[k,v]=t.useState(null);return{tooltipVisible:c,tooltipX:u,tooltipY:x,activePoint:p,activeSeries:y,activeSeriesId:k,handleMouseMove:t.useCallback(t=>{const l=e.current;if(!l)return;const c=l.getBoundingClientRect(),u=t.clientX-c.left-r,x=t.clientY-c.top-s;if(u<0||u>a)return d(!1),void v(null);let p=0,y=1/0;for(const e of n){const t=f(e.data,u,o);if(!t)continue;const n=Math.abs(o(t.x)-u);n<y&&(y=n,p=t.x)}let k=null,w=null,C=1/0;for(const e of n){let t=null,n=1/0;for(const o of e.data){const e=Math.abs(o.x-p);e<n&&(n=e,t=o)}if(!t)continue;const o=i(t.y),r=Math.abs(o-x);r<C&&(C=r,k=t,w=e)}k&&w&&(h(o(k.x)),m(i(k.y)),g(k),b(w),v(w.id),d(!0))},[e,n,o,i,r,s,a]),handleMouseLeave:t.useCallback(()=>{d(!1),g(null),b(null),v(null)},[])}}const m=e=>Math.abs(e)>=1e6?`${(e/1e6).toFixed(1)}M`:Math.abs(e)>=1e3?`${(e/1e3).toFixed(1)}K`:Number.isInteger(e)?e.toString():e.toFixed(1),p=t.memo(({xTicks:t,yTicks:n,xScale:o,yScale:i,plotWidth:r,plotHeight:s,xAxisConfig:a,yAxisConfig:l,style:c})=>{const d=c?.axisColor??"#333",u=c?.tickColor??"#666",h=c?.fontFamily??"sans-serif",f=c?.fontSize??11,x=a?.tickFormat??m,p=l?.tickFormat??m;return e.jsxs("g",{className:"chartifypdf-axes",children:[e.jsx("line",{x1:0,y1:s,x2:r,y2:s,stroke:d,strokeWidth:1}),t.map(t=>{const n=o(t);return e.jsxs("g",{children:[e.jsx("line",{x1:n,y1:s,x2:n,y2:s+6,stroke:d,strokeWidth:1}),e.jsx("text",{x:n,y:s+18,textAnchor:"middle",fill:u,fontFamily:h,fontSize:f,children:x(t)})]},`x-tick-${t}`)}),a?.label&&e.jsx("text",{x:r/2,y:s+38,textAnchor:"middle",fill:d,fontFamily:h,fontSize:f+1,fontWeight:"bold",children:a.label}),e.jsx("line",{x1:0,y1:0,x2:0,y2:s,stroke:d,strokeWidth:1}),n.map(t=>{const n=i(t);return e.jsxs("g",{children:[e.jsx("line",{x1:-6,y1:n,x2:0,y2:n,stroke:d,strokeWidth:1}),e.jsx("text",{x:-10,y:n,textAnchor:"end",dominantBaseline:"middle",fill:u,fontFamily:h,fontSize:f,children:p(t)})]},`y-tick-${t}`)}),l?.label&&e.jsx("text",{x:0,y:0,textAnchor:"middle",fill:d,fontFamily:h,fontSize:f+1,fontWeight:"bold",transform:`translate(-40, ${s/2}) rotate(-90)`,children:l.label})]})});p.displayName="Axes";const g=t.memo(({xTicks:t,yTicks:n,xScale:o,yScale:i,plotWidth:r,plotHeight:s,showXGrid:a,showYGrid:l,xGridColor:c="#e0e0e0",yGridColor:d="#e0e0e0"})=>e.jsxs("g",{className:"chartifypdf-grid",children:[l&&n.map(t=>{const n=i(t);return e.jsx("line",{x1:0,y1:n,x2:r,y2:n,stroke:d,strokeDasharray:"4 4",strokeOpacity:.5},`y-grid-${t}`)}),a&&t.map(t=>{const n=o(t);return e.jsx("line",{x1:n,y1:0,x2:n,y2:s,stroke:c,strokeDasharray:"4 4",strokeOpacity:.5},`x-grid-${t}`)})]}));function y(e){if(0===e.length)return"";const[t,...n]=e;return`M${t.x},${t.y}`+n.map(e=>`L${e.x},${e.y}`).join("")}function b(e,t){switch(t){case"monotone":return function(e){const t=e.length;if(t<2)return y(e);if(2===t)return y(e);const n=[],o=[],i=[];for(let r=0;r<t-1;r++)n.push(e[r+1].x-e[r].x),o.push(e[r+1].y-e[r].y),i.push(0===n[r]?0:o[r]/n[r]);const r=new Array(t);r[0]=i[0],r[t-1]=i[t-2];for(let e=1;e<t-1;e++)i[e-1]*i[e]<=0?r[e]=0:r[e]=2/(1/i[e-1]+1/i[e]);for(let e=0;e<t-1;e++)if(0===i[e])r[e]=0,r[e+1]=0;else{const t=r[e]/i[e],n=r[e+1]/i[e],o=t*t+n*n;if(o>9){const s=3/Math.sqrt(o);r[e]=s*t*i[e],r[e+1]=s*n*i[e]}}let s=`M${e[0].x},${e[0].y}`;for(let o=0;o<t-1;o++){const t=n[o]/3;s+=`C${e[o].x+t},${e[o].y+r[o]*t},${e[o+1].x-t},${e[o+1].y-r[o+1]*t},${e[o+1].x},${e[o+1].y}`}return s}(e);case"natural":return function(e){const t=e.length;if(t<2)return y(e);if(2===t)return y(e);function n(e){const t=e.length-1,n=new Array(t),o=new Array(t),i=new Array(t);n[0]=0,o[0]=2,i[0]=e[0]+2*e[1];for(let r=1;r<t-1;r++)n[r]=1,o[r]=4,i[r]=4*e[r]+2*e[r+1];n[t-1]=2,o[t-1]=7,i[t-1]=8*e[t-1]+e[t];for(let e=1;e<t;e++){const t=n[e]/o[e-1];o[e]-=t,i[e]-=t*i[e-1]}const r=new Array(t);r[t-1]=i[t-1]/o[t-1];for(let e=t-2;e>=0;e--)r[e]=(i[e]-r[e+1])/o[e];const s=new Array(t);for(let n=0;n<t-1;n++)s[n]=2*e[n+1]-r[n+1];s[t-1]=(e[t]+r[t-1])/2;const a=[];for(let e=0;e<t;e++)a.push({cp1:r[e],cp2:s[e]});return a}const o=e.map(e=>e.x),i=e.map(e=>e.y),r=n(o),s=n(i);let a=`M${e[0].x},${e[0].y}`;for(let n=0;n<t-1;n++)a+=`C${r[n].cp1},${s[n].cp1},${r[n].cp2},${s[n].cp2},${e[n+1].x},${e[n+1].y}`;return a}(e);default:return y(e)}}g.displayName="GridLines";const k=t.memo(({series:n,xScale:o,yScale:i,color:r,animation:s,onPointClick:a,curveType:l,highlightOpacity:c})=>{const d=t.useRef(null),[u,h]=t.useState(0),[f,x]=t.useState(!s?.enabled),m=n.strokeWidth??2,p=n.showDots??!1,g=n.dotRadius??3.5,k=n.curveType??l??"linear",v=c??1,w=n.data.map(e=>({x:o(e.x),y:i(e.y)})),C="linear"===k?y(w):b(w,k);t.useEffect(()=>{if(s?.enabled&&d.current){const e=d.current.getTotalLength();h(e),x(!1);const t=setTimeout(()=>{x(!0)},s.duration??800);return()=>clearTimeout(t)}},[C,s?.enabled,s?.duration]);const M=s?.enabled&&u>0?{strokeDasharray:u,strokeDashoffset:f?0:u,transition:`stroke-dashoffset ${s.duration??800}ms ${s.easing??"ease-in-out"}`}:{};return e.jsxs("g",{className:"chartifypdf-line-path",style:{opacity:v,transition:"opacity 150ms ease"},children:[e.jsx("path",{ref:d,d:C,fill:"none",stroke:r,strokeWidth:m,strokeDasharray:n.strokeDasharray,strokeLinecap:"round",strokeLinejoin:"round",style:M}),p&&n.data.map((t,s)=>e.jsx("circle",{cx:o(t.x),cy:i(t.y),r:g,fill:r,stroke:"#fff",strokeWidth:1.5,style:{cursor:a?"pointer":"default"},onClick:a?()=>a(t,n):void 0},`dot-${n.id}-${s}`))]})});k.displayName="LinePath";const v=t.memo(({visible:t,x:n,y:o,point:i,series:r,plotHeight:s,plotWidth:a,config:l,seriesColor:c})=>{if(!t||!i||!r)return null;const d=l?.backgroundColor??"rgba(0, 0, 0, 0.8)",u=l?.textColor??"#fff";let h;if(l?.renderCustom)h=l.renderCustom(i,r);else{h=l?.formatter?l.formatter(i,r):`${r.name}: (${i.x}, ${i.y})`}let f=n+12,x=o-40-8;return f+140>a&&(f=n-140-12),x<0&&(x=o+12),e.jsxs("g",{className:"chartifypdf-tooltip",pointerEvents:"none",children:[e.jsx("line",{x1:n,y1:0,x2:n,y2:s,stroke:"#999",strokeWidth:1,strokeDasharray:"4 4",opacity:.6}),e.jsx("circle",{cx:n,cy:o,r:5,fill:c,stroke:"#fff",strokeWidth:2}),e.jsx("foreignObject",{x:f,y:x,width:140,height:60,overflow:"visible",children:e.jsx("div",{style:{backgroundColor:d,color:u,padding:"6px 10px",borderRadius:"4px",fontSize:"12px",fontFamily:"sans-serif",whiteSpace:"nowrap",lineHeight:1.4,boxShadow:"0 2px 6px rgba(0,0,0,0.2)"},children:h})})]})});v.displayName="Tooltip";const w=t.memo(({config:t,svgWidth:n,svgHeight:o,margin:i,scale:r,onZoomIn:s,onZoomOut:a,onReset:l})=>{if(!t?.enabled||!1===t.showControls)return null;const c=t.controlsPosition??"top-right",d=24;let u,h;switch(c){case"top-left":u=i.left+8,h=i.top+8;break;case"bottom-left":u=i.left+8,h=o-i.bottom-24-8;break;case"bottom-right":u=n-i.right-80-8,h=o-i.bottom-24-8;break;default:u=n-i.right-80-8,h=i.top+8}const f=r>1?[{label:"+",onClick:s},{label:"−",onClick:a},{label:"↺",onClick:l}]:[{label:"+",onClick:s},{label:"−",onClick:a}];return e.jsx("g",{className:"chartifypdf-zoom-controls",transform:`translate(${u}, ${h})`,children:f.map((t,n)=>e.jsxs("g",{transform:`translate(${28*n}, 0)`,onClick:t.onClick,style:{cursor:"pointer"},children:[e.jsx("rect",{width:d,height:d,rx:4,fill:"rgba(255,255,255,0.9)",stroke:"#ccc",strokeWidth:1}),e.jsx("text",{x:12,y:12,textAnchor:"middle",dominantBaseline:"central",fontSize:14,fontFamily:"sans-serif",fill:"#333",fontWeight:"bold",children:t.label})]},t.label))})});function C({x:t,y:n,color:o}){return e.jsx("polygon",{points:`${t},${n} ${t-5},${n-10} ${t+5},${n-10}`,fill:o})}function M({x:t,y:n,color:o}){return e.jsx("polygon",{points:`${t},${n-6} ${t+5},${n} ${t},${n+6} ${t-5},${n}`,fill:o})}function S({x:t,y:n,color:o}){const i=[];for(let e=0;e<5;e++){const o=(72*e-90)*(Math.PI/180),r=(72*e+36-90)*(Math.PI/180);i.push(`${t+6*Math.cos(o)},${n+6*Math.sin(o)}`),i.push(`${t+3*Math.cos(r)},${n+3*Math.sin(r)}`)}return e.jsx("polygon",{points:i.join(" "),fill:o})}w.displayName="ZoomControls";const j=t.memo(({peaks:t,data:n,xScale:o,yScale:i})=>e.jsx("g",{className:"chartifypdf-peak-markers",children:t.map((t,r)=>{const s=function(e,t){let n=-1/0,o=-1;for(let i=0;i<e.length;i++){const r=e[i];let s=r.data[0],a=1/0;for(const e of r.data){const n=Math.abs(e.x-t);n<a&&(a=n,s=e)}s&&s.y>n&&(n=s.y,o=i)}return-1===o?null:{y:n,seriesIndex:o}}(n,t.x);if(!s)return null;const a=o(t.x),l=i(s.y),c=t.color??"#ef4444",d=t.icon??"arrow",u=t.label,h=l-14;return e.jsxs("g",{children:[e.jsx("line",{x1:a,y1:l,x2:a,y2:h+6,stroke:c,strokeWidth:1,strokeDasharray:"3 2",opacity:.6}),"arrow"===d&&e.jsx(C,{x:a,y:h,color:c}),"diamond"===d&&e.jsx(M,{x:a,y:h,color:c}),"star"===d&&e.jsx(S,{x:a,y:h,color:c}),u&&e.jsx("text",{x:a,y:h-8,textAnchor:"middle",fill:c,fontSize:11,fontWeight:600,children:u})]},`peak-${r}`)})}));j.displayName="PeakMarkers";const $=({visible:n,x:o,y:i,nearestX:r,data:s,config:a,getSeriesColor:l,onClose:c})=>{const d=t.useRef(null);if(t.useEffect(()=>{if(!n)return;const e=e=>{d.current&&!d.current.contains(e.target)&&c()},t=e=>{"Escape"===e.key&&c()},o=setTimeout(()=>{document.addEventListener("mousedown",e),document.addEventListener("keydown",t)},0);return()=>{clearTimeout(o),document.removeEventListener("mousedown",e),document.removeEventListener("keydown",t)}},[n,c]),!n)return null;const u=a?.backgroundColor??"#ffffff",h=a?.textColor??"#1f2937",f=a?.borderColor??"#e5e7eb",x=s.map((e,t)=>{const n=function(e,t){if(0===e.data.length)return null;let n=e.data[0],o=Math.abs(n.x-t);for(const i of e.data){const e=Math.abs(i.x-t);e<o&&(o=e,n=i)}return n.y}(e,r);return{name:e.name,color:e.color??l(t),x:r,y:n}});return e.jsxs("div",{ref:d,style:{position:"fixed",left:o,top:i,zIndex:9999,backgroundColor:u,color:h,border:`1px solid ${f}`,borderRadius:6,boxShadow:"0 4px 12px rgba(0,0,0,0.15)",padding:"8px 0",minWidth:200,fontSize:12,fontFamily:"system-ui, -apple-system, sans-serif"},children:[e.jsxs("div",{style:{padding:"4px 12px 8px",fontWeight:600,fontSize:11,color:h,opacity:.6,borderBottom:`1px solid ${f}`,marginBottom:4},children:["Data at X = ","number"==typeof r?r.toLocaleString():r]}),e.jsxs("table",{style:{width:"100%",borderCollapse:"collapse"},children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{style:{textAlign:"left",padding:"4px 12px",fontWeight:600,opacity:.7},children:"Series"}),e.jsx("th",{style:{textAlign:"right",padding:"4px 12px",fontWeight:600,opacity:.7},children:"Y"})]})}),e.jsx("tbody",{children:x.map((t,n)=>e.jsxs("tr",{style:{borderTop:n>0?`1px solid ${f}`:void 0},children:[e.jsxs("td",{style:{padding:"4px 12px",display:"flex",alignItems:"center",gap:6},children:[e.jsx("span",{style:{display:"inline-block",width:8,height:8,borderRadius:"50%",backgroundColor:t.color,flexShrink:0}}),t.name]}),e.jsx("td",{style:{padding:"4px 12px",textAlign:"right",fontVariantNumeric:"tabular-nums"},children:null!==t.y?t.y.toLocaleString():"—"})]},n))})]})]})};function L(e){const t=e.cloneNode(!0),n=e.getBoundingClientRect();t.setAttribute("width",String(n.width)),t.setAttribute("height",String(n.height)),t.setAttribute("xmlns","http://www.w3.org/2000/svg"),t.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink");const o=e.querySelectorAll("*"),i=t.querySelectorAll("*");for(let e=0;e<o.length;e++){const t=o[e],n=i[e];if(!n.style)continue;const r=window.getComputedStyle(t),s=["fill","stroke","stroke-width","stroke-dasharray","opacity","font-family","font-size","font-weight","text-anchor","dominant-baseline","visibility","display"];for(const e of s){const t=r.getPropertyValue(e);t&&n.style.setProperty(e,t)}}return t}function P(e,t){const n=URL.createObjectURL(e),o=document.createElement("a");o.href=n,o.download=t,document.body.appendChild(o),o.click(),document.body.removeChild(o),URL.revokeObjectURL(n)}async function D(e,t=2){const n=e.getBoundingClientRect(),o=n.width*t,i=n.height*t,r=document.createElement("canvas");r.width=o,r.height=i;const s=r.getContext("2d");if(!s)throw new Error("Cannot get canvas 2d context");s.scale(t,t);const a=function(e){const t=L(e),n=(new XMLSerializer).serializeToString(t),o=new Blob([n],{type:"image/svg+xml;charset=utf-8"});return URL.createObjectURL(o)}(e);return new Promise((e,t)=>{const o=new Image;o.onload=()=>{s.fillStyle="#ffffff",s.fillRect(0,0,n.width,n.height),s.drawImage(o,0,0,n.width,n.height),URL.revokeObjectURL(a),e(r)},o.onerror=()=>{URL.revokeObjectURL(a),t(new Error("Failed to load SVG as image"))},o.src=a})}async function T(e,t="chart"){const n=L(e),o=(new XMLSerializer).serializeToString(n);P(new Blob([o],{type:"image/svg+xml;charset=utf-8"}),`${t}.svg`)}async function R(e,t="chart"){const n=await D(e);P(await new Promise((e,t)=>{n.toBlob(n=>n?e(n):t(new Error("Canvas toBlob failed")),"image/png")}),`${t}.png`)}async function W(e,t="chart"){const n=(await D(e)).toDataURL("image/png"),o=e.getBoundingClientRect(),i=window.open("","_blank");if(!i)throw new Error("Popup blocked. Please allow popups to export PDF.");i.document.write(`\n <!DOCTYPE html>\n <html>\n <head>\n <title>${t}</title>\n <style>\n @page { size: landscape; margin: 10mm; }\n body { margin: 0; display: flex; justify-content: center; align-items: center; min-height: 100vh; }\n img { max-width: 100%; height: auto; }\n </style>\n </head>\n <body>\n <img src="${n}" width="${o.width}" height="${o.height}" />\n <script>\n window.onload = function() {\n setTimeout(function() { window.print(); window.close(); }, 300);\n };\n <\/script>\n </body>\n </html>\n `),i.document.close()}async function A(e,t="pdf",n="chart"){switch(t){case"svg":return T(e,n);case"png":return R(e,n);case"pdf":return W(e,n)}}$.displayName="ContextMenu";const z=t.memo(({config:n,svgRef:o,svgWidth:i,svgHeight:r,margin:s})=>{if(!n?.enabled)return null;let a,l;switch(n.buttonPosition??"top-right"){case"top-left":a=s.left+8,l=s.top+8+24+8;break;case"bottom-left":a=s.left+8,l=r-s.bottom-24-8;break;case"bottom-right":a=i-s.right-28-8,l=r-s.bottom-24-8;break;default:a=i-s.right-28-8,l=s.top+8+24+8}const c=t.useCallback(()=>{const e=o.current;if(!e)return;A(e,n?.format??"pdf",n?.fileName??"chart")},[o,n?.format,n?.fileName]);return e.jsxs("g",{className:"chartifypdf-export-button",transform:`translate(${a}, ${l})`,onClick:c,style:{cursor:"pointer"},children:[e.jsx("rect",{width:28,height:24,rx:4,fill:"rgba(255,255,255,0.9)",stroke:"#ccc",strokeWidth:1}),e.jsx("g",{transform:"translate(7, 4)",children:e.jsx("path",{d:"M7,2 L7,10 L4,7 M7,10 L10,7 M3,13 L11,13",fill:"none",stroke:"#333",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round"})})]})});z.displayName="ExportButton";const N={top:20,right:20,bottom:50,left:60},X=({data:i,width:r,height:s,margin:a,xAxis:l,yAxis:c,tooltip:f,zoom:m,style:y,animation:b,colorPalette:C,className:M,onPointClick:S,ariaLabel:L,curveType:P,peaks:D,contextMenu:T,export:R})=>{const W=t.useRef(null),A=t.useRef(null),X=t.useId(),E={...N,...a},Y=o(W,r,s??400),{width:F,height:I}=Y,B=Math.max(0,F-E.left-E.right),O=Math.max(0,I-E.top-E.bottom),{fullXDomain:H,fullYDomain:U}=d(i,l,c),Z=h(m,H,U,B,O),G=m?.enabled??!1,q=m?.enableClickZoom??!1,{xScale:K,yScale:V,xTicks:_,yTicks:J}=u(i,B,O,l,c,G?Z.viewXDomain:void 0,G?Z.viewYDomain:void 0),Q=!1!==f?.enabled,ee=x(A,i,K,V,E.left,E.top,B),te=ee.activeSeriesId,ne=ee.tooltipVisible&&null!==te,oe=e=>ne?e===te?1:.2:1,ie=m?.requireCtrlKey??!0,re=m?.enableWheel??!0;t.useEffect(()=>{const e=A.current;if(!e||!G||!re)return;const t=e=>{ie?(e.ctrlKey||e.metaKey)&&e.preventDefault():e.preventDefault()};return e.addEventListener("wheel",t,{passive:!1}),()=>e.removeEventListener("wheel",t)},[G,re,ie]);const se=t.useCallback(e=>{if(!G||!q)return;if(Z.isPanning)return;const t=A.current;if(!t)return;const n=t.getBoundingClientRect(),o=e.clientX-n.left-E.left,r=e.clientY-n.top-E.top;if(o<0||o>B||r<0||r>O)return;let s=0,a=0,l=1/0;for(const e of i)for(const t of e.data){const e=K(t.x),n=V(t.y),i=Math.hypot(e-o,n-r);i<l&&(l=i,s=t.x,a=t.y)}Z.zoomToPoint(s,a)},[G,q,Z,i,K,V,E.left,E.top,B,O]),ae=t.useCallback(()=>{G&&q&&Z.resetZoom()},[G,q,Z]),[le,ce]=t.useState({visible:!1,clientX:0,clientY:0,nearestX:0}),de=t.useCallback(e=>{if(!T?.enabled)return;e.preventDefault();const t=A.current;if(!t)return;const n=t.getBoundingClientRect(),o=e.clientX-n.left-E.left;if(o<0||o>B)return;let r=0,s=1/0;for(const e of i)for(const t of e.data){const e=K(t.x),n=Math.abs(e-o);n<s&&(s=n,r=t.x)}ce({visible:!0,clientX:e.clientX,clientY:e.clientY,nearestX:r})},[T?.enabled,i,K,E.left,B]),ue=t.useCallback(()=>{ce(e=>({...e,visible:!1}))},[]),he=l?.gridLines??!1,fe=c?.gridLines??!0,xe=e=>function(e,t){const o=t??n;return o[e%o.length]}(e,C);return 0===F||0===I?e.jsx("div",{ref:W,className:M,style:{width:r??"100%",height:s??400,backgroundColor:y?.backgroundColor}}):e.jsxs("div",{ref:W,className:M,style:{width:r??"100%",height:s??400,backgroundColor:y?.backgroundColor,position:"relative"},children:[e.jsxs("svg",{ref:A,width:F,height:I,role:"img","aria-label":L??"Line chart",onMouseMove:Q&&!Z.isPanning?ee.handleMouseMove:void 0,onMouseLeave:Q?ee.handleMouseLeave:void 0,onWheel:G?Z.handleWheel:void 0,onMouseDown:G?Z.handlePanStart:void 0,onMouseUp:G?Z.handlePanEnd:void 0,onClick:se,onDoubleClick:ae,onContextMenu:de,style:{userSelect:Z.isPanning?"none":void 0,cursor:Z.isPanning?"grabbing":G&&Z.scale>1?"grab":void 0},children:[e.jsx("defs",{children:e.jsx("clipPath",{id:X,children:e.jsx("rect",{width:B,height:O})})}),e.jsxs("g",{transform:`translate(${E.left}, ${E.top})`,children:[e.jsx(p,{xTicks:_,yTicks:J,xScale:K,yScale:V,plotWidth:B,plotHeight:O,xAxisConfig:l,yAxisConfig:c,style:y}),e.jsx(g,{xTicks:_,yTicks:J,xScale:K,yScale:V,plotWidth:B,plotHeight:O,showXGrid:he,showYGrid:fe,xGridColor:l?.gridLineColor,yGridColor:c?.gridLineColor}),e.jsxs("g",{clipPath:`url(#${X})`,children:[G?e.jsx("g",{onMouseMove:Z.handlePanMove,children:i.map((t,n)=>e.jsx(k,{series:t,xScale:K,yScale:V,color:t.color??xe(n),animation:b,onPointClick:S,curveType:P,highlightOpacity:oe(t.id)},t.id))}):i.map((t,n)=>e.jsx(k,{series:t,xScale:K,yScale:V,color:t.color??xe(n),animation:b,onPointClick:S,curveType:P,highlightOpacity:oe(t.id)},t.id)),D&&D.length>0&&e.jsx(j,{peaks:D,data:i,xScale:K,yScale:V,colorPalette:C})]}),Q&&e.jsx(v,{visible:ee.tooltipVisible,x:ee.tooltipX,y:ee.tooltipY,point:ee.activePoint,series:ee.activeSeries,plotHeight:O,plotWidth:B,config:f,seriesColor:ee.activeSeries?.color??xe(i.findIndex(e=>e.id===ee.activeSeries?.id))})]}),e.jsx(w,{config:m,svgWidth:F,svgHeight:I,margin:E,scale:Z.scale,onZoomIn:Z.zoomIn,onZoomOut:Z.zoomOut,onReset:Z.resetZoom}),e.jsx(z,{config:R,svgRef:A,svgWidth:F,svgHeight:I,margin:E})]}),Z.showZoomHint&&e.jsx("div",{style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",background:"rgba(0, 0, 0, 0.7)",color:"#fff",padding:"8px 16px",borderRadius:6,fontSize:13,fontFamily:"system-ui, -apple-system, sans-serif",pointerEvents:"none",whiteSpace:"nowrap",zIndex:10},children:"Hold Ctrl + scroll to zoom"}),T?.enabled&&e.jsx($,{visible:le.visible,x:le.clientX,y:le.clientY,nearestX:le.nearestX,data:i,config:T,getSeriesColor:xe,onClose:ue})]})};X.displayName="LineChart",exports.LineChart=X,exports.exportChart=A,exports.exportChartAsPdf=W,exports.exportChartAsPng=R,exports.exportChartAsSvg=T,exports.useChartDimensions=o,exports.useDataDomain=d,exports.useScales=u,exports.useTooltip=x,exports.useZoom=h;
1
+ "use strict";var e=require("react/jsx-runtime"),t=require("react");const n=["#4e79a7","#f28e2b","#e15759","#76b7b2","#59a14f","#edc948","#b07aa1","#ff9da7","#9c755f","#bab0ac"];function o(e,n,o){const[i,r]=t.useState({width:n??0,height:o??0}),s=void 0!==n&&void 0!==o;return t.useLayoutEffect(()=>{if(s)return void r({width:n,height:o});const t=e.current;if(!t)return;const i=()=>{const e=t.getBoundingClientRect();r({width:e.width,height:e.height})};i();const a=new ResizeObserver(()=>{i()});return a.observe(t),()=>a.disconnect()},[e,s,n,o]),i}function i(e,t,n){return Math.min(Math.max(e,t),n)}function r(e,t,n){return e+(t-e)*n}function s(e,t){const n=Math.floor(Math.log10(e)),o=e/Math.pow(10,n);let i;return i=t?o<1.5?1:o<3?2:o<7?5:10:o<=1?1:o<=2?2:o<=5?5:10,i*Math.pow(10,n)}function a(e,t,n){if(e===t){const n=0===e?1:.1*Math.abs(e);e-=n,t+=n}const o=s(t-e,!1),i=s(o/(n-1),!0);return{niceMin:Math.floor(e/i)*i,niceMax:Math.ceil(t/i)*i,tickStep:i}}function l(e,t,n,o){return i=>{if(t===e)return(n+o)/2;const s=function(e,t,n){return e===t?0:(n-e)/(t-e)}(e,t,i);return r(n,o,s)}}function c(e,t,n){const o=[];for(let i=e;i<=t+.5*n;i+=n)o.push(parseFloat(i.toPrecision(12)));return o}function d(e,n,o){return t.useMemo(()=>{let t=1/0,i=-1/0,r=1/0,s=-1/0;for(const n of e)for(const e of n.data)e.x<t&&(t=e.x),e.x>i&&(i=e.x),e.y<r&&(r=e.y),e.y>s&&(s=e.y);isFinite(t)||(t=0,i=1,r=0,s=1),void 0!==n?.min&&(t=n.min),void 0!==n?.max&&(i=n.max),void 0!==o?.min&&(r=o.min),void 0!==o?.max&&(s=o.max);const l=n?.tickCount??6,c=o?.tickCount??6,d=a(t,i,l),u=a(r,s,c);return{fullXDomain:[d.niceMin,d.niceMax],fullYDomain:[u.niceMin,u.niceMax]}},[e,n,o])}function u(e,n,o,i,r,s,d){return t.useMemo(()=>{let t=1/0,u=-1/0,h=1/0,f=-1/0;for(const n of e)for(const e of n.data)e.x<t&&(t=e.x),e.x>u&&(u=e.x),e.y<h&&(h=e.y),e.y>f&&(f=e.y);isFinite(t)||(t=0,u=1,h=0,f=1),void 0!==i?.min&&(t=i.min),void 0!==i?.max&&(u=i.max),void 0!==r?.min&&(h=r.min),void 0!==r?.max&&(f=r.max);const x=i?.tickCount??6,m=r?.tickCount??6;let p,y,g,b;if(s)p=s[0],y=s[1];else{const e=a(t,u,x);p=e.niceMin,y=e.niceMax}if(d)g=d[0],b=d[1];else{const e=a(h,f,m);g=e.niceMin,b=e.niceMax}const k=a(p,y,x),v=a(g,b,m),w=l(p,y,0,n),C=l(g,b,o,0);let M=k.tickStep,S=k.niceMin,j=k.niceMax;i?.integerTicks&&(M=Math.max(1,Math.ceil(M)),S=Math.ceil(p),j=Math.floor(y));let $=v.tickStep,L=v.niceMin,P=v.niceMax;r?.integerTicks&&($=Math.max(1,Math.ceil($)),L=Math.ceil(g),P=Math.floor(b));return{xScale:w,yScale:C,xTicks:c(S,j,M).filter(e=>e>=p&&e<=y).filter(e=>!i?.integerTicks||Number.isInteger(e)),yTicks:c(L,P,$).filter(e=>e>=g&&e<=b).filter(e=>!r?.integerTicks||Number.isInteger(e)),xDomain:[p,y],yDomain:[g,b]}},[e,n,o,i,r,s,d])}function h(e,n,o,s,a){const l=e?.enabled??!1,c=e?.maxScale??10,d=e?.step??.5,u=e?.enableWheel??!0,h=e?.enablePan??!0,f=e?.requireModifierKey??!0,x=e?.modifierKey??"shift",[m,p]=t.useState(n),[y,g]=t.useState(o),[b,k]=t.useState(!1),[v,w]=t.useState(!1),C=t.useRef({x:0,y:0,xDomain:n,yDomain:o}),M=t.useRef(null),S=t.useRef({x:n,y:o});n[0]===S.current.x[0]&&n[1]===S.current.x[1]&&o[0]===S.current.y[0]&&o[1]===S.current.y[1]||(S.current={x:n,y:o},p(n),g(o));const j=n[1]-n[0],$=m[1]-m[0],L=j>0&&$>0?j/$:1,P=t.useCallback((e,t)=>{const n=e[1]-e[0];if(n>=t[1]-t[0])return t;let o=e[0],i=e[1];return o<t[0]&&(o=t[0],i=o+n),i>t[1]&&(i=t[1],o=i-n),[o,i]},[]),D=t.useCallback(()=>{M.current&&clearTimeout(M.current),w(!0),M.current=setTimeout(()=>w(!1),2e3)},[]),T=t.useCallback((e,t,i)=>{if(!l)return;const s=t??.5,a=i??.5;p(t=>{const o=(t[1]-t[0])/e,i=j/c,a=Math.max(o,i),l=Math.min(a,j),d=r(t[0],t[1],s)-l*s;return P([d,d+l],n)}),g(t=>{const n=t[1]-t[0],i=o[1]-o[0],s=n/e,l=i/c,d=Math.max(s,l),u=Math.min(d,i),h=r(t[0],t[1],a)-u*a;return P([h,h+u],o)})},[l,n,o,j,c,P]),R=t.useCallback(()=>{T(1+d)},[d,T]),W=t.useCallback(()=>{T(1/(1+d))},[d,T]),A=t.useCallback(()=>{p(n),g(o)},[n,o]),z=t.useCallback((e,t)=>{if(!l)return;p(t=>{const o=(t[1]-t[0])/2,i=j/c,r=Math.max(o,i),s=Math.min(r,j),a=e-s/2;return P([a,a+s],n)}),g(e=>{const n=e[1]-e[0],i=o[1]-o[0],r=n/2,s=i/c,a=Math.max(r,s),l=Math.min(a,i),d=t-l/2;return P([d,d+l],o)})},[l,n,o,j,c,P]),N=t.useCallback(e=>{if(!l||!u)return;if(f){if(!("shift"===x?e.shiftKey:"ctrl"===x?e.ctrlKey||e.metaKey:"alt"===x&&e.altKey))return void D()}e.preventDefault();const t=e.currentTarget.getBoundingClientRect(),n=e.clientX-t.left,o=e.clientY-t.top,r=i(n/(t.width||1),0,1),s=i(o/(t.height||1),0,1),a=e.deltaY<0?1+d:1/(1+d);T(a,r,s)},[l,u,f,x,d,D,T]),X=t.useCallback(e=>{!l||!h||L<=1||0===e.button&&(k(!0),C.current={x:e.clientX,y:e.clientY,xDomain:m,yDomain:y})},[l,h,L,m,y]),E=t.useCallback(e=>{if(!b)return;const t=e.clientX-C.current.x,i=e.clientY-C.current.y,r=C.current.xDomain,l=C.current.yDomain,c=r[1]-r[0],d=l[1]-l[0],u=-t/s*c,h=i/a*d,f=[r[0]+u,r[1]+u],x=[l[0]+h,l[1]+h];p(P(f,n)),g(P(x,o))},[b,s,a,n,o,P]),Y=t.useCallback(()=>{k(!1)},[]);return{viewXDomain:m,viewYDomain:y,scale:L,isPanning:b,showZoomHint:v,zoomIn:R,zoomOut:W,resetZoom:A,zoomToPoint:z,handleWheel:N,handlePanStart:X,handlePanMove:E,handlePanEnd:Y}}function f(e,t,n){if(0===e.length)return null;let o=0,i=e.length-1;for(;o<i;){const r=Math.floor((o+i)/2);n(e[r].x)<t?o=r+1:i=r}let r=e[o],s=Math.abs(n(r.x)-t);if(o>0){const i=Math.abs(n(e[o-1].x)-t);i<s&&(s=i,r=e[o-1])}return r}function x(e,n,o,i,r,s,a,l){const[c,d]=t.useState(!1),[u,h]=t.useState(0),[x,m]=t.useState(0),[p,y]=t.useState(null),[g,b]=t.useState(null),[k,v]=t.useState(null);return{tooltipVisible:c,tooltipX:u,tooltipY:x,activePoint:p,activeSeries:g,activeSeriesId:k,handleMouseMove:t.useCallback(t=>{const l=e.current;if(!l)return;const c=l.getBoundingClientRect(),u=t.clientX-c.left-r,x=t.clientY-c.top-s;if(u<0||u>a)return d(!1),void v(null);let p=0,g=1/0;for(const e of n){const t=f(e.data,u,o);if(!t)continue;const n=Math.abs(o(t.x)-u);n<g&&(g=n,p=t.x)}let k=null,w=null,C=1/0;for(const e of n){let t=null,n=1/0;for(const o of e.data){const e=Math.abs(o.x-p);e<n&&(n=e,t=o)}if(!t)continue;const o=i(t.y),r=Math.abs(o-x);r<C&&(C=r,k=t,w=e)}k&&w&&(h(o(k.x)),m(i(k.y)),y(k),b(w),v(w.id),d(!0))},[e,n,o,i,r,s,a]),handleMouseLeave:t.useCallback(()=>{d(!1),y(null),b(null),v(null)},[])}}const m=e=>Math.abs(e)>=1e6?`${(e/1e6).toFixed(1)}M`:Math.abs(e)>=1e3?`${(e/1e3).toFixed(1)}K`:Number.isInteger(e)?e.toString():e.toFixed(1),p=t.memo(({xTicks:t,yTicks:n,xScale:o,yScale:i,plotWidth:r,plotHeight:s,xAxisConfig:a,yAxisConfig:l,style:c})=>{const d=c?.axisColor??"#333",u=c?.tickColor??"#666",h=c?.fontFamily??"sans-serif",f=c?.fontSize??11,x=a?.tickFormat??m,p=l?.tickFormat??m;return e.jsxs("g",{className:"chartifypdf-axes",children:[e.jsx("line",{x1:0,y1:s,x2:r,y2:s,stroke:d,strokeWidth:1}),t.map(t=>{const n=o(t);return e.jsxs("g",{children:[e.jsx("line",{x1:n,y1:s,x2:n,y2:s+6,stroke:d,strokeWidth:1}),e.jsx("text",{x:n,y:s+18,textAnchor:"middle",fill:u,fontFamily:h,fontSize:f,children:x(t)})]},`x-tick-${t}`)}),a?.label&&e.jsx("text",{x:r/2,y:s+38,textAnchor:"middle",fill:d,fontFamily:h,fontSize:f+1,fontWeight:"bold",children:a.label}),e.jsx("line",{x1:0,y1:0,x2:0,y2:s,stroke:d,strokeWidth:1}),n.map(t=>{const n=i(t);return e.jsxs("g",{children:[e.jsx("line",{x1:-6,y1:n,x2:0,y2:n,stroke:d,strokeWidth:1}),e.jsx("text",{x:-10,y:n,textAnchor:"end",dominantBaseline:"middle",fill:u,fontFamily:h,fontSize:f,children:p(t)})]},`y-tick-${t}`)}),l?.label&&e.jsx("text",{x:0,y:0,textAnchor:"middle",fill:d,fontFamily:h,fontSize:f+1,fontWeight:"bold",transform:`translate(-40, ${s/2}) rotate(-90)`,children:l.label})]})});p.displayName="Axes";const y=t.memo(({xTicks:t,yTicks:n,xScale:o,yScale:i,plotWidth:r,plotHeight:s,showXGrid:a,showYGrid:l,xGridColor:c="#e0e0e0",yGridColor:d="#e0e0e0"})=>e.jsxs("g",{className:"chartifypdf-grid",children:[l&&n.map(t=>{const n=i(t);return e.jsx("line",{x1:0,y1:n,x2:r,y2:n,stroke:d,strokeDasharray:"4 4",strokeOpacity:.5},`y-grid-${t}`)}),a&&t.map(t=>{const n=o(t);return e.jsx("line",{x1:n,y1:0,x2:n,y2:s,stroke:c,strokeDasharray:"4 4",strokeOpacity:.5},`x-grid-${t}`)})]}));function g(e){if(0===e.length)return"";const[t,...n]=e;return`M${t.x},${t.y}`+n.map(e=>`L${e.x},${e.y}`).join("")}function b(e,t){switch(t){case"monotone":return function(e){const t=e.length;if(t<2)return g(e);if(2===t)return g(e);const n=[],o=[],i=[];for(let r=0;r<t-1;r++)n.push(e[r+1].x-e[r].x),o.push(e[r+1].y-e[r].y),i.push(0===n[r]?0:o[r]/n[r]);const r=new Array(t);r[0]=i[0],r[t-1]=i[t-2];for(let e=1;e<t-1;e++)i[e-1]*i[e]<=0?r[e]=0:r[e]=2/(1/i[e-1]+1/i[e]);for(let e=0;e<t-1;e++)if(0===i[e])r[e]=0,r[e+1]=0;else{const t=r[e]/i[e],n=r[e+1]/i[e],o=t*t+n*n;if(o>9){const s=3/Math.sqrt(o);r[e]=s*t*i[e],r[e+1]=s*n*i[e]}}let s=`M${e[0].x},${e[0].y}`;for(let o=0;o<t-1;o++){const t=n[o]/3;s+=`C${e[o].x+t},${e[o].y+r[o]*t},${e[o+1].x-t},${e[o+1].y-r[o+1]*t},${e[o+1].x},${e[o+1].y}`}return s}(e);case"natural":return function(e){const t=e.length;if(t<2)return g(e);if(2===t)return g(e);function n(e){const t=e.length-1,n=new Array(t),o=new Array(t),i=new Array(t);n[0]=0,o[0]=2,i[0]=e[0]+2*e[1];for(let r=1;r<t-1;r++)n[r]=1,o[r]=4,i[r]=4*e[r]+2*e[r+1];n[t-1]=2,o[t-1]=7,i[t-1]=8*e[t-1]+e[t];for(let e=1;e<t;e++){const t=n[e]/o[e-1];o[e]-=t,i[e]-=t*i[e-1]}const r=new Array(t);r[t-1]=i[t-1]/o[t-1];for(let e=t-2;e>=0;e--)r[e]=(i[e]-r[e+1])/o[e];const s=new Array(t);for(let n=0;n<t-1;n++)s[n]=2*e[n+1]-r[n+1];s[t-1]=(e[t]+r[t-1])/2;const a=[];for(let e=0;e<t;e++)a.push({cp1:r[e],cp2:s[e]});return a}const o=e.map(e=>e.x),i=e.map(e=>e.y),r=n(o),s=n(i);let a=`M${e[0].x},${e[0].y}`;for(let n=0;n<t-1;n++)a+=`C${r[n].cp1},${s[n].cp1},${r[n].cp2},${s[n].cp2},${e[n+1].x},${e[n+1].y}`;return a}(e);default:return g(e)}}y.displayName="GridLines";const k=t.memo(({series:n,xScale:o,yScale:i,color:r,animation:s,onPointClick:a,curveType:l,highlightOpacity:c})=>{const d=t.useRef(null),[u,h]=t.useState(0),[f,x]=t.useState(!s?.enabled),m=n.strokeWidth??2,p=n.showDots??!1,y=n.dotRadius??3.5,k=n.curveType??l??"linear",v=c??1,w=n.data.map(e=>({x:o(e.x),y:i(e.y)})),C="linear"===k?g(w):b(w,k);t.useEffect(()=>{if(s?.enabled&&d.current){const e=d.current.getTotalLength();h(e),x(!1);const t=setTimeout(()=>{x(!0)},s.duration??800);return()=>clearTimeout(t)}},[C,s?.enabled,s?.duration]);const M=s?.enabled&&u>0?{strokeDasharray:u,strokeDashoffset:f?0:u,transition:`stroke-dashoffset ${s.duration??800}ms ${s.easing??"ease-in-out"}`}:{};return e.jsxs("g",{className:"chartifypdf-line-path",style:{opacity:v,transition:"opacity 150ms ease"},children:[e.jsx("path",{ref:d,d:C,fill:"none",stroke:r,strokeWidth:m,strokeDasharray:n.strokeDasharray,strokeLinecap:"round",strokeLinejoin:"round",style:M}),p&&n.data.map((t,s)=>e.jsx("circle",{cx:o(t.x),cy:i(t.y),r:y,fill:r,stroke:"#fff",strokeWidth:1.5,style:{cursor:a?"pointer":"default"},onClick:a?()=>a(t,n):void 0},`dot-${n.id}-${s}`))]})});k.displayName="LinePath";const v=t.memo(({visible:t,x:n,y:o,point:i,series:r,plotHeight:s,plotWidth:a,config:l,seriesColor:c})=>{if(!t||!i||!r)return null;const d=l?.backgroundColor??"rgba(0, 0, 0, 0.8)",u=l?.textColor??"#fff";let h;if(l?.renderCustom)h=l.renderCustom(i,r);else{h=l?.formatter?l.formatter(i,r):`${r.name}: (${i.x}, ${i.y})`}let f=n+12,x=o-40-8;return f+140>a&&(f=n-140-12),x<0&&(x=o+12),e.jsxs("g",{className:"chartifypdf-tooltip",pointerEvents:"none",children:[e.jsx("line",{x1:n,y1:0,x2:n,y2:s,stroke:"#999",strokeWidth:1,strokeDasharray:"4 4",opacity:.6}),e.jsx("circle",{cx:n,cy:o,r:5,fill:c,stroke:"#fff",strokeWidth:2}),e.jsx("foreignObject",{x:f,y:x,width:140,height:60,overflow:"visible",children:e.jsx("div",{style:{backgroundColor:d,color:u,padding:"6px 10px",borderRadius:"4px",fontSize:"12px",fontFamily:"sans-serif",whiteSpace:"nowrap",lineHeight:1.4,boxShadow:"0 2px 6px rgba(0,0,0,0.2)"},children:h})})]})});v.displayName="Tooltip";const w=t.memo(({config:t,svgWidth:n,svgHeight:o,margin:i,scale:r,onZoomIn:s,onZoomOut:a,onReset:l})=>{if(!t?.enabled||!1===t.showControls)return null;const c=t.controlsPosition??"top-right",d=24;let u,h;switch(c){case"top-left":u=i.left+8,h=i.top+8;break;case"bottom-left":u=i.left+8,h=o-i.bottom-24-8;break;case"bottom-right":u=n-i.right-80-8,h=o-i.bottom-24-8;break;default:u=n-i.right-80-8,h=i.top+8}const f=r>1?[{label:"+",onClick:s},{label:"−",onClick:a},{label:"↺",onClick:l}]:[{label:"+",onClick:s},{label:"−",onClick:a}];return e.jsx("g",{className:"chartifypdf-zoom-controls",transform:`translate(${u}, ${h})`,children:f.map((t,n)=>e.jsxs("g",{transform:`translate(${28*n}, 0)`,onClick:t.onClick,style:{cursor:"pointer"},children:[e.jsx("rect",{width:d,height:d,rx:4,fill:"rgba(255,255,255,0.9)",stroke:"#ccc",strokeWidth:1}),e.jsx("text",{x:12,y:12,textAnchor:"middle",dominantBaseline:"central",fontSize:14,fontFamily:"sans-serif",fill:"#333",fontWeight:"bold",children:t.label})]},t.label))})});function C({x:t,y:n,color:o}){return e.jsx("polygon",{points:`${t},${n} ${t-5},${n-10} ${t+5},${n-10}`,fill:o})}function M({x:t,y:n,color:o}){return e.jsx("polygon",{points:`${t},${n-6} ${t+5},${n} ${t},${n+6} ${t-5},${n}`,fill:o})}function S({x:t,y:n,color:o}){const i=[];for(let e=0;e<5;e++){const o=(72*e-90)*(Math.PI/180),r=(72*e+36-90)*(Math.PI/180);i.push(`${t+6*Math.cos(o)},${n+6*Math.sin(o)}`),i.push(`${t+3*Math.cos(r)},${n+3*Math.sin(r)}`)}return e.jsx("polygon",{points:i.join(" "),fill:o})}w.displayName="ZoomControls";const j=t.memo(({peaks:t,data:n,xScale:o,yScale:i})=>e.jsx("g",{className:"chartifypdf-peak-markers",children:t.map((t,r)=>{const s=function(e,t){let n=-1/0,o=-1;for(let i=0;i<e.length;i++){const r=e[i];let s=r.data[0],a=1/0;for(const e of r.data){const n=Math.abs(e.x-t);n<a&&(a=n,s=e)}s&&s.y>n&&(n=s.y,o=i)}return-1===o?null:{y:n,seriesIndex:o}}(n,t.x);if(!s)return null;const a=o(t.x),l=i(s.y),c=t.color??"#ef4444",d=t.icon??"arrow",u=t.label,h=l-14;return e.jsxs("g",{children:[e.jsx("line",{x1:a,y1:l,x2:a,y2:h+6,stroke:c,strokeWidth:1,strokeDasharray:"3 2",opacity:.6}),"arrow"===d&&e.jsx(C,{x:a,y:h,color:c}),"diamond"===d&&e.jsx(M,{x:a,y:h,color:c}),"star"===d&&e.jsx(S,{x:a,y:h,color:c}),u&&e.jsx("text",{x:a,y:h-8,textAnchor:"middle",fill:c,fontSize:11,fontWeight:600,children:u})]},`peak-${r}`)})}));j.displayName="PeakMarkers";const $=({visible:n,x:o,y:i,nearestX:r,data:s,config:a,getSeriesColor:l,onClose:c})=>{const d=t.useRef(null);if(t.useEffect(()=>{if(!n)return;const e=e=>{d.current&&!d.current.contains(e.target)&&c()},t=e=>{"Escape"===e.key&&c()},o=setTimeout(()=>{document.addEventListener("mousedown",e),document.addEventListener("keydown",t)},0);return()=>{clearTimeout(o),document.removeEventListener("mousedown",e),document.removeEventListener("keydown",t)}},[n,c]),!n)return null;const u=a?.backgroundColor??"#ffffff",h=a?.textColor??"#1f2937",f=a?.borderColor??"#e5e7eb",x=s.map((e,t)=>{const n=function(e,t){if(0===e.data.length)return null;let n=e.data[0],o=Math.abs(n.x-t);for(const i of e.data){const e=Math.abs(i.x-t);e<o&&(o=e,n=i)}return n.y}(e,r);return{name:e.name,color:e.color??l(t),x:r,y:n}});return e.jsxs("div",{ref:d,style:{position:"fixed",left:o,top:i,zIndex:9999,backgroundColor:u,color:h,border:`1px solid ${f}`,borderRadius:6,boxShadow:"0 4px 12px rgba(0,0,0,0.15)",padding:"8px 0",minWidth:200,fontSize:12,fontFamily:"system-ui, -apple-system, sans-serif"},children:[e.jsxs("div",{style:{padding:"4px 12px 8px",fontWeight:600,fontSize:11,color:h,opacity:.6,borderBottom:`1px solid ${f}`,marginBottom:4},children:["Data at X = ","number"==typeof r?r.toLocaleString():r]}),e.jsxs("table",{style:{width:"100%",borderCollapse:"collapse"},children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{style:{textAlign:"left",padding:"4px 12px",fontWeight:600,opacity:.7},children:"Series"}),e.jsx("th",{style:{textAlign:"right",padding:"4px 12px",fontWeight:600,opacity:.7},children:"Y"})]})}),e.jsx("tbody",{children:x.map((t,n)=>e.jsxs("tr",{style:{borderTop:n>0?`1px solid ${f}`:void 0},children:[e.jsxs("td",{style:{padding:"4px 12px",display:"flex",alignItems:"center",gap:6},children:[e.jsx("span",{style:{display:"inline-block",width:8,height:8,borderRadius:"50%",backgroundColor:t.color,flexShrink:0}}),t.name]}),e.jsx("td",{style:{padding:"4px 12px",textAlign:"right",fontVariantNumeric:"tabular-nums"},children:null!==t.y?t.y.toLocaleString():"—"})]},n))})]})]})};function L(e){const t=e.cloneNode(!0),n=e.getBoundingClientRect();t.setAttribute("width",String(n.width)),t.setAttribute("height",String(n.height)),t.setAttribute("xmlns","http://www.w3.org/2000/svg"),t.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink");const o=e.querySelectorAll("*"),i=t.querySelectorAll("*");for(let e=0;e<o.length;e++){const t=o[e],n=i[e];if(!n.style)continue;const r=window.getComputedStyle(t),s=["fill","stroke","stroke-width","stroke-dasharray","opacity","font-family","font-size","font-weight","text-anchor","dominant-baseline","visibility","display"];for(const e of s){const t=r.getPropertyValue(e);t&&n.style.setProperty(e,t)}}return t}function P(e,t){const n=URL.createObjectURL(e),o=document.createElement("a");o.href=n,o.download=t,document.body.appendChild(o),o.click(),document.body.removeChild(o),URL.revokeObjectURL(n)}async function D(e,t=2){const n=e.getBoundingClientRect(),o=n.width*t,i=n.height*t,r=document.createElement("canvas");r.width=o,r.height=i;const s=r.getContext("2d");if(!s)throw new Error("Cannot get canvas 2d context");s.scale(t,t);const a=function(e){const t=L(e),n=(new XMLSerializer).serializeToString(t),o=new Blob([n],{type:"image/svg+xml;charset=utf-8"});return URL.createObjectURL(o)}(e);return new Promise((e,t)=>{const o=new Image;o.onload=()=>{s.fillStyle="#ffffff",s.fillRect(0,0,n.width,n.height),s.drawImage(o,0,0,n.width,n.height),URL.revokeObjectURL(a),e(r)},o.onerror=()=>{URL.revokeObjectURL(a),t(new Error("Failed to load SVG as image"))},o.src=a})}async function T(e,t="chart"){const n=L(e),o=(new XMLSerializer).serializeToString(n);P(new Blob([o],{type:"image/svg+xml;charset=utf-8"}),`${t}.svg`)}async function R(e,t="chart"){const n=await D(e);P(await new Promise((e,t)=>{n.toBlob(n=>n?e(n):t(new Error("Canvas toBlob failed")),"image/png")}),`${t}.png`)}async function W(e,t="chart"){const n=(await D(e)).toDataURL("image/png"),o=e.getBoundingClientRect(),i=window.open("","_blank");if(!i)throw new Error("Popup blocked. Please allow popups to export PDF.");i.document.write(`\n <!DOCTYPE html>\n <html>\n <head>\n <title>${t}</title>\n <style>\n @page { size: landscape; margin: 10mm; }\n body { margin: 0; display: flex; justify-content: center; align-items: center; min-height: 100vh; }\n img { max-width: 100%; height: auto; }\n </style>\n </head>\n <body>\n <img src="${n}" width="${o.width}" height="${o.height}" />\n <script>\n window.onload = function() {\n setTimeout(function() { window.print(); window.close(); }, 300);\n };\n <\/script>\n </body>\n </html>\n `),i.document.close()}async function A(e,t="pdf",n="chart"){switch(t){case"svg":return T(e,n);case"png":return R(e,n);case"pdf":return W(e,n)}}$.displayName="ContextMenu";const z=t.memo(({config:n,svgRef:o,svgWidth:i,svgHeight:r,margin:s})=>{if(!n?.enabled)return null;let a,l;switch(n.buttonPosition??"top-right"){case"top-left":a=s.left+8,l=s.top+8+24+8;break;case"bottom-left":a=s.left+8,l=r-s.bottom-24-8;break;case"bottom-right":a=i-s.right-28-8,l=r-s.bottom-24-8;break;default:a=i-s.right-28-8,l=s.top+8+24+8}const c=t.useCallback(()=>{const e=o.current;if(!e)return;A(e,n?.format??"pdf",n?.fileName??"chart")},[o,n?.format,n?.fileName]);return e.jsxs("g",{className:"chartifypdf-export-button",transform:`translate(${a}, ${l})`,onClick:c,style:{cursor:"pointer"},children:[e.jsx("rect",{width:28,height:24,rx:4,fill:"rgba(255,255,255,0.9)",stroke:"#ccc",strokeWidth:1}),e.jsx("g",{transform:"translate(7, 4)",children:e.jsx("path",{d:"M7,2 L7,10 L4,7 M7,10 L10,7 M3,13 L11,13",fill:"none",stroke:"#333",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round"})})]})});z.displayName="ExportButton";const N={top:20,right:20,bottom:50,left:60},X=({data:i,width:r,height:s,margin:a,xAxis:l,yAxis:c,tooltip:f,zoom:m,style:g,animation:b,colorPalette:C,className:M,onPointClick:S,ariaLabel:L,curveType:P,peaks:D,contextMenu:T,export:R})=>{const W=t.useRef(null),A=t.useRef(null),X=t.useId(),E={...N,...a},Y=o(W,r,s??400),{width:F,height:I}=Y,B=Math.max(0,F-E.left-E.right),O=Math.max(0,I-E.top-E.bottom),{fullXDomain:H,fullYDomain:K}=d(i,l,c),U=h(m,H,K,B,O),Z=m?.enabled??!1,G=m?.enableClickZoom??!1,{xScale:q,yScale:V,xTicks:_,yTicks:J}=u(i,B,O,l,c,Z?U.viewXDomain:void 0,Z?U.viewYDomain:void 0),Q=!1!==f?.enabled,ee=x(A,i,q,V,E.left,E.top,B),te=ee.activeSeriesId,ne=ee.tooltipVisible&&null!==te,oe=e=>ne?e===te?1:.2:1,ie=m?.requireModifierKey??!0,re=m?.modifierKey??"shift",se=m?.enableWheel??!0;t.useEffect(()=>{const e=A.current;if(!e||!Z||!se)return;const t=e=>{if(ie){("shift"===re?e.shiftKey:"ctrl"===re?e.ctrlKey||e.metaKey:"alt"===re&&e.altKey)&&e.preventDefault()}else e.preventDefault()};return e.addEventListener("wheel",t,{passive:!1}),()=>e.removeEventListener("wheel",t)},[Z,se,ie,re]);const ae=t.useCallback(e=>{if(!Z||!G)return;if(U.isPanning)return;const t=A.current;if(!t)return;const n=t.getBoundingClientRect(),o=e.clientX-n.left-E.left,r=e.clientY-n.top-E.top;if(o<0||o>B||r<0||r>O)return;let s=0,a=0,l=1/0;for(const e of i)for(const t of e.data){const e=q(t.x),n=V(t.y),i=Math.hypot(e-o,n-r);i<l&&(l=i,s=t.x,a=t.y)}U.zoomToPoint(s,a)},[Z,G,U,i,q,V,E.left,E.top,B,O]),le=t.useCallback(()=>{Z&&G&&U.resetZoom()},[Z,G,U]),[ce,de]=t.useState({visible:!1,clientX:0,clientY:0,nearestX:0}),ue=t.useCallback(e=>{if(!T?.enabled)return;e.preventDefault();const t=A.current;if(!t)return;const n=t.getBoundingClientRect(),o=e.clientX-n.left-E.left;if(o<0||o>B)return;let r=0,s=1/0;for(const e of i)for(const t of e.data){const e=q(t.x),n=Math.abs(e-o);n<s&&(s=n,r=t.x)}de({visible:!0,clientX:e.clientX,clientY:e.clientY,nearestX:r})},[T?.enabled,i,q,E.left,B]),he=t.useCallback(()=>{de(e=>({...e,visible:!1}))},[]),fe=l?.gridLines??!1,xe=c?.gridLines??!0,me=e=>function(e,t){const o=t??n;return o[e%o.length]}(e,C);return 0===F||0===I?e.jsx("div",{ref:W,className:M,style:{width:r??"100%",height:s??400,backgroundColor:g?.backgroundColor}}):e.jsxs("div",{ref:W,className:M,style:{width:r??"100%",height:s??400,backgroundColor:g?.backgroundColor,position:"relative"},children:[e.jsxs("svg",{ref:A,width:F,height:I,role:"img","aria-label":L??"Line chart",onMouseMove:Q&&!U.isPanning?ee.handleMouseMove:void 0,onMouseLeave:Q?ee.handleMouseLeave:void 0,onWheel:Z?U.handleWheel:void 0,onMouseDown:Z?U.handlePanStart:void 0,onMouseUp:Z?U.handlePanEnd:void 0,onClick:ae,onDoubleClick:le,onContextMenu:ue,style:{userSelect:U.isPanning?"none":void 0,cursor:U.isPanning?"grabbing":Z&&U.scale>1?"grab":void 0},children:[e.jsx("defs",{children:e.jsx("clipPath",{id:X,children:e.jsx("rect",{width:B,height:O})})}),e.jsxs("g",{transform:`translate(${E.left}, ${E.top})`,children:[e.jsx(p,{xTicks:_,yTicks:J,xScale:q,yScale:V,plotWidth:B,plotHeight:O,xAxisConfig:l,yAxisConfig:c,style:g}),e.jsx(y,{xTicks:_,yTicks:J,xScale:q,yScale:V,plotWidth:B,plotHeight:O,showXGrid:fe,showYGrid:xe,xGridColor:l?.gridLineColor,yGridColor:c?.gridLineColor}),e.jsxs("g",{clipPath:`url(#${X})`,children:[Z?e.jsx("g",{onMouseMove:U.handlePanMove,children:i.map((t,n)=>e.jsx(k,{series:t,xScale:q,yScale:V,color:t.color??me(n),animation:b,onPointClick:S,curveType:P,highlightOpacity:oe(t.id)},t.id))}):i.map((t,n)=>e.jsx(k,{series:t,xScale:q,yScale:V,color:t.color??me(n),animation:b,onPointClick:S,curveType:P,highlightOpacity:oe(t.id)},t.id)),D&&D.length>0&&e.jsx(j,{peaks:D,data:i,xScale:q,yScale:V,colorPalette:C})]}),Q&&e.jsx(v,{visible:ee.tooltipVisible,x:ee.tooltipX,y:ee.tooltipY,point:ee.activePoint,series:ee.activeSeries,plotHeight:O,plotWidth:B,config:f,seriesColor:ee.activeSeries?.color??me(i.findIndex(e=>e.id===ee.activeSeries?.id))})]}),e.jsx(w,{config:m,svgWidth:F,svgHeight:I,margin:E,scale:U.scale,onZoomIn:U.zoomIn,onZoomOut:U.zoomOut,onReset:U.resetZoom}),e.jsx(z,{config:R,svgRef:A,svgWidth:F,svgHeight:I,margin:E})]}),U.showZoomHint&&e.jsx("div",{style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",background:"rgba(0, 0, 0, 0.7)",color:"#fff",padding:"8px 16px",borderRadius:6,fontSize:13,fontFamily:"system-ui, -apple-system, sans-serif",pointerEvents:"none",whiteSpace:"nowrap",zIndex:10},children:`Hold ${"shift"===re?"Shift":"ctrl"===re?"Ctrl":"Alt"} + scroll to zoom`}),T?.enabled&&e.jsx($,{visible:ce.visible,x:ce.clientX,y:ce.clientY,nearestX:ce.nearestX,data:i,config:T,getSeriesColor:me,onClose:he})]})};X.displayName="LineChart",exports.LineChart=X,exports.exportChart=A,exports.exportChartAsPdf=W,exports.exportChartAsPng=R,exports.exportChartAsSvg=T,exports.useChartDimensions=o,exports.useDataDomain=d,exports.useScales=u,exports.useTooltip=x,exports.useZoom=h;
2
2
  //# sourceMappingURL=index.js.map