@obitrain/charts 0.9.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 (116) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +125 -0
  3. package/lib/commonjs/Charts/BottomAxis/AxisLine.js +38 -0
  4. package/lib/commonjs/Charts/BottomAxis/AxisLine.js.map +1 -0
  5. package/lib/commonjs/Charts/BottomAxis/BottomAxis.js +45 -0
  6. package/lib/commonjs/Charts/BottomAxis/BottomAxis.js.map +1 -0
  7. package/lib/commonjs/Charts/BottomAxis/Tick.js +43 -0
  8. package/lib/commonjs/Charts/BottomAxis/Tick.js.map +1 -0
  9. package/lib/commonjs/Charts/BottomAxis/index.js +27 -0
  10. package/lib/commonjs/Charts/BottomAxis/index.js.map +1 -0
  11. package/lib/commonjs/Charts/Cursor.js +50 -0
  12. package/lib/commonjs/Charts/Cursor.js.map +1 -0
  13. package/lib/commonjs/Charts/Linechart/index.js +55 -0
  14. package/lib/commonjs/Charts/Linechart/index.js.map +1 -0
  15. package/lib/commonjs/Charts/ZoomableLinechart/ScalablePath.js +43 -0
  16. package/lib/commonjs/Charts/ZoomableLinechart/ScalablePath.js.map +1 -0
  17. package/lib/commonjs/Charts/ZoomableLinechart/index.js +43 -0
  18. package/lib/commonjs/Charts/ZoomableLinechart/index.js.map +1 -0
  19. package/lib/commonjs/Charts/gesture.js +185 -0
  20. package/lib/commonjs/Charts/gesture.js.map +1 -0
  21. package/lib/commonjs/Charts/graphUtils.js +131 -0
  22. package/lib/commonjs/Charts/graphUtils.js.map +1 -0
  23. package/lib/commonjs/Charts/index.js +151 -0
  24. package/lib/commonjs/Charts/index.js.map +1 -0
  25. package/lib/commonjs/Charts/maths.js +195 -0
  26. package/lib/commonjs/Charts/maths.js.map +1 -0
  27. package/lib/commonjs/Charts/types.js +6 -0
  28. package/lib/commonjs/Charts/types.js.map +1 -0
  29. package/lib/commonjs/dateUtils.js +151 -0
  30. package/lib/commonjs/dateUtils.js.map +1 -0
  31. package/lib/commonjs/index.js +39 -0
  32. package/lib/commonjs/index.js.map +1 -0
  33. package/lib/commonjs/package.json +1 -0
  34. package/lib/commonjs/textUtils.js +21 -0
  35. package/lib/commonjs/textUtils.js.map +1 -0
  36. package/lib/module/Charts/BottomAxis/AxisLine.js +34 -0
  37. package/lib/module/Charts/BottomAxis/AxisLine.js.map +1 -0
  38. package/lib/module/Charts/BottomAxis/BottomAxis.js +40 -0
  39. package/lib/module/Charts/BottomAxis/BottomAxis.js.map +1 -0
  40. package/lib/module/Charts/BottomAxis/Tick.js +37 -0
  41. package/lib/module/Charts/BottomAxis/Tick.js.map +1 -0
  42. package/lib/module/Charts/BottomAxis/index.js +6 -0
  43. package/lib/module/Charts/BottomAxis/index.js.map +1 -0
  44. package/lib/module/Charts/Cursor.js +46 -0
  45. package/lib/module/Charts/Cursor.js.map +1 -0
  46. package/lib/module/Charts/Linechart/index.js +50 -0
  47. package/lib/module/Charts/Linechart/index.js.map +1 -0
  48. package/lib/module/Charts/ZoomableLinechart/ScalablePath.js +39 -0
  49. package/lib/module/Charts/ZoomableLinechart/ScalablePath.js.map +1 -0
  50. package/lib/module/Charts/ZoomableLinechart/index.js +33 -0
  51. package/lib/module/Charts/ZoomableLinechart/index.js.map +1 -0
  52. package/lib/module/Charts/gesture.js +176 -0
  53. package/lib/module/Charts/gesture.js.map +1 -0
  54. package/lib/module/Charts/graphUtils.js +121 -0
  55. package/lib/module/Charts/graphUtils.js.map +1 -0
  56. package/lib/module/Charts/index.js +10 -0
  57. package/lib/module/Charts/index.js.map +1 -0
  58. package/lib/module/Charts/maths.js +187 -0
  59. package/lib/module/Charts/maths.js.map +1 -0
  60. package/lib/module/Charts/types.js +4 -0
  61. package/lib/module/Charts/types.js.map +1 -0
  62. package/lib/module/dateUtils.js +142 -0
  63. package/lib/module/dateUtils.js.map +1 -0
  64. package/lib/module/index.js +6 -0
  65. package/lib/module/index.js.map +1 -0
  66. package/lib/module/textUtils.js +16 -0
  67. package/lib/module/textUtils.js.map +1 -0
  68. package/lib/typescript/src/Charts/BottomAxis/AxisLine.d.ts +15 -0
  69. package/lib/typescript/src/Charts/BottomAxis/AxisLine.d.ts.map +1 -0
  70. package/lib/typescript/src/Charts/BottomAxis/BottomAxis.d.ts +17 -0
  71. package/lib/typescript/src/Charts/BottomAxis/BottomAxis.d.ts.map +1 -0
  72. package/lib/typescript/src/Charts/BottomAxis/Tick.d.ts +14 -0
  73. package/lib/typescript/src/Charts/BottomAxis/Tick.d.ts.map +1 -0
  74. package/lib/typescript/src/Charts/BottomAxis/index.d.ts +4 -0
  75. package/lib/typescript/src/Charts/BottomAxis/index.d.ts.map +1 -0
  76. package/lib/typescript/src/Charts/Cursor.d.ts +14 -0
  77. package/lib/typescript/src/Charts/Cursor.d.ts.map +1 -0
  78. package/lib/typescript/src/Charts/Linechart/index.d.ts +25 -0
  79. package/lib/typescript/src/Charts/Linechart/index.d.ts.map +1 -0
  80. package/lib/typescript/src/Charts/ZoomableLinechart/ScalablePath.d.ts +14 -0
  81. package/lib/typescript/src/Charts/ZoomableLinechart/ScalablePath.d.ts.map +1 -0
  82. package/lib/typescript/src/Charts/ZoomableLinechart/index.d.ts +23 -0
  83. package/lib/typescript/src/Charts/ZoomableLinechart/index.d.ts.map +1 -0
  84. package/lib/typescript/src/Charts/gesture.d.ts +54 -0
  85. package/lib/typescript/src/Charts/gesture.d.ts.map +1 -0
  86. package/lib/typescript/src/Charts/graphUtils.d.ts +43 -0
  87. package/lib/typescript/src/Charts/graphUtils.d.ts.map +1 -0
  88. package/lib/typescript/src/Charts/index.d.ts +14 -0
  89. package/lib/typescript/src/Charts/index.d.ts.map +1 -0
  90. package/lib/typescript/src/Charts/maths.d.ts +19 -0
  91. package/lib/typescript/src/Charts/maths.d.ts.map +1 -0
  92. package/lib/typescript/src/Charts/types.d.ts +14 -0
  93. package/lib/typescript/src/Charts/types.d.ts.map +1 -0
  94. package/lib/typescript/src/dateUtils.d.ts +37 -0
  95. package/lib/typescript/src/dateUtils.d.ts.map +1 -0
  96. package/lib/typescript/src/index.d.ts +5 -0
  97. package/lib/typescript/src/index.d.ts.map +1 -0
  98. package/lib/typescript/src/textUtils.d.ts +3 -0
  99. package/lib/typescript/src/textUtils.d.ts.map +1 -0
  100. package/package.json +226 -0
  101. package/src/Charts/BottomAxis/AxisLine.tsx +40 -0
  102. package/src/Charts/BottomAxis/BottomAxis.tsx +41 -0
  103. package/src/Charts/BottomAxis/Tick.tsx +54 -0
  104. package/src/Charts/BottomAxis/index.tsx +3 -0
  105. package/src/Charts/Cursor.tsx +51 -0
  106. package/src/Charts/Linechart/index.tsx +79 -0
  107. package/src/Charts/ZoomableLinechart/ScalablePath.tsx +49 -0
  108. package/src/Charts/ZoomableLinechart/index.tsx +47 -0
  109. package/src/Charts/gesture.ts +254 -0
  110. package/src/Charts/graphUtils.ts +198 -0
  111. package/src/Charts/index.tsx +32 -0
  112. package/src/Charts/maths.ts +245 -0
  113. package/src/Charts/types.ts +16 -0
  114. package/src/dateUtils.ts +163 -0
  115. package/src/index.tsx +4 -0
  116. package/src/textUtils.ts +21 -0
@@ -0,0 +1,245 @@
1
+ import type { PathCommand, Vector } from '@shopify/react-native-skia';
2
+ import { PathVerb, vec } from '@shopify/react-native-skia';
3
+
4
+ // code from William Candillon
5
+
6
+ const round = (value: number, precision = 0): number => {
7
+ 'worklet';
8
+
9
+ const p = Math.pow(10, precision);
10
+ return Math.round(value * p) / p;
11
+ };
12
+
13
+ // https://stackoverflow.com/questions/27176423/function-to-solve-cubic-equation-analytically
14
+ const cuberoot = (x: number): number => {
15
+ 'worklet';
16
+
17
+ const y = Math.pow(Math.abs(x), 1 / 3);
18
+ return x < 0 ? -y : y;
19
+ };
20
+
21
+ const solveCubic = (a: number, b: number, c: number, d: number): number[] => {
22
+ 'worklet';
23
+
24
+ if (Math.abs(a) < 1e-8) {
25
+ // Quadratic case, ax^2+bx+c=0
26
+ a = b;
27
+ b = c;
28
+ c = d;
29
+ if (Math.abs(a) < 1e-8) {
30
+ // Linear case, ax+b=0
31
+ a = b;
32
+ b = c;
33
+ if (Math.abs(a) < 1e-8) {
34
+ // Degenerate case
35
+ return [];
36
+ }
37
+ return [-b / a];
38
+ }
39
+
40
+ const D = b * b - 4 * a * c;
41
+ if (Math.abs(D) < 1e-8) return [-b / (2 * a)];
42
+ if (D > 0)
43
+ return [(-b + Math.sqrt(D)) / (2 * a), (-b - Math.sqrt(D)) / (2 * a)];
44
+
45
+ return [];
46
+ }
47
+
48
+ // Convert to depressed cubic t^3+pt+q = 0 (subst x = t - b/3a)
49
+ const p = (3 * a * c - b * b) / (3 * a * a);
50
+ const q = (2 * b * b * b - 9 * a * b * c + 27 * a * a * d) / (27 * a * a * a);
51
+ let roots: number[] = [];
52
+
53
+ if (Math.abs(p) < 1e-8) {
54
+ // p = 0 -> t^3 = -q -> t = -q^1/3
55
+ roots = [cuberoot(-q)];
56
+ } else if (Math.abs(q) < 1e-8) {
57
+ // q = 0 -> t^3 + pt = 0 -> t(t^2+p)=0
58
+ roots = [0].concat(p < 0 ? [Math.sqrt(-p), -Math.sqrt(-p)] : []);
59
+ } else {
60
+ const D = (q * q) / 4 + (p * p * p) / 27;
61
+ if (Math.abs(D) < 1e-8) {
62
+ // D = 0 -> two roots
63
+ roots = [(-1.5 * q) / p, (3 * q) / p];
64
+ } else if (D > 0) {
65
+ // Only one real root
66
+ const u = cuberoot(-q / 2 - Math.sqrt(D));
67
+ roots = [u - p / (3 * u)];
68
+ } else {
69
+ // D < 0, three roots, but needs to use complex numbers/trigonometric solution
70
+ const u = 2 * Math.sqrt(-p / 3);
71
+ const t = Math.acos((3 * q) / p / u) / 3; // D < 0 implies p < 0 and acos argument in [-1..1]
72
+ const k = (2 * Math.PI) / 3;
73
+ roots = [u * Math.cos(t), u * Math.cos(t - k), u * Math.cos(t - 2 * k)];
74
+ }
75
+ }
76
+
77
+
78
+
79
+ // Convert back from depressed cubic
80
+ for (let i = 0; i < roots.length; i++) roots[i]! -= b / (3 * a);
81
+
82
+ return roots;
83
+ };
84
+
85
+ // const cubicBezier = (
86
+ // t: number,
87
+ // from: number,
88
+ // c1: number,
89
+ // c2: number,
90
+ // to: number
91
+ // ): number => {
92
+ // 'worklet';
93
+
94
+ // const term = 1 - t;
95
+ // const a = 1 * term ** 3 * t ** 0 * from;
96
+ // const b = 3 * term ** 2 * t ** 1 * c1;
97
+ // const c = 3 * term ** 1 * t ** 2 * c2;
98
+ // const d = 1 * term ** 0 * t ** 3 * to;
99
+ // return a + b + c + d;
100
+ // };
101
+
102
+ const cubicSolve = function (
103
+ t: number,
104
+ p0: number,
105
+ p1: number,
106
+ p2: number,
107
+ p3: number
108
+ ) {
109
+ 'worklet';
110
+ return (
111
+ (1 - t) * (1 - t) * (1 - t) * p0 +
112
+ 3 * (1 - t) * (1 - t) * t * p1 +
113
+ 3 * (1 - t) * t * t * p2 +
114
+ t * t * t * p3
115
+ );
116
+ };
117
+
118
+ export const cubicBezierYForX = (
119
+ x: number,
120
+ a: Vector,
121
+ b: Vector,
122
+ c: Vector,
123
+ d: Vector,
124
+ precision = 2
125
+ ): number => {
126
+ 'worklet';
127
+
128
+ const pa = -a.x + 3 * b.x - 3 * c.x + d.x;
129
+ const pb = 3 * a.x - 6 * b.x + 3 * c.x;
130
+ const pc = -3 * a.x + 3 * b.x;
131
+ const pd = a.x - x;
132
+ const ts = solveCubic(pa, pb, pc, pd)
133
+ .map((root) => round(root, precision))
134
+ .filter((root) => root >= 0 && root <= 1);
135
+ const t = ts[0];
136
+ if (t == null) return 0;
137
+ // return cubicBezier(t, a.y, b.y, c.y, d.y);
138
+ return cubicSolve(t, a.y, b.y, c.y, d.y);
139
+ };
140
+
141
+ interface Cubic {
142
+ from: Vector;
143
+ c1: Vector;
144
+ c2: Vector;
145
+ to: Vector;
146
+ }
147
+
148
+ export const selectCurve = (
149
+ cmds: PathCommand[],
150
+ x: number
151
+ ): Cubic | undefined => {
152
+ 'worklet';
153
+
154
+ let from: Vector = vec(0, 0);
155
+ for (let i = 0; i < cmds.length; i++) {
156
+ const cmd = cmds[i];
157
+ if (cmd == null) {
158
+ return undefined;
159
+ }
160
+
161
+ if (cmd[0] === PathVerb.Move) {
162
+ from = vec(cmd[1], cmd[2]);
163
+ } else if (cmd[0] === PathVerb.Cubic) {
164
+ const c1 = vec(cmd[1], cmd[2]);
165
+ const c2 = vec(cmd[3], cmd[4]);
166
+ const to = vec(cmd[5], cmd[6]);
167
+ if (x >= from.x && x <= to.x) {
168
+ return {
169
+ from,
170
+ c1,
171
+ c2,
172
+ to,
173
+ };
174
+ }
175
+ from = to;
176
+ }
177
+ }
178
+
179
+ return undefined;
180
+ };
181
+
182
+ /**
183
+ * Convert commands to cubic bezier
184
+ */
185
+ export const commandsToBezier = (cmds: PathCommand[]): PathCommand[] => {
186
+ 'worklet';
187
+ const normCmds: PathCommand[] = [];
188
+ let x = 0,
189
+ y = 0;
190
+ for (let i = 0; i < cmds.length; i++) {
191
+ const currCmd = cmds[i];
192
+ if (currCmd === undefined)
193
+ throw new Error(`No command found at index ${i}`);
194
+
195
+ let normCmd;
196
+ const cmd = currCmd[0];
197
+ if (cmd === undefined) throw new Error('Got undefined command');
198
+
199
+ if (cmd === PathVerb.Line) {
200
+ normCmd = [
201
+ PathVerb.Cubic,
202
+ x,
203
+ y,
204
+ currCmd[1]!,
205
+ currCmd[2]!,
206
+ currCmd[1]!,
207
+ currCmd[2]!,
208
+ ];
209
+ } else {
210
+ normCmd = currCmd;
211
+ }
212
+
213
+ x = normCmd[normCmd.length - 2]!;
214
+ y = normCmd[normCmd.length - 1]!;
215
+
216
+ normCmds.push(normCmd);
217
+ }
218
+
219
+ return normCmds;
220
+ };
221
+
222
+ export const getYForX = (
223
+ cmds: PathCommand[],
224
+ x: number,
225
+ precision = 2
226
+ ): number | undefined => {
227
+ 'worklet';
228
+ const cmdsNorm = commandsToBezier(cmds);
229
+ const c = selectCurve(cmdsNorm, x);
230
+ if (c == null) return undefined;
231
+
232
+ return cubicBezierYForX(x, c.from, c.c1, c.c2, c.to, precision);
233
+ };
234
+
235
+ // See Path/getPath2D
236
+
237
+ import { type SkPoint } from '@shopify/react-native-skia';
238
+
239
+ export const magnitude = (p: SkPoint): number =>
240
+ Math.sqrt(p.x * p.x + p.y * p.y);
241
+
242
+ export const normalize = (p: SkPoint) => {
243
+ const m = magnitude(p);
244
+ return { x: p.x / m, y: p.y / m } as SkPoint;
245
+ };
@@ -0,0 +1,16 @@
1
+ import type { SharedValue } from 'react-native-reanimated';
2
+ import type { GraphData } from './graphUtils';
3
+
4
+ export type LineGraphType = GraphData; // Omit<GraphData, 'path'> & { path: RPath };
5
+
6
+ export type DataPoint = {
7
+ x: number;
8
+ y: number;
9
+ value: number;
10
+ };
11
+
12
+ export type AnimatedDot = {
13
+ x: SharedValue<number>;
14
+ y: SharedValue<number>;
15
+ opacity: SharedValue<number>;
16
+ };
@@ -0,0 +1,163 @@
1
+ export type DateRange = 'day' | 'month' | 'trimester' | 'year' | 'all';
2
+
3
+ export const getMonthInterval = function (
4
+ month: number,
5
+ nbMonths: number
6
+ ): string {
7
+ if (month <= 0) throw new Error('Months should start at 1');
8
+ return (month - (month % nbMonths) + 1).toString().padStart(2, '0');
9
+ };
10
+
11
+ /**
12
+ * Get the date interval based on the date range.
13
+ * For example, for the date 2021-01-01:
14
+ * - day: 2021-01-01
15
+ * - month: 2021-01
16
+ * - trimester: 2021-01
17
+ * - year: 2021
18
+ * @param date
19
+ * @param dateRange
20
+ * @returns
21
+ */
22
+ export const getDateInterval = function (
23
+ date: Date,
24
+ dateRange: DateRange
25
+ ): string {
26
+ const year = date.getFullYear();
27
+ const month = date.getMonth() + 1;
28
+ const day = date.getDate().toString().padStart(2, '0');
29
+
30
+ const monthStr = month.toString().padStart(2, '0');
31
+
32
+ switch (dateRange) {
33
+ case 'day':
34
+ return `${year}-${monthStr}-${day}`;
35
+ case 'month':
36
+ return `${year}-${monthStr}`;
37
+ case 'trimester':
38
+ return `${year}-${getMonthInterval(month, 3)}`;
39
+ case 'year':
40
+ return `${year}`;
41
+ }
42
+ throw new Error('Invalid date range');
43
+ };
44
+
45
+ //@ts-ignore
46
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
47
+ const fmtData = function (data: [Date, number][], dateRange: DateRange) {
48
+ const _dataFmt = new Map<string, [number, number]>();
49
+ for (const [date, value] of data) {
50
+ const _dateStr = getDateInterval(date, dateRange);
51
+ if (!_dataFmt.has(_dateStr))
52
+ _dataFmt.set(_dateStr, [date.getTime(), value]);
53
+ }
54
+
55
+ return [..._dataFmt.values()];
56
+ };
57
+
58
+ /**
59
+ * Groups an array of Date objects by a specific time interval (day, month, trimester, year)
60
+ * and calculates the earliest and latest dates within each interval.
61
+ * For instance, given the dates [2021-01-01, 2021-01-25, 2021-03-01, 2021-10-01]:
62
+ * - month: { '2021-01': [2021-01-01, 2021-01-25],
63
+ * '2021-03': [2021-03-01, 2021-03-01],
64
+ '2021-10': [2021-10-01, 2021-10-01] }
65
+
66
+ * @param {Date[]} dates - An array of dates to group and find boundary dates for.
67
+ * @returns {Map<string, [Date, Date]>} - A map where each key represents an interval
68
+ * as a string (formatted according to the interval type, e.g., '2021', '2021-03', '2021-01-01'),
69
+ * and each value is a tuple containing the earliest and latest dates within that interval.
70
+ */
71
+ export function getDateBoundaries(dates: Date[], dateRange: DateRange) {
72
+ const ranges = new Map<string, [Date, Date]>();
73
+
74
+ for (const date of dates) {
75
+ const _dateStr = getDateInterval(date, dateRange);
76
+ const _range = ranges.get(_dateStr);
77
+ if (!_range) ranges.set(_dateStr, [date, date]);
78
+ else if (date > _range[1]) ranges.set(_dateStr, [_range[0], date]);
79
+ }
80
+ return ranges;
81
+ }
82
+
83
+ export function sampleDates(
84
+ dates: Date[],
85
+ sampleSize: number,
86
+ indexOffset: number = 0
87
+ ): { dates: Date[]; indexes: number[] } {
88
+ if (sampleSize <= 0 || dates.length === 0) {
89
+ return { dates: [], indexes: [] };
90
+ }
91
+
92
+ if (sampleSize >= dates.length) {
93
+ return {
94
+ dates,
95
+ indexes: Array.from({ length: dates.length }, (_, i) => indexOffset + i),
96
+ };
97
+ }
98
+
99
+ // Calculate total time span and interval
100
+ const firstItem = dates[0]!;
101
+ const lastItem = dates[dates.length - 1]!;
102
+ const startTime = firstItem.getTime();
103
+ const endTime = lastItem.getTime();
104
+ const timeSpan = endTime - startTime;
105
+ const timeInterval = timeSpan / (sampleSize - 1);
106
+
107
+ const sampledDates: Date[] = [firstItem]; // Always include the first date
108
+ const sampledIndexes = [0];
109
+ let nextTime = startTime + timeInterval;
110
+
111
+ // Select dates closest to each time interval
112
+ for (let i = 1; i < sampleSize - 1; i++) {
113
+ let closestDate = dates[0];
114
+ let minDiff = Math.abs(startTime - nextTime);
115
+ let closestIndex = 0;
116
+ for (let j = 1; j < dates.length; j++) {
117
+ const diff = Math.abs(dates[j]!.getTime() - nextTime);
118
+ if (diff < minDiff) {
119
+ closestDate = dates[j];
120
+ closestIndex = j;
121
+ minDiff = diff;
122
+ }
123
+ }
124
+ sampledDates.push(closestDate!);
125
+ sampledIndexes.push(closestIndex);
126
+ nextTime += timeInterval;
127
+ }
128
+
129
+ sampledDates.push(lastItem); // Always include the last date
130
+ sampledIndexes.push(dates.length - 1);
131
+
132
+ return {
133
+ dates: sampledDates,
134
+ indexes: sampledIndexes.map((x) => indexOffset + x),
135
+ };
136
+ }
137
+
138
+ export function sampleDatesByRange(
139
+ dates: Date[],
140
+ sampleSize: number,
141
+ dateRange: DateRange
142
+ ): Map<string, { dates: Date[]; indexes: number[] }> {
143
+ const boundaries = getDateBoundaries(dates, dateRange);
144
+ const rangedData = new Map<string, Date[]>();
145
+ for (let i = 0; i < dates.length; i++) {
146
+ let date = dates[i]!;
147
+ for (const [key, [minDate, maxDate]] of boundaries) {
148
+ if (date >= minDate && date <= maxDate) {
149
+ if (!rangedData.has(key)) rangedData.set(key, []);
150
+ rangedData.get(key)!.push(date);
151
+ break;
152
+ }
153
+ }
154
+ }
155
+ const sampledData = new Map<string, { dates: Date[]; indexes: number[] }>();
156
+ let offset = 0;
157
+ for (const [key, value] of rangedData) {
158
+ sampledData.set(key, sampleDates(value, sampleSize, offset));
159
+ offset += value.length;
160
+ }
161
+
162
+ return sampledData;
163
+ }
package/src/index.tsx ADDED
@@ -0,0 +1,4 @@
1
+ export * from './Charts';
2
+ export * from './dateUtils';
3
+ export type { DateRange } from './dateUtils';
4
+ export * from './textUtils';
@@ -0,0 +1,21 @@
1
+ import {
2
+ useDerivedValue,
3
+ useSharedValue,
4
+ type SharedValue,
5
+ } from 'react-native-reanimated';
6
+
7
+ const textToString = function (value: number) {
8
+ 'worklet';
9
+ return value.toFixed(0).toString();
10
+ };
11
+
12
+ export const useSharedNumberToStr = function (
13
+ initValue: number = 0
14
+ ): [SharedValue<number>, SharedValue<string>] {
15
+ const value = useSharedValue<number>(initValue);
16
+ const valueStr = useDerivedValue(() => {
17
+ return textToString(value.value);
18
+ }, [value]);
19
+
20
+ return [value, valueStr];
21
+ };