@entropix/data 1.0.0 → 1.0.1

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 (49) hide show
  1. package/dist/area-chart.cjs +14 -0
  2. package/dist/area-chart.css +144 -0
  3. package/dist/area-chart.d.cts +19 -0
  4. package/dist/area-chart.d.ts +19 -0
  5. package/dist/area-chart.js +5 -0
  6. package/dist/bar-chart.cjs +14 -0
  7. package/dist/bar-chart.css +144 -0
  8. package/dist/bar-chart.d.cts +18 -0
  9. package/dist/bar-chart.d.ts +18 -0
  10. package/dist/bar-chart.js +5 -0
  11. package/dist/chunk-42HKJHUY.js +96 -0
  12. package/dist/chunk-4WXLJDQU.js +74 -0
  13. package/dist/chunk-6YAOO76S.cjs +142 -0
  14. package/dist/chunk-CMAQ7DZD.js +135 -0
  15. package/dist/chunk-FQACLZYR.js +137 -0
  16. package/dist/chunk-GCZSXJAA.cjs +77 -0
  17. package/dist/chunk-K6ZRQYSZ.cjs +131 -0
  18. package/dist/chunk-QBI5NOHT.cjs +126 -0
  19. package/dist/chunk-SDCNTA7E.cjs +275 -0
  20. package/dist/chunk-VCSKHJLZ.js +124 -0
  21. package/dist/chunk-VGT2QF7D.cjs +98 -0
  22. package/dist/chunk-WOVSQALY.cjs +137 -0
  23. package/dist/chunk-X7GZD7KZ.js +129 -0
  24. package/dist/chunk-YINCJQN6.js +271 -0
  25. package/dist/data-table.cjs +20 -0
  26. package/dist/data-table.css +227 -0
  27. package/dist/data-table.d.cts +20 -0
  28. package/dist/data-table.d.ts +20 -0
  29. package/dist/data-table.js +3 -0
  30. package/dist/index.cjs +35 -913
  31. package/dist/index.d.cts +7 -75
  32. package/dist/index.d.ts +7 -75
  33. package/dist/index.js +7 -910
  34. package/dist/line-chart.cjs +14 -0
  35. package/dist/line-chart.css +144 -0
  36. package/dist/line-chart.d.cts +19 -0
  37. package/dist/line-chart.d.ts +19 -0
  38. package/dist/line-chart.js +5 -0
  39. package/dist/pie-chart.cjs +13 -0
  40. package/dist/pie-chart.css +144 -0
  41. package/dist/pie-chart.d.cts +15 -0
  42. package/dist/pie-chart.d.ts +15 -0
  43. package/dist/pie-chart.js +4 -0
  44. package/dist/styles/chart.css +1 -193
  45. package/dist/styles/data-table.css +1 -304
  46. package/package.json +54 -3
  47. package/dist/index.cjs.map +0 -1
  48. package/dist/index.css.map +0 -1
  49. package/dist/index.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,912 +1,9 @@
1
- import { createContext, useContext, useMemo, useState, useRef, useCallback, useEffect } from 'react';
2
- import { useTable, normalizeChartData, getDataExtent, niceBounds, createLinearScale, createBandScale, computeBarGeometry, computeLinePoints, describeLinePath, describeAreaPath, getSeriesColor, computeArcGeometry } from '@entropix/core';
3
- import { jsx, jsxs } from 'react/jsx-runtime';
4
-
5
- // src/components/data-table/data-table.tsx
6
- var DataTableContext = createContext(
7
- null
8
- );
9
- function useDataTableContext() {
10
- const ctx = useContext(DataTableContext);
11
- if (!ctx) {
12
- throw new Error(
13
- "useDataTableContext must be used within a <DataTable /> component."
14
- );
15
- }
16
- return ctx;
17
- }
18
- function mapA11yToAria(a) {
19
- const result = {};
20
- if (a.role) result.role = a.role;
21
- if (a.label) result["aria-label"] = a.label;
22
- if (a.labelledBy) result["aria-labelledby"] = a.labelledBy;
23
- if (a.describedBy) result["aria-describedby"] = a.describedBy;
24
- if (a.disabled != null) result["aria-disabled"] = a.disabled;
25
- if (a.expanded != null) result["aria-expanded"] = a.expanded;
26
- if (a.selected != null) result["aria-selected"] = a.selected;
27
- if (a.checked != null) result["aria-checked"] = a.checked;
28
- if (a.busy != null) result["aria-busy"] = a.busy;
29
- if (a.hidden != null) result["aria-hidden"] = a.hidden;
30
- if (a.tabIndex != null) result.tabIndex = a.tabIndex;
31
- if (a.controls) result["aria-controls"] = a.controls;
32
- if (a.orientation) result["aria-orientation"] = a.orientation;
33
- if (a.required != null) result["aria-required"] = a.required;
34
- if (a.invalid != null) result["aria-invalid"] = a.invalid;
35
- return result;
36
- }
37
- function DataTable(props) {
38
- const {
39
- className,
40
- emptyMessage = "No data",
41
- renderCell,
42
- stickyHeader = false,
43
- ...tableOptions
44
- } = props;
45
- const table = useTable(tableOptions);
46
- const {
47
- columns,
48
- getRowKey = (_, i) => String(i),
49
- selectionMode = "none"
50
- } = tableOptions;
51
- const contextValue = useMemo(
52
- () => ({
53
- ...table,
54
- columns,
55
- getRowKey
56
- }),
57
- [table, columns, getRowKey]
58
- );
59
- const tableAriaProps = mapA11yToAria(table.getTableProps().accessibility);
60
- const getSortDir = (colKey) => {
61
- const s = table.sortState.find((st) => st.columnKey === colKey);
62
- return s ? s.direction : "none";
63
- };
64
- const hasFilters = columns.some((c) => c.filterable);
65
- return /* @__PURE__ */ jsx(DataTableContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs("div", { className: `entropix-datatable ${className ?? ""}`.trim(), children: [
66
- /* @__PURE__ */ jsxs("table", { className: "entropix-datatable__table", ...tableAriaProps, children: [
67
- /* @__PURE__ */ jsxs(
68
- "thead",
69
- {
70
- className: "entropix-datatable__thead",
71
- "data-sticky": stickyHeader ? "true" : void 0,
72
- ...mapA11yToAria(table.getHeaderRowProps().accessibility),
73
- children: [
74
- hasFilters && /* @__PURE__ */ jsxs("tr", { className: "entropix-datatable__filter-row", children: [
75
- selectionMode !== "none" && /* @__PURE__ */ jsx("th", { className: "entropix-datatable__th entropix-datatable__th--checkbox" }),
76
- columns.map((col) => /* @__PURE__ */ jsx(
77
- "th",
78
- {
79
- className: "entropix-datatable__th entropix-datatable__th--filter",
80
- children: col.filterable ? /* @__PURE__ */ jsx(
81
- "input",
82
- {
83
- type: "text",
84
- className: "entropix-datatable__filter",
85
- placeholder: `Filter ${col.header}...`,
86
- value: table.columnFilters[col.key] ?? "",
87
- onChange: (e) => table.setColumnFilter(col.key, e.target.value),
88
- "aria-label": `Filter by ${col.header}`
89
- }
90
- ) : null
91
- },
92
- `filter-${col.key}`
93
- ))
94
- ] }),
95
- /* @__PURE__ */ jsxs("tr", { className: "entropix-datatable__tr entropix-datatable__tr--header", children: [
96
- selectionMode !== "none" && /* @__PURE__ */ jsx("th", { className: "entropix-datatable__th entropix-datatable__th--checkbox", children: selectionMode === "multi" && /* @__PURE__ */ jsx(
97
- "input",
98
- {
99
- type: "checkbox",
100
- className: "entropix-datatable__checkbox",
101
- checked: table.isAllSelected,
102
- ref: (el) => {
103
- if (el) el.indeterminate = table.isIndeterminate;
104
- },
105
- onChange: table.toggleAllSelection,
106
- "aria-label": "Select all rows"
107
- }
108
- ) }),
109
- columns.map((col) => {
110
- const headerProps = table.getHeaderCellProps(col.key);
111
- const ariaProps = mapA11yToAria(headerProps.accessibility);
112
- const sortDir = getSortDir(col.key);
113
- return /* @__PURE__ */ jsx(
114
- "th",
115
- {
116
- className: `entropix-datatable__th${col.sortable ? " entropix-datatable__th--sortable" : ""}`,
117
- "data-sort": col.sortable ? sortDir : void 0,
118
- onClick: headerProps.onAction,
119
- onKeyDown: col.sortable ? (e) => {
120
- if (e.key === "Enter" || e.key === " ") {
121
- e.preventDefault();
122
- headerProps.onAction?.();
123
- }
124
- } : void 0,
125
- style: col.width ? {
126
- width: typeof col.width === "number" ? `${col.width}px` : col.width
127
- } : void 0,
128
- ...ariaProps,
129
- children: /* @__PURE__ */ jsxs("span", { className: "entropix-datatable__th-content", children: [
130
- col.header,
131
- col.sortable && sortDir !== "none" && /* @__PURE__ */ jsx(
132
- "span",
133
- {
134
- className: "entropix-datatable__sort-icon",
135
- "aria-hidden": "true",
136
- children: sortDir === "asc" ? " \u25B2" : " \u25BC"
137
- }
138
- )
139
- ] })
140
- },
141
- col.key
142
- );
143
- })
144
- ] })
145
- ]
146
- }
147
- ),
148
- /* @__PURE__ */ jsx(
149
- "tbody",
150
- {
151
- className: "entropix-datatable__tbody",
152
- ...mapA11yToAria(table.getBodyProps().accessibility),
153
- children: table.isLoading ? /* @__PURE__ */ jsx("tr", { className: "entropix-datatable__tr entropix-datatable__tr--loading", children: /* @__PURE__ */ jsx(
154
- "td",
155
- {
156
- className: "entropix-datatable__td entropix-datatable__td--loading",
157
- colSpan: columns.length + (selectionMode !== "none" ? 1 : 0),
158
- children: /* @__PURE__ */ jsx("div", { className: "entropix-datatable__loading", children: "Loading..." })
159
- }
160
- ) }) : table.rows.length === 0 ? /* @__PURE__ */ jsx("tr", { className: "entropix-datatable__tr entropix-datatable__tr--empty", children: /* @__PURE__ */ jsx(
161
- "td",
162
- {
163
- className: "entropix-datatable__td entropix-datatable__td--empty",
164
- colSpan: columns.length + (selectionMode !== "none" ? 1 : 0),
165
- children: /* @__PURE__ */ jsx("div", { className: "entropix-datatable__empty", children: emptyMessage })
166
- }
167
- ) }) : table.rows.map((row, i) => {
168
- const globalIndex = table.page * table.pageSize + i;
169
- const rowKey = getRowKey(row, globalIndex);
170
- const rowProps = table.getRowProps(rowKey, i);
171
- const isSelected = table.selectedKeys.has(rowKey);
172
- return /* @__PURE__ */ jsxs(
173
- "tr",
174
- {
175
- className: "entropix-datatable__tr",
176
- "data-selected": isSelected ? "true" : void 0,
177
- ...mapA11yToAria(rowProps.accessibility),
178
- children: [
179
- selectionMode !== "none" && /* @__PURE__ */ jsx("td", { className: "entropix-datatable__td entropix-datatable__td--checkbox", children: /* @__PURE__ */ jsx(
180
- "input",
181
- {
182
- type: "checkbox",
183
- className: "entropix-datatable__checkbox",
184
- checked: isSelected,
185
- onChange: () => table.toggleRowSelection(rowKey),
186
- "aria-label": `Select row ${rowKey}`
187
- }
188
- ) }),
189
- columns.map((col) => {
190
- const cellValue = col.accessor ? col.accessor(row) : row[col.key];
191
- return /* @__PURE__ */ jsx(
192
- "td",
193
- {
194
- className: "entropix-datatable__td",
195
- ...mapA11yToAria(
196
- table.getCellProps(col.key, rowKey).accessibility
197
- ),
198
- children: renderCell ? renderCell(cellValue, row, col) : String(cellValue ?? "")
199
- },
200
- col.key
201
- );
202
- })
203
- ]
204
- },
205
- rowKey
206
- );
207
- })
208
- }
209
- )
210
- ] }),
211
- table.pageCount > 1 && /* @__PURE__ */ jsxs(
212
- "nav",
213
- {
214
- className: "entropix-datatable__pagination",
215
- "aria-label": "Table pagination",
216
- children: [
217
- /* @__PURE__ */ jsx(
218
- "button",
219
- {
220
- className: "entropix-datatable__pagination-btn",
221
- onClick: table.firstPage,
222
- disabled: !table.canPreviousPage,
223
- "aria-label": "First page",
224
- children: "\u27E8\u27E8"
225
- }
226
- ),
227
- /* @__PURE__ */ jsx(
228
- "button",
229
- {
230
- className: "entropix-datatable__pagination-btn",
231
- onClick: table.previousPage,
232
- disabled: !table.canPreviousPage,
233
- "aria-label": "Previous page",
234
- children: "\u27E8"
235
- }
236
- ),
237
- /* @__PURE__ */ jsxs("span", { className: "entropix-datatable__pagination-info", children: [
238
- "Page ",
239
- table.page + 1,
240
- " of ",
241
- table.pageCount
242
- ] }),
243
- /* @__PURE__ */ jsx(
244
- "button",
245
- {
246
- className: "entropix-datatable__pagination-btn",
247
- onClick: table.nextPage,
248
- disabled: !table.canNextPage,
249
- "aria-label": "Next page",
250
- children: "\u27E9"
251
- }
252
- ),
253
- /* @__PURE__ */ jsx(
254
- "button",
255
- {
256
- className: "entropix-datatable__pagination-btn",
257
- onClick: table.lastPage,
258
- disabled: !table.canNextPage,
259
- "aria-label": "Last page",
260
- children: "\u27E9\u27E9"
261
- }
262
- )
263
- ]
264
- }
265
- )
266
- ] }) });
267
- }
268
- function ChartContainer({
269
- height = 300,
270
- className,
271
- children
272
- }) {
273
- const containerRef = useRef(null);
274
- const [width, setWidth] = useState(0);
275
- const handleResize = useCallback(() => {
276
- if (containerRef.current) {
277
- setWidth(containerRef.current.clientWidth);
278
- }
279
- }, []);
280
- useEffect(() => {
281
- const el = containerRef.current;
282
- if (!el) return;
283
- handleResize();
284
- const observer = new ResizeObserver(() => {
285
- handleResize();
286
- });
287
- observer.observe(el);
288
- return () => observer.disconnect();
289
- }, [handleResize]);
290
- return /* @__PURE__ */ jsx(
291
- "div",
292
- {
293
- ref: containerRef,
294
- className: className ? `entropix-chart ${className}` : "entropix-chart",
295
- style: { position: "relative", width: "100%" },
296
- children: width > 0 && /* @__PURE__ */ jsx(
297
- "svg",
298
- {
299
- className: "entropix-chart__svg",
300
- width,
301
- height,
302
- viewBox: `0 0 ${width} ${height}`,
303
- children: children(width, height)
304
- }
305
- )
306
- }
307
- );
308
- }
309
- function XAxis({ scale, y, height: _height, formatter }) {
310
- const domain = scale.domain();
311
- const bandwidth = scale.bandwidth();
312
- return /* @__PURE__ */ jsxs("g", { children: [
313
- domain.map((label) => {
314
- const x = scale(label) + bandwidth / 2;
315
- return /* @__PURE__ */ jsxs("g", { transform: `translate(${x}, ${y})`, children: [
316
- /* @__PURE__ */ jsx("line", { y2: 6, stroke: "currentColor", strokeWidth: 1 }),
317
- /* @__PURE__ */ jsx(
318
- "text",
319
- {
320
- className: "entropix-chart__axis-text",
321
- y: 18,
322
- textAnchor: "middle",
323
- dominantBaseline: "auto",
324
- children: formatter ? formatter(label) : label
325
- }
326
- )
327
- ] }, label);
328
- }),
329
- /* @__PURE__ */ jsx(
330
- "line",
331
- {
332
- x1: scale.range()[0],
333
- x2: scale.range()[1],
334
- y1: y,
335
- y2: y,
336
- stroke: "currentColor",
337
- strokeWidth: 1
338
- }
339
- )
340
- ] });
341
- }
342
- function YAxis({
343
- scale,
344
- x,
345
- width,
346
- formatter,
347
- showGrid = true
348
- }) {
349
- const ticks = scale.ticks();
350
- return /* @__PURE__ */ jsx("g", { children: ticks.map((tick) => {
351
- const y = scale(tick);
352
- return /* @__PURE__ */ jsxs("g", { transform: `translate(${x}, ${y})`, children: [
353
- /* @__PURE__ */ jsx(
354
- "text",
355
- {
356
- className: "entropix-chart__axis-text",
357
- x: -8,
358
- textAnchor: "end",
359
- dominantBaseline: "middle",
360
- children: formatter ? formatter(tick) : String(tick)
361
- }
362
- ),
363
- showGrid && /* @__PURE__ */ jsx(
364
- "line",
365
- {
366
- className: "entropix-chart__grid-line",
367
- x1: 0,
368
- x2: width,
369
- y1: 0,
370
- y2: 0
371
- }
372
- )
373
- ] }, tick);
374
- }) });
375
- }
376
- function ChartTooltip({ data, containerRef }) {
377
- const tooltipRef = useRef(null);
378
- const [position, setPosition] = useState({
379
- left: 0,
380
- top: 0
381
- });
382
- useEffect(() => {
383
- if (!data || !tooltipRef.current || !containerRef.current) return;
384
- const container = containerRef.current;
385
- const tooltip = tooltipRef.current;
386
- const containerRect = container.getBoundingClientRect();
387
- const tooltipWidth = tooltip.offsetWidth;
388
- const tooltipHeight = tooltip.offsetHeight;
389
- let left = data.x + 12;
390
- let top = data.y - tooltipHeight / 2;
391
- if (left + tooltipWidth > containerRect.width) {
392
- left = data.x - tooltipWidth - 12;
393
- }
394
- if (top < 0) {
395
- top = 0;
396
- }
397
- if (top + tooltipHeight > containerRect.height) {
398
- top = containerRect.height - tooltipHeight;
399
- }
400
- setPosition({ left, top });
401
- }, [data, containerRef]);
402
- return /* @__PURE__ */ jsx(
403
- "div",
404
- {
405
- ref: tooltipRef,
406
- className: `entropix-chart__tooltip${data ? " entropix-chart__tooltip--visible" : ""}`,
407
- style: {
408
- left: position.left,
409
- top: position.top
410
- },
411
- children: data && /* @__PURE__ */ jsxs("div", { className: "entropix-chart__tooltip-row", children: [
412
- /* @__PURE__ */ jsx(
413
- "span",
414
- {
415
- className: "entropix-chart__tooltip-swatch",
416
- style: { backgroundColor: data.color }
417
- }
418
- ),
419
- /* @__PURE__ */ jsxs("span", { children: [
420
- data.series,
421
- ": ",
422
- data.label,
423
- " \u2014 ",
424
- data.value
425
- ] })
426
- ] })
427
- }
428
- );
429
- }
430
- function ChartLegend({ items, onToggle }) {
431
- if (items.length === 0) return null;
432
- return /* @__PURE__ */ jsx("div", { className: "entropix-chart__legend", children: items.map((item) => /* @__PURE__ */ jsxs(
433
- "button",
434
- {
435
- type: "button",
436
- className: `entropix-chart__legend-item${!item.active ? " entropix-chart__legend-item--inactive" : ""}`,
437
- onClick: () => onToggle(item.name),
438
- children: [
439
- /* @__PURE__ */ jsx(
440
- "span",
441
- {
442
- className: "entropix-chart__legend-swatch",
443
- style: { backgroundColor: item.color }
444
- }
445
- ),
446
- /* @__PURE__ */ jsx("span", { children: item.name })
447
- ]
448
- },
449
- item.name
450
- )) });
451
- }
452
-
453
- // src/utils/chart-colors.ts
454
- var CSS_CHART_COLORS = [
455
- "var(--chart-series-1)",
456
- "var(--chart-series-2)",
457
- "var(--chart-series-3)",
458
- "var(--chart-series-4)",
459
- "var(--chart-series-5)",
460
- "var(--chart-series-6)",
461
- "var(--chart-series-7)",
462
- "var(--chart-series-8)"
463
- ];
464
- var MARGINS = { top: 20, right: 20, bottom: 40, left: 50 };
465
- function BarChart({
466
- data,
467
- height = 300,
468
- colors,
469
- stacked = false,
470
- showGrid = true,
471
- showTooltip = true,
472
- showLegend = true,
473
- xAxis,
474
- yAxis,
475
- className
476
- }) {
477
- const [hiddenSeries, setHiddenSeries] = useState(/* @__PURE__ */ new Set());
478
- const [tooltip, setTooltip] = useState(null);
479
- const containerRef = useRef(null);
480
- const toggleSeries = useCallback((name) => {
481
- setHiddenSeries((prev) => {
482
- const next = new Set(prev);
483
- if (next.has(name)) {
484
- next.delete(name);
485
- } else {
486
- next.add(name);
487
- }
488
- return next;
489
- });
490
- }, []);
491
- const allSeries = normalizeChartData(data, colors ?? CSS_CHART_COLORS);
492
- const visibleSeries = allSeries.filter((s) => !hiddenSeries.has(s.name));
493
- const { categories, yMin, yMax } = getDataExtent(visibleSeries);
494
- const legendItems = allSeries.map((s) => ({
495
- name: s.name,
496
- color: s.color,
497
- active: !hiddenSeries.has(s.name)
498
- }));
499
- const handleBarEnter = useCallback(
500
- (rect, seriesName, event) => {
501
- if (!showTooltip) return;
502
- const svg = event.target.closest("svg");
503
- if (!svg) return;
504
- svg.getBoundingClientRect();
505
- const container = containerRef.current;
506
- if (!container) return;
507
- container.getBoundingClientRect();
508
- setTooltip({
509
- x: rect.x + rect.width / 2 + MARGINS.left,
510
- y: rect.y + MARGINS.top,
511
- series: seriesName,
512
- label: rect.label,
513
- value: rect.value,
514
- color: rect.color
515
- });
516
- },
517
- [showTooltip]
518
- );
519
- const handleBarLeave = useCallback(() => {
520
- setTooltip(null);
521
- }, []);
522
- return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: className ? `entropix-chart ${className}` : "entropix-chart", style: { position: "relative" }, children: [
523
- /* @__PURE__ */ jsx(ChartContainer, { height, children: (width, h) => {
524
- const innerWidth = width - MARGINS.left - MARGINS.right;
525
- const innerHeight = h - MARGINS.top - MARGINS.bottom;
526
- if (innerWidth <= 0 || innerHeight <= 0) return null;
527
- const bounds = niceBounds(yMin, yMax, yAxis?.tickCount ?? 5);
528
- const yScale = createLinearScale(
529
- [bounds.min, bounds.max],
530
- [innerHeight, 0]
531
- );
532
- const xScale = createBandScale(categories, [0, innerWidth]);
533
- const bars = computeBarGeometry(
534
- visibleSeries,
535
- xScale,
536
- yScale,
537
- innerHeight,
538
- stacked
539
- );
540
- return /* @__PURE__ */ jsxs("g", { transform: `translate(${MARGINS.left}, ${MARGINS.top})`, children: [
541
- yAxis?.show !== false && /* @__PURE__ */ jsx(
542
- YAxis,
543
- {
544
- scale: yScale,
545
- x: 0,
546
- width: innerWidth,
547
- showGrid,
548
- formatter: yAxis?.formatter
549
- }
550
- ),
551
- xAxis?.show !== false && /* @__PURE__ */ jsx(
552
- XAxis,
553
- {
554
- scale: xScale,
555
- y: innerHeight,
556
- height: innerHeight,
557
- formatter: xAxis?.formatter
558
- }
559
- ),
560
- bars.map((rect, i) => {
561
- const series = visibleSeries[rect.seriesIndex];
562
- return /* @__PURE__ */ jsx(
563
- "rect",
564
- {
565
- className: "entropix-chart__bar",
566
- x: rect.x,
567
- y: rect.y,
568
- width: rect.width,
569
- height: rect.height,
570
- fill: rect.color,
571
- onMouseEnter: (e) => handleBarEnter(rect, series?.name ?? "", e),
572
- onMouseLeave: handleBarLeave
573
- },
574
- i
575
- );
576
- })
577
- ] });
578
- } }),
579
- showTooltip && /* @__PURE__ */ jsx(ChartTooltip, { data: tooltip, containerRef }),
580
- showLegend && allSeries.length > 1 && /* @__PURE__ */ jsx(ChartLegend, { items: legendItems, onToggle: toggleSeries })
581
- ] });
582
- }
583
- var MARGINS2 = { top: 20, right: 20, bottom: 40, left: 50 };
584
- function LineChart({
585
- data,
586
- height = 300,
587
- colors,
588
- curved = false,
589
- showPoints = true,
590
- showGrid = true,
591
- showTooltip = true,
592
- showLegend = true,
593
- xAxis,
594
- yAxis,
595
- className
596
- }) {
597
- const [hiddenSeries, setHiddenSeries] = useState(/* @__PURE__ */ new Set());
598
- const [tooltip, setTooltip] = useState(null);
599
- const containerRef = useRef(null);
600
- const toggleSeries = useCallback((name) => {
601
- setHiddenSeries((prev) => {
602
- const next = new Set(prev);
603
- if (next.has(name)) next.delete(name);
604
- else next.add(name);
605
- return next;
606
- });
607
- }, []);
608
- const allSeries = normalizeChartData(data, colors ?? CSS_CHART_COLORS);
609
- const visibleSeries = allSeries.filter((s) => !hiddenSeries.has(s.name));
610
- const { categories, yMin, yMax } = getDataExtent(visibleSeries);
611
- const legendItems = allSeries.map((s) => ({
612
- name: s.name,
613
- color: s.color,
614
- active: !hiddenSeries.has(s.name)
615
- }));
616
- const handlePointEnter = useCallback(
617
- (point, seriesName, color) => {
618
- if (!showTooltip) return;
619
- setTooltip({
620
- x: point.x + MARGINS2.left,
621
- y: point.y + MARGINS2.top,
622
- series: seriesName,
623
- label: point.label,
624
- value: point.value,
625
- color
626
- });
627
- },
628
- [showTooltip]
629
- );
630
- const handlePointLeave = useCallback(() => {
631
- setTooltip(null);
632
- }, []);
633
- return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: className ? `entropix-chart ${className}` : "entropix-chart", style: { position: "relative" }, children: [
634
- /* @__PURE__ */ jsx(ChartContainer, { height, children: (width, h) => {
635
- const innerWidth = width - MARGINS2.left - MARGINS2.right;
636
- const innerHeight = h - MARGINS2.top - MARGINS2.bottom;
637
- if (innerWidth <= 0 || innerHeight <= 0) return null;
638
- const bounds = niceBounds(yMin, yMax, yAxis?.tickCount ?? 5);
639
- const yScale = createLinearScale(
640
- [bounds.min, bounds.max],
641
- [innerHeight, 0]
642
- );
643
- const xScale = createBandScale(categories, [0, innerWidth]);
644
- return /* @__PURE__ */ jsxs("g", { transform: `translate(${MARGINS2.left}, ${MARGINS2.top})`, children: [
645
- yAxis?.show !== false && /* @__PURE__ */ jsx(
646
- YAxis,
647
- {
648
- scale: yScale,
649
- x: 0,
650
- width: innerWidth,
651
- showGrid,
652
- formatter: yAxis?.formatter
653
- }
654
- ),
655
- xAxis?.show !== false && /* @__PURE__ */ jsx(
656
- XAxis,
657
- {
658
- scale: xScale,
659
- y: innerHeight,
660
- height: innerHeight,
661
- formatter: xAxis?.formatter
662
- }
663
- ),
664
- visibleSeries.map((series) => {
665
- const points = computeLinePoints(series, xScale, yScale);
666
- const pathD = describeLinePath(points, curved);
667
- return /* @__PURE__ */ jsxs("g", { children: [
668
- /* @__PURE__ */ jsx(
669
- "path",
670
- {
671
- className: "entropix-chart__line",
672
- d: pathD,
673
- stroke: series.color
674
- }
675
- ),
676
- showPoints && points.map((pt, i) => /* @__PURE__ */ jsx(
677
- "circle",
678
- {
679
- className: "entropix-chart__point",
680
- cx: pt.x,
681
- cy: pt.y,
682
- r: 3.5,
683
- fill: series.color,
684
- onMouseEnter: () => handlePointEnter(pt, series.name, series.color),
685
- onMouseLeave: handlePointLeave
686
- },
687
- i
688
- ))
689
- ] }, series.name);
690
- })
691
- ] });
692
- } }),
693
- showTooltip && /* @__PURE__ */ jsx(ChartTooltip, { data: tooltip, containerRef }),
694
- showLegend && allSeries.length > 1 && /* @__PURE__ */ jsx(ChartLegend, { items: legendItems, onToggle: toggleSeries })
695
- ] });
696
- }
697
- var MARGINS3 = { top: 20, right: 20, bottom: 40, left: 50 };
698
- function AreaChart({
699
- data,
700
- height = 300,
701
- colors,
702
- curved = false,
703
- opacity = 0.3,
704
- showGrid = true,
705
- showTooltip = true,
706
- showLegend = true,
707
- xAxis,
708
- yAxis,
709
- className
710
- }) {
711
- const [hiddenSeries, setHiddenSeries] = useState(/* @__PURE__ */ new Set());
712
- const [tooltip, setTooltip] = useState(null);
713
- const containerRef = useRef(null);
714
- const toggleSeries = useCallback((name) => {
715
- setHiddenSeries((prev) => {
716
- const next = new Set(prev);
717
- if (next.has(name)) next.delete(name);
718
- else next.add(name);
719
- return next;
720
- });
721
- }, []);
722
- const allSeries = normalizeChartData(data, colors ?? CSS_CHART_COLORS);
723
- const visibleSeries = allSeries.filter((s) => !hiddenSeries.has(s.name));
724
- const { categories, yMin, yMax } = getDataExtent(visibleSeries);
725
- const legendItems = allSeries.map((s) => ({
726
- name: s.name,
727
- color: s.color,
728
- active: !hiddenSeries.has(s.name)
729
- }));
730
- const handlePointEnter = useCallback(
731
- (point, seriesName, color) => {
732
- if (!showTooltip) return;
733
- setTooltip({
734
- x: point.x + MARGINS3.left,
735
- y: point.y + MARGINS3.top,
736
- series: seriesName,
737
- label: point.label,
738
- value: point.value,
739
- color
740
- });
741
- },
742
- [showTooltip]
743
- );
744
- const handlePointLeave = useCallback(() => {
745
- setTooltip(null);
746
- }, []);
747
- return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: className ? `entropix-chart ${className}` : "entropix-chart", style: { position: "relative" }, children: [
748
- /* @__PURE__ */ jsx(ChartContainer, { height, children: (width, h) => {
749
- const innerWidth = width - MARGINS3.left - MARGINS3.right;
750
- const innerHeight = h - MARGINS3.top - MARGINS3.bottom;
751
- if (innerWidth <= 0 || innerHeight <= 0) return null;
752
- const bounds = niceBounds(yMin, yMax, yAxis?.tickCount ?? 5);
753
- const yScale = createLinearScale(
754
- [bounds.min, bounds.max],
755
- [innerHeight, 0]
756
- );
757
- const xScale = createBandScale(categories, [0, innerWidth]);
758
- const baselineY = yScale(bounds.min);
759
- return /* @__PURE__ */ jsxs("g", { transform: `translate(${MARGINS3.left}, ${MARGINS3.top})`, children: [
760
- yAxis?.show !== false && /* @__PURE__ */ jsx(
761
- YAxis,
762
- {
763
- scale: yScale,
764
- x: 0,
765
- width: innerWidth,
766
- showGrid,
767
- formatter: yAxis?.formatter
768
- }
769
- ),
770
- xAxis?.show !== false && /* @__PURE__ */ jsx(
771
- XAxis,
772
- {
773
- scale: xScale,
774
- y: innerHeight,
775
- height: innerHeight,
776
- formatter: xAxis?.formatter
777
- }
778
- ),
779
- visibleSeries.map((series) => {
780
- const points = computeLinePoints(series, xScale, yScale);
781
- const areaD = describeAreaPath(points, baselineY, curved);
782
- const lineD = describeLinePath(points, curved);
783
- return /* @__PURE__ */ jsxs("g", { children: [
784
- /* @__PURE__ */ jsx(
785
- "path",
786
- {
787
- className: "entropix-chart__area",
788
- d: areaD,
789
- fill: series.color,
790
- fillOpacity: opacity
791
- }
792
- ),
793
- /* @__PURE__ */ jsx(
794
- "path",
795
- {
796
- className: "entropix-chart__line",
797
- d: lineD,
798
- stroke: series.color
799
- }
800
- ),
801
- points.map((pt, i) => /* @__PURE__ */ jsx(
802
- "circle",
803
- {
804
- className: "entropix-chart__point",
805
- cx: pt.x,
806
- cy: pt.y,
807
- r: 3,
808
- fill: series.color,
809
- onMouseEnter: () => handlePointEnter(pt, series.name, series.color),
810
- onMouseLeave: handlePointLeave
811
- },
812
- i
813
- ))
814
- ] }, series.name);
815
- })
816
- ] });
817
- } }),
818
- showTooltip && /* @__PURE__ */ jsx(ChartTooltip, { data: tooltip, containerRef }),
819
- showLegend && allSeries.length > 1 && /* @__PURE__ */ jsx(ChartLegend, { items: legendItems, onToggle: toggleSeries })
820
- ] });
821
- }
822
- function PieChart({
823
- data,
824
- height = 300,
825
- colors,
826
- innerRadius = 0,
827
- showTooltip = true,
828
- showLegend = true,
829
- className
830
- }) {
831
- const [hiddenSlices, setHiddenSlices] = useState(/* @__PURE__ */ new Set());
832
- const [tooltip, setTooltip] = useState(null);
833
- const containerRef = useRef(null);
834
- const toggleSlice = useCallback((name) => {
835
- setHiddenSlices((prev) => {
836
- const next = new Set(prev);
837
- if (next.has(name)) next.delete(name);
838
- else next.add(name);
839
- return next;
840
- });
841
- }, []);
842
- const palette = colors ?? CSS_CHART_COLORS;
843
- const coloredData = data.map((d, i) => ({
844
- ...d,
845
- color: getSeriesColor(i, palette)
846
- }));
847
- const visibleData = coloredData.filter((d) => !hiddenSlices.has(d.label));
848
- const legendItems = coloredData.map((d) => ({
849
- name: d.label,
850
- color: d.color,
851
- active: !hiddenSlices.has(d.label)
852
- }));
853
- const handleArcEnter = useCallback(
854
- (label, value, percentage, color, cx, cy) => {
855
- if (!showTooltip) return;
856
- setTooltip({
857
- x: cx,
858
- y: cy,
859
- series: `${(percentage * 100).toFixed(1)}%`,
860
- label,
861
- value,
862
- color
863
- });
864
- },
865
- [showTooltip]
866
- );
867
- const handleArcLeave = useCallback(() => {
868
- setTooltip(null);
869
- }, []);
870
- return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: className ? `entropix-chart ${className}` : "entropix-chart", style: { position: "relative" }, children: [
871
- /* @__PURE__ */ jsx(ChartContainer, { height, children: (width, h) => {
872
- const cx = width / 2;
873
- const cy = h / 2;
874
- const outerRadius = Math.min(cx, cy) - 10;
875
- if (outerRadius <= 0) return null;
876
- const slices = computeArcGeometry(
877
- visibleData,
878
- outerRadius,
879
- innerRadius
880
- );
881
- return /* @__PURE__ */ jsx("g", { transform: `translate(${cx}, ${cy})`, children: slices.map((slice, i) => {
882
- const midAngle = (slice.startAngle + slice.endAngle) / 2;
883
- const tooltipX = cx + outerRadius * 0.6 * Math.cos(midAngle);
884
- const tooltipY = cy + outerRadius * 0.6 * Math.sin(midAngle);
885
- return /* @__PURE__ */ jsx(
886
- "path",
887
- {
888
- className: "entropix-chart__arc",
889
- d: slice.path,
890
- fill: slice.color,
891
- onMouseEnter: () => handleArcEnter(
892
- slice.label,
893
- slice.value,
894
- slice.percentage,
895
- slice.color,
896
- tooltipX,
897
- tooltipY
898
- ),
899
- onMouseLeave: handleArcLeave
900
- },
901
- i
902
- );
903
- }) });
904
- } }),
905
- showTooltip && /* @__PURE__ */ jsx(ChartTooltip, { data: tooltip, containerRef }),
906
- showLegend && /* @__PURE__ */ jsx(ChartLegend, { items: legendItems, onToggle: toggleSlice })
907
- ] });
908
- }
909
-
910
- export { AreaChart, BarChart, DataTable, DataTableContext, LineChart, PieChart, useDataTableContext };
1
+ export { DataTable, DataTableContext, useDataTableContext } from './chunk-YINCJQN6.js';
2
+ export { BarChart } from './chunk-X7GZD7KZ.js';
3
+ export { LineChart } from './chunk-VCSKHJLZ.js';
4
+ export { AreaChart } from './chunk-CMAQ7DZD.js';
5
+ import './chunk-4WXLJDQU.js';
6
+ export { PieChart } from './chunk-42HKJHUY.js';
7
+ import './chunk-FQACLZYR.js';
911
8
  //# sourceMappingURL=index.js.map
912
9
  //# sourceMappingURL=index.js.map