react-native-metrify 0.1.0-alpha.4 → 0.1.0-beta.2
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/CHANGELOG.md +82 -0
- package/README.md +249 -10
- package/dist/cjs/core/hooks/index.js +18 -0
- package/dist/cjs/core/hooks/index.js.map +1 -1
- package/dist/cjs/core/hooks/useChartAnimation.js +215 -0
- package/dist/cjs/core/hooks/useChartAnimation.js.map +1 -0
- package/dist/cjs/core/index.js +1 -0
- package/dist/cjs/core/index.js.map +1 -1
- package/dist/cjs/core/math/index.js +1 -0
- package/dist/cjs/core/math/index.js.map +1 -1
- package/dist/cjs/core/utils/dataTransform.js +331 -0
- package/dist/cjs/core/utils/dataTransform.js.map +1 -0
- package/dist/cjs/renderer-svg/paths/arc.js +3 -0
- package/dist/cjs/renderer-svg/paths/arc.js.map +1 -1
- package/dist/cjs/renderer-svg/primitives/AnimatedPath.js +5 -2
- package/dist/cjs/renderer-svg/primitives/AnimatedPath.js.map +1 -1
- package/dist/cjs/renderer-svg/primitives/AnimatedPolygon.js +51 -0
- package/dist/cjs/renderer-svg/primitives/AnimatedPolygon.js.map +1 -0
- package/dist/cjs/renderer-svg/primitives/index.js +1 -0
- package/dist/cjs/renderer-svg/primitives/index.js.map +1 -1
- package/dist/cjs/widgets/AreaChart/AreaChart.js +17 -137
- package/dist/cjs/widgets/AreaChart/AreaChart.js.map +1 -1
- package/dist/cjs/widgets/BarChart/BarChart.js +34 -3
- package/dist/cjs/widgets/BarChart/BarChart.js.map +1 -1
- package/dist/cjs/widgets/BoxPlot/BoxPlot.js +82 -19
- package/dist/cjs/widgets/BoxPlot/BoxPlot.js.map +1 -1
- package/dist/cjs/widgets/BubbleChart/BubbleChart.js +61 -3
- package/dist/cjs/widgets/BubbleChart/BubbleChart.js.map +1 -1
- package/dist/cjs/widgets/CandlestickChart/CandlestickChart.js +50 -8
- package/dist/cjs/widgets/CandlestickChart/CandlestickChart.js.map +1 -1
- package/dist/cjs/widgets/FunnelChart/FunnelChart.js +28 -2
- package/dist/cjs/widgets/FunnelChart/FunnelChart.js.map +1 -1
- package/dist/cjs/widgets/Gauge/Gauge.js +30 -12
- package/dist/cjs/widgets/Gauge/Gauge.js.map +1 -1
- package/dist/cjs/widgets/GroupedBarChart/GroupedBarChart.js +47 -5
- package/dist/cjs/widgets/GroupedBarChart/GroupedBarChart.js.map +1 -1
- package/dist/cjs/widgets/Heatmap/Heatmap.js +36 -5
- package/dist/cjs/widgets/Heatmap/Heatmap.js.map +1 -1
- package/dist/cjs/widgets/Histogram/Histogram.js +32 -2
- package/dist/cjs/widgets/Histogram/Histogram.js.map +1 -1
- package/dist/cjs/widgets/HorizontalBarChart/HorizontalBarChart.js +46 -19
- package/dist/cjs/widgets/HorizontalBarChart/HorizontalBarChart.js.map +1 -1
- package/dist/cjs/widgets/KPI/KPI.js +20 -7
- package/dist/cjs/widgets/KPI/KPI.js.map +1 -1
- package/dist/cjs/widgets/LineChart/LineChart.js +71 -6
- package/dist/cjs/widgets/LineChart/LineChart.js.map +1 -1
- package/dist/cjs/widgets/MultiLineSparkline/MultiLineSparkline.js +22 -2
- package/dist/cjs/widgets/MultiLineSparkline/MultiLineSparkline.js.map +1 -1
- package/dist/cjs/widgets/PieChart/PieChart.js +52 -2
- package/dist/cjs/widgets/PieChart/PieChart.js.map +1 -1
- package/dist/cjs/widgets/Progress/Progress.js +19 -7
- package/dist/cjs/widgets/Progress/Progress.js.map +1 -1
- package/dist/cjs/widgets/RadarChart/RadarChart.js +50 -5
- package/dist/cjs/widgets/RadarChart/RadarChart.js.map +1 -1
- package/dist/cjs/widgets/SankeyDiagram/SankeyDiagram.js +51 -6
- package/dist/cjs/widgets/SankeyDiagram/SankeyDiagram.js.map +1 -1
- package/dist/cjs/widgets/ScatterPlot/ScatterPlot.js +62 -3
- package/dist/cjs/widgets/ScatterPlot/ScatterPlot.js.map +1 -1
- package/dist/cjs/widgets/Sparkline/Sparkline.js +23 -3
- package/dist/cjs/widgets/Sparkline/Sparkline.js.map +1 -1
- package/dist/cjs/widgets/StackedBarChart/StackedBarChart.js +32 -2
- package/dist/cjs/widgets/StackedBarChart/StackedBarChart.js.map +1 -1
- package/dist/cjs/widgets/SunburstChart/SunburstChart.js +47 -2
- package/dist/cjs/widgets/SunburstChart/SunburstChart.js.map +1 -1
- package/dist/cjs/widgets/Treemap/Treemap.js +30 -4
- package/dist/cjs/widgets/Treemap/Treemap.js.map +1 -1
- package/dist/cjs/widgets/WaterfallChart/WaterfallChart.js +44 -5
- package/dist/cjs/widgets/WaterfallChart/WaterfallChart.js.map +1 -1
- package/dist/core/hooks/index.d.ts +4 -0
- package/dist/core/hooks/index.d.ts.map +1 -1
- package/dist/core/hooks/useChartAnimation.d.ts +45 -0
- package/dist/core/hooks/useChartAnimation.d.ts.map +1 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/math/index.d.ts.map +1 -1
- package/dist/core/utils/dataTransform.d.ts +209 -0
- package/dist/core/utils/dataTransform.d.ts.map +1 -0
- package/dist/esm/core/hooks/index.js +4 -0
- package/dist/esm/core/hooks/index.js.map +1 -1
- package/dist/esm/core/hooks/useChartAnimation.js +206 -0
- package/dist/esm/core/hooks/useChartAnimation.js.map +1 -0
- package/dist/esm/core/index.js +1 -0
- package/dist/esm/core/index.js.map +1 -1
- package/dist/esm/core/math/index.js +1 -0
- package/dist/esm/core/math/index.js.map +1 -1
- package/dist/esm/core/utils/dataTransform.js +309 -0
- package/dist/esm/core/utils/dataTransform.js.map +1 -0
- package/dist/esm/renderer-svg/paths/arc.js +3 -0
- package/dist/esm/renderer-svg/paths/arc.js.map +1 -1
- package/dist/esm/renderer-svg/primitives/AnimatedPath.js +5 -2
- package/dist/esm/renderer-svg/primitives/AnimatedPath.js.map +1 -1
- package/dist/esm/renderer-svg/primitives/AnimatedPolygon.js +12 -0
- package/dist/esm/renderer-svg/primitives/AnimatedPolygon.js.map +1 -0
- package/dist/esm/renderer-svg/primitives/index.js +1 -0
- package/dist/esm/renderer-svg/primitives/index.js.map +1 -1
- package/dist/esm/widgets/AreaChart/AreaChart.js +18 -138
- package/dist/esm/widgets/AreaChart/AreaChart.js.map +1 -1
- package/dist/esm/widgets/BarChart/BarChart.js +35 -4
- package/dist/esm/widgets/BarChart/BarChart.js.map +1 -1
- package/dist/esm/widgets/BoxPlot/BoxPlot.js +83 -20
- package/dist/esm/widgets/BoxPlot/BoxPlot.js.map +1 -1
- package/dist/esm/widgets/BubbleChart/BubbleChart.js +62 -4
- package/dist/esm/widgets/BubbleChart/BubbleChart.js.map +1 -1
- package/dist/esm/widgets/CandlestickChart/CandlestickChart.js +51 -9
- package/dist/esm/widgets/CandlestickChart/CandlestickChart.js.map +1 -1
- package/dist/esm/widgets/FunnelChart/FunnelChart.js +29 -3
- package/dist/esm/widgets/FunnelChart/FunnelChart.js.map +1 -1
- package/dist/esm/widgets/Gauge/Gauge.js +31 -13
- package/dist/esm/widgets/Gauge/Gauge.js.map +1 -1
- package/dist/esm/widgets/GroupedBarChart/GroupedBarChart.js +48 -6
- package/dist/esm/widgets/GroupedBarChart/GroupedBarChart.js.map +1 -1
- package/dist/esm/widgets/Heatmap/Heatmap.js +37 -6
- package/dist/esm/widgets/Heatmap/Heatmap.js.map +1 -1
- package/dist/esm/widgets/Histogram/Histogram.js +33 -3
- package/dist/esm/widgets/Histogram/Histogram.js.map +1 -1
- package/dist/esm/widgets/HorizontalBarChart/HorizontalBarChart.js +47 -20
- package/dist/esm/widgets/HorizontalBarChart/HorizontalBarChart.js.map +1 -1
- package/dist/esm/widgets/KPI/KPI.js +21 -8
- package/dist/esm/widgets/KPI/KPI.js.map +1 -1
- package/dist/esm/widgets/LineChart/LineChart.js +74 -9
- package/dist/esm/widgets/LineChart/LineChart.js.map +1 -1
- package/dist/esm/widgets/MultiLineSparkline/MultiLineSparkline.js +23 -3
- package/dist/esm/widgets/MultiLineSparkline/MultiLineSparkline.js.map +1 -1
- package/dist/esm/widgets/PieChart/PieChart.js +53 -3
- package/dist/esm/widgets/PieChart/PieChart.js.map +1 -1
- package/dist/esm/widgets/Progress/Progress.js +20 -8
- package/dist/esm/widgets/Progress/Progress.js.map +1 -1
- package/dist/esm/widgets/RadarChart/RadarChart.js +54 -9
- package/dist/esm/widgets/RadarChart/RadarChart.js.map +1 -1
- package/dist/esm/widgets/SankeyDiagram/SankeyDiagram.js +52 -7
- package/dist/esm/widgets/SankeyDiagram/SankeyDiagram.js.map +1 -1
- package/dist/esm/widgets/ScatterPlot/ScatterPlot.js +63 -4
- package/dist/esm/widgets/ScatterPlot/ScatterPlot.js.map +1 -1
- package/dist/esm/widgets/Sparkline/Sparkline.js +24 -4
- package/dist/esm/widgets/Sparkline/Sparkline.js.map +1 -1
- package/dist/esm/widgets/StackedBarChart/StackedBarChart.js +33 -3
- package/dist/esm/widgets/StackedBarChart/StackedBarChart.js.map +1 -1
- package/dist/esm/widgets/SunburstChart/SunburstChart.js +48 -3
- package/dist/esm/widgets/SunburstChart/SunburstChart.js.map +1 -1
- package/dist/esm/widgets/Treemap/Treemap.js +31 -5
- package/dist/esm/widgets/Treemap/Treemap.js.map +1 -1
- package/dist/esm/widgets/WaterfallChart/WaterfallChart.js +45 -6
- package/dist/esm/widgets/WaterfallChart/WaterfallChart.js.map +1 -1
- package/dist/renderer-svg/paths/arc.d.ts.map +1 -1
- package/dist/renderer-svg/primitives/AnimatedPath.d.ts +9 -1
- package/dist/renderer-svg/primitives/AnimatedPath.d.ts.map +1 -1
- package/dist/renderer-svg/primitives/AnimatedPolygon.d.ts +20 -0
- package/dist/renderer-svg/primitives/AnimatedPolygon.d.ts.map +1 -0
- package/dist/renderer-svg/primitives/index.d.ts +1 -0
- package/dist/renderer-svg/primitives/index.d.ts.map +1 -1
- package/dist/widgets/AreaChart/AreaChart.d.ts +14 -3
- package/dist/widgets/AreaChart/AreaChart.d.ts.map +1 -1
- package/dist/widgets/AreaChart/types.d.ts +8 -26
- package/dist/widgets/AreaChart/types.d.ts.map +1 -1
- package/dist/widgets/BarChart/BarChart.d.ts.map +1 -1
- package/dist/widgets/BarChart/types.d.ts +34 -5
- package/dist/widgets/BarChart/types.d.ts.map +1 -1
- package/dist/widgets/BoxPlot/BoxPlot.d.ts.map +1 -1
- package/dist/widgets/BoxPlot/types.d.ts +40 -5
- package/dist/widgets/BoxPlot/types.d.ts.map +1 -1
- package/dist/widgets/BubbleChart/BubbleChart.d.ts.map +1 -1
- package/dist/widgets/BubbleChart/types.d.ts +37 -5
- package/dist/widgets/BubbleChart/types.d.ts.map +1 -1
- package/dist/widgets/CandlestickChart/CandlestickChart.d.ts.map +1 -1
- package/dist/widgets/CandlestickChart/types.d.ts +40 -2
- package/dist/widgets/CandlestickChart/types.d.ts.map +1 -1
- package/dist/widgets/FunnelChart/FunnelChart.d.ts.map +1 -1
- package/dist/widgets/FunnelChart/types.d.ts +31 -5
- package/dist/widgets/FunnelChart/types.d.ts.map +1 -1
- package/dist/widgets/Gauge/Gauge.d.ts.map +1 -1
- package/dist/widgets/Gauge/types.d.ts +2 -2
- package/dist/widgets/Gauge/types.d.ts.map +1 -1
- package/dist/widgets/GroupedBarChart/GroupedBarChart.d.ts.map +1 -1
- package/dist/widgets/GroupedBarChart/types.d.ts +36 -5
- package/dist/widgets/GroupedBarChart/types.d.ts.map +1 -1
- package/dist/widgets/Heatmap/Heatmap.d.ts.map +1 -1
- package/dist/widgets/Heatmap/types.d.ts +34 -5
- package/dist/widgets/Heatmap/types.d.ts.map +1 -1
- package/dist/widgets/Histogram/Histogram.d.ts.map +1 -1
- package/dist/widgets/Histogram/types.d.ts +29 -5
- package/dist/widgets/Histogram/types.d.ts.map +1 -1
- package/dist/widgets/HorizontalBarChart/HorizontalBarChart.d.ts.map +1 -1
- package/dist/widgets/HorizontalBarChart/types.d.ts +32 -5
- package/dist/widgets/HorizontalBarChart/types.d.ts.map +1 -1
- package/dist/widgets/KPI/KPI.d.ts.map +1 -1
- package/dist/widgets/KPI/types.d.ts +2 -2
- package/dist/widgets/KPI/types.d.ts.map +1 -1
- package/dist/widgets/LineChart/LineChart.d.ts.map +1 -1
- package/dist/widgets/LineChart/types.d.ts +43 -2
- package/dist/widgets/LineChart/types.d.ts.map +1 -1
- package/dist/widgets/MultiLineSparkline/MultiLineSparkline.d.ts.map +1 -1
- package/dist/widgets/MultiLineSparkline/types.d.ts +30 -5
- package/dist/widgets/MultiLineSparkline/types.d.ts.map +1 -1
- package/dist/widgets/PieChart/PieChart.d.ts.map +1 -1
- package/dist/widgets/PieChart/types.d.ts +33 -5
- package/dist/widgets/PieChart/types.d.ts.map +1 -1
- package/dist/widgets/Progress/Progress.d.ts.map +1 -1
- package/dist/widgets/Progress/types.d.ts +2 -2
- package/dist/widgets/Progress/types.d.ts.map +1 -1
- package/dist/widgets/RadarChart/RadarChart.d.ts.map +1 -1
- package/dist/widgets/RadarChart/types.d.ts +34 -5
- package/dist/widgets/RadarChart/types.d.ts.map +1 -1
- package/dist/widgets/SankeyDiagram/SankeyDiagram.d.ts.map +1 -1
- package/dist/widgets/SankeyDiagram/types.d.ts +34 -5
- package/dist/widgets/SankeyDiagram/types.d.ts.map +1 -1
- package/dist/widgets/ScatterPlot/ScatterPlot.d.ts.map +1 -1
- package/dist/widgets/ScatterPlot/types.d.ts +34 -5
- package/dist/widgets/ScatterPlot/types.d.ts.map +1 -1
- package/dist/widgets/Sparkline/Sparkline.d.ts.map +1 -1
- package/dist/widgets/Sparkline/types.d.ts +26 -5
- package/dist/widgets/Sparkline/types.d.ts.map +1 -1
- package/dist/widgets/StackedBarChart/StackedBarChart.d.ts.map +1 -1
- package/dist/widgets/StackedBarChart/types.d.ts +35 -5
- package/dist/widgets/StackedBarChart/types.d.ts.map +1 -1
- package/dist/widgets/SunburstChart/SunburstChart.d.ts.map +1 -1
- package/dist/widgets/SunburstChart/types.d.ts +32 -5
- package/dist/widgets/SunburstChart/types.d.ts.map +1 -1
- package/dist/widgets/Treemap/Treemap.d.ts.map +1 -1
- package/dist/widgets/Treemap/types.d.ts +33 -5
- package/dist/widgets/Treemap/types.d.ts.map +1 -1
- package/dist/widgets/WaterfallChart/WaterfallChart.d.ts.map +1 -1
- package/dist/widgets/WaterfallChart/types.d.ts +34 -5
- package/dist/widgets/WaterfallChart/types.d.ts.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,88 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.1.0-beta.2] - 2026-01-27
|
|
6
|
+
|
|
7
|
+
**🎨 Animation System Overhaul**
|
|
8
|
+
|
|
9
|
+
This release brings a complete animation upgrade to all 24 widgets, making them more dynamic and visually impressive.
|
|
10
|
+
|
|
11
|
+
### 🚀 New Features
|
|
12
|
+
- **All 24 widgets now have element-level animations** - No more basic fade in/out!
|
|
13
|
+
- **New AnimatedPolygon primitive** - Consistent with AnimatedPath and AnimatedCircle for stroke drawing effects
|
|
14
|
+
- **RadarChart drawing animation** - Polygon now draws like LineChart using strokeDasharray/strokeDashoffset
|
|
15
|
+
- **11 widgets upgraded** with dynamic animations:
|
|
16
|
+
- **Histogram**: Bars grow from baseline with stagger
|
|
17
|
+
- **StackedBarChart**: Stacked bars grow up with stagger
|
|
18
|
+
- **WaterfallChart**: Bars grow up/down with stagger
|
|
19
|
+
- **CandlestickChart**: Candles grow from center price
|
|
20
|
+
- **FunnelChart**: Segments fade in with stagger
|
|
21
|
+
- **Heatmap**: Cells appear one by one
|
|
22
|
+
- **Treemap**: Rectangles fade in with stagger
|
|
23
|
+
- **BoxPlot**: Boxes scale + whiskers extend
|
|
24
|
+
- **SankeyDiagram**: Flow paths and nodes animate
|
|
25
|
+
- **SunburstChart**: Arc segments sweep clockwise
|
|
26
|
+
- **RadarChart**: Polygon draws with stroke animation
|
|
27
|
+
|
|
28
|
+
### 🎬 Animation Types by Widget
|
|
29
|
+
- **Bar Growth** (7 widgets): BarChart, GroupedBarChart, HorizontalBarChart, StackedBarChart, WaterfallChart, Histogram
|
|
30
|
+
- **Path/Stroke Drawing** (8 widgets): LineChart, AreaChart, Sparkline, MultiLineSparkline, Gauge, Progress, PieChart, RadarChart
|
|
31
|
+
- **Scale/Pop** (3 widgets): ScatterPlot, BubbleChart, RadarChart
|
|
32
|
+
- **Element Stagger** (8 widgets): FunnelChart, Heatmap, Treemap, CandlestickChart, BoxPlot, SankeyDiagram, SunburstChart, KPI
|
|
33
|
+
|
|
34
|
+
### 🐛 Bug Fixes
|
|
35
|
+
- Fixed animation count bugs in 9 widgets (was using hardcoded values like 10, 20, 50)
|
|
36
|
+
- Fixed RadarChart to use actual `dataPolygons.length` instead of hardcoded 10
|
|
37
|
+
- Fixed worklet closure issues in complex animations
|
|
38
|
+
- All widgets now properly calculate perimeter/length for stroke animations
|
|
39
|
+
|
|
40
|
+
### 🔧 Technical Improvements
|
|
41
|
+
- Moved `useStaggeredAnimation` calls to after data calculation
|
|
42
|
+
- All animations now use actual element counts dynamically
|
|
43
|
+
- Removed hardcoded animation counts that caused rendering issues
|
|
44
|
+
- Created reusable AnimatedPolygon primitive in renderer-svg
|
|
45
|
+
- Consistent animation architecture across all widget types
|
|
46
|
+
|
|
47
|
+
### ⚠️ Breaking Changes
|
|
48
|
+
- None! All changes are backwards compatible.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## [0.1.0-beta.1] - 2026-01-23
|
|
53
|
+
|
|
54
|
+
**🎉 Beta Release - Significant API Improvements**
|
|
55
|
+
|
|
56
|
+
This release includes major improvements and consolidations. Moving to beta indicates the API is stabilizing.
|
|
57
|
+
|
|
58
|
+
### 🚀 New Features
|
|
59
|
+
- **LineChart**: Added `filled` prop to create area charts (replaces AreaChart)
|
|
60
|
+
- **LineChart**: Added `showGradient` prop for beautiful gradient fills when `filled={true}`
|
|
61
|
+
- **ScatterPlot**: Added X-axis labels and grid lines for better data visualization
|
|
62
|
+
- **BubbleChart**: Added X-axis labels and grid lines for better data visualization
|
|
63
|
+
|
|
64
|
+
### 🐛 Bug Fixes
|
|
65
|
+
- **LineChart**: Fixed duplicate X-axis labels when using multiple `dataKeys`
|
|
66
|
+
- **ScatterPlot**: Now shows meaningful X-axis metrics instead of just dots
|
|
67
|
+
- **BubbleChart**: Better visual differentiation from ScatterPlot
|
|
68
|
+
|
|
69
|
+
### ⚠️ Deprecations
|
|
70
|
+
- **AreaChart**: Now deprecated in favor of `LineChart` with `filled={true}`
|
|
71
|
+
- AreaChart still works (backward compatible) but is now just a wrapper around LineChart
|
|
72
|
+
- Migration: Replace `<AreaChart ... />` with `<LineChart ... filled={true} />`
|
|
73
|
+
|
|
74
|
+
### 📚 Documentation
|
|
75
|
+
- Updated README.md with LineChart area chart examples
|
|
76
|
+
- Updated API_REFERENCE.md with new props and deprecation notices
|
|
77
|
+
- Updated SIMPLE_API_GUIDE.md with consolidated LineChart/AreaChart usage
|
|
78
|
+
- Added migration examples for AreaChart → LineChart
|
|
79
|
+
|
|
80
|
+
### 🔧 Technical Improvements
|
|
81
|
+
- Reduced code duplication (~200 lines) by consolidating AreaChart into LineChart
|
|
82
|
+
- Improved TypeScript types - AreaChart now uses LineChart types directly
|
|
83
|
+
- Better axis rendering with proper X-axis support across scatter-based charts
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
5
87
|
## [0.1.0-alpha.4] - 2026-01-22
|
|
6
88
|
|
|
7
89
|
### Fixed
|
package/README.md
CHANGED
|
@@ -4,22 +4,22 @@
|
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/react-native-metrify)
|
|
6
6
|
|
|
7
|
-
## ⚠️
|
|
7
|
+
## ⚠️ Beta Release
|
|
8
8
|
|
|
9
|
-
**This package is in
|
|
9
|
+
**This package is in beta.** The core functionality works, but the library is under active development.
|
|
10
10
|
|
|
11
11
|
- ✅ 24 chart types implemented and working
|
|
12
12
|
- ✅ TypeScript support with full type definitions
|
|
13
13
|
- ✅ Responsive font sizing
|
|
14
|
+
- ✅ Complete examples and demos available in `examples/basic-demo/`
|
|
14
15
|
- ⚠️ Limited testing coverage
|
|
15
|
-
- ⚠️ APIs may change in future versions
|
|
16
|
-
- 🚧 Examples and demos coming soon
|
|
16
|
+
- ⚠️ APIs may change in future versions (beta release)
|
|
17
17
|
|
|
18
18
|
**Installation:**
|
|
19
19
|
```bash
|
|
20
|
-
npm install react-native-metrify@
|
|
20
|
+
npm install react-native-metrify@beta
|
|
21
21
|
# or
|
|
22
|
-
yarn add react-native-metrify@
|
|
22
|
+
yarn add react-native-metrify@beta
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
Feedback and contributions welcome!
|
|
@@ -31,7 +31,7 @@ A comprehensive, performance-focused chart library built specifically for React
|
|
|
31
31
|
|
|
32
32
|
- 🎨 **24+ Chart Types** - KPI, Gauge, Line, Bar, Pie, Area, Scatter, Heatmap, and more
|
|
33
33
|
- 📱 **Mobile-First** - Optimized for small screens and touch interactions
|
|
34
|
-
- ⚡ **High Performance** - UI thread
|
|
34
|
+
- ⚡ **High Performance** - Element-level animations on UI thread (60 FPS)
|
|
35
35
|
- 🎭 **Theme Support** - Built-in light/dark themes with customization
|
|
36
36
|
- 📦 **Zero Config** - Sensible defaults, minimal API surface
|
|
37
37
|
- 🔧 **TypeScript** - Full type definitions included
|
|
@@ -41,7 +41,7 @@ A comprehensive, performance-focused chart library built specifically for React
|
|
|
41
41
|
## 📦 Installation
|
|
42
42
|
|
|
43
43
|
```bash
|
|
44
|
-
npm install react-native-metrify@
|
|
44
|
+
npm install react-native-metrify@beta
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
### Peer Dependencies
|
|
@@ -80,6 +80,68 @@ export default function App() {
|
|
|
80
80
|
|
|
81
81
|
### 2. Use any chart component
|
|
82
82
|
|
|
83
|
+
#### Simple API (Recommended)
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
import { LineChart, AreaChart, BarChart } from 'react-native-metrify';
|
|
87
|
+
import { View } from 'react-native';
|
|
88
|
+
|
|
89
|
+
// Your data - just a simple array of objects!
|
|
90
|
+
const data = [
|
|
91
|
+
{ name: 'Jan', sales: 4000, expenses: 2400 },
|
|
92
|
+
{ name: 'Feb', sales: 3000, expenses: 1398 },
|
|
93
|
+
{ name: 'Mar', sales: 2000, expenses: 9800 },
|
|
94
|
+
{ name: 'Apr', sales: 2780, expenses: 3908 },
|
|
95
|
+
{ name: 'May', sales: 1890, expenses: 4800 },
|
|
96
|
+
{ name: 'Jun', sales: 2390, expenses: 3800 },
|
|
97
|
+
];
|
|
98
|
+
|
|
99
|
+
export default function Dashboard() {
|
|
100
|
+
return (
|
|
101
|
+
<View>
|
|
102
|
+
{/* LineChart - Just specify data and keys! */}
|
|
103
|
+
<LineChart
|
|
104
|
+
data={data}
|
|
105
|
+
xKey="name"
|
|
106
|
+
dataKeys={['sales', 'expenses']}
|
|
107
|
+
colors={['#82ca9d', '#ff7c7c']}
|
|
108
|
+
labels={['Sales', 'Expenses']}
|
|
109
|
+
width={350}
|
|
110
|
+
height={250}
|
|
111
|
+
showGrid
|
|
112
|
+
showLegend
|
|
113
|
+
/>
|
|
114
|
+
|
|
115
|
+
{/* LineChart as Area Chart - Just add filled prop! */}
|
|
116
|
+
<LineChart
|
|
117
|
+
data={data}
|
|
118
|
+
xKey="name"
|
|
119
|
+
dataKeys={['revenue']}
|
|
120
|
+
colors={['#8884d8']}
|
|
121
|
+
width={350}
|
|
122
|
+
height={250}
|
|
123
|
+
filled={true} // Makes it an area chart!
|
|
124
|
+
showGradient={true} // Beautiful gradient fill
|
|
125
|
+
/>
|
|
126
|
+
|
|
127
|
+
{/* BarChart - Single value per item */}
|
|
128
|
+
<BarChart
|
|
129
|
+
data={data}
|
|
130
|
+
xKey="name"
|
|
131
|
+
dataKey="sales"
|
|
132
|
+
width={350}
|
|
133
|
+
height={250}
|
|
134
|
+
showValues
|
|
135
|
+
/>
|
|
136
|
+
</View>
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
#### Advanced API (Full Control)
|
|
142
|
+
|
|
143
|
+
For more control, you can still use the original API:
|
|
144
|
+
|
|
83
145
|
```tsx
|
|
84
146
|
import { KPI, LineChart, Gauge } from 'react-native-metrify';
|
|
85
147
|
import { View } from 'react-native';
|
|
@@ -136,6 +198,62 @@ export default function Dashboard() {
|
|
|
136
198
|
}
|
|
137
199
|
```
|
|
138
200
|
|
|
201
|
+
## ✨ Smooth Animations
|
|
202
|
+
|
|
203
|
+
All widgets include beautiful, element-level animations powered by react-native-reanimated:
|
|
204
|
+
|
|
205
|
+
```tsx
|
|
206
|
+
// Animations enabled by default
|
|
207
|
+
<Gauge
|
|
208
|
+
data={{ value: 75, max: 100, label: 'Progress' }}
|
|
209
|
+
animated={true} // Arc sweeps smoothly from 0° to 75°
|
|
210
|
+
/>
|
|
211
|
+
|
|
212
|
+
<KPI
|
|
213
|
+
data={{ value: 1234, label: 'Revenue', format: 'currency' }}
|
|
214
|
+
animated={true} // Numbers count up smoothly
|
|
215
|
+
/>
|
|
216
|
+
|
|
217
|
+
<BarChart
|
|
218
|
+
data={salesData}
|
|
219
|
+
xKey="month"
|
|
220
|
+
dataKey="sales"
|
|
221
|
+
animated={true} // Bars grow from baseline with stagger
|
|
222
|
+
/>
|
|
223
|
+
|
|
224
|
+
<LineChart
|
|
225
|
+
data={trendData}
|
|
226
|
+
xKey="date"
|
|
227
|
+
dataKeys={['revenue', 'profit']}
|
|
228
|
+
animated={true} // Lines draw across the chart
|
|
229
|
+
/>
|
|
230
|
+
|
|
231
|
+
<RadarChart
|
|
232
|
+
data={radarData}
|
|
233
|
+
animated={true} // Polygon draws around perimeter
|
|
234
|
+
/>
|
|
235
|
+
|
|
236
|
+
<StackedBarChart
|
|
237
|
+
data={stackedData}
|
|
238
|
+
animated={true} // Stacked segments grow together
|
|
239
|
+
/>
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Animation Types
|
|
243
|
+
All 24 widgets have element-level animations:
|
|
244
|
+
- **📊 Bar Growth** (7 widgets) - Bars grow from 0 to full height with stagger
|
|
245
|
+
- **✏️ Path Drawing** (8 widgets) - Lines/arcs draw using stroke animation
|
|
246
|
+
- **⭕ Scale/Pop** (3 widgets) - Elements scale from center outward
|
|
247
|
+
- **🎬 Element Stagger** (8 widgets) - Items appear one by one
|
|
248
|
+
|
|
249
|
+
**Performance:**
|
|
250
|
+
- ⚡ 60 FPS on UI thread (no JS thread blocking)
|
|
251
|
+
- 🎯 Dynamic animations based on actual data
|
|
252
|
+
- 🔄 Calculated perimeter/length for stroke animations
|
|
253
|
+
- 🎨 Customizable duration and easing
|
|
254
|
+
|
|
255
|
+
Disable animations anytime with `animated={false}`.
|
|
256
|
+
|
|
139
257
|
## 📊 Available Charts
|
|
140
258
|
|
|
141
259
|
### Widget Showcase
|
|
@@ -202,7 +320,7 @@ export default function Dashboard() {
|
|
|
202
320
|
|
|
203
321
|
**Bar Charts:** BarChart, HorizontalBarChart, StackedBarChart, GroupedBarChart, WaterfallChart, Histogram
|
|
204
322
|
|
|
205
|
-
**Line & Area:** LineChart, AreaChart,
|
|
323
|
+
**Line & Area:** LineChart (with area support), MultiLineSparkline, ~~AreaChart~~ (deprecated, use LineChart with `filled={true}`)
|
|
206
324
|
|
|
207
325
|
**Distribution:** PieChart, FunnelChart, BoxPlot
|
|
208
326
|
|
|
@@ -210,6 +328,104 @@ export default function Dashboard() {
|
|
|
210
328
|
|
|
211
329
|
**Hierarchical:** Treemap, SunburstChart, SankeyDiagram
|
|
212
330
|
|
|
331
|
+
## 💡 Simple API (Data-Driven)
|
|
332
|
+
|
|
333
|
+
We've made it super easy to use charts! Inspired by Recharts, you can now pass your data directly without manual transformation.
|
|
334
|
+
|
|
335
|
+
### Before vs After
|
|
336
|
+
|
|
337
|
+
**❌ Old Way (Complex):**
|
|
338
|
+
```tsx
|
|
339
|
+
// Had to manually transform your data
|
|
340
|
+
const chartData = {
|
|
341
|
+
series: [
|
|
342
|
+
{
|
|
343
|
+
data: data.map(d => ({ x: d.month, y: d.sales })),
|
|
344
|
+
color: '#82ca9d',
|
|
345
|
+
label: 'Sales'
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
data: data.map(d => ({ x: d.month, y: d.expenses })),
|
|
349
|
+
color: '#ff7c7c',
|
|
350
|
+
label: 'Expenses'
|
|
351
|
+
}
|
|
352
|
+
]
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
<LineChart data={chartData} width={350} height={250} />
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
**✅ New Way (Simple):**
|
|
359
|
+
```tsx
|
|
360
|
+
// Just pass your data and specify the keys!
|
|
361
|
+
<LineChart
|
|
362
|
+
data={data}
|
|
363
|
+
xKey="month"
|
|
364
|
+
dataKeys={['sales', 'expenses']}
|
|
365
|
+
colors={['#82ca9d', '#ff7c7c']}
|
|
366
|
+
labels={['Sales', 'Expenses']}
|
|
367
|
+
width={350}
|
|
368
|
+
height={250}
|
|
369
|
+
/>
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### Supported Charts
|
|
373
|
+
|
|
374
|
+
The Simple API is available for **ALL** chart types:
|
|
375
|
+
|
|
376
|
+
**Line & Area:** LineChart, AreaChart
|
|
377
|
+
**Bar Charts:** BarChart, GroupedBarChart, StackedBarChart, HorizontalBarChart
|
|
378
|
+
**Pie & Distribution:** PieChart, FunnelChart
|
|
379
|
+
**Scatter:** ScatterPlot, BubbleChart
|
|
380
|
+
**Multi-Axis:** RadarChart
|
|
381
|
+
**Statistical:** Heatmap, BoxPlot, Histogram
|
|
382
|
+
**Financial:** WaterfallChart, CandlestickChart
|
|
383
|
+
|
|
384
|
+
### Quick Examples
|
|
385
|
+
|
|
386
|
+
```tsx
|
|
387
|
+
// LineChart - Multiple series
|
|
388
|
+
<LineChart data={data} xKey="month" dataKeys={['sales', 'expenses']} />
|
|
389
|
+
|
|
390
|
+
// LineChart as Area Chart - Just add filled prop
|
|
391
|
+
<LineChart data={data} xKey="month" dataKeys={['revenue']} filled={true} showGradient />
|
|
392
|
+
|
|
393
|
+
// AreaChart still works (deprecated, uses LineChart internally)
|
|
394
|
+
<AreaChart data={data} xKey="month" dataKeys={['revenue']} />
|
|
395
|
+
|
|
396
|
+
// BarChart - Single value
|
|
397
|
+
<BarChart data={data} xKey="category" dataKey="revenue" />
|
|
398
|
+
|
|
399
|
+
// PieChart - Segments
|
|
400
|
+
<PieChart data={data} labelKey="category" valueKey="amount" />
|
|
401
|
+
|
|
402
|
+
// ScatterPlot - X/Y coordinates
|
|
403
|
+
<ScatterPlot data={data} xKey="x" yKey="y" />
|
|
404
|
+
|
|
405
|
+
// RadarChart - Multi-axis comparison
|
|
406
|
+
<RadarChart data={data} categoryKey="skill" dataKeys={['you', 'teamAvg']} />
|
|
407
|
+
|
|
408
|
+
// Heatmap - Grid visualization
|
|
409
|
+
<Heatmap data={data} xKey="day" yKey="hour" valueKey="activity" />
|
|
410
|
+
|
|
411
|
+
// And 15+ more charts!
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
### Full Documentation
|
|
415
|
+
|
|
416
|
+
📖 **[Complete Simple API Reference →](./examples/API_REFERENCE.md)**
|
|
417
|
+
|
|
418
|
+
See all chart types with detailed examples in `examples/API_REFERENCE.md`
|
|
419
|
+
|
|
420
|
+
### Benefits
|
|
421
|
+
|
|
422
|
+
✓ **60% less code** - No manual data transformation needed
|
|
423
|
+
✓ **Works with ALL charts** - Consistent API across 20+ chart types
|
|
424
|
+
✓ **Familiar API** - Similar to Recharts and other popular charting libraries
|
|
425
|
+
✓ **Backward compatible** - Old API still works perfectly
|
|
426
|
+
✓ **Automatic colors** - Uses a nice default palette if you don't specify colors
|
|
427
|
+
✓ **TypeScript support** - Full type safety with autocomplete
|
|
428
|
+
|
|
213
429
|
## 🎨 Theming
|
|
214
430
|
|
|
215
431
|
### Using Built-in Themes
|
|
@@ -283,7 +499,30 @@ interface BaseWidgetProps {
|
|
|
283
499
|
|
|
284
500
|
### LineChart Component
|
|
285
501
|
|
|
502
|
+
**New in v0.1.0-beta.1:** LineChart now supports area charts with the `filled` prop!
|
|
503
|
+
|
|
286
504
|
```tsx
|
|
505
|
+
// Regular Line Chart
|
|
506
|
+
<LineChart
|
|
507
|
+
data={data}
|
|
508
|
+
xKey="month"
|
|
509
|
+
dataKeys={['sales', 'expenses']}
|
|
510
|
+
width={350}
|
|
511
|
+
height={250}
|
|
512
|
+
/>
|
|
513
|
+
|
|
514
|
+
// Area Chart (filled line chart)
|
|
515
|
+
<LineChart
|
|
516
|
+
data={data}
|
|
517
|
+
xKey="month"
|
|
518
|
+
dataKeys={['revenue']}
|
|
519
|
+
width={350}
|
|
520
|
+
height={250}
|
|
521
|
+
filled={true} // Enable area fill
|
|
522
|
+
showGradient={true} // Show gradient (optional)
|
|
523
|
+
/>
|
|
524
|
+
|
|
525
|
+
// Legacy API still works
|
|
287
526
|
<LineChart
|
|
288
527
|
data={{
|
|
289
528
|
series: [
|
|
@@ -360,7 +599,7 @@ Text automatically scales based on widget dimensions:
|
|
|
360
599
|
## 🎯 Design Philosophy
|
|
361
600
|
|
|
362
601
|
- **Mobile-First**: Optimized for small screens and touch interactions
|
|
363
|
-
- **Performance**: UI thread animations with react-native-reanimated
|
|
602
|
+
- **Performance**: UI thread animations with react-native-reanimated for smooth 60 FPS animations
|
|
364
603
|
- **Type-Safe**: Full TypeScript support with inference
|
|
365
604
|
- **Zero Config**: Sensible defaults, minimal API surface
|
|
366
605
|
|
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
2
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
17
|
exports.useWidgetDimensions = useWidgetDimensions;
|
|
4
18
|
exports.useWidgetTheme = useWidgetTheme;
|
|
@@ -47,4 +61,8 @@ function useInnerDimensions(width, height, padding) {
|
|
|
47
61
|
height: Math.max(0, height - padding.vertical),
|
|
48
62
|
}), [width, height, padding.horizontal, padding.vertical]);
|
|
49
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Export animation hooks
|
|
66
|
+
*/
|
|
67
|
+
__exportStar(require("./useChartAnimation"), exports);
|
|
50
68
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/hooks/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/hooks/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAUA,kDAaC;AAKD,wCAGC;AAKD,4CAYC;AAKD,gDAYC;AAjED;;GAEG;AACH,iCAAgC;AAEhC,oCAAoC;AAEpC;;GAEG;AACH,SAAgB,mBAAmB,CACjC,KAAc,EACd,MAAe,EACf,eAAuB,GAAG,EAC1B,gBAAwB,GAAG;IAE3B,OAAO,IAAA,eAAO,EACZ,GAAG,EAAE,CAAC,CAAC;QACL,KAAK,EAAE,KAAK,IAAI,YAAY;QAC5B,MAAM,EAAE,MAAM,IAAI,aAAa;KAChC,CAAC,EACF,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,CAAC,CAC7C,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,cAAc,CAAC,aAAqB;IAClD,MAAM,YAAY,GAAG,IAAA,gBAAQ,GAAE,CAAC;IAChC,OAAO,aAAa,IAAI,YAAY,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,SAAgB,gBAAgB,CAAC,KAAY;IAC3C,OAAO,IAAA,eAAO,EACZ,GAAG,EAAE,CAAC,CAAC;QACL,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE;QACrB,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE;QACvB,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE;QACxB,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE;QACtB,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC;QAChC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC;KAC/B,CAAC,EACF,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CACnB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,kBAAkB,CAChC,KAAa,EACb,MAAc,EACd,OAAiD;IAEjD,OAAO,IAAA,eAAO,EACZ,GAAG,EAAE,CAAC,CAAC;QACL,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC;QAC9C,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;KAC/C,CAAC,EACF,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,CACtD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,sDAAoC"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useEntryAnimation = useEntryAnimation;
|
|
4
|
+
exports.useValueAnimation = useValueAnimation;
|
|
5
|
+
exports.usePathDrawAnimation = usePathDrawAnimation;
|
|
6
|
+
exports.useScaleAnimation = useScaleAnimation;
|
|
7
|
+
exports.useStaggeredAnimation = useStaggeredAnimation;
|
|
8
|
+
exports.useRotationAnimation = useRotationAnimation;
|
|
9
|
+
exports.estimatePathLength = estimatePathLength;
|
|
10
|
+
/**
|
|
11
|
+
* Chart animation hooks using react-native-reanimated
|
|
12
|
+
*/
|
|
13
|
+
const react_1 = require("react");
|
|
14
|
+
const react_native_reanimated_1 = require("react-native-reanimated");
|
|
15
|
+
const DEFAULT_DURATION = 500;
|
|
16
|
+
const DEFAULT_DELAY = 0;
|
|
17
|
+
/**
|
|
18
|
+
* Get easing function based on type
|
|
19
|
+
* Using Recharts-style easing curves
|
|
20
|
+
*/
|
|
21
|
+
function getEasing(type) {
|
|
22
|
+
switch (type) {
|
|
23
|
+
case 'linear':
|
|
24
|
+
return react_native_reanimated_1.Easing.linear;
|
|
25
|
+
case 'ease-in':
|
|
26
|
+
return react_native_reanimated_1.Easing.in(react_native_reanimated_1.Easing.cubic);
|
|
27
|
+
case 'ease-out':
|
|
28
|
+
return react_native_reanimated_1.Easing.out(react_native_reanimated_1.Easing.cubic);
|
|
29
|
+
case 'spring':
|
|
30
|
+
return react_native_reanimated_1.Easing.elastic(1.2); // Bouncy spring
|
|
31
|
+
case 'ease-in-out':
|
|
32
|
+
default:
|
|
33
|
+
return react_native_reanimated_1.Easing.bezier(0.4, 0, 0.2, 1); // Recharts default easing
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Hook for entry animations (fade in, scale, etc.)
|
|
38
|
+
*/
|
|
39
|
+
function useEntryAnimation(options = {}) {
|
|
40
|
+
const { enabled = true, duration = DEFAULT_DURATION, delay = DEFAULT_DELAY, easing = 'ease-in-out', } = options;
|
|
41
|
+
const progress = (0, react_native_reanimated_1.useSharedValue)(enabled ? 0 : 1);
|
|
42
|
+
(0, react_1.useEffect)(() => {
|
|
43
|
+
if (enabled) {
|
|
44
|
+
if (easing === 'spring') {
|
|
45
|
+
progress.value = (0, react_native_reanimated_1.withSpring)(1, {
|
|
46
|
+
damping: 15,
|
|
47
|
+
stiffness: 100,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
progress.value = (0, react_native_reanimated_1.withTiming)(1, {
|
|
52
|
+
duration,
|
|
53
|
+
easing: getEasing(easing),
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}, [enabled, duration, easing, progress]);
|
|
58
|
+
return progress;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Hook for value animations (numbers, progress bars, etc.)
|
|
62
|
+
* Handles both initial animation AND data updates
|
|
63
|
+
* When targetValue changes, it smoothly transitions to the new value
|
|
64
|
+
*/
|
|
65
|
+
function useValueAnimation(targetValue, options = {}) {
|
|
66
|
+
const { enabled = true, duration = DEFAULT_DURATION, delay = DEFAULT_DELAY, easing = 'ease-in-out', } = options;
|
|
67
|
+
const animatedValue = (0, react_native_reanimated_1.useSharedValue)(enabled ? 0 : targetValue);
|
|
68
|
+
const isFirstMount = (0, react_native_reanimated_1.useSharedValue)(true);
|
|
69
|
+
(0, react_1.useEffect)(() => {
|
|
70
|
+
if (enabled) {
|
|
71
|
+
// On first mount, animate from 0
|
|
72
|
+
// On data change, animate from current value to new value
|
|
73
|
+
const startValue = isFirstMount.value ? 0 : animatedValue.value;
|
|
74
|
+
if (easing === 'spring') {
|
|
75
|
+
animatedValue.value = (0, react_native_reanimated_1.withSpring)(targetValue, {
|
|
76
|
+
damping: 15,
|
|
77
|
+
stiffness: 100,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
animatedValue.value = (0, react_native_reanimated_1.withTiming)(targetValue, {
|
|
82
|
+
duration: isFirstMount.value ? duration : duration * 0.6, // Faster for updates
|
|
83
|
+
easing: getEasing(easing),
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
isFirstMount.value = false;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
animatedValue.value = targetValue;
|
|
90
|
+
}
|
|
91
|
+
}, [targetValue, enabled, duration, easing, animatedValue, isFirstMount]);
|
|
92
|
+
return animatedValue;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Hook for true path drawing animation (SVG paths)
|
|
96
|
+
* Returns strokeDasharray and animated strokeDashoffset for Recharts-style line drawing
|
|
97
|
+
* The line literally draws from start to finish
|
|
98
|
+
* Handles both initial draw AND data changes (path morphs smoothly)
|
|
99
|
+
*/
|
|
100
|
+
function usePathDrawAnimation(pathLength, options = {}) {
|
|
101
|
+
const { enabled = true, duration = 1000, // Longer for smooth drawing effect
|
|
102
|
+
delay = DEFAULT_DELAY, easing = 'ease-in-out', } = options;
|
|
103
|
+
// Start with line fully hidden (offset = pathLength)
|
|
104
|
+
// Animate to fully visible (offset = 0)
|
|
105
|
+
const dashOffset = (0, react_native_reanimated_1.useSharedValue)(enabled ? pathLength : 0);
|
|
106
|
+
const isFirstMount = (0, react_native_reanimated_1.useSharedValue)(true);
|
|
107
|
+
(0, react_1.useEffect)(() => {
|
|
108
|
+
if (enabled && pathLength > 0) {
|
|
109
|
+
if (isFirstMount.value) {
|
|
110
|
+
// First mount: draw from start
|
|
111
|
+
dashOffset.value = pathLength;
|
|
112
|
+
dashOffset.value = (0, react_native_reanimated_1.withTiming)(0, {
|
|
113
|
+
duration,
|
|
114
|
+
easing: getEasing(easing),
|
|
115
|
+
});
|
|
116
|
+
isFirstMount.value = false;
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
// Data change: quickly redraw (path morphs via SVG, we just flash the animation)
|
|
120
|
+
// Brief redraw effect to show data changed
|
|
121
|
+
dashOffset.value = pathLength * 0.3; // Start from 30% hidden
|
|
122
|
+
dashOffset.value = (0, react_native_reanimated_1.withTiming)(0, {
|
|
123
|
+
duration: duration * 0.4, // Faster for updates
|
|
124
|
+
easing: getEasing(easing),
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
dashOffset.value = 0;
|
|
130
|
+
}
|
|
131
|
+
}, [enabled, duration, easing, dashOffset, pathLength, isFirstMount]);
|
|
132
|
+
return {
|
|
133
|
+
dashArray: pathLength,
|
|
134
|
+
dashOffset,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Hook for scale-in animation (circles, points, markers)
|
|
139
|
+
* Recharts-style: starts small and scales to full size
|
|
140
|
+
*/
|
|
141
|
+
function useScaleAnimation(options = {}) {
|
|
142
|
+
const { enabled = true, duration = DEFAULT_DURATION, delay = DEFAULT_DELAY, easing = 'ease-out', } = options;
|
|
143
|
+
const scale = (0, react_native_reanimated_1.useSharedValue)(enabled ? 0 : 1);
|
|
144
|
+
(0, react_1.useEffect)(() => {
|
|
145
|
+
if (enabled) {
|
|
146
|
+
scale.value = (0, react_native_reanimated_1.withTiming)(1, {
|
|
147
|
+
duration,
|
|
148
|
+
easing: getEasing(easing),
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}, [enabled, duration, easing, scale]);
|
|
152
|
+
return scale;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Hook for staggered animations (multiple items with delay)
|
|
156
|
+
*/
|
|
157
|
+
function useStaggeredAnimation(itemCount, options = {}) {
|
|
158
|
+
const { enabled = true, duration = DEFAULT_DURATION, easing = 'ease-in-out', } = options;
|
|
159
|
+
const staggerDelay = duration / itemCount / 2; // Half duration spread across items
|
|
160
|
+
const progresses = Array.from({ length: itemCount }, (_, index) => {
|
|
161
|
+
const progress = (0, react_native_reanimated_1.useSharedValue)(enabled ? 0 : 1);
|
|
162
|
+
(0, react_1.useEffect)(() => {
|
|
163
|
+
if (enabled) {
|
|
164
|
+
progress.value = (0, react_native_reanimated_1.withTiming)(1, {
|
|
165
|
+
duration,
|
|
166
|
+
easing: getEasing(easing),
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}, [enabled, duration, easing]);
|
|
170
|
+
return progress;
|
|
171
|
+
});
|
|
172
|
+
return progresses;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Hook for rotation animation (gauges, pie charts, etc.)
|
|
176
|
+
*/
|
|
177
|
+
function useRotationAnimation(targetRotation, options = {}) {
|
|
178
|
+
const { enabled = true, duration = DEFAULT_DURATION, easing = 'spring', } = options;
|
|
179
|
+
const rotation = (0, react_native_reanimated_1.useSharedValue)(enabled ? 0 : targetRotation);
|
|
180
|
+
(0, react_1.useEffect)(() => {
|
|
181
|
+
if (enabled) {
|
|
182
|
+
if (easing === 'spring') {
|
|
183
|
+
rotation.value = (0, react_native_reanimated_1.withSpring)(targetRotation, {
|
|
184
|
+
damping: 12,
|
|
185
|
+
stiffness: 80,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
rotation.value = (0, react_native_reanimated_1.withTiming)(targetRotation, {
|
|
190
|
+
duration,
|
|
191
|
+
easing: getEasing(easing),
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
rotation.value = targetRotation;
|
|
197
|
+
}
|
|
198
|
+
}, [targetRotation, enabled, duration, easing, rotation]);
|
|
199
|
+
return rotation;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Estimate SVG path length
|
|
203
|
+
* Since we can't measure paths in React Native, we estimate based on data points
|
|
204
|
+
*/
|
|
205
|
+
function estimatePathLength(dataPoints, width, height) {
|
|
206
|
+
if (dataPoints < 2)
|
|
207
|
+
return 0;
|
|
208
|
+
// Estimate: sum of diagonal distances between points
|
|
209
|
+
// Rough approximation: width + height gives us a reasonable path length estimate
|
|
210
|
+
const avgSegmentLength = width / (dataPoints - 1);
|
|
211
|
+
const avgHeight = height / 2; // Average vertical movement
|
|
212
|
+
const estimatedSegmentLength = Math.sqrt(avgSegmentLength ** 2 + (avgHeight / dataPoints) ** 2);
|
|
213
|
+
return dataPoints * estimatedSegmentLength;
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=useChartAnimation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useChartAnimation.js","sourceRoot":"","sources":["../../../../src/core/hooks/useChartAnimation.ts"],"names":[],"mappings":";;AAuCA,8CA2BC;AAOD,8CAuCC;AAQD,oDA4CC;AAMD,8CAoBC;AAKD,sDA4BC;AAKD,oDA+BC;AAMD,gDAUC;AAnRD;;GAEG;AACH,iCAAkC;AAClC,qEAA2G;AAS3G,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAC7B,MAAM,aAAa,GAAG,CAAC,CAAC;AAExB;;;GAGG;AACH,SAAS,SAAS,CAAC,IAAwC;IACzD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ;YACX,OAAO,gCAAM,CAAC,MAAM,CAAC;QACvB,KAAK,SAAS;YACZ,OAAO,gCAAM,CAAC,EAAE,CAAC,gCAAM,CAAC,KAAK,CAAC,CAAC;QACjC,KAAK,UAAU;YACb,OAAO,gCAAM,CAAC,GAAG,CAAC,gCAAM,CAAC,KAAK,CAAC,CAAC;QAClC,KAAK,QAAQ;YACX,OAAO,gCAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,gBAAgB;QAC9C,KAAK,aAAa,CAAC;QACnB;YACE,OAAO,gCAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,0BAA0B;IACpE,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,iBAAiB,CAAC,UAAoC,EAAE;IACtE,MAAM,EACJ,OAAO,GAAG,IAAI,EACd,QAAQ,GAAG,gBAAgB,EAC3B,KAAK,GAAG,aAAa,EACrB,MAAM,GAAG,aAAa,GACvB,GAAG,OAAO,CAAC;IAEZ,MAAM,QAAQ,GAAG,IAAA,wCAAc,EAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEjD,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;gBACxB,QAAQ,CAAC,KAAK,GAAG,IAAA,oCAAU,EAAC,CAAC,EAAE;oBAC7B,OAAO,EAAE,EAAE;oBACX,SAAS,EAAE,GAAG;iBACf,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,QAAQ,CAAC,KAAK,GAAG,IAAA,oCAAU,EAAC,CAAC,EAAE;oBAC7B,QAAQ;oBACR,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC;iBACN,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;IACH,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAE1C,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;GAIG;AACH,SAAgB,iBAAiB,CAC/B,WAAmB,EACnB,UAAoC,EAAE;IAEtC,MAAM,EACJ,OAAO,GAAG,IAAI,EACd,QAAQ,GAAG,gBAAgB,EAC3B,KAAK,GAAG,aAAa,EACrB,MAAM,GAAG,aAAa,GACvB,GAAG,OAAO,CAAC;IAEZ,MAAM,aAAa,GAAG,IAAA,wCAAc,EAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAChE,MAAM,YAAY,GAAG,IAAA,wCAAc,EAAC,IAAI,CAAC,CAAC;IAE1C,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,OAAO,EAAE,CAAC;YACZ,iCAAiC;YACjC,0DAA0D;YAC1D,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC;YAEhE,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;gBACxB,aAAa,CAAC,KAAK,GAAG,IAAA,oCAAU,EAAC,WAAW,EAAE;oBAC5C,OAAO,EAAE,EAAE;oBACX,SAAS,EAAE,GAAG;iBACf,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,aAAa,CAAC,KAAK,GAAG,IAAA,oCAAU,EAAC,WAAW,EAAE;oBAC5C,QAAQ,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,GAAG,GAAG,EAAE,qBAAqB;oBAC/E,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC;iBACN,CAAC,CAAC;YACzB,CAAC;YAED,YAAY,CAAC,KAAK,GAAG,KAAK,CAAC;QAC7B,CAAC;aAAM,CAAC;YACN,aAAa,CAAC,KAAK,GAAG,WAAW,CAAC;QACpC,CAAC;IACH,CAAC,EAAE,CAAC,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC;IAE1E,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;;;;GAKG;AACH,SAAgB,oBAAoB,CAClC,UAAkB,EAClB,UAAoC,EAAE;IAEtC,MAAM,EACJ,OAAO,GAAG,IAAI,EACd,QAAQ,GAAG,IAAI,EAAE,mCAAmC;IACpD,KAAK,GAAG,aAAa,EACrB,MAAM,GAAG,aAAa,GACvB,GAAG,OAAO,CAAC;IAEZ,qDAAqD;IACrD,wCAAwC;IACxC,MAAM,UAAU,GAAG,IAAA,wCAAc,EAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5D,MAAM,YAAY,GAAG,IAAA,wCAAc,EAAC,IAAI,CAAC,CAAC;IAE1C,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,OAAO,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;YAC9B,IAAI,YAAY,CAAC,KAAK,EAAE,CAAC;gBACvB,+BAA+B;gBAC/B,UAAU,CAAC,KAAK,GAAG,UAAU,CAAC;gBAC9B,UAAU,CAAC,KAAK,GAAG,IAAA,oCAAU,EAAC,CAAC,EAAE;oBAC/B,QAAQ;oBACR,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC;iBACN,CAAC,CAAC;gBACvB,YAAY,CAAC,KAAK,GAAG,KAAK,CAAC;YAC7B,CAAC;iBAAM,CAAC;gBACN,iFAAiF;gBACjF,2CAA2C;gBAC3C,UAAU,CAAC,KAAK,GAAG,UAAU,GAAG,GAAG,CAAC,CAAC,wBAAwB;gBAC7D,UAAU,CAAC,KAAK,GAAG,IAAA,oCAAU,EAAC,CAAC,EAAE;oBAC/B,QAAQ,EAAE,QAAQ,GAAG,GAAG,EAAE,qBAAqB;oBAC/C,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC;iBACN,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC;IAEtE,OAAO;QACL,SAAS,EAAE,UAAU;QACrB,UAAU;KACX,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAgB,iBAAiB,CAAC,UAAoC,EAAE;IACtE,MAAM,EACJ,OAAO,GAAG,IAAI,EACd,QAAQ,GAAG,gBAAgB,EAC3B,KAAK,GAAG,aAAa,EACrB,MAAM,GAAG,UAAU,GACpB,GAAG,OAAO,CAAC;IAEZ,MAAM,KAAK,GAAG,IAAA,wCAAc,EAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE9C,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,OAAO,EAAE,CAAC;YACZ,KAAK,CAAC,KAAK,GAAG,IAAA,oCAAU,EAAC,CAAC,EAAE;gBAC1B,QAAQ;gBACR,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC;aACN,CAAC,CAAC;QACzB,CAAC;IACH,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;IAEvC,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAgB,qBAAqB,CACnC,SAAiB,EACjB,UAAoC,EAAE;IAEtC,MAAM,EACJ,OAAO,GAAG,IAAI,EACd,QAAQ,GAAG,gBAAgB,EAC3B,MAAM,GAAG,aAAa,GACvB,GAAG,OAAO,CAAC;IAEZ,MAAM,YAAY,GAAG,QAAQ,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,oCAAoC;IAEnF,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE;QAChE,MAAM,QAAQ,GAAG,IAAA,wCAAc,EAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAEjD,IAAA,iBAAS,EAAC,GAAG,EAAE;YACb,IAAI,OAAO,EAAE,CAAC;gBACZ,QAAQ,CAAC,KAAK,GAAG,IAAA,oCAAU,EAAC,CAAC,EAAE;oBAC7B,QAAQ;oBACR,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC;iBACN,CAAC,CAAC;YACzB,CAAC;QACH,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;QAEhC,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,SAAgB,oBAAoB,CAClC,cAAsB,EACtB,UAAoC,EAAE;IAEtC,MAAM,EACJ,OAAO,GAAG,IAAI,EACd,QAAQ,GAAG,gBAAgB,EAC3B,MAAM,GAAG,QAAQ,GAClB,GAAG,OAAO,CAAC;IAEZ,MAAM,QAAQ,GAAG,IAAA,wCAAc,EAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;IAE9D,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;gBACxB,QAAQ,CAAC,KAAK,GAAG,IAAA,oCAAU,EAAC,cAAc,EAAE;oBAC1C,OAAO,EAAE,EAAE;oBACX,SAAS,EAAE,EAAE;iBACd,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,QAAQ,CAAC,KAAK,GAAG,IAAA,oCAAU,EAAC,cAAc,EAAE;oBAC1C,QAAQ;oBACR,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC;iBACN,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,KAAK,GAAG,cAAc,CAAC;QAClC,CAAC;IACH,CAAC,EAAE,CAAC,cAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAE1D,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,SAAgB,kBAAkB,CAAC,UAAkB,EAAE,KAAa,EAAE,MAAc;IAClF,IAAI,UAAU,GAAG,CAAC;QAAE,OAAO,CAAC,CAAC;IAE7B,qDAAqD;IACrD,iFAAiF;IACjF,MAAM,gBAAgB,GAAG,KAAK,GAAG,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,4BAA4B;IAC1D,MAAM,sBAAsB,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IAEhG,OAAO,UAAU,GAAG,sBAAsB,CAAC;AAC7C,CAAC"}
|