@wavemaker/react-native-echarts 1.0.0-dev.0

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 (145) hide show
  1. package/.npmignore +4 -0
  2. package/LICENSE +21 -0
  3. package/README.md +39 -0
  4. package/area/area-chart.d.ts +12 -0
  5. package/area/area-chart.d.ts.map +1 -0
  6. package/area/area-chart.js +404 -0
  7. package/area/area-chart.props.d.ts +64 -0
  8. package/area/area-chart.props.d.ts.map +1 -0
  9. package/area/area-chart.props.js +0 -0
  10. package/area/index.d.ts +3 -0
  11. package/area/index.d.ts.map +1 -0
  12. package/area/index.js +1 -0
  13. package/axis.d.ts +3 -0
  14. package/axis.d.ts.map +1 -0
  15. package/axis.js +16 -0
  16. package/bar/bar-chart.d.ts +11 -0
  17. package/bar/bar-chart.d.ts.map +1 -0
  18. package/bar/bar-chart.js +6 -0
  19. package/bar/bar-chart.props.d.ts +7 -0
  20. package/bar/bar-chart.props.d.ts.map +1 -0
  21. package/bar/bar-chart.props.js +0 -0
  22. package/bar/index.d.ts +3 -0
  23. package/bar/index.d.ts.map +1 -0
  24. package/bar/index.js +1 -0
  25. package/bubble/bubble-chart.d.ts +13 -0
  26. package/bubble/bubble-chart.d.ts.map +1 -0
  27. package/bubble/bubble-chart.js +305 -0
  28. package/bubble/bubble-chart.props.d.ts +26 -0
  29. package/bubble/bubble-chart.props.d.ts.map +1 -0
  30. package/bubble/bubble-chart.props.js +0 -0
  31. package/bubble/index.d.ts +3 -0
  32. package/bubble/index.d.ts.map +1 -0
  33. package/bubble/index.js +1 -0
  34. package/candlestick/candlestick-chart.d.ts +12 -0
  35. package/candlestick/candlestick-chart.d.ts.map +1 -0
  36. package/candlestick/candlestick-chart.js +292 -0
  37. package/candlestick/candlestick-chart.props.d.ts +51 -0
  38. package/candlestick/candlestick-chart.props.d.ts.map +1 -0
  39. package/candlestick/candlestick-chart.props.js +0 -0
  40. package/candlestick/index.d.ts +3 -0
  41. package/candlestick/index.d.ts.map +1 -0
  42. package/candlestick/index.js +1 -0
  43. package/chart-container.d.ts +6 -0
  44. package/chart-container.d.ts.map +1 -0
  45. package/chart-container.js +63 -0
  46. package/chart-theme.context.d.ts +191 -0
  47. package/chart-theme.context.d.ts.map +1 -0
  48. package/chart-theme.context.js +276 -0
  49. package/column/column-chart.d.ts +13 -0
  50. package/column/column-chart.d.ts.map +1 -0
  51. package/column/column-chart.js +481 -0
  52. package/column/column-chart.props.d.ts +83 -0
  53. package/column/column-chart.props.d.ts.map +1 -0
  54. package/column/column-chart.props.js +0 -0
  55. package/column/index.d.ts +3 -0
  56. package/column/index.d.ts.map +1 -0
  57. package/column/index.js +1 -0
  58. package/gauge/digital/digital.gauge.d.ts +28 -0
  59. package/gauge/digital/digital.gauge.d.ts.map +1 -0
  60. package/gauge/digital/digital.gauge.js +213 -0
  61. package/gauge/gauge.types.d.ts +51 -0
  62. package/gauge/gauge.types.d.ts.map +1 -0
  63. package/gauge/gauge.types.js +0 -0
  64. package/gauge/index.d.ts +6 -0
  65. package/gauge/index.d.ts.map +1 -0
  66. package/gauge/index.js +4 -0
  67. package/gauge/radial/radial.gauge.d.ts +18 -0
  68. package/gauge/radial/radial.gauge.d.ts.map +1 -0
  69. package/gauge/radial/radial.gauge.js +284 -0
  70. package/gauge/simple/simple.gauge.d.ts +28 -0
  71. package/gauge/simple/simple.gauge.d.ts.map +1 -0
  72. package/gauge/simple/simple.gauge.js +102 -0
  73. package/gauge/speedometer/speedometer.gauge.d.ts +35 -0
  74. package/gauge/speedometer/speedometer.gauge.d.ts.map +1 -0
  75. package/gauge/speedometer/speedometer.gauge.js +241 -0
  76. package/geo/geo-chart.d.ts +15 -0
  77. package/geo/geo-chart.d.ts.map +1 -0
  78. package/geo/geo-chart.js +200 -0
  79. package/geo/geo-chart.props.d.ts +96 -0
  80. package/geo/geo-chart.props.d.ts.map +1 -0
  81. package/geo/geo-chart.props.js +0 -0
  82. package/geo/index.d.ts +7 -0
  83. package/geo/index.d.ts.map +1 -0
  84. package/geo/index.js +3 -0
  85. package/geo/us-chart.d.ts +15 -0
  86. package/geo/us-chart.d.ts.map +1 -0
  87. package/geo/us-chart.js +15 -0
  88. package/geo/world-chart.d.ts +15 -0
  89. package/geo/world-chart.d.ts.map +1 -0
  90. package/geo/world-chart.js +10 -0
  91. package/index.d.ts +17 -0
  92. package/index.d.ts.map +1 -0
  93. package/index.js +15 -0
  94. package/line/index.d.ts +3 -0
  95. package/line/index.d.ts.map +1 -0
  96. package/line/index.js +1 -0
  97. package/line/line-chart.d.ts +9 -0
  98. package/line/line-chart.d.ts.map +1 -0
  99. package/line/line-chart.js +8 -0
  100. package/line/line-chart.props.d.ts +12 -0
  101. package/line/line-chart.props.d.ts.map +1 -0
  102. package/line/line-chart.props.js +0 -0
  103. package/package.json +39 -0
  104. package/pie/index.d.ts +4 -0
  105. package/pie/index.d.ts.map +1 -0
  106. package/pie/index.js +2 -0
  107. package/pie/pie-chart.d.ts +13 -0
  108. package/pie/pie-chart.d.ts.map +1 -0
  109. package/pie/pie-chart.js +222 -0
  110. package/pie/pie-chart.props.d.ts +97 -0
  111. package/pie/pie-chart.props.d.ts.map +1 -0
  112. package/pie/pie-chart.props.js +12 -0
  113. package/props/cartesian.d.ts +120 -0
  114. package/props/cartesian.d.ts.map +1 -0
  115. package/props/cartesian.js +0 -0
  116. package/props/common.d.ts +28 -0
  117. package/props/common.d.ts.map +1 -0
  118. package/props/common.js +0 -0
  119. package/radar/index.d.ts +3 -0
  120. package/radar/index.d.ts.map +1 -0
  121. package/radar/index.js +1 -0
  122. package/radar/radar-chart.d.ts +12 -0
  123. package/radar/radar-chart.d.ts.map +1 -0
  124. package/radar/radar-chart.js +197 -0
  125. package/radar/radar-chart.props.d.ts +80 -0
  126. package/radar/radar-chart.props.d.ts.map +1 -0
  127. package/radar/radar-chart.props.js +0 -0
  128. package/radial/index.d.ts +3 -0
  129. package/radial/index.d.ts.map +1 -0
  130. package/radial/index.js +1 -0
  131. package/radial/radial-chart.d.ts +12 -0
  132. package/radial/radial-chart.d.ts.map +1 -0
  133. package/radial/radial-chart.js +235 -0
  134. package/radial/radial-chart.props.d.ts +74 -0
  135. package/radial/radial-chart.props.d.ts.map +1 -0
  136. package/radial/radial-chart.props.js +0 -0
  137. package/scatter/index.d.ts +3 -0
  138. package/scatter/index.d.ts.map +1 -0
  139. package/scatter/index.js +1 -0
  140. package/scatter/scatter-chart.d.ts +13 -0
  141. package/scatter/scatter-chart.d.ts.map +1 -0
  142. package/scatter/scatter-chart.js +310 -0
  143. package/scatter/scatter-chart.props.d.ts +36 -0
  144. package/scatter/scatter-chart.props.d.ts.map +1 -0
  145. package/scatter/scatter-chart.props.js +0 -0
@@ -0,0 +1,213 @@
1
+ import { withResponsiveContainer } from '../../chart-container';
2
+ import { useChartTheme, withChartTheme } from '../../chart-theme.context';
3
+ import React, { useEffect, useRef, useState } from 'react';
4
+ import { useWindowDimensions } from 'react-native';
5
+ import Svg, { Defs, G, LinearGradient, Path, Stop, Text as SvgText } from 'react-native-svg';
6
+ // SVG Gauge Component
7
+ const SVGGaugeChart = ({ value, max = 100, showInnerArc = false, width, height, animationDuration = 1000, colors, axisBgColor: axisBgColorProp, axisWidth: axisWidthProp, tickColor: tickColorProp, }) => {
8
+ const { theme: chartTheme } = useChartTheme(undefined, colors);
9
+ // Use theme colors; allow overrides from props
10
+ const gradientColors = chartTheme.series.map(item => item.color);
11
+ const inactiveTickColor = tickColorProp ?? axisBgColorProp ?? chartTheme.axis.r.tickColor;
12
+ const labelColor = chartTheme.axis.r.tickLabelColor;
13
+ const innerTickColor = chartTheme.axis.r.lineColor;
14
+ const arcColor = axisBgColorProp ?? chartTheme.grid.r.lineColor;
15
+ const dimensions = useWindowDimensions();
16
+ const [animatedValue, setAnimatedValue] = useState(value);
17
+ const currentValueRef = useRef(value); // Stores the current animated value synchronously
18
+ const animationFrameRef = useRef(undefined);
19
+ const startTimeRef = useRef(undefined);
20
+ // Animation effect when value changes
21
+ useEffect(() => {
22
+ // Start from the current animated position (stored in ref)
23
+ const startValue = currentValueRef.current;
24
+ const endValue = value;
25
+ const startTime = new Date().getTime();
26
+ startTimeRef.current = startTime;
27
+ const animate = () => {
28
+ const currentTime = new Date().getTime();
29
+ const elapsed = currentTime - startTime;
30
+ const progress = Math.min(elapsed / animationDuration, 1);
31
+ // Easing function (easeOutCubic for smooth deceleration)
32
+ const easeOutCubic = (t) => 1 - Math.pow(1 - t, 3);
33
+ const easedProgress = easeOutCubic(progress);
34
+ const currentValue = startValue + (endValue - startValue) * easedProgress;
35
+ // Update both state and ref synchronously
36
+ currentValueRef.current = currentValue;
37
+ setAnimatedValue(currentValue);
38
+ if (progress < 1) {
39
+ animationFrameRef.current = requestAnimationFrame(animate);
40
+ }
41
+ };
42
+ // Cancel any ongoing animation
43
+ if (animationFrameRef.current) {
44
+ cancelAnimationFrame(animationFrameRef.current);
45
+ }
46
+ animationFrameRef.current = requestAnimationFrame(animate);
47
+ return () => {
48
+ if (animationFrameRef.current) {
49
+ cancelAnimationFrame(animationFrameRef.current);
50
+ }
51
+ };
52
+ }, [value, animationDuration]);
53
+ // If height not provided, use 90% of available height
54
+ // If width not provided, use the same as height to keep it square
55
+ const calculatedHeight = height ?? dimensions.height * 0.9;
56
+ const calculatedWidth = width ?? calculatedHeight;
57
+ const size = Math.min(calculatedWidth, calculatedHeight);
58
+ const strokeWidth = 12;
59
+ const center = size / 2;
60
+ const radius = (size - strokeWidth) / 2 - 20;
61
+ const tickStrokeWidth = axisWidthProp ?? 3;
62
+ const startAngle = -135;
63
+ const endAngle = 135;
64
+ const totalAngle = endAngle - startAngle;
65
+ const percentage = (animatedValue / max) * 100;
66
+ const valueAngle = (percentage / 100) * totalAngle;
67
+ const polarToCartesian = (centerX, centerY, radius, angleInDegrees) => {
68
+ const angleInRadians = ((angleInDegrees - 90) * Math.PI) / 180.0;
69
+ return {
70
+ x: centerX + radius * Math.cos(angleInRadians),
71
+ y: centerY + radius * Math.sin(angleInRadians),
72
+ };
73
+ };
74
+ const describeArc = (centerX, centerY, radius, startAngle, endAngle) => {
75
+ const start = polarToCartesian(centerX, centerY, radius, endAngle);
76
+ const end = polarToCartesian(centerX, centerY, radius, startAngle);
77
+ const largeArcFlag = endAngle - startAngle <= 180 ? '0' : '1';
78
+ return `M ${start.x} ${start.y} A ${radius} ${radius} 0 ${largeArcFlag} 0 ${end.x} ${end.y}`;
79
+ };
80
+ // Helper function to interpolate between two colors
81
+ const interpolateColor = (color1, color2, factor) => {
82
+ const hex = (color) => {
83
+ const hex = color.replace('#', '');
84
+ return {
85
+ r: parseInt(hex.substring(0, 2), 16),
86
+ g: parseInt(hex.substring(2, 4), 16),
87
+ b: parseInt(hex.substring(4, 6), 16),
88
+ };
89
+ };
90
+ const c1 = hex(color1);
91
+ const c2 = hex(color2);
92
+ const r = Math.round(c1.r + factor * (c2.r - c1.r));
93
+ const g = Math.round(c1.g + factor * (c2.g - c1.g));
94
+ const b = Math.round(c1.b + factor * (c2.b - c1.b));
95
+ return `rgb(${r}, ${g}, ${b})`;
96
+ };
97
+ // Helper function to get color from gradient array based on position
98
+ const getGradientColor = (factor) => {
99
+ if (gradientColors.length === 0)
100
+ return '#FF6B6B';
101
+ if (gradientColors.length === 1)
102
+ return gradientColors[0];
103
+ // Determine which two colors to interpolate between
104
+ const scaledPosition = factor * (gradientColors.length - 1);
105
+ const lowerIndex = Math.floor(scaledPosition);
106
+ const upperIndex = Math.min(lowerIndex + 1, gradientColors.length - 1);
107
+ const localFactor = scaledPosition - lowerIndex;
108
+ return interpolateColor(gradientColors[lowerIndex], gradientColors[upperIndex], localFactor);
109
+ };
110
+ // Generate tick marks
111
+ const numTicks = 50;
112
+ const ticks = [];
113
+ const activeTickCount = Math.round((valueAngle / totalAngle) * numTicks);
114
+ const outerTickLength = 20;
115
+ for (let i = 0; i <= numTicks; i++) {
116
+ const angle = startAngle + (i / numTicks) * totalAngle;
117
+ const isActive = i <= activeTickCount;
118
+ const isMajor = i % 5 === 0;
119
+ const tickLength = outerTickLength;
120
+ const outerPoint = polarToCartesian(center, center, radius + 10, angle);
121
+ const innerPoint = polarToCartesian(center, center, radius + 10 - tickLength, angle);
122
+ // Calculate gradient factor for active ticks
123
+ let tickColor;
124
+ if (isActive) {
125
+ const gradientFactor = numTicks > 0 ? i / numTicks : 0;
126
+ tickColor = getGradientColor(gradientFactor);
127
+ }
128
+ else {
129
+ tickColor = inactiveTickColor;
130
+ }
131
+ ticks.push(<Path key={i} d={`M ${outerPoint.x} ${outerPoint.y} L ${innerPoint.x} ${innerPoint.y}`} stroke={tickColor} strokeWidth={tickStrokeWidth} strokeLinecap="round"/>);
132
+ }
133
+ // Generate scale labels and inner ticks
134
+ const scaleLabels = [];
135
+ const innerTicks = [];
136
+ const majorTickPositions = [0, 20, 40, 60, 80, 100];
137
+ const labelRadius = radius - 40;
138
+ const innerTickLength = 4;
139
+ const minorTickLength = 2;
140
+ const gapFromOuterTicks = 4; // Gap between outer and inner elements
141
+ const innerTickOuterRadius = radius - outerTickLength - gapFromOuterTicks;
142
+ // Add major ticks and labels
143
+ for (const labelValue of majorTickPositions) {
144
+ const labelAngle = startAngle + (labelValue / max) * totalAngle;
145
+ const labelPosition = polarToCartesian(center, center, labelRadius, labelAngle);
146
+ // Add scale label
147
+ scaleLabels.push(<SvgText key={`label-${labelValue}`} x={labelPosition.x} y={labelPosition.y} textAnchor="middle" fontSize="12" fill={labelColor}>
148
+ {labelValue}
149
+ </SvgText>);
150
+ // Add major inner tick mark
151
+ const tickOuterPoint = polarToCartesian(center, center, innerTickOuterRadius, labelAngle);
152
+ const tickInnerPoint = polarToCartesian(center, center, innerTickOuterRadius - innerTickLength, labelAngle);
153
+ innerTicks.push(<Path key={`inner-tick-${labelValue}`} d={`M ${tickOuterPoint.x} ${tickOuterPoint.y} L ${tickInnerPoint.x} ${tickInnerPoint.y}`} stroke={innerTickColor} strokeWidth={2} strokeLinecap="round"/>);
154
+ }
155
+ // Add minor ticks (9 ticks between each major tick)
156
+ // Major ticks are at 0, 20, 40, 60, 80, 100
157
+ // So we need ticks at every 2 units, excluding the major positions
158
+ for (let value = 0; value <= max; value += 2) {
159
+ // Skip if this is a major tick position
160
+ if (majorTickPositions.includes(value))
161
+ continue;
162
+ const tickAngle = startAngle + (value / max) * totalAngle;
163
+ const tickOuterPoint = polarToCartesian(center, center, innerTickOuterRadius, tickAngle);
164
+ const tickInnerPoint = polarToCartesian(center, center, innerTickOuterRadius - minorTickLength, tickAngle);
165
+ innerTicks.push(<Path key={`inner-minor-tick-${value}`} d={`M ${tickOuterPoint.x} ${tickOuterPoint.y} L ${tickInnerPoint.x} ${tickInnerPoint.y}`} stroke={inactiveTickColor} strokeWidth={1} strokeLinecap="round"/>);
166
+ }
167
+ // Calculate the animated end angle for the outer arc
168
+ const animatedEndAngle = startAngle + valueAngle;
169
+ const outerArcRadius = radius + 10;
170
+ return (<Svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
171
+ <Defs>
172
+ <LinearGradient id="gaugeGradient" x1="0%" y1="0%" x2="100%" y2="0%">
173
+ <Stop offset="0%" stopColor={gradientColors[0]} stopOpacity="1"/>
174
+ <Stop offset="100%" stopColor={gradientColors[gradientColors.length - 1]} stopOpacity="1"/>
175
+ </LinearGradient>
176
+
177
+ {/* Radial gradient for a more dynamic look */}
178
+ <LinearGradient id="outerArcGradient" x1="0%" y1="0%" x2="100%" y2="0%">
179
+ <Stop offset="0%" stopColor={gradientColors[0]} stopOpacity="0.8"/>
180
+ <Stop offset="100%" stopColor={gradientColors[gradientColors.length - 1]} stopOpacity="0.8"/>
181
+ </LinearGradient>
182
+ </Defs>
183
+
184
+
185
+ {/* Tick marks */}
186
+ <G>{ticks}</G>
187
+
188
+ {/* Inner arc connecting the inner ticks (from 0 to 100) */}
189
+ {showInnerArc && (<Path d={describeArc(center, center, innerTickOuterRadius, startAngle, endAngle)} fill="none" stroke={arcColor} strokeWidth={1} opacity={0.5}/>)}
190
+
191
+ {/* Inner scale ticks */}
192
+ <G>{innerTicks}</G>
193
+
194
+ {/* Scale labels */}
195
+ <G>{scaleLabels}</G>
196
+
197
+ {/* Value display */}
198
+ <SvgText x={center} y={center + 10} textAnchor="middle" fontSize="56" fontWeight="bold" fill={chartTheme.axis.r.tickLabelColor}>
199
+ {Math.round(animatedValue)}
200
+ </SvgText>
201
+
202
+ {/* Label */}
203
+ <SvgText x={center} y={center + 30} textAnchor="middle" fontSize="14" fill={labelColor}>
204
+ Value
205
+ </SvgText>
206
+ </Svg>);
207
+ };
208
+ const ChartComponent = ({ value = 46, min = 0, max = 90, width, height, axisBgColor, axisWidth, tickColor, showInnerArc, animationDuration, ...props }) => {
209
+ return (<SVGGaugeChart value={value} max={max} width={width} height={height} colors={props.colors} axisBgColor={axisBgColor} axisWidth={axisWidth} tickColor={tickColor} showInnerArc={showInnerArc} animationDuration={animationDuration}/>);
210
+ };
211
+ export const DigitalGauge = Object.assign(withResponsiveContainer(withChartTheme(ChartComponent), 'value'), {
212
+ displayName: 'DigitalGauge',
213
+ });
@@ -0,0 +1,51 @@
1
+ import type { ChartTheme } from '../chart-theme.context';
2
+ /**
3
+ * Common props shared by all gauge chart components.
4
+ * Individual gauge components extend this interface with their specific props.
5
+ */
6
+ export interface BaseGaugeProps {
7
+ /**
8
+ * Current value to display on the gauge.
9
+ */
10
+ value: number;
11
+ /**
12
+ * Minimum value of the gauge scale.
13
+ * @default 0
14
+ */
15
+ min?: number;
16
+ /**
17
+ * Maximum value of the gauge scale.
18
+ * @default 100
19
+ */
20
+ max?: number;
21
+ /**
22
+ * Width of the chart in pixels.
23
+ */
24
+ width?: number;
25
+ /**
26
+ * Height of the chart in pixels.
27
+ */
28
+ height?: number;
29
+ /**
30
+ * Partial theme override for customizing chart appearance.
31
+ */
32
+ theme?: Partial<ChartTheme>;
33
+ /**
34
+ * Colors for the chart.
35
+ * @default theme.itemStyles.map(item => item.color)
36
+ */
37
+ colors?: string[];
38
+ /**
39
+ * Background color for the axis/track.
40
+ */
41
+ axisBgColor?: string;
42
+ /**
43
+ * Width of the axis line in pixels.
44
+ */
45
+ axisWidth?: number;
46
+ /**
47
+ * Color for tick marks and split lines.
48
+ */
49
+ tickColor?: string;
50
+ }
51
+ //# sourceMappingURL=gauge.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gauge.types.d.ts","sourceRoot":"","sources":["../../../../components/chart/gauge/gauge.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEzD;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAE5B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAElB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
File without changes
@@ -0,0 +1,6 @@
1
+ export type { BaseGaugeProps } from './gauge.types';
2
+ export { SimpleGauge } from './simple/simple.gauge';
3
+ export { DigitalGauge } from './digital/digital.gauge';
4
+ export { SpeedometerGauge } from './speedometer/speedometer.gauge';
5
+ export { RadialGauge } from './radial/radial.gauge';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/chart/gauge/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC"}
package/gauge/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { SimpleGauge } from './simple/simple.gauge';
2
+ export { DigitalGauge } from './digital/digital.gauge';
3
+ export { SpeedometerGauge } from './speedometer/speedometer.gauge';
4
+ export { RadialGauge } from './radial/radial.gauge';
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ import type { BaseGaugeProps } from '../gauge.types';
3
+ /**
4
+ * Props for the RadialGauge component.
5
+ * A composite gauge with both radial progress bar and traditional gauge display.
6
+ */
7
+ interface RadialGaugeProps extends BaseGaugeProps {
8
+ }
9
+ export declare const RadialGauge: ((props: RadialGaugeProps & {
10
+ theme?: Partial<import("../..").ChartTheme>;
11
+ } & {
12
+ width?: number | string;
13
+ height?: number | string;
14
+ }) => React.JSX.Element) & {
15
+ displayName: string;
16
+ };
17
+ export {};
18
+ //# sourceMappingURL=radial.gauge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"radial.gauge.d.ts","sourceRoot":"","sources":["../../../../../components/chart/gauge/radial/radial.gauge.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAqC,MAAM,OAAO,CAAC;AAE1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAUrD;;;GAGG;AACH,UAAU,gBAAiB,SAAQ,cAAc;CAAG;AAgSpD,eAAO,MAAM,WAAW;;;;;;;CAEtB,CAAC"}
@@ -0,0 +1,284 @@
1
+ import { withResponsiveContainer } from '../../chart-container';
2
+ import { useChartTheme, withChartTheme } from '../../chart-theme.context';
3
+ import { SkiaChart, SkiaRenderer } from '@wuba/react-native-echarts';
4
+ import { BarChart } from 'echarts/charts';
5
+ import { GaugeChart } from 'echarts/charts';
6
+ import { PolarComponent } from 'echarts/components';
7
+ import * as echarts from 'echarts/core';
8
+ import React, { useEffect, useMemo, useRef } from 'react';
9
+ import { View, StyleSheet } from 'react-native';
10
+ // Register necessary components for this chart
11
+ echarts.use([
12
+ SkiaRenderer,
13
+ GaugeChart,
14
+ BarChart,
15
+ PolarComponent,
16
+ ]);
17
+ const ChartComponent = ({ value, min = 0, max = 100, width = 220, height = 240, axisBgColor: axisBgColorProp, axisWidth: axisWidthProp, tickColor: tickColorProp, ...props }) => {
18
+ const { theme: chartTheme } = useChartTheme(props.theme, props.colors);
19
+ const chartRef = useRef(null);
20
+ const radialChartRef = useRef(null);
21
+ // Radial background chart option (textRadialOption)
22
+ const radialOption = useMemo(() => {
23
+ // Calculate radius as percentage of the smaller dimension with gap
24
+ const minDim = Math.min(width, height);
25
+ const innerRadius = minDim * 0.30; // ~77px at 240px - inner edge of radial ring
26
+ const outerRadius = minDim * 0.48; // ~115px at 240px - outer edge of radial ring
27
+ const backgroundColor = axisBgColorProp ?? chartTheme.axis.r.tickColor;
28
+ const progressColor = chartTheme.series[0].color;
29
+ return {
30
+ polar: {
31
+ center: ['50%', '50%'],
32
+ radius: [innerRadius, outerRadius],
33
+ },
34
+ angleAxis: {
35
+ max: max,
36
+ startAngle: 225,
37
+ endAngle: -45,
38
+ clockwise: true,
39
+ show: false
40
+ },
41
+ radiusAxis: {
42
+ type: 'category',
43
+ data: ['Data'],
44
+ show: false
45
+ },
46
+ series: [
47
+ {
48
+ type: 'bar',
49
+ data: [max],
50
+ coordinateSystem: 'polar',
51
+ name: 'Background',
52
+ tooltip: {
53
+ show: false,
54
+ },
55
+ itemStyle: {
56
+ color: backgroundColor,
57
+ borderRadius: [50, 50],
58
+ },
59
+ animation: false,
60
+ barWidth: '50%',
61
+ emphasis: {
62
+ disabled: true,
63
+ },
64
+ },
65
+ {
66
+ type: 'bar',
67
+ data: [value],
68
+ coordinateSystem: 'polar',
69
+ name: 'Value',
70
+ itemStyle: {
71
+ color: progressColor,
72
+ borderRadius: [50, 50],
73
+ },
74
+ barWidth: '50%',
75
+ barGap: '-100%',
76
+ emphasis: {
77
+ disabled: true,
78
+ },
79
+ },
80
+ ]
81
+ };
82
+ }, [chartTheme, value, max, width, height, axisBgColorProp]);
83
+ // Gauge option (progressArcOption)
84
+ const gaugeOption = useMemo(() => {
85
+ // Gauge radius smaller than radial inner ring to create a gap
86
+ const minDim = Math.min(width, height);
87
+ const gaugeRadius = minDim * 0.32; // ~65px at 240px - creates gap with radial inner ring (77px)
88
+ const axisLineColor = axisBgColorProp ?? chartTheme.axis.r.tickColor;
89
+ const pointerColor = chartTheme.axis.r.lineColor;
90
+ const tickColor = tickColorProp ?? chartTheme.axis.r.tickColor;
91
+ const splitLineColor = tickColorProp ?? chartTheme.axis.r.tickColor;
92
+ const labelColor = chartTheme.axis.r.tickLabelColor;
93
+ const anchorColor = chartTheme.axis.r.lineColor;
94
+ const anchorBorderColor = tickColorProp ?? chartTheme.axis.r.tickColor;
95
+ const valueColor = chartTheme.axis.r.tickLabelColor;
96
+ const unitColor = chartTheme.axis.r.tickLabelColor;
97
+ return {
98
+ series: [
99
+ {
100
+ type: 'gauge',
101
+ center: ['50%', '50%'],
102
+ radius: gaugeRadius,
103
+ startAngle: 225,
104
+ endAngle: -45,
105
+ min: min,
106
+ max: max,
107
+ splitNumber: 5,
108
+ axisLine: {
109
+ show: false,
110
+ distance: 1,
111
+ length: 8,
112
+ lineStyle: {
113
+ width: axisWidthProp ?? 1,
114
+ color: [[1, axisLineColor]],
115
+ },
116
+ },
117
+ pointer: {
118
+ length: '80%',
119
+ width: 8,
120
+ icon: 'path://M-4,0 L-2,-50 A1, 1 0 0 1 2, -50 L4,0 A1, 1 0 0 1 -4, 0 Z',
121
+ itemStyle: {
122
+ color: pointerColor,
123
+ },
124
+ },
125
+ axisTick: {
126
+ distance: 1,
127
+ length: 4,
128
+ splitNumber: 16,
129
+ lineStyle: {
130
+ color: tickColor,
131
+ width: 0.5,
132
+ },
133
+ },
134
+ splitLine: {
135
+ distance: 1,
136
+ length: 8,
137
+ lineStyle: {
138
+ color: splitLineColor,
139
+ width: 1,
140
+ },
141
+ },
142
+ axisLabel: {
143
+ show: true,
144
+ distance: 16,
145
+ fontSize: 12,
146
+ color: labelColor,
147
+ formatter: function (value) {
148
+ if (value === 20 || value === 80) {
149
+ return value.toString();
150
+ }
151
+ return '';
152
+ },
153
+ },
154
+ anchor: {
155
+ show: true,
156
+ showAbove: true,
157
+ size: 8,
158
+ itemStyle: {
159
+ color: anchorColor,
160
+ borderColor: anchorBorderColor,
161
+ borderWidth: 3,
162
+ shadowBlur: 3,
163
+ shadowColor: 'rgba(0,0,0,0.15)',
164
+ },
165
+ },
166
+ detail: {
167
+ valueAnimation: true,
168
+ formatter: function (value) {
169
+ return '{value|' + Math.round(value) + '}{unit|/100}';
170
+ },
171
+ offsetCenter: [0, '70%'],
172
+ rich: {
173
+ value: {
174
+ fontSize: 40,
175
+ fontWeight: 'bold',
176
+ color: valueColor,
177
+ },
178
+ unit: {
179
+ verticalAlign: 'bottom',
180
+ fontSize: 16,
181
+ color: unitColor,
182
+ fontWeight: 'normal',
183
+ },
184
+ }
185
+ },
186
+ data: [{ value: value }],
187
+ }
188
+ ],
189
+ style: {
190
+ backgroundColor: 'transparent',
191
+ },
192
+ };
193
+ }, [chartTheme, value, min, max, width, height, axisBgColorProp, axisWidthProp, tickColorProp]);
194
+ // Initialize radial background chart
195
+ useEffect(() => {
196
+ let chart;
197
+ if (radialChartRef.current) {
198
+ try {
199
+ chart = echarts.init(radialChartRef.current, 'light', {
200
+ width: width,
201
+ height: height,
202
+ });
203
+ chart.setOption(radialOption);
204
+ }
205
+ catch (error) {
206
+ console.warn('Radial chart initialization error:', error);
207
+ }
208
+ }
209
+ return () => {
210
+ if (chart) {
211
+ try {
212
+ chart.dispose();
213
+ }
214
+ catch (error) {
215
+ console.warn('Radial chart disposal error:', error);
216
+ }
217
+ }
218
+ };
219
+ }, [radialOption, width, height]);
220
+ // Initialize gauge chart (same size as radial chart)
221
+ useEffect(() => {
222
+ let chart;
223
+ if (chartRef.current) {
224
+ try {
225
+ chart = echarts.init(chartRef.current, 'light', {
226
+ width: width,
227
+ height: height,
228
+ });
229
+ chart.setOption(gaugeOption);
230
+ }
231
+ catch (error) {
232
+ console.warn('Gauge chart initialization error:', error);
233
+ }
234
+ }
235
+ return () => {
236
+ if (chart) {
237
+ try {
238
+ chart.dispose();
239
+ }
240
+ catch (error) {
241
+ console.warn('Gauge chart disposal error:', error);
242
+ }
243
+ }
244
+ };
245
+ }, [gaugeOption, width, height]);
246
+ return (<View style={[styles.container, { width, height }]}>
247
+ <View style={styles.radialChart}>
248
+ <SkiaChart ref={radialChartRef}/>
249
+ </View>
250
+ <View style={styles.gaugeChart}>
251
+ <SkiaChart ref={chartRef}/>
252
+ </View>
253
+ </View>);
254
+ };
255
+ const styles = StyleSheet.create({
256
+ container: {
257
+ position: 'relative',
258
+ justifyContent: 'center',
259
+ alignItems: 'center',
260
+ },
261
+ radialChart: {
262
+ position: 'absolute',
263
+ top: 0,
264
+ left: 0,
265
+ right: 0,
266
+ bottom: 0,
267
+ justifyContent: 'center',
268
+ alignItems: 'center',
269
+ backgroundColor: 'transparent',
270
+ },
271
+ gaugeChart: {
272
+ position: 'absolute',
273
+ top: 0,
274
+ left: 0,
275
+ right: 0,
276
+ bottom: 0,
277
+ justifyContent: 'center',
278
+ alignItems: 'center',
279
+ backgroundColor: 'transparent',
280
+ },
281
+ });
282
+ export const RadialGauge = Object.assign(withResponsiveContainer(withChartTheme(ChartComponent), 'value'), {
283
+ displayName: 'RadialGauge',
284
+ });
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import type { BaseGaugeProps } from '../gauge.types';
3
+ /**
4
+ * Props for the SimpleGauge component.
5
+ * A gauge chart with customizable title and detail text labels.
6
+ */
7
+ interface SimpleGaugeProps extends BaseGaugeProps {
8
+ /**
9
+ * Title text displayed on the gauge.
10
+ * @default 'Metric'
11
+ */
12
+ title?: string;
13
+ /**
14
+ * Detail text showing the value.
15
+ * @default '30%'
16
+ */
17
+ detailText?: string;
18
+ }
19
+ export declare const SimpleGauge: ((props: SimpleGaugeProps & {
20
+ theme?: Partial<import("../..").ChartTheme>;
21
+ } & {
22
+ width?: number | string;
23
+ height?: number | string;
24
+ }) => React.JSX.Element) & {
25
+ displayName: string;
26
+ };
27
+ export {};
28
+ //# sourceMappingURL=simple.gauge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simple.gauge.d.ts","sourceRoot":"","sources":["../../../../../components/chart/gauge/simple/simple.gauge.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAqC,MAAM,OAAO,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAQrD;;;GAGG;AACH,UAAU,gBAAiB,SAAQ,cAAc;IAC/C;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA2GD,eAAO,MAAM,WAAW;;;;;;;CAEtB,CAAC"}