react-native-metrify 0.1.0-alpha.1 → 0.1.0-alpha.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 (100) hide show
  1. package/package.json +1 -2
  2. package/src/core/animation/index.ts +0 -113
  3. package/src/core/animation/index.web.ts +0 -112
  4. package/src/core/hooks/index.ts +0 -66
  5. package/src/core/index.ts +0 -26
  6. package/src/core/layout/index.ts +0 -101
  7. package/src/core/math/index.ts +0 -72
  8. package/src/core/package.json +0 -13
  9. package/src/core/theme/ThemeProvider.tsx +0 -36
  10. package/src/core/theme/index.ts +0 -5
  11. package/src/core/theme/themes.ts +0 -132
  12. package/src/core/types/index.ts +0 -164
  13. package/src/core/utils/responsive.ts +0 -203
  14. package/src/core/utils/time.ts +0 -100
  15. package/src/index.ts +0 -13
  16. package/src/renderer-svg/adapters/index.ts +0 -84
  17. package/src/renderer-svg/index.ts +0 -8
  18. package/src/renderer-svg/package.json +0 -17
  19. package/src/renderer-svg/paths/arc.ts +0 -93
  20. package/src/renderer-svg/paths/index.ts +0 -6
  21. package/src/renderer-svg/paths/line.ts +0 -83
  22. package/src/renderer-svg/paths/rect.ts +0 -80
  23. package/src/renderer-svg/primitives/AnimatedCircle.tsx +0 -48
  24. package/src/renderer-svg/primitives/AnimatedPath.tsx +0 -48
  25. package/src/renderer-svg/primitives/Text.tsx +0 -73
  26. package/src/renderer-svg/primitives/index.ts +0 -6
  27. package/src/widgets/AreaChart/AreaChart.tsx +0 -213
  28. package/src/widgets/AreaChart/index.ts +0 -2
  29. package/src/widgets/AreaChart/types.ts +0 -34
  30. package/src/widgets/BarChart/BarChart.tsx +0 -249
  31. package/src/widgets/BarChart/index.ts +0 -10
  32. package/src/widgets/BarChart/types.ts +0 -27
  33. package/src/widgets/BoxPlot/BoxPlot.tsx +0 -252
  34. package/src/widgets/BoxPlot/index.ts +0 -2
  35. package/src/widgets/BoxPlot/types.ts +0 -27
  36. package/src/widgets/BubbleChart/BubbleChart.tsx +0 -175
  37. package/src/widgets/BubbleChart/index.ts +0 -2
  38. package/src/widgets/BubbleChart/types.ts +0 -33
  39. package/src/widgets/CandlestickChart/CandlestickChart.tsx +0 -204
  40. package/src/widgets/CandlestickChart/index.ts +0 -2
  41. package/src/widgets/CandlestickChart/types.ts +0 -29
  42. package/src/widgets/FunnelChart/FunnelChart.tsx +0 -172
  43. package/src/widgets/FunnelChart/index.ts +0 -2
  44. package/src/widgets/FunnelChart/types.ts +0 -22
  45. package/src/widgets/Gauge/Gauge.tsx +0 -235
  46. package/src/widgets/Gauge/index.ts +0 -5
  47. package/src/widgets/Gauge/types.ts +0 -19
  48. package/src/widgets/GroupedBarChart/GroupedBarChart.tsx +0 -190
  49. package/src/widgets/GroupedBarChart/index.ts +0 -2
  50. package/src/widgets/GroupedBarChart/types.ts +0 -30
  51. package/src/widgets/Heatmap/Heatmap.tsx +0 -216
  52. package/src/widgets/Heatmap/index.ts +0 -2
  53. package/src/widgets/Heatmap/types.ts +0 -27
  54. package/src/widgets/Histogram/Histogram.tsx +0 -173
  55. package/src/widgets/Histogram/index.ts +0 -2
  56. package/src/widgets/Histogram/types.ts +0 -18
  57. package/src/widgets/HorizontalBarChart/HorizontalBarChart.tsx +0 -125
  58. package/src/widgets/HorizontalBarChart/index.ts +0 -2
  59. package/src/widgets/HorizontalBarChart/types.ts +0 -23
  60. package/src/widgets/KPI/KPI.tsx +0 -222
  61. package/src/widgets/KPI/index.ts +0 -5
  62. package/src/widgets/KPI/types.ts +0 -19
  63. package/src/widgets/LineChart/LineChart.tsx +0 -364
  64. package/src/widgets/LineChart/index.ts +0 -10
  65. package/src/widgets/LineChart/types.ts +0 -34
  66. package/src/widgets/MultiLineSparkline/MultiLineSparkline.tsx +0 -234
  67. package/src/widgets/MultiLineSparkline/index.ts +0 -10
  68. package/src/widgets/MultiLineSparkline/types.ts +0 -25
  69. package/src/widgets/PieChart/PieChart.tsx +0 -275
  70. package/src/widgets/PieChart/index.ts +0 -10
  71. package/src/widgets/PieChart/types.ts +0 -26
  72. package/src/widgets/Progress/Progress.tsx +0 -201
  73. package/src/widgets/Progress/index.ts +0 -5
  74. package/src/widgets/Progress/types.ts +0 -19
  75. package/src/widgets/RadarChart/RadarChart.tsx +0 -213
  76. package/src/widgets/RadarChart/index.ts +0 -2
  77. package/src/widgets/RadarChart/types.ts +0 -29
  78. package/src/widgets/SankeyDiagram/SankeyDiagram.tsx +0 -272
  79. package/src/widgets/SankeyDiagram/index.ts +0 -2
  80. package/src/widgets/SankeyDiagram/types.ts +0 -29
  81. package/src/widgets/ScatterPlot/ScatterPlot.tsx +0 -167
  82. package/src/widgets/ScatterPlot/index.ts +0 -2
  83. package/src/widgets/ScatterPlot/types.ts +0 -32
  84. package/src/widgets/Sparkline/Sparkline.tsx +0 -203
  85. package/src/widgets/Sparkline/index.ts +0 -5
  86. package/src/widgets/Sparkline/types.ts +0 -18
  87. package/src/widgets/StackedBarChart/StackedBarChart.tsx +0 -181
  88. package/src/widgets/StackedBarChart/index.ts +0 -2
  89. package/src/widgets/StackedBarChart/types.ts +0 -29
  90. package/src/widgets/SunburstChart/SunburstChart.tsx +0 -176
  91. package/src/widgets/SunburstChart/index.ts +0 -2
  92. package/src/widgets/SunburstChart/types.ts +0 -22
  93. package/src/widgets/Treemap/Treemap.tsx +0 -191
  94. package/src/widgets/Treemap/index.ts +0 -2
  95. package/src/widgets/Treemap/types.ts +0 -23
  96. package/src/widgets/WaterfallChart/WaterfallChart.tsx +0 -226
  97. package/src/widgets/WaterfallChart/index.ts +0 -2
  98. package/src/widgets/WaterfallChart/types.ts +0 -26
  99. package/src/widgets/index.ts +0 -40
  100. package/src/widgets/package.json +0 -18
@@ -1,83 +0,0 @@
1
- /**
2
- * SVG line path generators
3
- */
4
- import { Point } from '../../core/layout';
5
-
6
- /**
7
- * Creates a simple line path from points
8
- */
9
- export function createLinePath(points: Point[]): string {
10
- if (points.length === 0) return '';
11
-
12
- const pathParts = points.map((point, index) => {
13
- const command = index === 0 ? 'M' : 'L';
14
- return `${command} ${point.x} ${point.y}`;
15
- });
16
-
17
- return pathParts.join(' ');
18
- }
19
-
20
- /**
21
- * Creates a smooth curve path using quadratic bezier curves
22
- */
23
- export function createSmoothLinePath(points: Point[]): string {
24
- if (points.length === 0) return '';
25
- if (points.length === 1) return `M ${points[0].x} ${points[0].y}`;
26
-
27
- const pathParts: string[] = [`M ${points[0].x} ${points[0].y}`];
28
-
29
- for (let i = 0; i < points.length - 1; i++) {
30
- const current = points[i];
31
- const next = points[i + 1];
32
-
33
- // Calculate control point (midpoint)
34
- const controlX = (current.x + next.x) / 2;
35
- const controlY = (current.y + next.y) / 2;
36
-
37
- if (i === 0) {
38
- // First segment: use simple control point
39
- pathParts.push(`Q ${current.x} ${current.y} ${controlX} ${controlY}`);
40
- } else {
41
- // Subsequent segments: smooth curve
42
- pathParts.push(`T ${controlX} ${controlY}`);
43
- }
44
- }
45
-
46
- // Final point
47
- const lastPoint = points[points.length - 1];
48
- pathParts.push(`T ${lastPoint.x} ${lastPoint.y}`);
49
-
50
- return pathParts.join(' ');
51
- }
52
-
53
- /**
54
- * Creates an area path (filled under line)
55
- */
56
- export function createAreaPath(
57
- points: Point[],
58
- baselineY: number
59
- ): string {
60
- if (points.length === 0) return '';
61
-
62
- const linePath = createLinePath(points);
63
- const lastPoint = points[points.length - 1];
64
- const firstPoint = points[0];
65
-
66
- return `${linePath} L ${lastPoint.x} ${baselineY} L ${firstPoint.x} ${baselineY} Z`;
67
- }
68
-
69
- /**
70
- * Creates a smooth area path
71
- */
72
- export function createSmoothAreaPath(
73
- points: Point[],
74
- baselineY: number
75
- ): string {
76
- if (points.length === 0) return '';
77
-
78
- const linePath = createSmoothLinePath(points);
79
- const lastPoint = points[points.length - 1];
80
- const firstPoint = points[0];
81
-
82
- return `${linePath} L ${lastPoint.x} ${baselineY} L ${firstPoint.x} ${baselineY} Z`;
83
- }
@@ -1,80 +0,0 @@
1
- /**
2
- * SVG rectangle path generators
3
- */
4
-
5
- export interface RectConfig {
6
- x: number;
7
- y: number;
8
- width: number;
9
- height: number;
10
- radius?: number;
11
- }
12
-
13
- /**
14
- * Creates a rounded rectangle path
15
- */
16
- export function createRoundedRectPath(config: RectConfig): string {
17
- const { x, y, width, height, radius = 0 } = config;
18
-
19
- if (radius === 0) {
20
- return `M ${x} ${y} L ${x + width} ${y} L ${x + width} ${y + height} L ${x} ${y + height} Z`;
21
- }
22
-
23
- const r = Math.min(radius, width / 2, height / 2);
24
-
25
- return [
26
- `M ${x + r} ${y}`,
27
- `L ${x + width - r} ${y}`,
28
- `Q ${x + width} ${y} ${x + width} ${y + r}`,
29
- `L ${x + width} ${y + height - r}`,
30
- `Q ${x + width} ${y + height} ${x + width - r} ${y + height}`,
31
- `L ${x + r} ${y + height}`,
32
- `Q ${x} ${y + height} ${x} ${y + height - r}`,
33
- `L ${x} ${y + r}`,
34
- `Q ${x} ${y} ${x + r} ${y}`,
35
- 'Z',
36
- ].join(' ');
37
- }
38
-
39
- /**
40
- * Creates a rectangle with only specific corners rounded
41
- */
42
- export function createPartiallyRoundedRectPath(
43
- config: RectConfig & {
44
- radiusTopLeft?: number;
45
- radiusTopRight?: number;
46
- radiusBottomRight?: number;
47
- radiusBottomLeft?: number;
48
- }
49
- ): string {
50
- const {
51
- x,
52
- y,
53
- width,
54
- height,
55
- radiusTopLeft = 0,
56
- radiusTopRight = 0,
57
- radiusBottomRight = 0,
58
- radiusBottomLeft = 0,
59
- } = config;
60
-
61
- const rtl = Math.min(radiusTopLeft, width / 2, height / 2);
62
- const rtr = Math.min(radiusTopRight, width / 2, height / 2);
63
- const rbr = Math.min(radiusBottomRight, width / 2, height / 2);
64
- const rbl = Math.min(radiusBottomLeft, width / 2, height / 2);
65
-
66
- return [
67
- `M ${x + rtl} ${y}`,
68
- `L ${x + width - rtr} ${y}`,
69
- rtr > 0 ? `Q ${x + width} ${y} ${x + width} ${y + rtr}` : '',
70
- `L ${x + width} ${y + height - rbr}`,
71
- rbr > 0 ? `Q ${x + width} ${y + height} ${x + width - rbr} ${y + height}` : '',
72
- `L ${x + rbl} ${y + height}`,
73
- rbl > 0 ? `Q ${x} ${y + height} ${x} ${y + height - rbl}` : '',
74
- `L ${x} ${y + rtl}`,
75
- rtl > 0 ? `Q ${x} ${y} ${x + rtl} ${y}` : '',
76
- 'Z',
77
- ]
78
- .filter(Boolean)
79
- .join(' ');
80
- }
@@ -1,48 +0,0 @@
1
- /**
2
- * Animated SVG Circle primitive
3
- */
4
- import React, { memo } from 'react';
5
- import Animated from 'react-native-reanimated';
6
- import { Circle } from 'react-native-svg';
7
-
8
- const AnimatedSVGCircle = Animated.createAnimatedComponent(Circle);
9
-
10
- export interface AnimatedCircleProps {
11
- cx: number;
12
- cy: number;
13
- r: number;
14
- fill?: string;
15
- stroke?: string;
16
- strokeWidth?: number;
17
- opacity?: number;
18
- testID?: string;
19
- }
20
-
21
- /**
22
- * Memoized animated circle component
23
- */
24
- export const AnimatedCircle = memo<AnimatedCircleProps>(({
25
- cx,
26
- cy,
27
- r,
28
- fill = 'transparent',
29
- stroke = 'transparent',
30
- strokeWidth = 1,
31
- opacity = 1,
32
- testID,
33
- }) => {
34
- return (
35
- <AnimatedSVGCircle
36
- cx={cx}
37
- cy={cy}
38
- r={r}
39
- fill={fill}
40
- stroke={stroke}
41
- strokeWidth={strokeWidth}
42
- opacity={opacity}
43
- testID={testID}
44
- />
45
- );
46
- });
47
-
48
- AnimatedCircle.displayName = 'AnimatedCircle';
@@ -1,48 +0,0 @@
1
- /**
2
- * Animated SVG Path primitive
3
- */
4
- import React, { memo } from 'react';
5
- import Animated from 'react-native-reanimated';
6
- import { Path } from 'react-native-svg';
7
-
8
- const AnimatedSVGPath = Animated.createAnimatedComponent(Path);
9
-
10
- export interface AnimatedPathProps {
11
- d: string;
12
- stroke?: string;
13
- strokeWidth?: number;
14
- fill?: string;
15
- opacity?: number;
16
- strokeLinecap?: 'butt' | 'round' | 'square';
17
- strokeLinejoin?: 'miter' | 'round' | 'bevel';
18
- testID?: string;
19
- }
20
-
21
- /**
22
- * Memoized animated path component
23
- */
24
- export const AnimatedPath = memo<AnimatedPathProps>(({
25
- d,
26
- stroke = 'transparent',
27
- strokeWidth = 1,
28
- fill = 'transparent',
29
- opacity = 1,
30
- strokeLinecap = 'round',
31
- strokeLinejoin = 'round',
32
- testID,
33
- }) => {
34
- return (
35
- <AnimatedSVGPath
36
- d={d}
37
- stroke={stroke}
38
- strokeWidth={strokeWidth}
39
- fill={fill}
40
- opacity={opacity}
41
- strokeLinecap={strokeLinecap}
42
- strokeLinejoin={strokeLinejoin}
43
- testID={testID}
44
- />
45
- );
46
- });
47
-
48
- AnimatedPath.displayName = 'AnimatedPath';
@@ -1,73 +0,0 @@
1
- /**
2
- * SVG Text primitive with centered text helper
3
- */
4
- import React, { memo } from 'react';
5
- import { Text as SVGText } from 'react-native-svg';
6
-
7
- export interface TextProps {
8
- x: number;
9
- y: number;
10
- text: string;
11
- fontSize?: number;
12
- fontWeight?: string | number;
13
- fill?: string;
14
- textAnchor?: 'start' | 'middle' | 'end';
15
- alignmentBaseline?: 'baseline' | 'text-bottom' | 'alphabetic' | 'ideographic' | 'middle' | 'central' | 'mathematical' | 'text-top' | 'bottom' | 'center' | 'top' | 'text-before-edge' | 'text-after-edge' | 'before-edge' | 'after-edge' | 'hanging';
16
- opacity?: number;
17
- testID?: string;
18
- }
19
-
20
- /**
21
- * SVG Text component with sensible defaults
22
- */
23
- export const Text = memo<TextProps>(({
24
- x,
25
- y,
26
- text,
27
- fontSize = 14,
28
- fontWeight = 'normal',
29
- fill = '#000000',
30
- textAnchor = 'middle',
31
- alignmentBaseline = 'middle',
32
- opacity = 1,
33
- testID,
34
- }) => {
35
- return (
36
- <SVGText
37
- x={x}
38
- y={y}
39
- fontSize={fontSize}
40
- fontWeight={fontWeight}
41
- fill={fill}
42
- textAnchor={textAnchor}
43
- alignmentBaseline={alignmentBaseline}
44
- opacity={opacity}
45
- testID={testID}
46
- >
47
- {text}
48
- </SVGText>
49
- );
50
- });
51
-
52
- Text.displayName = 'Text';
53
-
54
- /**
55
- * Helper to create centered text props
56
- */
57
- export function createCenteredTextProps(
58
- x: number,
59
- y: number,
60
- text: string,
61
- fontSize?: number,
62
- fill?: string
63
- ): TextProps {
64
- return {
65
- x,
66
- y,
67
- text,
68
- fontSize,
69
- fill,
70
- textAnchor: 'middle',
71
- alignmentBaseline: 'middle',
72
- };
73
- }
@@ -1,6 +0,0 @@
1
- /**
2
- * SVG primitives - Basic building blocks
3
- */
4
- export * from './Text';
5
- export * from './AnimatedPath';
6
- export * from './AnimatedCircle';
@@ -1,213 +0,0 @@
1
- /**
2
- * AreaChart Widget - Filled area under line
3
- */
4
- import React, { memo, useMemo } from 'react';
5
- import { View, Text as RNText, StyleSheet } from 'react-native';
6
- import Svg, { Defs, LinearGradient, Stop, Line as SvgLine } from 'react-native-svg';
7
- import {
8
- useWidgetDimensions,
9
- useWidgetTheme,
10
- normalize,
11
- formatTimeLabel,
12
- reduceLabels,
13
- } from '../../core';
14
- import {
15
- createLinePath,
16
- createAreaPath,
17
- AnimatedPath,
18
- } from '../../renderer-svg';
19
- import { AreaChartWidgetProps } from './types';
20
-
21
- export const AreaChart = memo<AreaChartWidgetProps>(({
22
- data: widgetData,
23
- width,
24
- height,
25
- loading = false,
26
- theme: themeOverride,
27
- showXAxis = true,
28
- showYAxis = true,
29
- showGrid = true,
30
- showLegend = true,
31
- showGradient = true,
32
- stacked = false,
33
- curveStyle = 'linear',
34
- maxXLabels = 6,
35
- testID,
36
- }) => {
37
- const theme = useWidgetTheme(themeOverride);
38
- const dimensions = useWidgetDimensions(width, height, 350, 250);
39
-
40
- if (loading) {
41
- return (
42
- <View style={[styles.container, { width: dimensions.width, height: dimensions.height, backgroundColor: theme.colors.surface, borderRadius: theme.radius.md }]} testID={`${testID}-loading`}>
43
- <RNText style={[styles.loadingText, { color: theme.colors.textSecondary }]}>Loading...</RNText>
44
- </View>
45
- );
46
- }
47
-
48
- if (!widgetData || !widgetData.series || widgetData.series.length === 0) {
49
- return (
50
- <View style={[styles.container, { width: dimensions.width, height: dimensions.height, backgroundColor: theme.colors.surface, borderRadius: theme.radius.md }]} testID={`${testID}-empty`}>
51
- <RNText style={[styles.emptyText, { color: theme.colors.textSecondary }]}>No data</RNText>
52
- </View>
53
- );
54
- }
55
-
56
- const { series, title, timeInterval } = widgetData;
57
- const padding = theme.spacing.md;
58
- const titleHeight = title ? theme.fontScale.md + theme.spacing.sm : 0;
59
- const legendHeight = showLegend ? 30 : 0;
60
- const xAxisHeight = showXAxis ? 30 : 0;
61
- const yAxisWidth = showYAxis ? 40 : 0;
62
-
63
- const chartWidth = dimensions.width - padding * 2 - yAxisWidth;
64
- const chartHeight = dimensions.height - padding * 2 - titleHeight - legendHeight - xAxisHeight;
65
-
66
- const { globalMinY, globalMaxY, xLabels } = useMemo(() => {
67
- let minY = Infinity;
68
- let maxY = -Infinity;
69
- const allXValues: (number | Date)[] = [];
70
-
71
- series.forEach(s => {
72
- s.data.forEach(point => {
73
- if (point.y < minY) minY = point.y;
74
- if (point.y > maxY) maxY = point.y;
75
- allXValues.push(point.x);
76
- });
77
- });
78
-
79
- const labels = allXValues.map((x, idx) => {
80
- if (x instanceof Date) {
81
- return timeInterval ? formatTimeLabel(x, timeInterval) : x.toLocaleDateString();
82
- }
83
- return x.toString();
84
- });
85
-
86
- return { globalMinY: minY, globalMaxY: maxY, xLabels: labels };
87
- }, [series, timeInterval]);
88
-
89
- const yAxisLabels = useMemo(() => {
90
- const range = globalMaxY - globalMinY;
91
- const step = range / 4;
92
- return Array.from({ length: 5 }, (_, i) => ({
93
- value: globalMinY + i * step,
94
- y: chartHeight - (i * chartHeight) / 4,
95
- }));
96
- }, [globalMinY, globalMaxY, chartHeight]);
97
-
98
- const xAxisLabelsReduced = useMemo(() => {
99
- return reduceLabels(xLabels, maxXLabels);
100
- }, [xLabels, maxXLabels]);
101
-
102
- const seriesPaths = useMemo(() => {
103
- return series.map((s, seriesIndex) => {
104
- const points = s.data.map((point, index) => {
105
- const x = (index / (s.data.length - 1 || 1)) * chartWidth;
106
- const normalizedY = normalize(point.y, globalMinY, globalMaxY);
107
- const y = chartHeight - normalizedY * chartHeight;
108
- return { x, y };
109
- });
110
-
111
- const linePath = createLinePath(points);
112
- const areaPath = createAreaPath(points, chartHeight);
113
-
114
- return {
115
- linePath,
116
- areaPath,
117
- color: s.color,
118
- label: s.label,
119
- gradientId: `gradient-${seriesIndex}`,
120
- };
121
- });
122
- }, [series, chartWidth, chartHeight, globalMinY, globalMaxY]);
123
-
124
- return (
125
- <View style={[styles.wrapper, { width: dimensions.width, height: dimensions.height, backgroundColor: theme.colors.surface, borderRadius: theme.radius.md, padding }]} testID={testID}>
126
- {title && (
127
- <RNText style={[styles.title, { color: theme.colors.text, fontSize: theme.fontScale.md, fontWeight: 'bold', marginBottom: theme.spacing.sm }]}>
128
- {title}
129
- </RNText>
130
- )}
131
-
132
- <View style={styles.chartRow}>
133
- {showYAxis && (
134
- <View style={[styles.yAxis, { width: yAxisWidth }]}>
135
- {yAxisLabels.map((label, index) => (
136
- <RNText key={`y-${index}`} style={[styles.yAxisLabel, { color: theme.colors.textSecondary, fontSize: theme.fontScale.xs, top: label.y - 6 }]}>
137
- {label.value.toFixed(0)}
138
- </RNText>
139
- ))}
140
- </View>
141
- )}
142
-
143
- <View>
144
- <Svg width={chartWidth} height={chartHeight}>
145
- {showGradient && (
146
- <Defs>
147
- {seriesPaths.map((series, index) => (
148
- <LinearGradient key={series.gradientId} id={series.gradientId} x1="0" y1="0" x2="0" y2="1">
149
- <Stop offset="0%" stopColor={series.color} stopOpacity="0.4" />
150
- <Stop offset="100%" stopColor={series.color} stopOpacity="0.05" />
151
- </LinearGradient>
152
- ))}
153
- </Defs>
154
- )}
155
-
156
- {showGrid && yAxisLabels.map((label, index) => (
157
- <SvgLine key={`grid-${index}`} x1={0} y1={label.y} x2={chartWidth} y2={label.y} stroke={theme.colors.borderLight} strokeWidth={1} />
158
- ))}
159
-
160
- {seriesPaths.map((series, index) => (
161
- <React.Fragment key={`series-${index}`}>
162
- <AnimatedPath d={series.areaPath} fill={showGradient ? `url(#${series.gradientId})` : series.color} opacity={showGradient ? 1 : 0.3} />
163
- <AnimatedPath d={series.linePath} stroke={series.color} strokeWidth={2} strokeLinecap="round" strokeLinejoin="round" fill="transparent" />
164
- </React.Fragment>
165
- ))}
166
- </Svg>
167
-
168
- {showXAxis && (
169
- <View style={[styles.xAxis, { width: chartWidth }]}>
170
- {xAxisLabelsReduced.map((item, index) => (
171
- <RNText key={`x-${index}`} style={[styles.xAxisLabel, { color: theme.colors.textSecondary, fontSize: theme.fontScale.xs, left: (item.index / (xLabels.length - 1 || 1)) * chartWidth - 20 }]}>
172
- {item.label}
173
- </RNText>
174
- ))}
175
- </View>
176
- )}
177
- </View>
178
- </View>
179
-
180
- {showLegend && (
181
- <View style={styles.legend}>
182
- {seriesPaths.map((series, index) => (
183
- series.label && (
184
- <View key={`legend-${index}`} style={styles.legendItem}>
185
- <View style={[styles.legendColor, { backgroundColor: series.color }]} />
186
- <RNText style={[styles.legendText, { color: theme.colors.textSecondary, fontSize: theme.fontScale.xs }]}>{series.label}</RNText>
187
- </View>
188
- )
189
- ))}
190
- </View>
191
- )}
192
- </View>
193
- );
194
- });
195
-
196
- AreaChart.displayName = 'AreaChart';
197
-
198
- const styles = StyleSheet.create({
199
- wrapper: { justifyContent: 'flex-start', alignItems: 'flex-start' },
200
- container: { justifyContent: 'center', alignItems: 'center' },
201
- loadingText: { fontSize: 16 },
202
- emptyText: { fontSize: 16 },
203
- title: { textAlign: 'center', width: '100%' },
204
- chartRow: { flexDirection: 'row', alignItems: 'flex-start' },
205
- yAxis: { position: 'relative', marginRight: 8 },
206
- yAxisLabel: { position: 'absolute', right: 0, textAlign: 'right' },
207
- xAxis: { position: 'relative', height: 30, marginTop: 4 },
208
- xAxisLabel: { position: 'absolute', width: 40, textAlign: 'center' },
209
- legend: { flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'center', marginTop: 12, gap: 12 },
210
- legendItem: { flexDirection: 'row', alignItems: 'center', gap: 6 },
211
- legendColor: { width: 12, height: 12, borderRadius: 2 },
212
- legendText: { textTransform: 'uppercase', letterSpacing: 0.5 },
213
- });
@@ -1,2 +0,0 @@
1
- export { AreaChart } from './AreaChart';
2
- export type { AreaChartWidgetProps, AreaChartData, AreaChartSeries, AreaChartDataPoint } from './types';
@@ -1,34 +0,0 @@
1
- /**
2
- * AreaChart Widget types
3
- */
4
- import { BaseWidgetProps, TimeInterval } from '../../core';
5
-
6
- export interface AreaChartDataPoint {
7
- x: number | Date;
8
- y: number;
9
- }
10
-
11
- export interface AreaChartSeries {
12
- data: AreaChartDataPoint[];
13
- color: string;
14
- label?: string;
15
- }
16
-
17
- export interface AreaChartData {
18
- series: AreaChartSeries[];
19
- title?: string;
20
- timeInterval?: TimeInterval;
21
- }
22
-
23
- export type AreaChartStyle = 'smooth' | 'linear';
24
-
25
- export interface AreaChartWidgetProps extends BaseWidgetProps<AreaChartData> {
26
- showXAxis?: boolean;
27
- showYAxis?: boolean;
28
- showGrid?: boolean;
29
- showLegend?: boolean;
30
- showGradient?: boolean;
31
- stacked?: boolean;
32
- curveStyle?: AreaChartStyle;
33
- maxXLabels?: number;
34
- }