@shohojdhara/atomix 0.5.0 → 0.5.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.
Files changed (168) hide show
  1. package/atomix.config.ts +12 -0
  2. package/build-tools/webpack-loader.js +5 -4
  3. package/dist/atomix.css +230 -83
  4. package/dist/atomix.css.map +1 -1
  5. package/dist/atomix.min.css +1 -1
  6. package/dist/atomix.min.css.map +1 -1
  7. package/dist/build-tools/webpack-loader.js +5 -4
  8. package/dist/charts.d.ts +24 -23
  9. package/dist/charts.js +271 -369
  10. package/dist/charts.js.map +1 -1
  11. package/dist/config.d.ts +624 -0
  12. package/dist/config.js +59 -0
  13. package/dist/config.js.map +1 -0
  14. package/dist/core.d.ts +3 -2
  15. package/dist/core.js +342 -382
  16. package/dist/core.js.map +1 -1
  17. package/dist/forms.d.ts +4 -6
  18. package/dist/forms.js +233 -334
  19. package/dist/forms.js.map +1 -1
  20. package/dist/heavy.d.ts +11 -2
  21. package/dist/heavy.js +406 -445
  22. package/dist/heavy.js.map +1 -1
  23. package/dist/index.d.ts +109 -65
  24. package/dist/index.esm.js +654 -748
  25. package/dist/index.esm.js.map +1 -1
  26. package/dist/index.js +621 -717
  27. package/dist/index.js.map +1 -1
  28. package/dist/index.min.js +1 -1
  29. package/dist/index.min.js.map +1 -1
  30. package/dist/layout.js +59 -60
  31. package/dist/layout.js.map +1 -1
  32. package/dist/theme.js +4 -4
  33. package/dist/theme.js.map +1 -1
  34. package/package.json +24 -9
  35. package/scripts/atomix-cli.js +15 -1
  36. package/scripts/cli/__tests__/complexity-utils.test.js +24 -0
  37. package/scripts/cli/__tests__/detector.test.js +50 -0
  38. package/scripts/cli/__tests__/template-engine.test.js +23 -0
  39. package/scripts/cli/__tests__/test-setup.js +1 -133
  40. package/scripts/cli/commands/doctor.js +15 -3
  41. package/scripts/cli/commands/generate.js +113 -51
  42. package/scripts/cli/internal/ai-engine.js +30 -10
  43. package/scripts/cli/internal/complexity-utils.js +60 -0
  44. package/scripts/cli/internal/component-validator.js +49 -16
  45. package/scripts/cli/internal/generator.js +89 -36
  46. package/scripts/cli/internal/hook-generator.js +5 -2
  47. package/scripts/cli/internal/itcss-generator.js +16 -12
  48. package/scripts/cli/templates/next-templates.js +81 -30
  49. package/scripts/cli/templates/storybook-templates.js +12 -2
  50. package/scripts/cli/utils/detector.js +45 -7
  51. package/scripts/cli/utils/diagnostics.js +78 -0
  52. package/scripts/cli/utils/telemetry.js +13 -0
  53. package/src/components/Accordion/Accordion.stories.tsx +4 -0
  54. package/src/components/AtomixGlass/AtomixGlass.tsx +188 -128
  55. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +63 -91
  56. package/src/components/AtomixGlass/PerformanceDashboard.tsx +153 -201
  57. package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +9 -6
  58. package/src/components/AtomixGlass/glass-utils.ts +51 -1
  59. package/src/components/AtomixGlass/stories/AnimationFeatures.stories.tsx +52 -46
  60. package/src/components/AtomixGlass/stories/Examples.stories.tsx +573 -236
  61. package/src/components/AtomixGlass/stories/Playground.stories.tsx +88 -41
  62. package/src/components/AtomixGlass/stories/argTypes.ts +19 -19
  63. package/src/components/AtomixGlass/stories/shared-components.tsx +7 -12
  64. package/src/components/AtomixGlass/stories/types.ts +3 -3
  65. package/src/components/Button/Button.tsx +114 -57
  66. package/src/components/Callout/Callout.tsx +4 -4
  67. package/src/components/Chart/ChartRenderer.tsx +1 -1
  68. package/src/components/Chart/DonutChart.tsx +11 -8
  69. package/src/components/EdgePanel/EdgePanel.tsx +119 -115
  70. package/src/components/Form/Select.tsx +4 -4
  71. package/src/components/List/List.tsx +4 -4
  72. package/src/components/Navigation/SideMenu/SideMenu.tsx +6 -6
  73. package/src/components/PhotoViewer/PhotoViewerImage.tsx +1 -1
  74. package/src/components/ProductReview/ProductReview.tsx +4 -2
  75. package/src/components/Rating/Rating.tsx +4 -2
  76. package/src/components/SectionIntro/SectionIntro.tsx +4 -2
  77. package/src/components/Steps/Steps.tsx +1 -1
  78. package/src/components/Tabs/Tabs.tsx +5 -5
  79. package/src/components/Testimonial/Testimonial.tsx +4 -2
  80. package/src/components/VideoPlayer/VideoPlayer.tsx +4 -2
  81. package/src/layouts/CssGrid/CssGrid.stories.tsx +464 -0
  82. package/src/layouts/CssGrid/CssGrid.tsx +215 -0
  83. package/src/layouts/CssGrid/index.ts +8 -0
  84. package/src/layouts/CssGrid/scripts/CssGrid.js +284 -0
  85. package/src/layouts/CssGrid/scripts/index.js +43 -0
  86. package/src/layouts/Grid/scripts/Container.js +139 -0
  87. package/src/layouts/Grid/scripts/Grid.js +184 -0
  88. package/src/layouts/Grid/scripts/GridCol.js +273 -0
  89. package/src/layouts/Grid/scripts/Row.js +154 -0
  90. package/src/layouts/Grid/scripts/index.js +48 -0
  91. package/src/layouts/MasonryGrid/MasonryGrid.tsx +71 -59
  92. package/src/lib/composables/atomix-glass/useGlassSize.ts +1 -1
  93. package/src/lib/composables/useAccordion.ts +5 -5
  94. package/src/lib/composables/useAtomixGlass.ts +111 -74
  95. package/src/lib/composables/useAtomixGlassStyles.ts +0 -2
  96. package/src/lib/composables/useBarChart.ts +2 -2
  97. package/src/lib/composables/useChart.ts +3 -2
  98. package/src/lib/composables/useChartToolbar.ts +48 -66
  99. package/src/lib/composables/useDataTable.ts +1 -1
  100. package/src/lib/composables/useDatePicker.ts +2 -2
  101. package/src/lib/composables/useEdgePanel.ts +45 -54
  102. package/src/lib/composables/useHeroBackgroundSlider.ts +5 -5
  103. package/src/lib/composables/usePhotoViewer.ts +2 -3
  104. package/src/lib/composables/usePieChart.ts +1 -1
  105. package/src/lib/composables/usePopover.ts +151 -139
  106. package/src/lib/composables/useSideMenu.ts +28 -41
  107. package/src/lib/composables/useSlider.ts +2 -6
  108. package/src/lib/composables/useTooltip.ts +2 -2
  109. package/src/lib/config/index.ts +39 -0
  110. package/src/lib/constants/components.ts +1 -0
  111. package/src/lib/theme/devtools/Comparator.tsx +1 -1
  112. package/src/lib/theme/devtools/Inspector.tsx +1 -1
  113. package/src/lib/theme/devtools/LiveEditor.tsx +1 -1
  114. package/src/lib/theme/runtime/ThemeProvider.tsx +1 -1
  115. package/src/lib/types/components.ts +1 -0
  116. package/src/styles/01-settings/_index.scss +1 -0
  117. package/src/styles/01-settings/_settings.atomix-glass.scss +174 -0
  118. package/src/styles/01-settings/_settings.masonry-grid.scss +42 -6
  119. package/src/styles/02-tools/_tools.glass.scss +6 -0
  120. package/src/styles/05-objects/_objects.masonry-grid.scss +162 -24
  121. package/src/styles/06-components/_components.atomix-glass.scss +160 -99
  122. package/scripts/cli/__tests__/README.md +0 -81
  123. package/scripts/cli/__tests__/basic.test.js +0 -116
  124. package/scripts/cli/__tests__/clean.test.js +0 -278
  125. package/scripts/cli/__tests__/component-generator.test.js +0 -332
  126. package/scripts/cli/__tests__/component-validator.test.js +0 -433
  127. package/scripts/cli/__tests__/generator.test.js +0 -613
  128. package/scripts/cli/__tests__/glass-motion.test.js +0 -256
  129. package/scripts/cli/__tests__/integration.test.js +0 -938
  130. package/scripts/cli/__tests__/migrate.test.js +0 -74
  131. package/scripts/cli/__tests__/security.test.js +0 -206
  132. package/scripts/cli/__tests__/theme-bridge.test.js +0 -507
  133. package/scripts/cli/__tests__/token-manager.test.js +0 -251
  134. package/scripts/cli/__tests__/token-provider.test.js +0 -361
  135. package/scripts/cli/__tests__/utils.test.js +0 -165
  136. package/src/components/AtomixGlass/stories/AnimationTests.stories.tsx +0 -95
  137. package/src/components/AtomixGlass/stories/CardExamples.stories.tsx +0 -212
  138. package/src/components/AtomixGlass/stories/Customization.stories.tsx +0 -131
  139. package/src/components/AtomixGlass/stories/DashboardExamples.stories.tsx +0 -348
  140. package/src/components/AtomixGlass/stories/EcommerceExamples.stories.tsx +0 -410
  141. package/src/components/AtomixGlass/stories/FormExamples.stories.tsx +0 -436
  142. package/src/components/AtomixGlass/stories/HeroExamples.stories.tsx +0 -264
  143. package/src/components/AtomixGlass/stories/InteractivePlayground.stories.tsx +0 -247
  144. package/src/components/AtomixGlass/stories/MobileUIExamples.stories.tsx +0 -418
  145. package/src/components/AtomixGlass/stories/ModalExamples.stories.tsx +0 -402
  146. package/src/components/AtomixGlass/stories/Modes.stories.tsx +0 -1082
  147. package/src/components/AtomixGlass/stories/Overview.stories.tsx +0 -497
  148. package/src/components/AtomixGlass/stories/Performance.stories.tsx +0 -103
  149. package/src/components/AtomixGlass/stories/PresetGallery.stories.tsx +0 -335
  150. package/src/components/AtomixGlass/stories/Shaders.stories.tsx +0 -395
  151. package/src/components/AtomixGlass/stories/WidgetExamples.stories.tsx +0 -441
  152. package/src/components/TypedButton/TypedButton.stories.tsx +0 -59
  153. package/src/components/TypedButton/TypedButton.tsx +0 -39
  154. package/src/components/TypedButton/index.ts +0 -2
  155. package/src/lib/composables/useBreadcrumb.ts +0 -81
  156. package/src/lib/composables/useChartInteractions.ts +0 -123
  157. package/src/lib/composables/useChartPerformance.ts +0 -347
  158. package/src/lib/composables/useDropdown.ts +0 -338
  159. package/src/lib/composables/useModal.ts +0 -110
  160. package/src/lib/composables/useTypedButton.ts +0 -66
  161. package/src/lib/hooks/usePerformanceMonitor.ts +0 -148
  162. package/src/lib/utils/displacement-generator.ts +0 -92
  163. package/src/lib/utils/memoryMonitor.ts +0 -191
  164. package/src/styles/01-settings/_settings.testtypecheck.scss +0 -53
  165. package/src/styles/01-settings/_settings.typedbutton.scss +0 -53
  166. package/src/styles/06-components/_components.testbutton.scss +0 -212
  167. package/src/styles/06-components/_components.testtypecheck.scss +0 -212
  168. package/src/styles/06-components/_components.typedbutton.scss +0 -212
@@ -1,123 +0,0 @@
1
- import { useCallback, useRef, useState } from 'react';
2
-
3
- interface InteractionState {
4
- isDragging: boolean;
5
- isZooming: boolean;
6
- lastPointerPos: { x: number; y: number } | null;
7
- zoomLevel: number;
8
- panOffset: { x: number; y: number };
9
- }
10
-
11
- export function useChartInteractions() {
12
- const [state, setState] = useState<InteractionState>({
13
- isDragging: false,
14
- isZooming: false,
15
- lastPointerPos: null,
16
- zoomLevel: 1,
17
- panOffset: { x: 0, y: 0 },
18
- });
19
-
20
- const wheelTimeoutRef = useRef<NodeJS.Timeout | null>(null);
21
- const lastWheelTime = useRef(0);
22
-
23
- // Improved wheel handling for both mouse and trackpad
24
- const handleWheel = useCallback((event: WheelEvent) => {
25
- event.preventDefault();
26
-
27
- const now = Date.now();
28
- const timeDelta = now - lastWheelTime.current;
29
- lastWheelTime.current = now;
30
-
31
- // Detect trackpad vs mouse wheel
32
- const isTrackpad = Math.abs(event.deltaY) < 50 && timeDelta < 50;
33
- const sensitivity = isTrackpad ? 0.01 : 0.1;
34
-
35
- if (wheelTimeoutRef.current) {
36
- clearTimeout(wheelTimeoutRef.current);
37
- }
38
-
39
- setState(prev => {
40
- const rect = (event.target as Element).getBoundingClientRect();
41
- const centerX = event.clientX - rect.left;
42
- const centerY = event.clientY - rect.top;
43
-
44
- // Zoom calculation
45
- const zoomFactor = 1 - event.deltaY * sensitivity;
46
- const newZoomLevel = Math.max(0.1, Math.min(10, prev.zoomLevel * zoomFactor));
47
-
48
- // Pan to zoom center
49
- const zoomRatio = newZoomLevel / prev.zoomLevel;
50
- const newPanOffset = {
51
- x: centerX - (centerX - prev.panOffset.x) * zoomRatio,
52
- y: centerY - (centerY - prev.panOffset.y) * zoomRatio,
53
- };
54
-
55
- return {
56
- ...prev,
57
- zoomLevel: newZoomLevel,
58
- panOffset: newPanOffset,
59
- isZooming: true,
60
- };
61
- });
62
-
63
- wheelTimeoutRef.current = setTimeout(() => {
64
- setState(prev => ({ ...prev, isZooming: false }));
65
- }, 150);
66
- }, []);
67
-
68
- // Unified pointer events for mouse and touch
69
- const handlePointerDown = useCallback((event: PointerEvent) => {
70
- setState(prev => ({
71
- ...prev,
72
- isDragging: true,
73
- lastPointerPos: { x: event.clientX, y: event.clientY },
74
- }));
75
- (event.target as Element).setPointerCapture(event.pointerId);
76
- }, []);
77
-
78
- const handlePointerMove = useCallback((event: PointerEvent) => {
79
- setState(prev => {
80
- if (!prev.isDragging || !prev.lastPointerPos) return prev;
81
-
82
- const deltaX = event.clientX - prev.lastPointerPos.x;
83
- const deltaY = event.clientY - prev.lastPointerPos.y;
84
-
85
- return {
86
- ...prev,
87
- panOffset: {
88
- x: prev.panOffset.x + deltaX,
89
- y: prev.panOffset.y + deltaY,
90
- },
91
- lastPointerPos: { x: event.clientX, y: event.clientY },
92
- };
93
- });
94
- }, []);
95
-
96
- const handlePointerUp = useCallback((event: PointerEvent) => {
97
- setState(prev => ({
98
- ...prev,
99
- isDragging: false,
100
- lastPointerPos: null,
101
- }));
102
- (event.target as Element).releasePointerCapture(event.pointerId);
103
- }, []);
104
-
105
- const resetView = useCallback(() => {
106
- setState(prev => ({
107
- ...prev,
108
- zoomLevel: 1,
109
- panOffset: { x: 0, y: 0 },
110
- }));
111
- }, []);
112
-
113
- return {
114
- state,
115
- handlers: {
116
- onWheel: handleWheel,
117
- onPointerDown: handlePointerDown,
118
- onPointerMove: handlePointerMove,
119
- onPointerUp: handlePointerUp,
120
- },
121
- resetView,
122
- };
123
- }
@@ -1,347 +0,0 @@
1
- import { useCallback, useMemo, useRef, useState } from 'react';
2
- import { ChartDataPoint, ChartDataset } from '../types/components';
3
-
4
- /**
5
- * Performance optimization hook for charts
6
- * Provides memoization, virtualization, and efficient re-rendering
7
- */
8
- export function useChartPerformance() {
9
- const renderCountRef = useRef(0);
10
- const lastRenderTimeRef = useRef(Date.now());
11
- const [performanceMetrics, setPerformanceMetrics] = useState({
12
- renderCount: 0,
13
- averageRenderTime: 0,
14
- lastRenderDuration: 0,
15
- });
16
-
17
- /**
18
- * Memoized chart data processing
19
- */
20
- const processDatasetsOptimized = useCallback((datasets: ChartDataset[]) => {
21
- const startTime = performance.now();
22
-
23
- // Process datasets with optimizations
24
- const processedDatasets = datasets.map(dataset => ({
25
- ...dataset,
26
- data: dataset.data.map((point, index) => ({
27
- ...point,
28
- // Add index for efficient lookups
29
- _index: index,
30
- // Pre-calculate commonly used values
31
- _stringValue: point.value.toString(),
32
- _hasMetadata: Boolean(point.metadata && Object.keys(point.metadata).length > 0),
33
- })),
34
- // Pre-calculate dataset statistics
35
- _stats: {
36
- min: Math.min(...dataset.data.map(p => p.value)),
37
- max: Math.max(...dataset.data.map(p => p.value)),
38
- average: dataset.data.reduce((sum, p) => sum + p.value, 0) / dataset.data.length,
39
- count: dataset.data.length,
40
- },
41
- }));
42
-
43
- const endTime = performance.now();
44
- const processingTime = endTime - startTime;
45
-
46
- // Update performance metrics
47
- renderCountRef.current += 1;
48
- const currentTime = Date.now();
49
- const timeSinceLastRender = currentTime - lastRenderTimeRef.current;
50
- lastRenderTimeRef.current = currentTime;
51
-
52
- setPerformanceMetrics(prev => ({
53
- renderCount: renderCountRef.current,
54
- averageRenderTime:
55
- (prev.averageRenderTime * (renderCountRef.current - 1) + processingTime) /
56
- renderCountRef.current,
57
- lastRenderDuration: processingTime,
58
- }));
59
-
60
- return processedDatasets;
61
- }, []);
62
-
63
- /**
64
- * Optimized scale calculations with caching
65
- */
66
- const createOptimizedScales = useCallback(
67
- (
68
- datasets: ChartDataset[],
69
- width: number,
70
- height: number,
71
- padding: { top: number; right: number; bottom: number; left: number }
72
- ) => {
73
- if (!datasets.length) return null;
74
-
75
- const innerWidth = width - padding.left - padding.right;
76
- const innerHeight = height - padding.top - padding.bottom;
77
-
78
- // Calculate bounds efficiently
79
- const allValues = datasets.flatMap(dataset => dataset.data.map(d => d.value));
80
- const minValue = Math.min(...allValues);
81
- const maxValue = Math.max(...allValues);
82
- const valueRange = maxValue - minValue;
83
-
84
- // Pre-calculate scale functions for better performance
85
- const xScale = (i: number, dataLength: number) =>
86
- padding.left + (i / (dataLength - 1)) * innerWidth;
87
-
88
- const yScale = (value: number) =>
89
- padding.top + innerHeight - ((value - minValue) / valueRange) * innerHeight;
90
-
91
- return {
92
- xScale,
93
- yScale,
94
- minValue,
95
- maxValue,
96
- valueRange,
97
- innerWidth,
98
- innerHeight,
99
- };
100
- },
101
- []
102
- );
103
-
104
- /**
105
- * Virtualization for large datasets
106
- */
107
- const useDataVirtualization = useCallback(
108
- (
109
- data: ChartDataPoint[],
110
- viewportStart: number,
111
- viewportEnd: number,
112
- bufferSize: number = 50
113
- ) => {
114
- if (data.length <= 1000) {
115
- // No virtualization needed for small datasets
116
- return {
117
- visibleData: data,
118
- startIndex: 0,
119
- endIndex: data.length - 1,
120
- isVirtualized: false,
121
- };
122
- }
123
-
124
- const start = Math.max(0, viewportStart - bufferSize);
125
- const end = Math.min(data.length - 1, viewportEnd + bufferSize);
126
-
127
- return {
128
- visibleData: data.slice(start, end + 1),
129
- startIndex: start,
130
- endIndex: end,
131
- isVirtualized: true,
132
- totalLength: data.length,
133
- };
134
- },
135
- []
136
- );
137
-
138
- /**
139
- * Debounced data updates for real-time charts
140
- * Returns a debounced function that maintains timeout state across calls
141
- * Uses a closure to maintain state - each call to useDebouncedUpdates creates
142
- * a new debounced function with its own persistent timeout state
143
- */
144
- const useDebouncedUpdates = useCallback((updateFunction: () => void, delay: number = 100) => {
145
- // Use a closure variable to maintain timeout state across multiple calls to the returned function
146
- // This variable is created once when useDebouncedUpdates is called and persists
147
- // across all invocations of the returned debounced function
148
- let timeoutId: NodeJS.Timeout | null = null;
149
-
150
- const debouncedFn: (() => void) & { cancel: () => void } = () => {
151
- // Clear any existing timeout before setting a new one
152
- if (timeoutId !== null) {
153
- clearTimeout(timeoutId);
154
- timeoutId = null;
155
- }
156
-
157
- // Set new timeout and store the ID
158
- timeoutId = setTimeout(() => {
159
- updateFunction();
160
- timeoutId = null;
161
- }, delay);
162
- };
163
-
164
- // Add cleanup method to cancel pending debounced calls
165
- debouncedFn.cancel = () => {
166
- if (timeoutId !== null) {
167
- clearTimeout(timeoutId);
168
- timeoutId = null;
169
- }
170
- };
171
-
172
- return debouncedFn;
173
- }, []);
174
-
175
- /**
176
- * Memory-efficient color palette generation using CSS custom properties
177
- */
178
- const generateOptimizedColorPalette = useMemo(() => {
179
- const baseColors = [
180
- 'var(--atomix-primary)',
181
- 'var(--atomix-secondary)',
182
- 'var(--atomix-success)',
183
- 'var(--atomix-info)',
184
- 'var(--atomix-warning)',
185
- 'var(--atomix-error)',
186
- 'var(--atomix-primary-5)',
187
- 'var(--atomix-primary-7)',
188
- 'var(--atomix-primary-3)',
189
- 'var(--atomix-gray-6)',
190
- 'var(--atomix-gray-8)',
191
- 'var(--atomix-gray-4)',
192
- 'var(--atomix-primary-2)',
193
- 'var(--atomix-primary-8)',
194
- 'var(--atomix-gray-5)',
195
- 'var(--atomix-gray-7)',
196
- 'var(--atomix-primary-4)',
197
- 'var(--atomix-primary-6)',
198
- ];
199
-
200
- // Pre-generate a large palette to avoid runtime calculations
201
- const extendedColors: string[] = [];
202
- for (let i = 0; i < 100; i++) {
203
- extendedColors.push(baseColors[i % baseColors.length] || '#000000');
204
- }
205
-
206
- return (index: number) => extendedColors[index % extendedColors.length];
207
- }, []);
208
-
209
- /**
210
- * Optimized animation frame handling
211
- * Returns animation control functions that maintain state across calls
212
- * Uses closures to maintain state - each call to useAnimationFrame creates
213
- * a new animation controller with its own persistent state
214
- */
215
- const useAnimationFrame = useCallback((callback: () => void) => {
216
- // Use closure variables to maintain animation state across multiple calls
217
- // These variables are created once when useAnimationFrame is called and persist
218
- // across all invocations of the returned animation control functions
219
- let requestId: number | null = null;
220
- let previousTime: number | null = null;
221
-
222
- const animate = (time: number) => {
223
- if (previousTime !== null && previousTime !== undefined) {
224
- const deltaTime = time - previousTime;
225
- callback();
226
- }
227
- previousTime = time;
228
- requestId = requestAnimationFrame(animate);
229
- };
230
-
231
- const startAnimation = () => {
232
- // Only start if not already running
233
- if (requestId === null) {
234
- requestId = requestAnimationFrame(animate);
235
- }
236
- };
237
-
238
- const stopAnimation = () => {
239
- if (requestId !== null) {
240
- cancelAnimationFrame(requestId);
241
- requestId = null;
242
- }
243
- previousTime = null;
244
- };
245
-
246
- return { startAnimation, stopAnimation };
247
- }, []);
248
-
249
- /**
250
- * Smart re-rendering based on data changes
251
- */
252
- const shouldUpdateChart = useCallback(
253
- (prevDatasets: ChartDataset[], newDatasets: ChartDataset[], threshold: number = 0.01) => {
254
- if (prevDatasets.length !== newDatasets.length) return true;
255
-
256
- // Check if any significant data changes occurred
257
- for (let i = 0; i < prevDatasets.length; i++) {
258
- const prevDataset = prevDatasets[i];
259
- const newDataset = newDatasets[i];
260
- if (!prevDataset || !newDataset) continue;
261
-
262
- const prevData = prevDataset.data;
263
- const newData = newDataset.data;
264
-
265
- if (prevData.length !== newData.length) return true;
266
-
267
- // Check for significant value changes
268
- for (let j = 0; j < prevData.length; j++) {
269
- const prevPoint = prevData[j];
270
- const newPoint = newData[j];
271
- if (!prevPoint || !newPoint) continue;
272
-
273
- const valueDiff = Math.abs(prevPoint.value - newPoint.value);
274
- const relativeChange = valueDiff / Math.abs(prevPoint.value);
275
-
276
- if (relativeChange > threshold) return true;
277
- }
278
- }
279
-
280
- return false;
281
- },
282
- []
283
- );
284
-
285
- /**
286
- * Canvas optimization for better performance
287
- */
288
- const optimizeCanvasRendering = useCallback(
289
- (
290
- canvasRef: React.RefObject<HTMLCanvasElement>,
291
- pixelRatio: number = window.devicePixelRatio || 1
292
- ) => {
293
- if (!canvasRef.current) return null;
294
-
295
- const canvas = canvasRef.current;
296
- const ctx = canvas.getContext('2d');
297
-
298
- if (!ctx) return null;
299
-
300
- // Set up high-DPI rendering
301
- const rect = canvas.getBoundingClientRect();
302
- canvas.width = rect.width * pixelRatio;
303
- canvas.height = rect.height * pixelRatio;
304
- canvas.style.width = rect.width + 'px';
305
- canvas.style.height = rect.height + 'px';
306
- ctx.scale(pixelRatio, pixelRatio);
307
-
308
- // Optimize canvas settings for better performance
309
- ctx.imageSmoothingEnabled = false;
310
- ctx.fillStyle = 'transparent';
311
- ctx.clearRect(0, 0, canvas.width, canvas.height);
312
-
313
- return { canvas, ctx, width: rect.width, height: rect.height };
314
- },
315
- []
316
- );
317
-
318
- /**
319
- * Batch DOM updates for better performance
320
- */
321
- const batchDOMUpdates = useCallback((updates: (() => void)[]) => {
322
- // Use requestAnimationFrame to batch DOM updates
323
- requestAnimationFrame(() => {
324
- updates.forEach(update => update());
325
- });
326
- }, []);
327
-
328
- return {
329
- // Data processing
330
- processDatasetsOptimized,
331
- createOptimizedScales,
332
- useDataVirtualization,
333
-
334
- // Performance monitoring
335
- performanceMetrics,
336
- shouldUpdateChart,
337
-
338
- // Rendering optimizations
339
- generateOptimizedColorPalette,
340
- optimizeCanvasRendering,
341
- batchDOMUpdates,
342
-
343
- // Animation and updates
344
- useAnimationFrame,
345
- useDebouncedUpdates,
346
- };
347
- }