@xaui/native 0.0.21 → 0.0.24

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 (113) hide show
  1. package/README.md +195 -2
  2. package/dist/alert/index.js +1 -2
  3. package/dist/app-bar/index.cjs +217 -0
  4. package/dist/app-bar/index.d.cts +52 -0
  5. package/dist/app-bar/index.d.ts +52 -0
  6. package/dist/app-bar/index.js +142 -0
  7. package/dist/autocomplete/index.js +48 -36
  8. package/dist/avatar/index.js +1 -2
  9. package/dist/badge/index.js +1 -2
  10. package/dist/bottom-sheet/index.js +1 -2
  11. package/dist/bottom-tab-bar/index.cjs +571 -0
  12. package/dist/bottom-tab-bar/index.d.cts +211 -0
  13. package/dist/bottom-tab-bar/index.d.ts +211 -0
  14. package/dist/bottom-tab-bar/index.js +497 -0
  15. package/dist/button/index.d.cts +102 -5
  16. package/dist/button/index.d.ts +102 -5
  17. package/dist/button/index.js +2 -3
  18. package/dist/button.type-j1ZdkkSl.d.cts +4 -0
  19. package/dist/button.type-j1ZdkkSl.d.ts +4 -0
  20. package/dist/card/index.cjs +2 -0
  21. package/dist/card/index.d.cts +6 -1
  22. package/dist/card/index.d.ts +6 -1
  23. package/dist/card/index.js +4 -2
  24. package/dist/carousel/index.js +1 -1
  25. package/dist/chart/index.cjs +1067 -0
  26. package/dist/chart/index.d.cts +218 -0
  27. package/dist/chart/index.d.ts +218 -0
  28. package/dist/chart/index.js +1026 -0
  29. package/dist/checkbox/index.js +1 -2
  30. package/dist/chip/index.js +1 -2
  31. package/dist/chunk-3XSXTM3G.js +661 -0
  32. package/dist/chunk-4KSZLONZ.js +79 -0
  33. package/dist/{chunk-DXXNBF5P.js → chunk-CZFDZPAS.js} +0 -5
  34. package/dist/{chunk-LTKYHG5V.js → chunk-GHCVNQET.js} +12 -5
  35. package/dist/chunk-I4V5Y5GD.js +76 -0
  36. package/dist/{chunk-F7WH4DMG.js → chunk-UI5L26KD.js} +1 -1
  37. package/dist/{chunk-LUBWRVI2.js → chunk-ULJSCNPE.js} +1 -1
  38. package/dist/chunk-URBEEDFX.js +79 -0
  39. package/dist/core/index.js +3 -5
  40. package/dist/datepicker/index.js +1 -2
  41. package/dist/divider/index.js +2 -3
  42. package/dist/drawer/index.cjs +310 -0
  43. package/dist/drawer/index.d.cts +58 -0
  44. package/dist/drawer/index.d.ts +58 -0
  45. package/dist/drawer/index.js +236 -0
  46. package/dist/{accordion → expansion-panel}/index.cjs +45 -45
  47. package/dist/{accordion → expansion-panel}/index.d.cts +30 -30
  48. package/dist/{accordion → expansion-panel}/index.d.ts +30 -30
  49. package/dist/{accordion → expansion-panel}/index.js +40 -41
  50. package/dist/fab/index.d.cts +3 -3
  51. package/dist/fab/index.d.ts +3 -3
  52. package/dist/fab/index.js +3 -4
  53. package/dist/fab-menu/index.d.cts +2 -2
  54. package/dist/fab-menu/index.d.ts +2 -2
  55. package/dist/fab-menu/index.js +3 -4
  56. package/dist/{fab.type-Ba0QMprb.d.ts → fab.type-CgIYqQlT.d.ts} +1 -1
  57. package/dist/{fab.type-U09H8B7D.d.cts → fab.type-l2vjG8-p.d.cts} +1 -1
  58. package/dist/feature-discovery/index.cjs +531 -0
  59. package/dist/feature-discovery/index.d.cts +82 -0
  60. package/dist/feature-discovery/index.d.ts +82 -0
  61. package/dist/feature-discovery/index.js +464 -0
  62. package/dist/indicator/index.js +2 -3
  63. package/dist/input/index.cjs +258 -164
  64. package/dist/input/index.d.cts +15 -1
  65. package/dist/input/index.d.ts +15 -1
  66. package/dist/input/index.js +219 -126
  67. package/dist/list/index.js +1 -2
  68. package/dist/menu/index.js +2 -2
  69. package/dist/menubox/index.cjs +369 -0
  70. package/dist/menubox/index.d.cts +98 -0
  71. package/dist/menubox/index.d.ts +98 -0
  72. package/dist/menubox/index.js +296 -0
  73. package/dist/pager/index.cjs +243 -0
  74. package/dist/pager/index.d.cts +93 -0
  75. package/dist/pager/index.d.ts +93 -0
  76. package/dist/pager/index.js +205 -0
  77. package/dist/progress/index.js +1 -2
  78. package/dist/radio/index.cjs +537 -0
  79. package/dist/radio/index.d.cts +145 -0
  80. package/dist/radio/index.d.ts +145 -0
  81. package/dist/radio/index.js +464 -0
  82. package/dist/segment-button/index.js +2 -2
  83. package/dist/select/index.js +22 -10
  84. package/dist/skeleton/index.js +2 -2
  85. package/dist/slider/index.cjs +655 -0
  86. package/dist/slider/index.d.cts +171 -0
  87. package/dist/slider/index.d.ts +171 -0
  88. package/dist/slider/index.js +575 -0
  89. package/dist/stepper/index.cjs +624 -0
  90. package/dist/stepper/index.d.cts +137 -0
  91. package/dist/stepper/index.d.ts +137 -0
  92. package/dist/stepper/index.js +549 -0
  93. package/dist/switch/index.js +1 -2
  94. package/dist/tabs/index.cjs +523 -0
  95. package/dist/tabs/index.d.cts +176 -0
  96. package/dist/tabs/index.d.ts +176 -0
  97. package/dist/tabs/index.js +438 -0
  98. package/dist/timepicker/index.cjs +1280 -0
  99. package/dist/timepicker/index.d.cts +215 -0
  100. package/dist/timepicker/index.d.ts +215 -0
  101. package/dist/timepicker/index.js +1181 -0
  102. package/dist/toolbar/index.cjs +395 -0
  103. package/dist/toolbar/index.d.cts +100 -0
  104. package/dist/toolbar/index.d.ts +100 -0
  105. package/dist/toolbar/index.js +325 -0
  106. package/dist/typography/index.js +1 -2
  107. package/dist/view/index.cjs +16 -2
  108. package/dist/view/index.js +16 -2
  109. package/package.json +73 -8
  110. package/dist/button.type-D8tzEBo7.d.ts +0 -104
  111. package/dist/button.type-ikaWzhIg.d.cts +0 -104
  112. package/dist/chunk-GBHQCAKW.js +0 -19
  113. package/dist/chunk-JEGEPGVU.js +0 -287
@@ -0,0 +1,1026 @@
1
+ // src/components/chart/donut-chart-card.tsx
2
+ import React from "react";
3
+ import { Text, View } from "react-native";
4
+ import Svg, { Circle } from "react-native-svg";
5
+
6
+ // src/components/chart/chart.style.ts
7
+ import { StyleSheet } from "react-native";
8
+ var styles = StyleSheet.create({
9
+ card: {
10
+ borderRadius: 22,
11
+ paddingHorizontal: 20,
12
+ paddingVertical: 18,
13
+ width: "100%"
14
+ },
15
+ contentVertical: {
16
+ flexDirection: "column",
17
+ alignItems: "center",
18
+ gap: 20
19
+ },
20
+ contentHorizontal: {
21
+ flexDirection: "row",
22
+ alignItems: "center",
23
+ justifyContent: "space-between",
24
+ gap: 18
25
+ },
26
+ pieContentVertical: {
27
+ flexDirection: "column",
28
+ alignItems: "center",
29
+ gap: 0
30
+ },
31
+ pieContentHorizontal: {
32
+ flexDirection: "row",
33
+ alignItems: "center",
34
+ justifyContent: "space-between",
35
+ gap: 0
36
+ },
37
+ chartWrapper: {
38
+ alignItems: "center",
39
+ justifyContent: "center"
40
+ },
41
+ pieHeader: {
42
+ width: "100%",
43
+ flexDirection: "row",
44
+ alignItems: "center",
45
+ justifyContent: "space-between",
46
+ marginBottom: 10
47
+ },
48
+ pieHeaderTitle: {
49
+ fontSize: 16,
50
+ fontWeight: "600",
51
+ flex: 1
52
+ },
53
+ pieHeaderTotal: {
54
+ fontSize: 16,
55
+ fontWeight: "600",
56
+ marginLeft: 12,
57
+ textAlign: "right"
58
+ },
59
+ centerContent: {
60
+ position: "absolute",
61
+ alignItems: "center",
62
+ justifyContent: "center",
63
+ width: "62%"
64
+ },
65
+ centerTitle: {
66
+ fontSize: 17,
67
+ color: "#aeb7c2",
68
+ fontWeight: "500",
69
+ textAlign: "center",
70
+ includeFontPadding: false
71
+ },
72
+ centerTotal: {
73
+ marginTop: 6,
74
+ fontSize: 44,
75
+ fontWeight: "600",
76
+ color: "#ffffff",
77
+ lineHeight: 50,
78
+ includeFontPadding: false
79
+ },
80
+ legend: {
81
+ width: "100%",
82
+ gap: 10
83
+ },
84
+ legendCompact: {
85
+ width: "auto",
86
+ minWidth: 180,
87
+ flexShrink: 1
88
+ },
89
+ legendItem: {
90
+ flexDirection: "row",
91
+ alignItems: "center",
92
+ justifyContent: "space-between",
93
+ gap: 14
94
+ },
95
+ legendLeft: {
96
+ flexDirection: "row",
97
+ alignItems: "center",
98
+ gap: 10,
99
+ flex: 1
100
+ },
101
+ legendDot: {
102
+ width: 14,
103
+ height: 14,
104
+ borderRadius: 14
105
+ },
106
+ legendTitle: {
107
+ fontSize: 16,
108
+ fontWeight: "500",
109
+ color: "#f4f6f8",
110
+ flexShrink: 1
111
+ },
112
+ legendValue: {
113
+ fontSize: 16,
114
+ fontWeight: "500",
115
+ color: "#ffffff",
116
+ minWidth: 34,
117
+ textAlign: "right"
118
+ },
119
+ barCard: {
120
+ borderRadius: 22,
121
+ paddingHorizontal: 18,
122
+ paddingTop: 16,
123
+ paddingBottom: 14,
124
+ width: "100%"
125
+ },
126
+ barTitle: {
127
+ fontSize: 16,
128
+ fontWeight: "600",
129
+ marginBottom: 14
130
+ },
131
+ barChartRow: {
132
+ flexDirection: "row",
133
+ alignItems: "stretch",
134
+ marginTop: 15
135
+ },
136
+ yAxis: {
137
+ width: 44,
138
+ justifyContent: "space-between",
139
+ paddingRight: 8
140
+ },
141
+ yAxisLabel: {
142
+ fontSize: 12,
143
+ fontWeight: "500",
144
+ textAlign: "right"
145
+ },
146
+ chartAndLabels: {
147
+ flex: 1
148
+ },
149
+ xAxisRow: {
150
+ flexDirection: "row",
151
+ alignItems: "flex-start",
152
+ marginTop: 8
153
+ },
154
+ xAxisLabel: {
155
+ fontSize: 12,
156
+ fontWeight: "500",
157
+ textAlign: "center",
158
+ includeFontPadding: false
159
+ },
160
+ legendBelow: {
161
+ marginTop: 20,
162
+ flexDirection: "row",
163
+ flexWrap: "wrap",
164
+ gap: 8
165
+ },
166
+ legendBelowItem: {
167
+ flexDirection: "row",
168
+ alignItems: "center",
169
+ gap: 6,
170
+ marginRight: 12
171
+ },
172
+ legendBelowDot: {
173
+ width: 8,
174
+ height: 8,
175
+ borderRadius: 8
176
+ },
177
+ legendBelowText: {
178
+ fontSize: 12,
179
+ fontWeight: "500"
180
+ },
181
+ legendBelowValue: {
182
+ fontSize: 12,
183
+ fontWeight: "600",
184
+ marginLeft: 2
185
+ },
186
+ lineChartArea: {
187
+ flex: 1
188
+ },
189
+ lineChartGrid: {
190
+ position: "absolute",
191
+ left: 0,
192
+ right: 0,
193
+ height: 1,
194
+ backgroundColor: "rgba(255,255,255,0.12)"
195
+ },
196
+ chartHeader: {
197
+ width: "100%",
198
+ marginBottom: 16
199
+ },
200
+ chartTitle: {
201
+ fontSize: 16,
202
+ fontWeight: "600"
203
+ },
204
+ heatmapContainer: {
205
+ alignItems: "flex-start"
206
+ },
207
+ heatmapGrid: {
208
+ flexDirection: "row",
209
+ alignItems: "center"
210
+ },
211
+ heatmapRow: {
212
+ flexDirection: "row",
213
+ alignItems: "center"
214
+ },
215
+ heatmapCell: {
216
+ alignItems: "center",
217
+ justifyContent: "center",
218
+ borderRadius: 4
219
+ },
220
+ heatmapCellText: {
221
+ fontSize: 10,
222
+ fontWeight: "600",
223
+ color: "#ffffff"
224
+ },
225
+ heatmapXLabel: {
226
+ alignItems: "center",
227
+ justifyContent: "center"
228
+ },
229
+ heatmapYLabel: {
230
+ alignItems: "flex-end",
231
+ justifyContent: "center",
232
+ paddingRight: 4
233
+ },
234
+ heatmapLabelText: {
235
+ fontSize: 12,
236
+ fontWeight: "500"
237
+ },
238
+ heatmapLegend: {
239
+ marginTop: 20,
240
+ width: "100%"
241
+ },
242
+ heatmapLegendGradient: {
243
+ flexDirection: "row",
244
+ justifyContent: "space-between",
245
+ gap: 8
246
+ },
247
+ heatmapLegendItem: {
248
+ alignItems: "center",
249
+ gap: 6
250
+ },
251
+ heatmapLegendBox: {
252
+ width: 24,
253
+ height: 24,
254
+ borderRadius: 4
255
+ },
256
+ heatmapLegendValue: {
257
+ fontSize: 11,
258
+ fontWeight: "500"
259
+ }
260
+ });
261
+
262
+ // src/components/chart/chart.shared.ts
263
+ var DEFAULT_CHART_BACKGROUND = "#6a6a6a30";
264
+ var resolveElevationStyles = (elevation) => {
265
+ if (elevation <= 0) {
266
+ return {
267
+ shadowOpacity: 0,
268
+ elevation: 0
269
+ };
270
+ }
271
+ return {
272
+ shadowColor: "#000000",
273
+ shadowOpacity: Math.min(0.18 + elevation * 0.04, 0.34),
274
+ shadowOffset: {
275
+ width: 0,
276
+ height: elevation * 2
277
+ },
278
+ shadowRadius: 6 + elevation * 2,
279
+ elevation
280
+ };
281
+ };
282
+ var formatAxisValue = (value) => {
283
+ if (Number.isInteger(value)) {
284
+ return `${value}`;
285
+ }
286
+ return value.toFixed(1);
287
+ };
288
+ var abbreviateLabel = (label, length) => {
289
+ const compact = label.trim();
290
+ if (compact.length <= length) {
291
+ return compact;
292
+ }
293
+ return `${compact.slice(0, length)}.`;
294
+ };
295
+ var isLegendHorizontal = (position) => position === "left" || position === "right";
296
+
297
+ // src/components/chart/donut-chart-card.tsx
298
+ var DonutChartCard = ({
299
+ data,
300
+ showLegend = true,
301
+ legendPosition = "top",
302
+ total,
303
+ title,
304
+ elevation = 0,
305
+ backgroundColor = DEFAULT_CHART_BACKGROUND,
306
+ textColor = "#ffffff",
307
+ size = 250,
308
+ strokeWidth,
309
+ style
310
+ }) => {
311
+ const normalizedData = React.useMemo(
312
+ () => data.filter((item) => item.value > 0),
313
+ [data]
314
+ );
315
+ const totalValue = React.useMemo(
316
+ () => normalizedData.reduce((sum, item) => sum + item.value, 0),
317
+ [normalizedData]
318
+ );
319
+ const effectiveStrokeWidth = React.useMemo(() => {
320
+ const autoStroke = Math.max(8, Math.min(24, Math.round(size * 0.082)));
321
+ if (strokeWidth === void 0) {
322
+ return autoStroke;
323
+ }
324
+ return Math.max(6, Math.min(strokeWidth, Math.round(size * 0.22)));
325
+ }, [size, strokeWidth]);
326
+ const radius = React.useMemo(
327
+ () => (size - effectiveStrokeWidth) / 2,
328
+ [effectiveStrokeWidth, size]
329
+ );
330
+ const circumference = React.useMemo(() => 2 * Math.PI * radius, [radius]);
331
+ const internalGapDegrees = React.useMemo(
332
+ () => Math.max(6.5, Math.min(12.5, 8.1 * (250 / size))),
333
+ [size]
334
+ );
335
+ const centerTitleFontSize = React.useMemo(
336
+ () => Math.max(12, Math.round(size * 0.058)),
337
+ [size]
338
+ );
339
+ const centerTotalFontSize = React.useMemo(
340
+ () => Math.max(24, Math.round(size * 0.128)),
341
+ [size]
342
+ );
343
+ const segments = React.useMemo(() => {
344
+ if (!normalizedData.length || totalValue <= 0) {
345
+ return [];
346
+ }
347
+ const requestedGap = internalGapDegrees / 360 * circumference;
348
+ const capCompensation = effectiveStrokeWidth * 0.66;
349
+ const maxGap = circumference / (normalizedData.length * 1.55);
350
+ const gapLength = Math.min(requestedGap + capCompensation, maxGap);
351
+ const availableArcLength = circumference - normalizedData.length * gapLength;
352
+ let offset = 0;
353
+ return normalizedData.map((item, index) => {
354
+ const segmentLength = item.value / totalValue * availableArcLength;
355
+ const segment = {
356
+ key: `${item.label}-${index}`,
357
+ color: item.color,
358
+ strokeDasharray: `${segmentLength} ${circumference}`,
359
+ strokeDashoffset: -offset
360
+ };
361
+ offset += segmentLength + gapLength;
362
+ return segment;
363
+ });
364
+ }, [
365
+ circumference,
366
+ effectiveStrokeWidth,
367
+ internalGapDegrees,
368
+ normalizedData,
369
+ totalValue
370
+ ]);
371
+ const chart = /* @__PURE__ */ React.createElement(View, { style: [styles.chartWrapper, { width: size, height: size }] }, /* @__PURE__ */ React.createElement(Svg, { width: size, height: size }, /* @__PURE__ */ React.createElement(
372
+ Circle,
373
+ {
374
+ cx: size / 2,
375
+ cy: size / 2,
376
+ r: radius,
377
+ stroke: "rgba(255,255,255,0.06)",
378
+ strokeWidth: effectiveStrokeWidth,
379
+ fill: "none"
380
+ }
381
+ ), /* @__PURE__ */ React.createElement(
382
+ Svg,
383
+ {
384
+ width: size,
385
+ height: size,
386
+ style: { transform: [{ rotate: "-90deg" }] }
387
+ },
388
+ segments.map((segment) => /* @__PURE__ */ React.createElement(
389
+ Circle,
390
+ {
391
+ key: segment.key,
392
+ cx: size / 2,
393
+ cy: size / 2,
394
+ r: radius,
395
+ stroke: segment.color,
396
+ strokeWidth: effectiveStrokeWidth,
397
+ strokeDasharray: segment.strokeDasharray,
398
+ strokeDashoffset: segment.strokeDashoffset,
399
+ strokeLinecap: "round",
400
+ fill: "none"
401
+ }
402
+ ))
403
+ )), (title !== void 0 || total !== void 0) && /* @__PURE__ */ React.createElement(View, { style: styles.centerContent, pointerEvents: "none" }, title !== void 0 && /* @__PURE__ */ React.createElement(
404
+ Text,
405
+ {
406
+ style: [
407
+ styles.centerTitle,
408
+ { fontSize: centerTitleFontSize, color: textColor }
409
+ ]
410
+ },
411
+ title
412
+ ), total !== void 0 && /* @__PURE__ */ React.createElement(
413
+ Text,
414
+ {
415
+ style: [
416
+ styles.centerTotal,
417
+ {
418
+ color: textColor,
419
+ fontSize: centerTotalFontSize,
420
+ lineHeight: Math.round(centerTotalFontSize * 1.14)
421
+ }
422
+ ]
423
+ },
424
+ total
425
+ )));
426
+ const legend = showLegend ? /* @__PURE__ */ React.createElement(
427
+ View,
428
+ {
429
+ style: [
430
+ styles.legend,
431
+ isLegendHorizontal(legendPosition) && styles.legendCompact
432
+ ]
433
+ },
434
+ data.map((item, index) => /* @__PURE__ */ React.createElement(View, { style: styles.legendItem, key: `${item.label}-${index}-legend` }, /* @__PURE__ */ React.createElement(View, { style: styles.legendLeft }, /* @__PURE__ */ React.createElement(View, { style: [styles.legendDot, { backgroundColor: item.color }] }), /* @__PURE__ */ React.createElement(
435
+ Text,
436
+ {
437
+ style: [styles.legendTitle, { color: item.labelColor ?? textColor }]
438
+ },
439
+ item.label
440
+ )), /* @__PURE__ */ React.createElement(Text, { style: [styles.legendValue, { color: textColor }] }, item.value)))
441
+ ) : null;
442
+ const content = isLegendHorizontal(legendPosition) ? /* @__PURE__ */ React.createElement(View, { style: styles.contentHorizontal }, legendPosition === "left" && legend, chart, legendPosition === "right" && legend) : /* @__PURE__ */ React.createElement(View, { style: styles.contentVertical }, legendPosition === "top" && legend, chart, legendPosition === "bottom" && legend);
443
+ return /* @__PURE__ */ React.createElement(
444
+ View,
445
+ {
446
+ style: [
447
+ styles.barCard,
448
+ { backgroundColor },
449
+ resolveElevationStyles(elevation),
450
+ style
451
+ ]
452
+ },
453
+ content
454
+ );
455
+ };
456
+
457
+ // src/components/chart/vertical-bar-chart-card.tsx
458
+ import React2 from "react";
459
+ import { Text as Text2, View as View2 } from "react-native";
460
+ var VerticalBarChartCard = ({
461
+ data,
462
+ title,
463
+ elevation = 0,
464
+ backgroundColor = DEFAULT_CHART_BACKGROUND,
465
+ textColor = "#ffffff",
466
+ size = 260,
467
+ showAxes = true,
468
+ abbreviateXAxisLabels = true,
469
+ xAxisAbbreviationLength = 3,
470
+ showFullLegendBelow = true,
471
+ justifyBars = true,
472
+ style
473
+ }) => {
474
+ const normalizedData = React2.useMemo(
475
+ () => data.filter((item) => item.value >= 0),
476
+ [data]
477
+ );
478
+ const minValue = React2.useMemo(() => {
479
+ if (!normalizedData.length) {
480
+ return 0;
481
+ }
482
+ return Math.min(...normalizedData.map((item) => item.value));
483
+ }, [normalizedData]);
484
+ const maxValue = React2.useMemo(() => {
485
+ if (!normalizedData.length) {
486
+ return 1;
487
+ }
488
+ return Math.max(...normalizedData.map((item) => item.value), 1);
489
+ }, [normalizedData]);
490
+ const meanValue = React2.useMemo(() => {
491
+ if (!normalizedData.length) {
492
+ return 0;
493
+ }
494
+ const total = normalizedData.reduce((sum, item) => sum + item.value, 0);
495
+ return total / normalizedData.length;
496
+ }, [normalizedData]);
497
+ const chartWidth = Math.max(170, size);
498
+ const chartHeight = Math.max(130, Math.min(220, Math.round(size * 0.56)));
499
+ const horizontalPadding = justifyBars ? 0 : Math.max(10, Math.round(size * 0.045));
500
+ const barsCount = Math.max(normalizedData.length, 1);
501
+ const usableWidth = chartWidth - horizontalPadding * 2;
502
+ const slotWidth = usableWidth / barsCount;
503
+ const dynamicBarWidth = Math.max(8, Math.min(30, slotWidth * 0.52));
504
+ const cornerRadius = Math.min(dynamicBarWidth / 2, 10);
505
+ const graphHeight = chartHeight - 8;
506
+ return /* @__PURE__ */ React2.createElement(
507
+ View2,
508
+ {
509
+ style: [
510
+ styles.barCard,
511
+ { backgroundColor },
512
+ resolveElevationStyles(elevation),
513
+ style
514
+ ]
515
+ },
516
+ title !== void 0 && /* @__PURE__ */ React2.createElement(Text2, { style: [styles.barTitle, { color: textColor }] }, title),
517
+ /* @__PURE__ */ React2.createElement(View2, { style: styles.barChartRow }, showAxes && /* @__PURE__ */ React2.createElement(View2, { style: [styles.yAxis, { height: chartHeight }] }, /* @__PURE__ */ React2.createElement(Text2, { style: [styles.yAxisLabel, { color: textColor }] }, formatAxisValue(maxValue)), /* @__PURE__ */ React2.createElement(Text2, { style: [styles.yAxisLabel, { color: textColor }] }, formatAxisValue(meanValue)), /* @__PURE__ */ React2.createElement(Text2, { style: [styles.yAxisLabel, { color: textColor }] }, formatAxisValue(minValue))), /* @__PURE__ */ React2.createElement(View2, { style: styles.chartAndLabels }, /* @__PURE__ */ React2.createElement(
518
+ View2,
519
+ {
520
+ style: {
521
+ width: chartWidth,
522
+ height: chartHeight,
523
+ position: "relative",
524
+ justifyContent: "flex-end"
525
+ }
526
+ },
527
+ showAxes && /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(
528
+ View2,
529
+ {
530
+ style: {
531
+ position: "absolute",
532
+ left: 0,
533
+ right: 0,
534
+ top: 0,
535
+ height: 1,
536
+ backgroundColor: "rgba(255,255,255,0.15)"
537
+ }
538
+ }
539
+ ), /* @__PURE__ */ React2.createElement(
540
+ View2,
541
+ {
542
+ style: {
543
+ position: "absolute",
544
+ left: 0,
545
+ right: 0,
546
+ top: Math.round((chartHeight - 1) / 2),
547
+ height: 1,
548
+ backgroundColor: "rgba(255,255,255,0.12)"
549
+ }
550
+ }
551
+ ), /* @__PURE__ */ React2.createElement(
552
+ View2,
553
+ {
554
+ style: {
555
+ position: "absolute",
556
+ left: 0,
557
+ right: 0,
558
+ bottom: 0,
559
+ height: 1,
560
+ backgroundColor: "rgba(255,255,255,0.15)"
561
+ }
562
+ }
563
+ )),
564
+ /* @__PURE__ */ React2.createElement(
565
+ View2,
566
+ {
567
+ style: {
568
+ flexDirection: "row",
569
+ alignItems: "flex-end",
570
+ height: chartHeight,
571
+ paddingHorizontal: horizontalPadding,
572
+ justifyContent: justifyBars ? "space-between" : "flex-start"
573
+ }
574
+ },
575
+ normalizedData.map((item, index) => {
576
+ const valueRatio = Math.max(0, Math.min(1, item.value / maxValue));
577
+ const barHeight = Math.max(2, Math.round(valueRatio * graphHeight));
578
+ return /* @__PURE__ */ React2.createElement(
579
+ View2,
580
+ {
581
+ key: `${item.label}-${index}-bar`,
582
+ style: {
583
+ width: slotWidth,
584
+ height: "100%",
585
+ alignItems: "center",
586
+ justifyContent: "flex-end"
587
+ }
588
+ },
589
+ /* @__PURE__ */ React2.createElement(
590
+ View2,
591
+ {
592
+ style: {
593
+ width: dynamicBarWidth,
594
+ height: barHeight,
595
+ borderRadius: cornerRadius,
596
+ backgroundColor: item.color ?? "#57C9ED"
597
+ }
598
+ }
599
+ )
600
+ );
601
+ })
602
+ )
603
+ ), /* @__PURE__ */ React2.createElement(View2, { style: [styles.xAxisRow, { width: chartWidth }] }, normalizedData.map((item, index) => /* @__PURE__ */ React2.createElement(View2, { key: `${item.label}-${index}-x`, style: { width: slotWidth } }, /* @__PURE__ */ React2.createElement(Text2, { style: [styles.xAxisLabel, { color: textColor }] }, abbreviateXAxisLabels ? abbreviateLabel(item.label, xAxisAbbreviationLength) : item.label)))))),
604
+ showFullLegendBelow && /* @__PURE__ */ React2.createElement(View2, { style: [styles.legend, { marginTop: 18 }] }, normalizedData.map((item, index) => /* @__PURE__ */ React2.createElement(View2, { key: `${item.label}-${index}-legend`, style: styles.legendItem }, /* @__PURE__ */ React2.createElement(View2, { style: styles.legendLeft }, /* @__PURE__ */ React2.createElement(
605
+ View2,
606
+ {
607
+ style: [
608
+ styles.legendDot,
609
+ { backgroundColor: item.color ?? "#57C9ED" }
610
+ ]
611
+ }
612
+ ), /* @__PURE__ */ React2.createElement(Text2, { style: [styles.legendTitle, { color: textColor }] }, item.label)), /* @__PURE__ */ React2.createElement(Text2, { style: [styles.legendValue, { color: textColor }] }, item.value))))
613
+ );
614
+ };
615
+
616
+ // src/components/chart/pie-chart-card.tsx
617
+ import React3 from "react";
618
+ import { Text as Text3, View as View3 } from "react-native";
619
+ import Svg2, { Circle as Circle2 } from "react-native-svg";
620
+ import * as SvgElements from "react-native-svg";
621
+ var polarToCartesian = (centerX, centerY, radius, angleInDegrees) => {
622
+ const angleInRadians = (angleInDegrees - 90) * Math.PI / 180;
623
+ return {
624
+ x: centerX + radius * Math.cos(angleInRadians),
625
+ y: centerY + radius * Math.sin(angleInRadians)
626
+ };
627
+ };
628
+ var createSectorPath = (centerX, centerY, radius, startAngle, endAngle) => {
629
+ const start = polarToCartesian(centerX, centerY, radius, endAngle);
630
+ const end = polarToCartesian(centerX, centerY, radius, startAngle);
631
+ const largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1";
632
+ return [
633
+ `M ${centerX} ${centerY}`,
634
+ `L ${start.x} ${start.y}`,
635
+ `A ${radius} ${radius} 0 ${largeArcFlag} 0 ${end.x} ${end.y}`,
636
+ "Z"
637
+ ].join(" ");
638
+ };
639
+ var PieChartCard = ({
640
+ data,
641
+ title,
642
+ total,
643
+ showLegend = true,
644
+ legendPosition = "bottom",
645
+ elevation = 0,
646
+ backgroundColor = DEFAULT_CHART_BACKGROUND,
647
+ textColor = "#ffffff",
648
+ size = 220,
649
+ style
650
+ }) => {
651
+ const normalizedData = React3.useMemo(
652
+ () => data.filter((item) => item.value > 0),
653
+ [data]
654
+ );
655
+ const totalValue = React3.useMemo(
656
+ () => normalizedData.reduce((sum, item) => sum + item.value, 0),
657
+ [normalizedData]
658
+ );
659
+ const chartSize = Math.max(120, size);
660
+ const center = chartSize / 2;
661
+ const radius = chartSize * 0.44;
662
+ const gapDegrees = 1;
663
+ const sectors = React3.useMemo(() => {
664
+ if (!normalizedData.length || totalValue <= 0) {
665
+ return [];
666
+ }
667
+ let startAngle = 0;
668
+ return normalizedData.map((item, index) => {
669
+ const portion = item.value / totalValue * 360;
670
+ const sweep = Math.max(0, portion - gapDegrees);
671
+ const endAngle = startAngle + sweep;
672
+ const path = createSectorPath(center, center, radius, startAngle, endAngle);
673
+ startAngle += portion;
674
+ return {
675
+ key: `${item.label}-${index}-sector`,
676
+ color: item.color,
677
+ path
678
+ };
679
+ });
680
+ }, [center, gapDegrees, normalizedData, radius, totalValue]);
681
+ const PathElement = SvgElements.Path;
682
+ const chart = /* @__PURE__ */ React3.createElement(View3, { style: [styles.chartWrapper, { width: chartSize, height: chartSize }] }, /* @__PURE__ */ React3.createElement(Svg2, { width: chartSize, height: chartSize }, PathElement ? sectors.map((sector) => /* @__PURE__ */ React3.createElement(PathElement, { key: sector.key, d: sector.path, fill: sector.color })) : sectors.map((sector, index) => /* @__PURE__ */ React3.createElement(
683
+ Circle2,
684
+ {
685
+ key: `${sector.key}-fallback`,
686
+ cx: chartSize / 2,
687
+ cy: chartSize / 2,
688
+ r: Math.max(8, radius - index * 8),
689
+ fill: sector.color
690
+ }
691
+ ))));
692
+ const legend = showLegend ? /* @__PURE__ */ React3.createElement(
693
+ View3,
694
+ {
695
+ style: [
696
+ styles.legend,
697
+ isLegendHorizontal(legendPosition) && styles.legendCompact
698
+ ]
699
+ },
700
+ data.map((item, index) => /* @__PURE__ */ React3.createElement(View3, { style: styles.legendItem, key: `${item.label}-${index}-legend` }, /* @__PURE__ */ React3.createElement(View3, { style: styles.legendLeft }, /* @__PURE__ */ React3.createElement(View3, { style: [styles.legendDot, { backgroundColor: item.color }] }), /* @__PURE__ */ React3.createElement(
701
+ Text3,
702
+ {
703
+ style: [styles.legendTitle, { color: item.labelColor ?? textColor }]
704
+ },
705
+ item.label
706
+ )), /* @__PURE__ */ React3.createElement(Text3, { style: [styles.legendValue, { color: textColor }] }, item.value)))
707
+ ) : null;
708
+ const content = isLegendHorizontal(legendPosition) ? /* @__PURE__ */ React3.createElement(View3, { style: styles.pieContentHorizontal }, legendPosition === "left" && legend, chart, legendPosition === "right" && legend) : /* @__PURE__ */ React3.createElement(View3, { style: styles.pieContentVertical }, legendPosition === "top" && legend, chart, legendPosition === "bottom" && legend);
709
+ return /* @__PURE__ */ React3.createElement(
710
+ View3,
711
+ {
712
+ style: [
713
+ styles.card,
714
+ { backgroundColor },
715
+ resolveElevationStyles(elevation),
716
+ style
717
+ ]
718
+ },
719
+ (title !== void 0 || total !== void 0) && /* @__PURE__ */ React3.createElement(View3, { style: styles.pieHeader }, /* @__PURE__ */ React3.createElement(Text3, { style: [styles.pieHeaderTitle, { color: textColor }] }, title ?? ""), /* @__PURE__ */ React3.createElement(Text3, { style: [styles.pieHeaderTotal, { color: textColor }] }, total ?? "")),
720
+ content
721
+ );
722
+ };
723
+
724
+ // src/components/chart/line-chart-card.tsx
725
+ import React4 from "react";
726
+ import { Text as Text4, View as View4 } from "react-native";
727
+ import Svg3, { Circle as Circle3 } from "react-native-svg";
728
+ import * as SvgElements2 from "react-native-svg";
729
+ var buildSmoothPath = (points) => {
730
+ if (points.length < 2) {
731
+ return "";
732
+ }
733
+ let path = `M ${points[0].x} ${points[0].y}`;
734
+ for (let index = 1; index < points.length; index += 1) {
735
+ const prev = points[index - 1];
736
+ const current = points[index];
737
+ const controlX = (prev.x + current.x) / 2;
738
+ path += ` C ${controlX} ${prev.y}, ${controlX} ${current.y}, ${current.x} ${current.y}`;
739
+ }
740
+ return path;
741
+ };
742
+ var buildDirectPath = (points) => {
743
+ if (!points.length) {
744
+ return "";
745
+ }
746
+ const [first, ...rest] = points;
747
+ return rest.reduce(
748
+ (path, point) => `${path} L ${point.x} ${point.y}`,
749
+ `M ${first.x} ${first.y}`
750
+ );
751
+ };
752
+ var LineChartCard = ({
753
+ data,
754
+ title,
755
+ elevation = 0,
756
+ backgroundColor = DEFAULT_CHART_BACKGROUND,
757
+ textColor = "#ffffff",
758
+ size = 280,
759
+ showAxes = true,
760
+ showPoints = true,
761
+ lineMode = "smooth",
762
+ lineColor = "#57C9ED",
763
+ areaColor = "rgba(87,201,237,0.16)",
764
+ abbreviateXAxisLabels = true,
765
+ xAxisAbbreviationLength = 3,
766
+ style
767
+ }) => {
768
+ const normalizedData = React4.useMemo(
769
+ () => data.filter((item) => Number.isFinite(item.value)),
770
+ [data]
771
+ );
772
+ const minValue = React4.useMemo(() => {
773
+ if (!normalizedData.length) {
774
+ return 0;
775
+ }
776
+ return Math.min(...normalizedData.map((item) => item.value));
777
+ }, [normalizedData]);
778
+ const maxValue = React4.useMemo(() => {
779
+ if (!normalizedData.length) {
780
+ return 1;
781
+ }
782
+ return Math.max(...normalizedData.map((item) => item.value), 1);
783
+ }, [normalizedData]);
784
+ const meanValue = React4.useMemo(() => {
785
+ if (!normalizedData.length) {
786
+ return 0;
787
+ }
788
+ return normalizedData.reduce((sum, item) => sum + item.value, 0) / normalizedData.length;
789
+ }, [normalizedData]);
790
+ const chartWidth = Math.max(190, size);
791
+ const chartHeight = Math.max(130, Math.min(220, Math.round(size * 0.56)));
792
+ const paddingX = Math.max(10, Math.round(size * 0.05));
793
+ const rightPadding = paddingX + 8;
794
+ const graphHeight = chartHeight - 10;
795
+ const dataRange = Math.max(1, maxValue - minValue);
796
+ const points = React4.useMemo(() => {
797
+ if (!normalizedData.length) {
798
+ return [];
799
+ }
800
+ const slots = Math.max(normalizedData.length - 1, 1);
801
+ return normalizedData.map((item, index) => {
802
+ const x = paddingX + index * (chartWidth - paddingX - rightPadding) / slots;
803
+ const ratio = (item.value - minValue) / dataRange;
804
+ const y = graphHeight - ratio * graphHeight;
805
+ return { x, y };
806
+ });
807
+ }, [
808
+ chartWidth,
809
+ dataRange,
810
+ graphHeight,
811
+ minValue,
812
+ normalizedData,
813
+ paddingX,
814
+ rightPadding
815
+ ]);
816
+ const linePath = lineMode === "smooth" ? buildSmoothPath(points) : buildDirectPath(points);
817
+ const areaPath = points.length ? `${linePath} L ${points[points.length - 1].x} ${graphHeight} L ${points[0].x} ${graphHeight} Z` : "";
818
+ const PathElement = SvgElements2.Path;
819
+ return /* @__PURE__ */ React4.createElement(
820
+ View4,
821
+ {
822
+ style: [
823
+ styles.barCard,
824
+ { backgroundColor },
825
+ resolveElevationStyles(elevation),
826
+ style
827
+ ]
828
+ },
829
+ title !== void 0 && /* @__PURE__ */ React4.createElement(Text4, { style: [styles.barTitle, { color: textColor }] }, title),
830
+ /* @__PURE__ */ React4.createElement(View4, { style: styles.barChartRow }, showAxes && /* @__PURE__ */ React4.createElement(View4, { style: styles.yAxis }, /* @__PURE__ */ React4.createElement(Text4, { style: [styles.yAxisLabel, { color: textColor }] }, formatAxisValue(maxValue)), /* @__PURE__ */ React4.createElement(Text4, { style: [styles.yAxisLabel, { color: textColor }] }, formatAxisValue(meanValue)), /* @__PURE__ */ React4.createElement(Text4, { style: [styles.yAxisLabel, { color: textColor }] }, formatAxisValue(minValue))), /* @__PURE__ */ React4.createElement(View4, { style: styles.chartAndLabels }, /* @__PURE__ */ React4.createElement(
831
+ View4,
832
+ {
833
+ style: [
834
+ styles.lineChartArea,
835
+ { width: chartWidth, height: chartHeight }
836
+ ]
837
+ },
838
+ showAxes && /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(View4, { style: [styles.lineChartGrid, { top: 0 }] }), /* @__PURE__ */ React4.createElement(
839
+ View4,
840
+ {
841
+ style: [
842
+ styles.lineChartGrid,
843
+ { top: Math.round(chartHeight / 2) }
844
+ ]
845
+ }
846
+ ), /* @__PURE__ */ React4.createElement(View4, { style: [styles.lineChartGrid, { top: chartHeight - 1 }] })),
847
+ /* @__PURE__ */ React4.createElement(Svg3, { width: chartWidth, height: chartHeight }, !!areaPath && (PathElement ? /* @__PURE__ */ React4.createElement(PathElement, { d: areaPath, fill: areaColor }) : null), !!linePath && (PathElement ? /* @__PURE__ */ React4.createElement(
848
+ PathElement,
849
+ {
850
+ d: linePath,
851
+ fill: "none",
852
+ stroke: lineColor,
853
+ strokeWidth: 2.5,
854
+ strokeLinecap: "round",
855
+ strokeLinejoin: "round"
856
+ }
857
+ ) : null), showPoints && points.map((point, index) => /* @__PURE__ */ React4.createElement(
858
+ Circle3,
859
+ {
860
+ key: `line-point-${index}`,
861
+ cx: point.x,
862
+ cy: point.y,
863
+ r: 3.8,
864
+ fill: lineColor
865
+ }
866
+ )))
867
+ ), /* @__PURE__ */ React4.createElement(View4, { style: [styles.xAxisRow, { width: chartWidth }] }, normalizedData.map((item, index) => /* @__PURE__ */ React4.createElement(
868
+ View4,
869
+ {
870
+ key: `${item.label}-${index}-line-x`,
871
+ style: { width: chartWidth / Math.max(normalizedData.length, 1) }
872
+ },
873
+ /* @__PURE__ */ React4.createElement(Text4, { style: [styles.xAxisLabel, { color: textColor }] }, abbreviateXAxisLabels ? abbreviateLabel(item.label, xAxisAbbreviationLength) : item.label)
874
+ )))))
875
+ );
876
+ };
877
+
878
+ // src/components/chart/heatmap-chart-card.tsx
879
+ import React5 from "react";
880
+ import { Text as Text5, View as View5 } from "react-native";
881
+ var getHeatmapColor = (value, min, max, startColor, endColor) => {
882
+ if (max === min) {
883
+ return startColor;
884
+ }
885
+ const ratio = (value - min) / (max - min);
886
+ const parseColor = (color) => {
887
+ const hex = color.replace("#", "");
888
+ return {
889
+ r: Number.parseInt(hex.substring(0, 2), 16),
890
+ g: Number.parseInt(hex.substring(2, 4), 16),
891
+ b: Number.parseInt(hex.substring(4, 6), 16)
892
+ };
893
+ };
894
+ const start = parseColor(startColor);
895
+ const end = parseColor(endColor);
896
+ const r = Math.round(start.r + (end.r - start.r) * ratio);
897
+ const g = Math.round(start.g + (end.g - start.g) * ratio);
898
+ const b = Math.round(start.b + (end.b - start.b) * ratio);
899
+ return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
900
+ };
901
+ var HeatmapChartCard = ({
902
+ data,
903
+ title,
904
+ xLabels,
905
+ yLabels,
906
+ showValues = false,
907
+ showLegend = true,
908
+ startColor = "#3B82F6",
909
+ endColor = "#EF4444",
910
+ elevation = 0,
911
+ backgroundColor = DEFAULT_CHART_BACKGROUND,
912
+ textColor = "#ffffff",
913
+ cellSize = 32,
914
+ cellGap = 4,
915
+ style
916
+ }) => {
917
+ const { minValue, maxValue } = React5.useMemo(() => {
918
+ let min = Number.POSITIVE_INFINITY;
919
+ let max = Number.NEGATIVE_INFINITY;
920
+ for (const row of data) {
921
+ for (const value of row) {
922
+ if (value < min) {
923
+ min = value;
924
+ }
925
+ if (value > max) {
926
+ max = value;
927
+ }
928
+ }
929
+ }
930
+ return { minValue: min, maxValue: max };
931
+ }, [data]);
932
+ const rows = data.length;
933
+ const cols = data[0]?.length ?? 0;
934
+ const labelWidth = 50;
935
+ const labelHeight = 30;
936
+ return /* @__PURE__ */ React5.createElement(
937
+ View5,
938
+ {
939
+ style: [
940
+ styles.card,
941
+ { backgroundColor },
942
+ resolveElevationStyles(elevation),
943
+ style
944
+ ]
945
+ },
946
+ title && /* @__PURE__ */ React5.createElement(View5, { style: styles.chartHeader }, /* @__PURE__ */ React5.createElement(Text5, { style: [styles.chartTitle, { color: textColor }] }, title)),
947
+ /* @__PURE__ */ React5.createElement(View5, { style: styles.heatmapContainer }, /* @__PURE__ */ React5.createElement(View5, { style: styles.heatmapGrid }, /* @__PURE__ */ React5.createElement(View5, { style: { width: labelWidth, height: labelHeight } }), xLabels?.map((label, index) => /* @__PURE__ */ React5.createElement(
948
+ View5,
949
+ {
950
+ key: `x-label-${index}`,
951
+ style: [
952
+ styles.heatmapXLabel,
953
+ {
954
+ width: cellSize,
955
+ height: labelHeight,
956
+ marginRight: index < cols - 1 ? cellGap : 0
957
+ }
958
+ ]
959
+ },
960
+ /* @__PURE__ */ React5.createElement(
961
+ Text5,
962
+ {
963
+ style: [styles.heatmapLabelText, { color: textColor }],
964
+ numberOfLines: 1
965
+ },
966
+ abbreviateLabel(label, 3)
967
+ )
968
+ ))), data.map((row, rowIndex) => /* @__PURE__ */ React5.createElement(View5, { key: `row-${rowIndex}`, style: styles.heatmapRow }, yLabels?.[rowIndex] && /* @__PURE__ */ React5.createElement(View5, { style: [styles.heatmapYLabel, { width: labelWidth }] }, /* @__PURE__ */ React5.createElement(
969
+ Text5,
970
+ {
971
+ style: [styles.heatmapLabelText, { color: textColor }],
972
+ numberOfLines: 1
973
+ },
974
+ abbreviateLabel(yLabels[rowIndex], 5)
975
+ )), row.map((value, colIndex) => {
976
+ const cellColor = getHeatmapColor(
977
+ value,
978
+ minValue,
979
+ maxValue,
980
+ startColor,
981
+ endColor
982
+ );
983
+ return /* @__PURE__ */ React5.createElement(
984
+ View5,
985
+ {
986
+ key: `cell-${rowIndex}-${colIndex}`,
987
+ style: [
988
+ styles.heatmapCell,
989
+ {
990
+ width: cellSize,
991
+ height: cellSize,
992
+ backgroundColor: cellColor,
993
+ marginRight: colIndex < cols - 1 ? cellGap : 0,
994
+ marginBottom: rowIndex < rows - 1 ? cellGap : 0
995
+ }
996
+ ]
997
+ },
998
+ showValues && /* @__PURE__ */ React5.createElement(Text5, { style: styles.heatmapCellText }, value)
999
+ );
1000
+ })))),
1001
+ showLegend && /* @__PURE__ */ React5.createElement(View5, { style: styles.heatmapLegend }, /* @__PURE__ */ React5.createElement(View5, { style: styles.heatmapLegendGradient }, Array.from({ length: 5 }).map((_, index) => {
1002
+ const ratio = index / 4;
1003
+ const value = minValue + (maxValue - minValue) * ratio;
1004
+ const color = getHeatmapColor(
1005
+ value,
1006
+ minValue,
1007
+ maxValue,
1008
+ startColor,
1009
+ endColor
1010
+ );
1011
+ return /* @__PURE__ */ React5.createElement(View5, { key: `legend-${index}`, style: styles.heatmapLegendItem }, /* @__PURE__ */ React5.createElement(
1012
+ View5,
1013
+ {
1014
+ style: [styles.heatmapLegendBox, { backgroundColor: color }]
1015
+ }
1016
+ ), /* @__PURE__ */ React5.createElement(Text5, { style: [styles.heatmapLegendValue, { color: textColor }] }, value.toFixed(1)));
1017
+ })))
1018
+ );
1019
+ };
1020
+ export {
1021
+ DonutChartCard,
1022
+ HeatmapChartCard,
1023
+ LineChartCard,
1024
+ PieChartCard,
1025
+ VerticalBarChartCard
1026
+ };