chartifypdf 0.3.0 → 0.4.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.
Files changed (2) hide show
  1. package/README.md +192 -10
  2. package/package.json +1 -1
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 Ctrl+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,35 @@ 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
+ | `requireCtrlKey` | `boolean` | `true` | Require Ctrl/Cmd key for wheel zoom (prevents accidental page scroll) |
131
+ | `enableClickZoom` | `boolean` | `false` | Click to zoom into a data point, double-click to reset |
132
+
133
+ ### `PeakConfig`
134
+
135
+ | Field | Type | Default | Description |
136
+ |-------|------|---------|-------------|
137
+ | `x` | `number` | *required* | X position of the peak |
138
+ | `label` | `string` | — | Label text above the marker |
139
+ | `color` | `string` | `"#ef4444"` | Marker color |
140
+ | `icon` | `string` | `"arrow"` | `"arrow"` \| `"diamond"` \| `"star"` |
141
+
142
+ ### `ContextMenuConfig`
143
+
144
+ | Field | Type | Default | Description |
145
+ |-------|------|---------|-------------|
146
+ | `enabled` | `boolean` | `false` | Enable right-click context menu |
147
+ | `backgroundColor` | `string` | `"#ffffff"` | Menu background color |
148
+ | `textColor` | `string` | `"#1f2937"` | Menu text color |
149
+ | `borderColor` | `string` | `"#e5e7eb"` | Menu border color |
150
+
151
+ ### `ExportConfig`
152
+
153
+ | Field | Type | Default | Description |
154
+ |-------|------|---------|-------------|
155
+ | `enabled` | `boolean` | `false` | Show export button |
156
+ | `buttonPosition` | `string` | `"top-right"` | `"top-left"` \| `"top-right"` \| `"bottom-left"` \| `"bottom-right"` |
157
+ | `fileName` | `string` | `"chart"` | Exported file name (without extension) |
158
+ | `format` | `string` | `"pdf"` | `"pdf"` \| `"png"` \| `"svg"` |
118
159
 
119
160
  ### `ChartStyle`
120
161
 
@@ -144,6 +185,31 @@ function App() {
144
185
 
145
186
  The chart fills its parent container's width and updates on resize.
146
187
 
188
+ ### Smooth Curved Lines
189
+
190
+ ```tsx
191
+ <LineChart
192
+ data={data}
193
+ curveType="monotone"
194
+ width={800}
195
+ height={400}
196
+ />
197
+ ```
198
+
199
+ Available curve types:
200
+ - `"linear"` — straight lines (default)
201
+ - `"monotone"` — Fritsch-Carlson monotone cubic, no overshoot (best for data)
202
+ - `"natural"` — natural cubic spline, smoother but may overshoot
203
+
204
+ Per-series override:
205
+
206
+ ```tsx
207
+ const data = [
208
+ { id: "a", name: "Smooth", data: [...], curveType: "monotone" },
209
+ { id: "b", name: "Linear", data: [...], curveType: "linear" },
210
+ ];
211
+ ```
212
+
147
213
  ### Multi-series with Custom Colors
148
214
 
149
215
  ```tsx
@@ -167,19 +233,91 @@ const data = [
167
233
  <LineChart data={data} width={800} height={400} />
168
234
  ```
169
235
 
170
- ### With Zoom and Custom Axes
236
+ Hover over any line to highlight it — the hovered series stays at full opacity while others dim to 20%.
237
+
238
+ ### Semantic Zoom with Integer Timeline
171
239
 
172
240
  ```tsx
173
241
  <LineChart
174
242
  data={data}
175
243
  width={800}
176
244
  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" }}
245
+ xAxis={{
246
+ label: "Day",
247
+ integerTicks: true,
248
+ tickFormat: (v) => `Day ${v}`,
249
+ }}
250
+ zoom={{
251
+ enabled: true,
252
+ maxScale: 5,
253
+ requireCtrlKey: true,
254
+ enableClickZoom: true,
255
+ }}
180
256
  />
181
257
  ```
182
258
 
259
+ - **Ctrl + scroll** to zoom — page scrolls normally without Ctrl
260
+ - **Click** a data point to zoom 2x centered at that point
261
+ - **Double-click** to reset zoom
262
+ - X-axis labels automatically update granularity when zoomed
263
+ - `integerTicks: true` prevents decimal values on date timelines
264
+
265
+ ### Peak Markers
266
+
267
+ ```tsx
268
+ <LineChart
269
+ data={data}
270
+ peaks={[
271
+ { x: 3, label: "Peak", icon: "star", color: "#ef4444" },
272
+ { x: 7, label: "ATH", icon: "arrow" },
273
+ ]}
274
+ />
275
+ ```
276
+
277
+ ### Right-Click Context Menu
278
+
279
+ ```tsx
280
+ <LineChart
281
+ data={data}
282
+ contextMenu={{
283
+ enabled: true,
284
+ backgroundColor: "#1a1a2e",
285
+ textColor: "#eee",
286
+ borderColor: "#333",
287
+ }}
288
+ />
289
+ ```
290
+
291
+ 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.
292
+
293
+ ### Export to PDF/PNG/SVG
294
+
295
+ ```tsx
296
+ <LineChart
297
+ data={data}
298
+ export={{
299
+ enabled: true,
300
+ format: "png",
301
+ fileName: "my-chart",
302
+ buttonPosition: "top-right",
303
+ }}
304
+ />
305
+ ```
306
+
307
+ A download button appears in the chart. Click to export.
308
+
309
+ For programmatic export:
310
+
311
+ ```tsx
312
+ import { exportChart, exportChartAsPdf, exportChartAsPng, exportChartAsSvg } from "chartifypdf";
313
+
314
+ // Using a ref to the SVG element
315
+ const svgElement = document.querySelector("svg");
316
+ await exportChart(svgElement, "pdf", "my-chart");
317
+ await exportChartAsPng(svgElement, "my-chart");
318
+ await exportChartAsSvg(svgElement, "my-chart");
319
+ ```
320
+
183
321
  ### Custom Tooltip
184
322
 
185
323
  ```tsx
@@ -231,20 +369,63 @@ const data = [
231
369
 
232
370
  Note: Set `showDots: true` on the series to make points clickable.
233
371
 
372
+ ### Full-featured Example
373
+
374
+ ```tsx
375
+ <LineChart
376
+ data={data}
377
+ width={900}
378
+ height={500}
379
+ curveType="monotone"
380
+ xAxis={{ label: "Date", integerTicks: true, gridLines: true }}
381
+ yAxis={{ label: "Value ($)", tickFormat: (v) => `$${v}` }}
382
+ zoom={{
383
+ enabled: true,
384
+ maxScale: 8,
385
+ requireCtrlKey: true,
386
+ enableClickZoom: true,
387
+ }}
388
+ peaks={[{ x: 15, label: "Peak", icon: "star" }]}
389
+ contextMenu={{ enabled: true }}
390
+ export={{ enabled: true, format: "png", fileName: "report" }}
391
+ animation={{ enabled: true }}
392
+ />
393
+ ```
394
+
234
395
  ## Exported Hooks
235
396
 
236
397
  For advanced usage, you can import the hooks directly:
237
398
 
238
399
  ```tsx
239
- import { useChartDimensions, useScales, useZoom, useTooltip } from "chartifypdf";
400
+ import {
401
+ useChartDimensions,
402
+ useDataDomain,
403
+ useScales,
404
+ useZoom,
405
+ useTooltip,
406
+ } from "chartifypdf";
240
407
  ```
241
408
 
242
409
  | Hook | Purpose |
243
410
  |------|---------|
244
411
  | `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 |
412
+ | `useDataDomain` | Extract full X/Y domain from data series |
413
+ | `useScales` | Compute linear scales, ticks, and domains (supports view domain override) |
414
+ | `useZoom` | Domain-based semantic zoom/pan state and event handlers |
415
+ | `useTooltip` | Track mouse position and find nearest data point with Y-proximity detection |
416
+
417
+ ## Exported Utilities
418
+
419
+ ```tsx
420
+ import { exportChart, exportChartAsPdf, exportChartAsPng, exportChartAsSvg } from "chartifypdf";
421
+ ```
422
+
423
+ | Utility | Description |
424
+ |---------|-------------|
425
+ | `exportChart(svg, format, fileName)` | Export SVG element as PDF, PNG, or SVG |
426
+ | `exportChartAsPdf(svg, fileName)` | Export as PDF (opens print dialog) |
427
+ | `exportChartAsPng(svg, fileName)` | Export as PNG (2x resolution) |
428
+ | `exportChartAsSvg(svg, fileName)` | Export as SVG file |
248
429
 
249
430
  ## Browser Support
250
431
 
@@ -252,6 +433,7 @@ Works in all modern browsers that support:
252
433
  - SVG
253
434
  - ResizeObserver
254
435
  - CSS transitions (for animation)
436
+ - Canvas API (for PNG/PDF export)
255
437
 
256
438
  ## License
257
439
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chartifypdf",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "A zero-dependency React line chart component using pure SVG. Supports zoom, tooltip, responsive sizing, and customizable styling.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",