@shohojdhara/atomix 0.2.3 → 0.2.5

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 (225) hide show
  1. package/README.md +19 -0
  2. package/dist/atomix.css +1703 -1544
  3. package/dist/atomix.min.css +4 -4
  4. package/dist/index.d.ts +1465 -963
  5. package/dist/index.esm.js +16289 -25908
  6. package/dist/index.esm.js.map +1 -1
  7. package/dist/index.js +15650 -21780
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.min.js +1 -1
  10. package/dist/index.min.js.map +1 -1
  11. package/dist/themes/applemix.css +15008 -0
  12. package/dist/themes/applemix.min.css +72 -0
  13. package/dist/themes/boomdevs.css +1608 -1450
  14. package/dist/themes/boomdevs.min.css +5 -5
  15. package/dist/themes/esrar.css +1702 -1543
  16. package/dist/themes/esrar.min.css +4 -4
  17. package/dist/themes/flashtrade.css +15159 -0
  18. package/dist/themes/flashtrade.min.css +86 -0
  19. package/dist/themes/mashroom.css +1699 -1540
  20. package/dist/themes/mashroom.min.css +7 -7
  21. package/dist/themes/shaj-default.css +1693 -1534
  22. package/dist/themes/shaj-default.min.css +4 -4
  23. package/package.json +6 -17
  24. package/src/components/Accordion/Accordion.stories.tsx +662 -21
  25. package/src/components/Accordion/Accordion.tsx +21 -14
  26. package/src/components/AtomixGlass/AtomixGlass.test.tsx +106 -72
  27. package/src/components/AtomixGlass/AtomixGlass.tsx +529 -1195
  28. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +400 -0
  29. package/src/components/AtomixGlass/GlassFilter.tsx +156 -0
  30. package/src/components/AtomixGlass/README.md +124 -2
  31. package/src/components/AtomixGlass/atomixGLass.old.tsx +1266 -0
  32. package/src/components/AtomixGlass/glass-utils.ts +263 -0
  33. package/src/components/AtomixGlass/shader-utils.ts +792 -68
  34. package/src/components/AtomixGlass/stories/AtomixGlass.stories.tsx +1250 -0
  35. package/src/components/AtomixGlass/stories/Examples.stories.tsx +5768 -0
  36. package/src/components/AtomixGlass/stories/Modes.stories.tsx +1065 -0
  37. package/src/components/AtomixGlass/stories/Playground.stories.tsx +1129 -0
  38. package/src/components/AtomixGlass/stories/ShaderVariants.stories.tsx +395 -0
  39. package/src/components/AtomixGlass/stories/shared-components.tsx +301 -0
  40. package/src/components/AtomixGlass/utils.ts +3 -3
  41. package/src/components/Avatar/Avatar.tsx +3 -0
  42. package/src/components/Avatar/AvatarGroup.tsx +2 -1
  43. package/src/components/Badge/Badge.stories.tsx +76 -55
  44. package/src/components/Badge/Badge.tsx +12 -14
  45. package/src/components/Breadcrumb/Breadcrumb.tsx +23 -4
  46. package/src/components/Button/Button.stories.tsx +501 -20
  47. package/src/components/Button/Button.tsx +5 -8
  48. package/src/components/Callout/Callout.stories.tsx +86 -35
  49. package/src/components/Callout/Callout.tsx +31 -9
  50. package/src/components/Card/Card.stories.tsx +565 -2
  51. package/src/components/Card/Card.tsx +15 -4
  52. package/src/components/Card/ElevationCard.tsx +2 -0
  53. package/src/components/Chart/AnimatedChart.tsx +179 -156
  54. package/src/components/Chart/AreaChart.tsx +123 -12
  55. package/src/components/Chart/BarChart.tsx +91 -100
  56. package/src/components/Chart/BaseChart.tsx +80 -0
  57. package/src/components/Chart/BubbleChart.tsx +114 -290
  58. package/src/components/Chart/CandlestickChart.tsx +282 -622
  59. package/src/components/Chart/Chart.stories.tsx +576 -179
  60. package/src/components/Chart/Chart.tsx +374 -75
  61. package/src/components/Chart/ChartRenderer.tsx +371 -220
  62. package/src/components/Chart/ChartToolbar.tsx +372 -61
  63. package/src/components/Chart/ChartTooltip.tsx +33 -18
  64. package/src/components/Chart/DonutChart.tsx +172 -254
  65. package/src/components/Chart/FunnelChart.tsx +169 -240
  66. package/src/components/Chart/GaugeChart.tsx +224 -392
  67. package/src/components/Chart/HeatmapChart.tsx +302 -440
  68. package/src/components/Chart/LineChart.tsx +148 -103
  69. package/src/components/Chart/MultiAxisChart.tsx +267 -395
  70. package/src/components/Chart/PieChart.tsx +114 -64
  71. package/src/components/Chart/RadarChart.tsx +202 -218
  72. package/src/components/Chart/ScatterChart.tsx +111 -97
  73. package/src/components/Chart/TreemapChart.tsx +147 -222
  74. package/src/components/Chart/WaterfallChart.tsx +253 -291
  75. package/src/components/Chart/index.ts +11 -9
  76. package/src/components/Chart/types.ts +85 -9
  77. package/src/components/Chart/utils.ts +66 -0
  78. package/src/components/ColorModeToggle/ColorModeToggle.tsx +6 -3
  79. package/src/components/Countdown/Countdown.tsx +4 -0
  80. package/src/components/DataTable/DataTable.tsx +2 -1
  81. package/src/components/DatePicker/DatePicker.stories.tsx +689 -12
  82. package/src/components/DatePicker/DatePicker.tsx +3 -9
  83. package/src/components/DatePicker/types.ts +5 -0
  84. package/src/components/Dropdown/Dropdown.stories.tsx +32 -25
  85. package/src/components/Dropdown/Dropdown.tsx +26 -28
  86. package/src/components/EdgePanel/EdgePanel.stories.tsx +473 -2
  87. package/src/components/EdgePanel/EdgePanel.tsx +101 -13
  88. package/src/components/Footer/Footer.stories.tsx +187 -60
  89. package/src/components/Footer/Footer.test.tsx +134 -0
  90. package/src/components/Footer/Footer.tsx +133 -34
  91. package/src/components/Footer/FooterLink.tsx +1 -1
  92. package/src/components/Footer/FooterSection.tsx +53 -36
  93. package/src/components/Footer/FooterSocialLink.tsx +32 -29
  94. package/src/components/Footer/README.md +82 -3
  95. package/src/components/Footer/index.ts +1 -1
  96. package/src/components/Form/Checkbox.stories.tsx +13 -5
  97. package/src/components/Form/Checkbox.tsx +3 -6
  98. package/src/components/Form/Form.stories.tsx +10 -3
  99. package/src/components/Form/Form.tsx +2 -0
  100. package/src/components/Form/FormGroup.tsx +2 -1
  101. package/src/components/Form/Input.stories.tsx +12 -11
  102. package/src/components/Form/Input.tsx +97 -95
  103. package/src/components/Form/Radio.stories.tsx +22 -7
  104. package/src/components/Form/Radio.tsx +3 -6
  105. package/src/components/Form/Select.stories.tsx +21 -6
  106. package/src/components/Form/Select.tsx +3 -5
  107. package/src/components/Form/Textarea.stories.tsx +13 -11
  108. package/src/components/Form/Textarea.tsx +88 -86
  109. package/src/components/Hero/Hero.stories.tsx +2 -3
  110. package/src/components/Hero/Hero.tsx +5 -6
  111. package/src/components/Icon/Icon.tsx +12 -1
  112. package/src/components/List/List.tsx +2 -1
  113. package/src/components/List/ListGroup.tsx +2 -1
  114. package/src/components/Messages/Messages.stories.tsx +113 -0
  115. package/src/components/Messages/Messages.tsx +52 -9
  116. package/src/components/Modal/Modal.stories.tsx +48 -32
  117. package/src/components/Modal/Modal.tsx +19 -24
  118. package/src/components/Navigation/Menu/MegaMenu.tsx +2 -2
  119. package/src/components/Navigation/Menu/Menu.tsx +2 -2
  120. package/src/components/Navigation/Nav/Nav.stories.tsx +469 -0
  121. package/src/components/Navigation/Nav/Nav.tsx +22 -4
  122. package/src/components/Navigation/Nav/NavDropdown.tsx +10 -1
  123. package/src/components/Navigation/Navbar/Navbar.stories.tsx +413 -0
  124. package/src/components/Navigation/Navbar/Navbar.tsx +70 -29
  125. package/src/components/Navigation/SideMenu/SideMenu.stories.tsx +340 -0
  126. package/src/components/Navigation/SideMenu/SideMenu.tsx +29 -2
  127. package/src/components/Pagination/Pagination.stories.tsx +13 -6
  128. package/src/components/Pagination/Pagination.tsx +7 -6
  129. package/src/components/PhotoViewer/PhotoViewer.tsx +2 -1
  130. package/src/components/Popover/Popover.stories.tsx +32 -24
  131. package/src/components/Popover/Popover.tsx +4 -1
  132. package/src/components/ProductReview/ProductReview.tsx +8 -2
  133. package/src/components/Progress/Progress.tsx +19 -3
  134. package/src/components/Rating/Rating.stories.tsx +11 -6
  135. package/src/components/Rating/Rating.tsx +3 -5
  136. package/src/components/River/River.tsx +5 -5
  137. package/src/components/SectionIntro/SectionIntro.tsx +8 -2
  138. package/src/components/Slider/Slider.stories.tsx +4 -4
  139. package/src/components/Slider/Slider.tsx +4 -3
  140. package/src/components/Spinner/Spinner.tsx +19 -3
  141. package/src/components/Steps/Steps.stories.tsx +5 -4
  142. package/src/components/Steps/Steps.tsx +8 -5
  143. package/src/components/Tab/Tab.stories.tsx +4 -3
  144. package/src/components/Tab/Tab.tsx +8 -6
  145. package/src/components/Testimonial/Testimonial.tsx +8 -2
  146. package/src/components/Todo/Todo.tsx +2 -1
  147. package/src/components/Toggle/Toggle.stories.tsx +5 -4
  148. package/src/components/Toggle/Toggle.tsx +8 -5
  149. package/src/components/Tooltip/Tooltip.stories.tsx +40 -30
  150. package/src/components/Tooltip/Tooltip.tsx +9 -2
  151. package/src/components/Upload/Upload.stories.tsx +252 -0
  152. package/src/components/Upload/Upload.tsx +92 -53
  153. package/src/components/VideoPlayer/VideoPlayer.tsx +3 -1
  154. package/src/components/index.ts +0 -4
  155. package/src/layouts/Grid/Grid.stories.tsx +10 -23
  156. package/src/layouts/Grid/Grid.tsx +20 -1
  157. package/src/layouts/Grid/GridCol.tsx +76 -48
  158. package/src/lib/composables/useAtomixGlass.ts +861 -44
  159. package/src/lib/composables/useBarChart.ts +21 -4
  160. package/src/lib/composables/useChart.ts +227 -370
  161. package/src/lib/composables/useChartExport.ts +19 -78
  162. package/src/lib/composables/useChartToolbar.ts +11 -21
  163. package/src/lib/composables/useEdgePanel.ts +125 -71
  164. package/src/lib/composables/useFooter.ts +3 -3
  165. package/src/lib/composables/useGlassContainer.ts +16 -7
  166. package/src/lib/composables/useLineChart.ts +11 -2
  167. package/src/lib/composables/usePieChart.ts +4 -14
  168. package/src/lib/composables/useRiver.ts +5 -0
  169. package/src/lib/composables/useSlider.ts +62 -24
  170. package/src/lib/composables/useVideoPlayer.ts +60 -63
  171. package/src/lib/constants/components.ts +147 -32
  172. package/src/lib/types/components.ts +355 -25
  173. package/src/lib/utils/displacement-generator.ts +55 -49
  174. package/src/lib/utils/icons.ts +1 -1
  175. package/src/lib/utils/index.ts +16 -10
  176. package/src/styles/01-settings/_settings.accordion.scss +19 -19
  177. package/src/styles/01-settings/_settings.animations.scss +5 -5
  178. package/src/styles/01-settings/_settings.avatar-group.scss +1 -1
  179. package/src/styles/01-settings/_settings.avatar.scss +17 -17
  180. package/src/styles/01-settings/_settings.background.scss +0 -3
  181. package/src/styles/01-settings/_settings.badge.scss +1 -1
  182. package/src/styles/01-settings/_settings.breadcrumb.scss +1 -1
  183. package/src/styles/01-settings/_settings.card.scss +1 -1
  184. package/src/styles/01-settings/_settings.chart.scss +65 -2
  185. package/src/styles/01-settings/_settings.dropdown.scss +1 -1
  186. package/src/styles/01-settings/_settings.edge-panel.scss +1 -1
  187. package/src/styles/01-settings/_settings.footer.scss +35 -42
  188. package/src/styles/01-settings/_settings.input.scss +1 -1
  189. package/src/styles/01-settings/_settings.list.scss +1 -1
  190. package/src/styles/01-settings/_settings.rating.scss +1 -1
  191. package/src/styles/01-settings/_settings.tabs.scss +1 -1
  192. package/src/styles/01-settings/_settings.upload.scss +6 -5
  193. package/src/styles/02-tools/_tools.animations.scss +4 -5
  194. package/src/styles/02-tools/_tools.background.scss +1 -13
  195. package/src/styles/02-tools/_tools.glass.scss +0 -1
  196. package/src/styles/02-tools/_tools.utility-api.scss +91 -48
  197. package/src/styles/03-generic/_generic.root.scss +1 -4
  198. package/src/styles/04-elements/_elements.body.scss +0 -1
  199. package/src/styles/06-components/_components.atomix-glass.scss +249 -0
  200. package/src/styles/06-components/_components.badge.scss +8 -23
  201. package/src/styles/06-components/_components.button.scss +8 -3
  202. package/src/styles/06-components/_components.callout.scss +10 -5
  203. package/src/styles/06-components/_components.card.scss +2 -14
  204. package/src/styles/06-components/_components.chart.scss +969 -1449
  205. package/src/styles/06-components/_components.dropdown.scss +19 -7
  206. package/src/styles/06-components/_components.edge-panel.scss +103 -0
  207. package/src/styles/06-components/_components.footer.scss +166 -85
  208. package/src/styles/06-components/_components.input.scss +8 -9
  209. package/src/styles/06-components/_components.list.scss +1 -0
  210. package/src/styles/06-components/_components.messages.scss +176 -0
  211. package/src/styles/06-components/_components.modal.scss +16 -4
  212. package/src/styles/06-components/_components.navbar.scss +12 -1
  213. package/src/styles/06-components/_components.side-menu.scss +5 -0
  214. package/src/styles/06-components/_components.skeleton.scss +8 -6
  215. package/src/styles/06-components/_components.upload.scss +219 -4
  216. package/src/styles/06-components/old.chart.styles.scss +1 -30
  217. package/src/styles/99-utilities/_index.scss +1 -0
  218. package/src/styles/99-utilities/_utilities.glass-fixes.scss +1 -0
  219. package/src/styles/99-utilities/_utilities.scss +1 -1
  220. package/src/components/AtomixGlass/AtomixGlass.stories.tsx +0 -3011
  221. package/src/components/AtomixGlass/AtomixGlassComprehensivePreview.stories.tsx +0 -1369
  222. package/src/components/Chart/AdvancedChart.tsx +0 -624
  223. package/src/components/Chart/LineChartNew.tsx +0 -167
  224. package/src/components/Chart/RealTimeChart.tsx +0 -436
  225. package/src/components/DatePicker/DatePicker copy.tsx +0 -551
@@ -1,8 +1,6 @@
1
- import { forwardRef, memo, useCallback, useEffect, useState } from 'react';
2
- import Chart from './Chart';
3
- import ChartRenderer from './ChartRenderer';
4
- import ChartTooltip from './ChartTooltip';
5
- import { ChartProps } from './types';
1
+ import { forwardRef, memo } from 'react';
2
+ import BaseChart from './BaseChart';
3
+ import { ChartProps, ChartRenderContentParams } from './types';
6
4
 
7
5
  export interface GaugeChartProps extends Omit<ChartProps, 'type' | 'datasets'> {
8
6
  /**
@@ -106,441 +104,275 @@ export interface GaugeChartProps extends Omit<ChartProps, 'type' | 'datasets'> {
106
104
 
107
105
  const GaugeChart = memo(
108
106
  forwardRef<HTMLDivElement, GaugeChartProps>(
109
- ({ value, min = 0, max = 100, config = {}, gaugeOptions = {}, ...props }, ref) => {
107
+ (
108
+ { value, min = 0, max = 100, config = {}, gaugeOptions = {}, onDataPointClick, ...props },
109
+ ref
110
+ ) => {
110
111
  const {
111
- startAngle = 225,
112
- endAngle = 315,
113
- thickness = 0.3,
112
+ startAngle = 180, // Default to left side (180 degrees)
113
+ endAngle = 0, // Default to right side (0 degrees)
114
+ thickness = 0.2,
114
115
  showNeedle = true,
115
- needleColor = 'var(--atomix-gray-8)',
116
+ needleColor = 'var(--atomix-brand-text-emphasis)',
116
117
  showValue = true,
117
- valueFormatter = v => v.toFixed(0),
118
+ valueFormatter = (val: number) => val.toFixed(1),
118
119
  showMinMaxLabels = true,
119
120
  showTicks = true,
120
121
  majorTicks = 5,
121
122
  minorTicks = 4,
122
- colorZones = [
123
- { from: 0, to: 30, color: 'var(--atomix-success)', label: 'Good' },
124
- { from: 30, to: 70, color: 'var(--atomix-warning)', label: 'Warning' },
125
- { from: 70, to: 100, color: 'var(--atomix-error)', label: 'Critical' },
126
- ],
123
+ colorZones = [],
127
124
  animate = true,
128
125
  animationDuration = 1000,
129
- animationEasing = 'ease-out',
130
- useGradient = true,
131
- label,
126
+ animationEasing = 'easeOutCubic',
127
+ useGradient = false,
128
+ label = '',
132
129
  labelPosition = 'bottom',
133
130
  } = gaugeOptions;
134
131
 
135
- const [animatedValue, setAnimatedValue] = useState(animate ? min : value);
136
- const [hoveredElement, setHoveredElement] = useState<{
137
- clientX: number;
138
- clientY: number;
139
- } | null>(null);
140
-
141
- useEffect(() => {
142
- if (animate) {
143
- const startTime = Date.now();
144
- const startValue = animatedValue;
145
- const targetValue = Math.max(min, Math.min(max, value));
146
- const valueChange = targetValue - startValue;
147
-
148
- const animateStep = () => {
149
- const elapsed = Date.now() - startTime;
150
- const progress = Math.min(elapsed / animationDuration, 1);
151
-
152
- // Apply easing
153
- let easedProgress = progress;
154
- if (animationEasing === 'ease-out') {
155
- easedProgress = 1 - Math.pow(1 - progress, 3);
156
- } else if (animationEasing === 'ease-in') {
157
- easedProgress = Math.pow(progress, 3);
158
- } else if (animationEasing === 'ease-in-out') {
159
- easedProgress =
160
- progress < 0.5 ? 4 * Math.pow(progress, 3) : 1 - Math.pow(-2 * progress + 2, 3) / 2;
161
- }
162
-
163
- const currentValue = startValue + valueChange * easedProgress;
164
- setAnimatedValue(currentValue);
165
-
166
- if (progress < 1) {
167
- requestAnimationFrame(animateStep);
168
- }
169
- };
170
-
171
- requestAnimationFrame(animateStep);
172
- } else {
173
- setAnimatedValue(value);
174
- }
175
- }, [value, min, max, animate, animationDuration, animationEasing, animatedValue]);
176
-
177
- const renderContent = useCallback(
178
- ({ scales, colors, handlers }: { scales: any; colors: any; handlers: any }) => {
179
- const centerX = scales.width / 2;
180
- const centerY = scales.height / 2;
181
- const radius = Math.min(centerX, centerY) * 0.8;
132
+ const renderContent = ({
133
+ scales,
134
+ colors,
135
+ datasets: renderedDatasets,
136
+ handlers,
137
+ hoveredPoint,
138
+ toolbarState,
139
+ config: renderConfig,
140
+ }: ChartRenderContentParams) => {
141
+ const width = scales.width;
142
+
143
+ // Use toolbar state if available, fallback to config for backward compatibility
144
+ const shouldAnimate = toolbarState?.animationsEnabled ?? renderConfig?.animate ?? animate;
145
+ const height = scales.height;
146
+ const centerX = width / 2;
147
+ const centerY = height / 2;
148
+ const radius = (Math.min(width, height) / 2) * 0.9;
149
+
150
+ // Calculate angles in radians
151
+ // In SVG, y-axis points down, so we need to adjust our angles accordingly
152
+ // We negate the angles to account for the SVG coordinate system
153
+ const startAngleRad = (-startAngle * Math.PI) / 180;
154
+ const endAngleRad = (-endAngle * Math.PI) / 180;
155
+ const angleRange = endAngleRad - startAngleRad;
156
+
157
+ // Clamp value to min/max range
158
+ const clampedValue = Math.min(Math.max(value, min), max);
159
+ const normalizedValue = (clampedValue - min) / (max - min);
160
+ const valueAngle = startAngleRad + normalizedValue * angleRange;
161
+
162
+ // Create SVG path for the track
163
+ const createArcPath = (
164
+ centerX: number,
165
+ centerY: number,
166
+ radius: number,
167
+ startAngle: number,
168
+ endAngle: number,
169
+ thickness: number
170
+ ) => {
182
171
  const innerRadius = radius * (1 - thickness);
172
+ const x1 = centerX + radius * Math.cos(startAngle);
173
+ const y1 = centerY + radius * Math.sin(startAngle);
174
+ const x2 = centerX + radius * Math.cos(endAngle);
175
+ const y2 = centerY + radius * Math.sin(endAngle);
176
+ const x3 = centerX + innerRadius * Math.cos(endAngle);
177
+ const y3 = centerY + innerRadius * Math.sin(endAngle);
178
+ const x4 = centerX + innerRadius * Math.cos(startAngle);
179
+ const y4 = centerY + innerRadius * Math.sin(startAngle);
180
+
181
+ // Determine large arc flag based on angle difference
182
+ const angleDiff = Math.abs(endAngle - startAngle);
183
+ const largeArcFlag = angleDiff > Math.PI ? 1 : 0;
184
+ // Sweep flag (1 for positive angle direction)
185
+ const sweepFlag = endAngle > startAngle ? 1 : 0;
186
+
187
+ return `M ${x1} ${y1}
188
+ A ${radius} ${radius} 0 ${largeArcFlag} ${sweepFlag} ${x2} ${y2}
189
+ L ${x3} ${y3}
190
+ A ${innerRadius} ${innerRadius} 0 ${largeArcFlag} ${1 - sweepFlag} ${x4} ${y4}
191
+ Z`;
192
+ };
183
193
 
184
- // Convert angles to radians
185
- const startRad = (startAngle * Math.PI) / 180;
186
- const endRad = (endAngle * Math.PI) / 180;
187
- const totalAngle = endRad - startRad;
188
-
189
- // Normalize value
190
- const normalizedValue = (animatedValue - min) / (max - min);
191
- const valueAngle = startRad + totalAngle * normalizedValue;
192
-
193
- const elements = [];
194
-
195
- // Background arc
196
- const backgroundPath = describeArc(
197
- centerX,
198
- centerY,
199
- radius,
200
- innerRadius,
201
- startAngle,
202
- endAngle
203
- );
204
- elements.push(
205
- <path key="background" d={backgroundPath} className="c-chart__gauge-background" />
194
+ // Create color zones
195
+ const zones = [];
196
+ for (const zone of colorZones) {
197
+ const zoneStart = startAngleRad + ((zone.from - min) / (max - min)) * angleRange;
198
+ const zoneEnd = startAngleRad + ((zone.to - min) / (max - min)) * angleRange;
199
+
200
+ zones.push(
201
+ <path
202
+ key={`zone-${zone.from}-${zone.to}`}
203
+ d={createArcPath(centerX, centerY, radius, zoneStart, zoneEnd, thickness)}
204
+ fill={zone.color}
205
+ />
206
206
  );
207
+ }
207
208
 
208
- // Color zones
209
- colorZones.forEach((zone, index) => {
210
- const zoneStartAngle =
211
- startAngle + ((zone.from - min) / (max - min)) * (endAngle - startAngle);
212
- const zoneEndAngle =
213
- startAngle + ((zone.to - min) / (max - min)) * (endAngle - startAngle);
214
-
215
- const zonePath = describeArc(
216
- centerX,
217
- centerY,
218
- radius,
219
- innerRadius,
220
- zoneStartAngle,
221
- zoneEndAngle
222
- );
223
-
224
- let fillColor = zone.color;
225
- if (useGradient) {
226
- const gradientId = `gauge-gradient-${index}`;
227
- elements.push(
228
- <defs key={`gradient-def-${index}`}>
229
- <linearGradient id={gradientId} x1="0%" y1="0%" x2="100%" y2="0%">
230
- <stop offset="0%" stopColor={zone.color} stopOpacity="0.8" />
231
- <stop offset="100%" stopColor={zone.color} stopOpacity="1" />
232
- </linearGradient>
233
- </defs>
234
- );
235
- fillColor = `url(#${gradientId})`;
236
- }
237
-
238
- elements.push(
239
- <path
240
- key={`zone-${index}`}
241
- d={zonePath}
242
- fill={fillColor}
243
- className="c-chart__gauge-zone"
209
+ // Create ticks
210
+ const ticks = [];
211
+ if (showTicks) {
212
+ // Major ticks
213
+ for (let i = 0; i <= majorTicks; i++) {
214
+ const tickValue = min + (max - min) * (i / majorTicks);
215
+ const tickAngle = startAngleRad + (i / majorTicks) * angleRange;
216
+ const tickRadius = radius * 0.95;
217
+ const tickLength = radius * 0.05;
218
+ const x1 = centerX + tickRadius * Math.cos(tickAngle);
219
+ const y1 = centerY + tickRadius * Math.sin(tickAngle);
220
+ const x2 = centerX + (tickRadius - tickLength) * Math.cos(tickAngle);
221
+ const y2 = centerY + (tickRadius - tickLength) * Math.sin(tickAngle);
222
+
223
+ ticks.push(
224
+ <line
225
+ key={`major-tick-${i}`}
226
+ x1={x1}
227
+ y1={y1}
228
+ x2={x2}
229
+ y2={y2}
230
+ stroke="var(--atomix-brand-border-subtle)"
231
+ strokeWidth="2"
244
232
  />
245
233
  );
246
- });
247
-
248
- // Ticks
249
- if (showTicks) {
250
- for (let i = 0; i <= majorTicks; i++) {
251
- const tickAngle = startAngle + (i / majorTicks) * (endAngle - startAngle);
252
- const tickRad = (tickAngle * Math.PI) / 180;
253
-
254
- // Major tick
255
- const majorTickStart = {
256
- x: centerX + Math.cos(tickRad) * (radius - 10),
257
- y: centerY + Math.sin(tickRad) * (radius - 10),
258
- };
259
- const majorTickEnd = {
260
- x: centerX + Math.cos(tickRad) * radius,
261
- y: centerY + Math.sin(tickRad) * radius,
262
- };
263
-
264
- elements.push(
265
- <line
266
- key={`major-tick-${i}`}
267
- x1={majorTickStart.x}
268
- y1={majorTickStart.y}
269
- x2={majorTickEnd.x}
270
- y2={majorTickEnd.y}
271
- className="c-chart__gauge-tick c-chart__gauge-tick--major"
272
- />
273
- );
274
234
 
275
- // Tick label
276
- const tickValue = min + (i / majorTicks) * (max - min);
277
- const labelRadius = radius + 15;
278
- const labelX = centerX + Math.cos(tickRad) * labelRadius;
279
- const labelY = centerY + Math.sin(tickRad) * labelRadius;
235
+ // Labels for major ticks
236
+ if (showMinMaxLabels) {
237
+ const labelX = centerX + (tickRadius - tickLength - 10) * Math.cos(tickAngle);
238
+ const labelY = centerY + (tickRadius - tickLength - 10) * Math.sin(tickAngle);
280
239
 
281
- elements.push(
240
+ ticks.push(
282
241
  <text
283
- key={`tick-label-${i}`}
242
+ key={`label-${i}`}
284
243
  x={labelX}
285
244
  y={labelY}
286
245
  textAnchor="middle"
287
246
  dominantBaseline="middle"
288
- className="c-chart__gauge-tick-label"
247
+ fontSize="12"
248
+ fill="var(--atomix-brand-text-emphasis)"
289
249
  >
290
- {tickValue.toFixed(0)}
250
+ {tickValue}
291
251
  </text>
292
252
  );
293
-
294
- // Minor ticks
295
- if (i < majorTicks) {
296
- for (let j = 1; j <= minorTicks; j++) {
297
- const minorTickAngle =
298
- tickAngle + (j / (minorTicks + 1)) * ((endAngle - startAngle) / majorTicks);
299
- const minorTickRad = (minorTickAngle * Math.PI) / 180;
300
-
301
- const minorTickStart = {
302
- x: centerX + Math.cos(minorTickRad) * (radius - 5),
303
- y: centerY + Math.sin(minorTickRad) * (radius - 5),
304
- };
305
- const minorTickEnd = {
306
- x: centerX + Math.cos(minorTickRad) * radius,
307
- y: centerY + Math.sin(minorTickRad) * radius,
308
- };
309
-
310
- elements.push(
311
- <line
312
- key={`minor-tick-${i}-${j}`}
313
- x1={minorTickStart.x}
314
- y1={minorTickStart.y}
315
- x2={minorTickEnd.x}
316
- y2={minorTickEnd.y}
317
- className="c-chart__gauge-tick c-chart__gauge-tick--minor"
318
- />
319
- );
320
- }
321
- }
322
253
  }
323
254
  }
324
255
 
325
- // Min/Max labels
326
- if (showMinMaxLabels) {
327
- const minLabelRadius = radius + 30;
328
- const maxLabelRadius = radius + 30;
329
-
330
- const minLabelX = centerX + Math.cos(startRad) * minLabelRadius;
331
- const minLabelY = centerY + Math.sin(startRad) * minLabelRadius;
332
- const maxLabelX = centerX + Math.cos(endRad) * maxLabelRadius;
333
- const maxLabelY = centerY + Math.sin(endRad) * maxLabelRadius;
334
-
335
- elements.push(
336
- <text
337
- key="min-label"
338
- x={minLabelX}
339
- y={minLabelY}
340
- textAnchor="middle"
341
- dominantBaseline="middle"
342
- className="c-chart__gauge-min-max-label"
343
- >
344
- {min}
345
- </text>
346
- );
347
-
348
- elements.push(
349
- <text
350
- key="max-label"
351
- x={maxLabelX}
352
- y={maxLabelY}
353
- textAnchor="middle"
354
- dominantBaseline="middle"
355
- className="c-chart__gauge-min-max-label"
356
- >
357
- {max}
358
- </text>
256
+ // Minor ticks
257
+ for (let i = 0; i < majorTicks * minorTicks; i++) {
258
+ const tickAngle = startAngleRad + (i / (majorTicks * minorTicks)) * angleRange;
259
+ const tickRadius = radius * 0.95;
260
+ const tickLength = radius * 0.025;
261
+ const x1 = centerX + tickRadius * Math.cos(tickAngle);
262
+ const y1 = centerY + tickRadius * Math.sin(tickAngle);
263
+ const x2 = centerX + (tickRadius - tickLength) * Math.cos(tickAngle);
264
+ const y2 = centerY + (tickRadius - tickLength) * Math.sin(tickAngle);
265
+
266
+ ticks.push(
267
+ <line
268
+ key={`minor-tick-${i}`}
269
+ x1={x1}
270
+ y1={y1}
271
+ x2={x2}
272
+ y2={y2}
273
+ stroke="var(--atomix-brand-border-subtle)"
274
+ strokeWidth="1"
275
+ />
359
276
  );
360
277
  }
278
+ }
361
279
 
362
- // Needle
363
- if (showNeedle) {
364
- const needleLength = radius * 0.8;
365
- const needleX = centerX + Math.cos(valueAngle) * needleLength;
366
- const needleY = centerY + Math.sin(valueAngle) * needleLength;
367
-
368
- elements.push(
369
- <g key="needle" className="c-chart__gauge-needle">
370
- <line
371
- x1={centerX}
372
- y1={centerY}
373
- x2={needleX}
374
- y2={needleY}
375
- stroke={needleColor}
376
- className="c-chart__gauge-needle-line"
377
- />
378
- <circle
379
- cx={centerX}
380
- cy={centerY}
381
- r="6"
382
- fill={needleColor}
383
- className="c-chart__gauge-needle-center"
384
- onMouseEnter={e => {
385
- const rect = e.currentTarget.ownerSVGElement?.getBoundingClientRect();
386
- const clientX = rect ? rect.left + centerX : e.clientX;
387
- const clientY = rect ? rect.top + centerY : e.clientY;
388
- setHoveredElement({ clientX, clientY });
389
- }}
390
- onMouseLeave={() => setHoveredElement(null)}
391
- />
392
- </g>
393
- );
394
- }
280
+ // Create needle
281
+ const needle = showNeedle ? (
282
+ <g>
283
+ <line
284
+ x1={centerX}
285
+ y1={centerY}
286
+ x2={centerX + radius * 0.8 * Math.cos(valueAngle)}
287
+ y2={centerY + radius * 0.8 * Math.sin(valueAngle)}
288
+ stroke={needleColor}
289
+ strokeWidth="3"
290
+ strokeLinecap="round"
291
+ />
292
+ <circle cx={centerX} cy={centerY} r="8" fill={needleColor} />
293
+ </g>
294
+ ) : null;
295
+
296
+ // Value text
297
+ const valueText = showValue ? (
298
+ <text
299
+ x={centerX}
300
+ y={centerY + 10}
301
+ textAnchor="middle"
302
+ fontSize="24"
303
+ fontWeight="bold"
304
+ fill="var(--atomix-primary-text-emphasis)"
305
+ >
306
+ {valueFormatter(clampedValue)}
307
+ </text>
308
+ ) : null;
309
+
310
+ // Label
311
+ const labelText = label ? (
312
+ <text
313
+ x={centerX}
314
+ y={labelPosition === 'top' ? centerY - radius * 0.7 : centerY + radius * 0.7}
315
+ textAnchor="middle"
316
+ fontSize="16"
317
+ fill="var(--atomix-brand-text-emphasis)"
318
+ >
319
+ {label}
320
+ </text>
321
+ ) : null;
322
+
323
+ return (
324
+ <g>
325
+ {/* Background track */}
326
+ <path
327
+ d={createArcPath(centerX, centerY, radius, startAngleRad, endAngleRad, thickness)}
328
+ fill="var(--atomix-secondary-bg-subtle)"
329
+ />
395
330
 
396
- // Value text
397
- if (showValue) {
398
- let valueY = centerY;
399
- if (labelPosition === 'top') valueY = centerY - 20;
400
- if (labelPosition === 'bottom') valueY = centerY + 20;
401
-
402
- elements.push(
403
- <text
404
- key="value-text"
405
- x={centerX}
406
- y={valueY}
407
- textAnchor="middle"
408
- dominantBaseline="middle"
409
- className="c-chart__gauge-value"
410
- >
411
- {valueFormatter(animatedValue)}
412
- </text>
413
- );
414
- }
331
+ {/* Color zones */}
332
+ {zones}
415
333
 
416
- // Custom label
417
- if (label) {
418
- let labelY = centerY + 40;
419
- if (labelPosition === 'top') labelY = centerY - 40;
420
- if (labelPosition === 'center') labelY = centerY + 10;
421
-
422
- elements.push(
423
- <text
424
- key="custom-label"
425
- x={centerX}
426
- y={labelY}
427
- textAnchor="middle"
428
- dominantBaseline="middle"
429
- className="c-chart__gauge-label"
430
- >
431
- {label}
432
- </text>
433
- );
434
- }
334
+ {/* Value track */}
335
+ <path
336
+ d={createArcPath(centerX, centerY, radius, startAngleRad, valueAngle, thickness)}
337
+ fill="var(--atomix-brand-bg-subtle)"
338
+ style={{
339
+ transition: shouldAnimate ? `all ${animationDuration}ms ${animationEasing}` : 'none',
340
+ }}
341
+ />
435
342
 
436
- return <g>{elements}</g>;
437
- },
438
- [
439
- animatedValue,
440
- min,
441
- max,
442
- startAngle,
443
- endAngle,
444
- thickness,
445
- showNeedle,
446
- needleColor,
447
- showValue,
448
- valueFormatter,
449
- showMinMaxLabels,
450
- showTicks,
451
- majorTicks,
452
- minorTicks,
453
- colorZones,
454
- useGradient,
455
- label,
456
- labelPosition,
457
- ]
458
- );
343
+ {/* Ticks */}
344
+ {ticks}
459
345
 
460
- // Helper function to create arc path
461
- const describeArc = (
462
- x: number,
463
- y: number,
464
- radius: number,
465
- innerRadius: number,
466
- startAngle: number,
467
- endAngle: number
468
- ) => {
469
- const start = polarToCartesian(x, y, radius, endAngle);
470
- const end = polarToCartesian(x, y, radius, startAngle);
471
- const innerStart = polarToCartesian(x, y, innerRadius, endAngle);
472
- const innerEnd = polarToCartesian(x, y, innerRadius, startAngle);
473
-
474
- const largeArcFlag = endAngle - startAngle <= 180 ? '0' : '1';
475
-
476
- return [
477
- 'M',
478
- start.x,
479
- start.y,
480
- 'A',
481
- radius,
482
- radius,
483
- 0,
484
- largeArcFlag,
485
- 0,
486
- end.x,
487
- end.y,
488
- 'L',
489
- innerEnd.x,
490
- innerEnd.y,
491
- 'A',
492
- innerRadius,
493
- innerRadius,
494
- 0,
495
- largeArcFlag,
496
- 1,
497
- innerStart.x,
498
- innerStart.y,
499
- 'Z',
500
- ].join(' ');
501
- };
346
+ {/* Needle */}
347
+ {needle}
502
348
 
503
- const polarToCartesian = (
504
- centerX: number,
505
- centerY: number,
506
- radius: number,
507
- angleInDegrees: number
508
- ) => {
509
- const angleInRadians = (angleInDegrees * Math.PI) / 180.0;
510
- return {
511
- x: centerX + radius * Math.cos(angleInRadians),
512
- y: centerY + radius * Math.sin(angleInRadians),
513
- };
349
+ {/* Value text */}
350
+ {valueText}
351
+
352
+ {/* Label */}
353
+ {labelText}
354
+ </g>
355
+ );
514
356
  };
515
357
 
516
- // Convert gauge value to datasets format for ChartRenderer
358
+ // Convert value to datasets format for BaseChart
517
359
  const datasets = [
518
360
  {
519
361
  label: 'Gauge Value',
520
- data: [{ label: 'Current', value: animatedValue }],
362
+ data: [{ label: 'Value', value }],
521
363
  },
522
364
  ];
523
365
 
524
366
  return (
525
- <Chart ref={ref} type="gauge" datasets={datasets} config={config} {...props}>
526
- <ChartRenderer datasets={datasets} config={config} renderContent={renderContent} />
527
- {hoveredElement && (
528
- <ChartTooltip
529
- dataPoint={{
530
- label: label || 'Current Value',
531
- value: animatedValue,
532
- metadata: {
533
- min,
534
- max,
535
- percentage: (((animatedValue - min) / (max - min)) * 100).toFixed(1) + '%',
536
- },
537
- }}
538
- datasetLabel="Gauge"
539
- position={{ x: hoveredElement.clientX, y: hoveredElement.clientY }}
540
- visible={true}
541
- />
542
- )}
543
- </Chart>
367
+ <BaseChart
368
+ ref={ref}
369
+ type="gauge"
370
+ datasets={datasets}
371
+ config={config}
372
+ renderContent={renderContent}
373
+ onDataPointClick={onDataPointClick}
374
+ {...props}
375
+ />
544
376
  );
545
377
  }
546
378
  )