rn-cute-stocks 1.0.1-beta.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.
- package/LICENSE +21 -0
- package/README.md +1 -0
- package/dist/esm/index.mjs +277 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/index.js +281 -0
- package/dist/index.js.map +1 -0
- package/package.json +56 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Divyanshu Shekhar
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# rn-cute-stocks
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { StyleSheet, View, Text } from 'react-native';
|
|
3
|
+
import { Skia, Canvas, Path, LinearGradient, vec, Circle } from '@shopify/react-native-skia';
|
|
4
|
+
import { line, curveBasis, curveNatural, curveMonotoneX, curveLinear, curveBumpX } from 'd3-shape';
|
|
5
|
+
import { min, max } from 'd3-array';
|
|
6
|
+
import { scaleTime, scaleLinear } from 'd3-scale';
|
|
7
|
+
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
|
|
8
|
+
import { useSharedValue, useDerivedValue, runOnJS, withTiming } from 'react-native-reanimated';
|
|
9
|
+
import { useState } from 'react';
|
|
10
|
+
|
|
11
|
+
var __defProp = Object.defineProperty;
|
|
12
|
+
var __defProps = Object.defineProperties;
|
|
13
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
14
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
15
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
16
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
17
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
18
|
+
var __spreadValues = (a, b) => {
|
|
19
|
+
for (var prop in b || (b = {}))
|
|
20
|
+
if (__hasOwnProp.call(b, prop))
|
|
21
|
+
__defNormalProp(a, prop, b[prop]);
|
|
22
|
+
if (__getOwnPropSymbols)
|
|
23
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
24
|
+
if (__propIsEnum.call(b, prop))
|
|
25
|
+
__defNormalProp(a, prop, b[prop]);
|
|
26
|
+
}
|
|
27
|
+
return a;
|
|
28
|
+
};
|
|
29
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
30
|
+
function getCurve(curveType) {
|
|
31
|
+
let curve;
|
|
32
|
+
switch (curveType) {
|
|
33
|
+
case "curveBasis":
|
|
34
|
+
curve = curveBasis;
|
|
35
|
+
break;
|
|
36
|
+
case "curveBumpX":
|
|
37
|
+
curve = curveBumpX;
|
|
38
|
+
break;
|
|
39
|
+
case "curveLinear":
|
|
40
|
+
curve = curveLinear;
|
|
41
|
+
break;
|
|
42
|
+
case "curveMonotoneX":
|
|
43
|
+
curve = curveMonotoneX;
|
|
44
|
+
break;
|
|
45
|
+
case "natural":
|
|
46
|
+
curve = curveNatural;
|
|
47
|
+
break;
|
|
48
|
+
default:
|
|
49
|
+
curve = curveBasis;
|
|
50
|
+
console.warn(
|
|
51
|
+
"Invalid curve, falling back to default bezier (curveBasis)"
|
|
52
|
+
);
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
return curve;
|
|
56
|
+
}
|
|
57
|
+
function GenerateStringPath(curveType, data, canvas_width, canvas_height) {
|
|
58
|
+
const curve = getCurve(curveType);
|
|
59
|
+
const X_PADDING = Math.max(8, canvas_width * 0.05);
|
|
60
|
+
const CHART_HEIGHT = canvas_height;
|
|
61
|
+
const min_x = min(data, (d) => {
|
|
62
|
+
return d.timestamp;
|
|
63
|
+
});
|
|
64
|
+
const max_x = max(data, (d) => {
|
|
65
|
+
return d.timestamp;
|
|
66
|
+
});
|
|
67
|
+
const x_func = scaleTime().domain([min_x, max_x]).range([X_PADDING, canvas_width - X_PADDING]);
|
|
68
|
+
const min_y = min(data, (d) => {
|
|
69
|
+
return d.price;
|
|
70
|
+
});
|
|
71
|
+
const max_y = max(data, (d) => {
|
|
72
|
+
return d.price;
|
|
73
|
+
});
|
|
74
|
+
const y_padding = (max_y - min_y) * 0.1;
|
|
75
|
+
const y_func = scaleLinear().domain([min_y - y_padding, max_y + y_padding]).range([CHART_HEIGHT, 0]);
|
|
76
|
+
const str_path = line().x((d) => x_func(d.timestamp)).y((d) => y_func(d.price)).curve(curve)(data);
|
|
77
|
+
return {
|
|
78
|
+
str_path,
|
|
79
|
+
x_func,
|
|
80
|
+
y_func,
|
|
81
|
+
data,
|
|
82
|
+
x_range_min: X_PADDING,
|
|
83
|
+
x_range_max: canvas_width - X_PADDING
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
let path_config = null;
|
|
87
|
+
function GetYForX(x_pos, canvas_width, data, canvas_height, y_search_alogorithm) {
|
|
88
|
+
if (!path_config || path_config.canvas_width !== canvas_width || path_config.canvas_height !== canvas_height || path_config.data.length !== data.length) {
|
|
89
|
+
path_config = __spreadProps(__spreadValues({}, GenerateStringPath("curveBumpX", data, canvas_width, canvas_height)), {
|
|
90
|
+
canvas_width,
|
|
91
|
+
canvas_height
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
const { x_func, y_func, x_range_min, x_range_max } = path_config;
|
|
95
|
+
let clamped_x_pos = Math.max(x_range_min, Math.min(x_range_max, x_pos));
|
|
96
|
+
let res = searchStrategy(
|
|
97
|
+
y_search_alogorithm,
|
|
98
|
+
clamped_x_pos,
|
|
99
|
+
x_func,
|
|
100
|
+
data,
|
|
101
|
+
y_func
|
|
102
|
+
);
|
|
103
|
+
return res;
|
|
104
|
+
}
|
|
105
|
+
const searchStrategy = (search_strategy, clamped_x_pos, x_func, data, y_func) => {
|
|
106
|
+
let res;
|
|
107
|
+
switch (search_strategy) {
|
|
108
|
+
case "binarySearchWithInterpolation":
|
|
109
|
+
res = binarySearchWithInterpolation(clamped_x_pos, x_func, data, y_func);
|
|
110
|
+
break;
|
|
111
|
+
// might add more strategies later
|
|
112
|
+
// one might be using lookup tables
|
|
113
|
+
// as for less data points interpolation fails
|
|
114
|
+
default:
|
|
115
|
+
console.warn(
|
|
116
|
+
"invalid search strategy, falling back to binary with interpolation"
|
|
117
|
+
);
|
|
118
|
+
res = binarySearchWithInterpolation(clamped_x_pos, x_func, data, y_func);
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
return res;
|
|
122
|
+
};
|
|
123
|
+
const binarySearchWithInterpolation = (clamped_x_pos, x_func, data, y_func) => {
|
|
124
|
+
let timestamp = x_func.invert(clamped_x_pos).getTime();
|
|
125
|
+
let left_idx = 0;
|
|
126
|
+
if (timestamp <= data[0].timestamp) {
|
|
127
|
+
const p = data[0].price;
|
|
128
|
+
return { y_coord: y_func(p), real_price: p };
|
|
129
|
+
}
|
|
130
|
+
if (timestamp >= data[data.length - 1].timestamp) {
|
|
131
|
+
const p = data[data.length - 1].price;
|
|
132
|
+
return { y_coord: y_func(p), real_price: p };
|
|
133
|
+
}
|
|
134
|
+
let left = 0;
|
|
135
|
+
let right = data.length - 1;
|
|
136
|
+
while (left < right - 1) {
|
|
137
|
+
const mid = Math.floor((left + right) / 2);
|
|
138
|
+
if (data[mid].timestamp <= timestamp) {
|
|
139
|
+
left = mid;
|
|
140
|
+
} else {
|
|
141
|
+
right = mid;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (left >= data.length - 1) left = data.length - 2;
|
|
145
|
+
left_idx = left;
|
|
146
|
+
const left_point = data[left_idx];
|
|
147
|
+
const right_point = data[left_idx + 1];
|
|
148
|
+
const denominator = right_point.timestamp - left_point.timestamp;
|
|
149
|
+
const ratio = denominator !== 0 ? (timestamp - left_point.timestamp) / denominator : 0;
|
|
150
|
+
const y_val = left_point.price + ratio * (right_point.price - left_point.price);
|
|
151
|
+
let real_price = y_val;
|
|
152
|
+
let y_coord = y_func(y_val);
|
|
153
|
+
return { y_coord, real_price };
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const StockCharts = ({
|
|
157
|
+
width,
|
|
158
|
+
height,
|
|
159
|
+
chartData,
|
|
160
|
+
priceTextStyles,
|
|
161
|
+
curveType = "curveBasis",
|
|
162
|
+
colors = ["#fff"],
|
|
163
|
+
cursorComponent,
|
|
164
|
+
curveStrokeWidth = 2,
|
|
165
|
+
curveFill = "stroke",
|
|
166
|
+
ySearch = "binarySearchWithInterpolation"
|
|
167
|
+
}) => {
|
|
168
|
+
const { str_path, x_func, y_func, data, x_range_min, x_range_max } = GenerateStringPath(curveType, chartData, width, height);
|
|
169
|
+
const skpath = Skia.Path.MakeFromSVGString(str_path);
|
|
170
|
+
let init_x = x_func(data[0].timestamp);
|
|
171
|
+
let init_y = y_func(data[0].price);
|
|
172
|
+
const xPos = useSharedValue(init_x);
|
|
173
|
+
const yPos = useSharedValue(init_y);
|
|
174
|
+
const price_animated_val = useSharedValue(data[0].price);
|
|
175
|
+
const [priceText, setPriceText] = useState(data[0].price);
|
|
176
|
+
useDerivedValue(() => {
|
|
177
|
+
const txt = price_animated_val.value.toFixed(2);
|
|
178
|
+
runOnJS(setPriceText)(txt);
|
|
179
|
+
}, [price_animated_val]);
|
|
180
|
+
const updateY = (clamped_x) => {
|
|
181
|
+
let res_prices = GetYForX(clamped_x, width, data, height, ySearch);
|
|
182
|
+
yPos.value = res_prices.y_coord;
|
|
183
|
+
price_animated_val.value = withTiming(res_prices.real_price, {
|
|
184
|
+
duration: 100
|
|
185
|
+
});
|
|
186
|
+
};
|
|
187
|
+
const pan = Gesture.Pan().onUpdate((evt) => {
|
|
188
|
+
"worklet";
|
|
189
|
+
const raw_x = Number(evt.x);
|
|
190
|
+
const clamped = Math.max(x_range_min, Math.min(x_range_max, raw_x));
|
|
191
|
+
xPos.value = clamped;
|
|
192
|
+
runOnJS(updateY)(clamped);
|
|
193
|
+
});
|
|
194
|
+
if (!chartData || chartData.length === 0) {
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
return /* @__PURE__ */ jsxs(View, { style: styles.home__main, children: [
|
|
198
|
+
/* @__PURE__ */ jsxs(Text, { style: [styles.home__price, priceTextStyles], children: [
|
|
199
|
+
"$",
|
|
200
|
+
priceText
|
|
201
|
+
] }),
|
|
202
|
+
/* @__PURE__ */ jsx(GestureDetector, { gesture: pan, children: /* @__PURE__ */ jsxs(
|
|
203
|
+
Canvas,
|
|
204
|
+
{
|
|
205
|
+
style: {
|
|
206
|
+
width,
|
|
207
|
+
height
|
|
208
|
+
},
|
|
209
|
+
children: [
|
|
210
|
+
cursorComponent ? cursorComponent({ xPos, yPos }) : /* @__PURE__ */ jsx(Cursor, { xPos, yPos }),
|
|
211
|
+
skpath && /* @__PURE__ */ jsx(
|
|
212
|
+
Path,
|
|
213
|
+
{
|
|
214
|
+
path: skpath,
|
|
215
|
+
style: curveFill,
|
|
216
|
+
strokeWidth: curveStrokeWidth,
|
|
217
|
+
color: "#fff",
|
|
218
|
+
children: /* @__PURE__ */ jsx(
|
|
219
|
+
LinearGradient,
|
|
220
|
+
{
|
|
221
|
+
start: vec(0, 0),
|
|
222
|
+
end: vec(width, height),
|
|
223
|
+
colors
|
|
224
|
+
}
|
|
225
|
+
)
|
|
226
|
+
}
|
|
227
|
+
)
|
|
228
|
+
]
|
|
229
|
+
}
|
|
230
|
+
) })
|
|
231
|
+
] });
|
|
232
|
+
};
|
|
233
|
+
const Cursor = ({ xPos, yPos }) => {
|
|
234
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
235
|
+
/* @__PURE__ */ jsx(Circle, { style: "fill", color: "#f69d69", cx: xPos, cy: yPos, r: 5 }),
|
|
236
|
+
/* @__PURE__ */ jsx(
|
|
237
|
+
Circle,
|
|
238
|
+
{
|
|
239
|
+
style: "stroke",
|
|
240
|
+
color: "#f69d69",
|
|
241
|
+
cx: xPos,
|
|
242
|
+
cy: yPos,
|
|
243
|
+
r: 12,
|
|
244
|
+
strokeWidth: 2,
|
|
245
|
+
opacity: 0.65
|
|
246
|
+
}
|
|
247
|
+
),
|
|
248
|
+
/* @__PURE__ */ jsx(
|
|
249
|
+
Circle,
|
|
250
|
+
{
|
|
251
|
+
style: "stroke",
|
|
252
|
+
color: "#f69d69",
|
|
253
|
+
cx: xPos,
|
|
254
|
+
cy: yPos,
|
|
255
|
+
r: 18,
|
|
256
|
+
strokeWidth: 2,
|
|
257
|
+
opacity: 0.65
|
|
258
|
+
}
|
|
259
|
+
)
|
|
260
|
+
] });
|
|
261
|
+
};
|
|
262
|
+
const styles = StyleSheet.create({
|
|
263
|
+
home__main: {
|
|
264
|
+
flex: 1,
|
|
265
|
+
paddingVertical: 50,
|
|
266
|
+
alignItems: "center",
|
|
267
|
+
backgroundColor: "#181818",
|
|
268
|
+
paddingHorizontal: 20
|
|
269
|
+
},
|
|
270
|
+
home__price: {
|
|
271
|
+
color: "#000",
|
|
272
|
+
fontSize: 52
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
export { GenerateStringPath, GetYForX, StockCharts };
|
|
277
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../src/math.js","../../src/rn.js"],"sourcesContent":["// FILE ka main goals kya hai ? =>\r\n// get the data\r\n// generate the skia-path for curve\r\n\r\nimport {\r\n curveBasis,\r\n curveBumpX,\r\n curveLinear,\r\n curveMonotoneX,\r\n curveNatural,\r\n line,\r\n} from \"d3-shape\";\r\n\r\nimport { max, min } from \"d3-array\";\r\nimport { scaleLinear, scaleTime } from \"d3-scale\";\r\n\r\nfunction getCurve(curveType) {\r\n let curve;\r\n\r\n // following are curves I believe are good matches for stock data\r\n switch (curveType) {\r\n case \"curveBasis\":\r\n curve = curveBasis;\r\n break;\r\n case \"curveBumpX\":\r\n curve = curveBumpX;\r\n break;\r\n case \"curveLinear\":\r\n curve = curveLinear;\r\n break;\r\n case \"curveMonotoneX\":\r\n curve = curveMonotoneX;\r\n break;\r\n case \"natural\":\r\n curve = curveNatural;\r\n break;\r\n default:\r\n curve = curveBasis;\r\n console.warn(\r\n \"Invalid curve, falling back to default bezier (curveBasis)\"\r\n );\r\n break;\r\n }\r\n return curve;\r\n}\r\n\r\nfunction GenerateStringPath(curveType, data, canvas_width, canvas_height) {\r\n const curve = getCurve(curveType);\r\n // const data = getPeriodData(period);\r\n\r\n const X_PADDING = Math.max(8, canvas_width * 0.05);\r\n // const CHART_HEIGHT = Math.round(canvas_width * 0.85);\r\n const CHART_HEIGHT = canvas_height;\r\n\r\n const min_x = min(data, (d) => {\r\n return d.timestamp;\r\n });\r\n const max_x = max(data, (d) => {\r\n return d.timestamp;\r\n });\r\n\r\n const x_func = scaleTime()\r\n .domain([min_x, max_x])\r\n .range([X_PADDING, canvas_width - X_PADDING]);\r\n // now we can call like x(someTimestampValue)\r\n // this is done while plotting the path like line().x((d) => x(d.timestamp))\r\n\r\n const min_y = min(data, (d) => {\r\n return d.price;\r\n });\r\n const max_y = max(data, (d) => {\r\n return d.price;\r\n });\r\n\r\n const y_padding = (max_y - min_y) * 0.1;\r\n\r\n const y_func = scaleLinear()\r\n .domain([min_y - y_padding, max_y + y_padding])\r\n .range([CHART_HEIGHT, 0]);\r\n\r\n const str_path = line()\r\n .x((d) => x_func(d.timestamp))\r\n .y((d) => y_func(d.price))\r\n .curve(curve)(data);\r\n\r\n return {\r\n str_path,\r\n x_func,\r\n y_func,\r\n data,\r\n x_range_min: X_PADDING,\r\n x_range_max: canvas_width - X_PADDING,\r\n };\r\n}\r\n\r\nlet path_config = null;\r\n\r\nfunction GetYForX(x_pos, canvas_width, data, canvas_height, y_search_alogorithm) {\r\n // IDEA BEHIND THIS FUNC. :\r\n // the curve is not linear so find two nearby points for the given X (timestamp)\r\n // then assume them as a linear line and get Y via linear interpolation\r\n // also cache the path configs\r\n\r\n if (\r\n !path_config || \r\n path_config.canvas_width !== canvas_width || \r\n path_config.canvas_height !== canvas_height ||\r\n path_config.data.length !== data.length\r\n ) {\r\n path_config = {\r\n ...GenerateStringPath(\"curveBumpX\", data, canvas_width, canvas_height),\r\n canvas_width,\r\n canvas_height\r\n };\r\n }\r\n\r\n const { x_func, y_func, x_range_min, x_range_max } = path_config;\r\n\r\n // keep x within bounds by clamping it\r\n let clamped_x_pos = Math.max(x_range_min, Math.min(x_range_max, x_pos));\r\n\r\n let res = searchStrategy(\r\n y_search_alogorithm,\r\n clamped_x_pos,\r\n x_func,\r\n data,\r\n y_func\r\n );\r\n\r\n return res;\r\n}\r\n\r\nconst searchStrategy = (\r\n search_strategy,\r\n clamped_x_pos,\r\n x_func,\r\n data,\r\n y_func\r\n) => {\r\n let res;\r\n switch (search_strategy) {\r\n case \"binarySearchWithInterpolation\":\r\n res = binarySearchWithInterpolation(clamped_x_pos, x_func, data, y_func);\r\n break;\r\n\r\n // might add more strategies later\r\n // one might be using lookup tables\r\n // as for less data points interpolation fails\r\n\r\n default:\r\n console.warn(\r\n \"invalid search strategy, falling back to binary with interpolation\"\r\n );\r\n res = binarySearchWithInterpolation(clamped_x_pos, x_func, data, y_func);\r\n break;\r\n }\r\n\r\n return res;\r\n};\r\n\r\nconst binarySearchWithInterpolation = (clamped_x_pos, x_func, data, y_func) => {\r\n let timestamp = x_func.invert(clamped_x_pos).getTime();\r\n\r\n let left_idx = 0;\r\n\r\n if (timestamp <= data[0].timestamp) {\r\n const p = data[0].price;\r\n return { y_coord: y_func(p), real_price: p };\r\n }\r\n if (timestamp >= data[data.length - 1].timestamp) {\r\n const p = data[data.length - 1].price;\r\n return { y_coord: y_func(p), real_price: p };\r\n }\r\n\r\n // Binary search (could have gone with linear search as well but lol why not better)\r\n let left = 0;\r\n let right = data.length - 1;\r\n\r\n while (left < right - 1) {\r\n const mid = Math.floor((left + right) / 2);\r\n if (data[mid].timestamp <= timestamp) {\r\n left = mid;\r\n } else {\r\n right = mid;\r\n }\r\n }\r\n\r\n if (left >= data.length - 1) left = data.length - 2;\r\n\r\n left_idx = left;\r\n\r\n const left_point = data[left_idx];\r\n const right_point = data[left_idx + 1];\r\n\r\n // do Linear interpolation here\r\n const denominator = right_point.timestamp - left_point.timestamp;\r\n const ratio =\r\n denominator !== 0 ? (timestamp - left_point.timestamp) / denominator : 0;\r\n const y_val =\r\n left_point.price + ratio * (right_point.price - left_point.price);\r\n\r\n let real_price = y_val;\r\n let y_coord = y_func(y_val);\r\n return { y_coord, real_price };\r\n};\r\n\r\nexport { GenerateStringPath, GetYForX };\r\n","import { Text, View, StyleSheet } from \"react-native\";\r\nimport {\r\n Canvas,\r\n LinearGradient,\r\n Path,\r\n vec,\r\n Skia,\r\n Circle,\r\n} from \"@shopify/react-native-skia\";\r\nimport { GenerateStringPath, GetYForX } from \"./math\";\r\nimport { Gesture, GestureDetector } from \"react-native-gesture-handler\";\r\nimport {\r\n useDerivedValue,\r\n useSharedValue,\r\n runOnJS,\r\n withTiming,\r\n} from \"react-native-reanimated\";\r\nimport { useState } from \"react\";\r\n\r\nexport const StockCharts = ({\r\n width,\r\n height,\r\n chartData,\r\n priceTextStyles,\r\n curveType = \"curveBasis\",\r\n colors = [\"#fff\"],\r\n cursorComponent,\r\n curveStrokeWidth = 2,\r\n curveFill = \"stroke\",\r\n ySearch = \"binarySearchWithInterpolation\",\r\n}) => {\r\n const { str_path, x_func, y_func, data, x_range_min, x_range_max } =\r\n GenerateStringPath(curveType, chartData, width, height);\r\n\r\n const skpath = Skia.Path.MakeFromSVGString(str_path);\r\n\r\n let init_x = x_func(data[0].timestamp);\r\n let init_y = y_func(data[0].price);\r\n\r\n const xPos = useSharedValue(init_x);\r\n const yPos = useSharedValue(init_y);\r\n const price_animated_val = useSharedValue(data[0].price);\r\n const [priceText, setPriceText] = useState(data[0].price);\r\n\r\n useDerivedValue(() => {\r\n const txt = price_animated_val.value.toFixed(2);\r\n runOnJS(setPriceText)(txt);\r\n }, [price_animated_val]);\r\n\r\n const updateY = (clamped_x) => {\r\n let res_prices = GetYForX(clamped_x, width, data, height, ySearch);\r\n yPos.value = res_prices.y_coord;\r\n\r\n price_animated_val.value = withTiming(res_prices.real_price, {\r\n duration: 100,\r\n });\r\n };\r\n\r\n const pan = Gesture.Pan().onUpdate((evt) => {\r\n \"worklet\";\r\n const raw_x = Number(evt.x);\r\n const clamped = Math.max(x_range_min, Math.min(x_range_max, raw_x));\r\n xPos.value = clamped;\r\n\r\n runOnJS(updateY)(clamped);\r\n });\r\n\r\n if (!chartData || chartData.length === 0) {\r\n return null; // or a fallback view in future , maybe :)\r\n }\r\n\r\n return (\r\n <View style={styles.home__main}>\r\n <Text style={[styles.home__price, priceTextStyles]}>${priceText}</Text>\r\n\r\n <GestureDetector gesture={pan}>\r\n <Canvas\r\n style={{\r\n width: width,\r\n height: height,\r\n }}\r\n >\r\n {cursorComponent ? (\r\n cursorComponent({ xPos, yPos })\r\n ) : (\r\n <Cursor xPos={xPos} yPos={yPos} />\r\n )}\r\n\r\n {skpath && (\r\n <Path\r\n path={skpath}\r\n style={curveFill} \r\n strokeWidth={curveStrokeWidth}\r\n color={\"#fff\"} // i forgot what's this :(\r\n >\r\n <LinearGradient\r\n start={vec(0, 0)}\r\n end={vec(width, height)}\r\n colors={colors}\r\n />\r\n </Path>\r\n )}\r\n </Canvas>\r\n </GestureDetector>\r\n </View>\r\n );\r\n};\r\n\r\nconst Cursor = ({ xPos, yPos }) => {\r\n return (\r\n <>\r\n <Circle style=\"fill\" color=\"#f69d69\" cx={xPos} cy={yPos} r={5} />\r\n <Circle\r\n style=\"stroke\"\r\n color=\"#f69d69\"\r\n cx={xPos}\r\n cy={yPos}\r\n r={12}\r\n strokeWidth={2}\r\n opacity={0.65}\r\n />\r\n <Circle\r\n style=\"stroke\"\r\n color=\"#f69d69\"\r\n cx={xPos}\r\n cy={yPos}\r\n r={18}\r\n strokeWidth={2}\r\n opacity={0.65}\r\n />\r\n </>\r\n );\r\n};\r\n\r\nconst styles = StyleSheet.create({\r\n home__main: {\r\n flex: 1,\r\n paddingVertical: 50,\r\n alignItems: \"center\",\r\n backgroundColor: \"#181818\",\r\n paddingHorizontal: 20,\r\n },\r\n home__price: {\r\n color: \"#000\",\r\n fontSize: 52,\r\n },\r\n});\r\n"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var reactNative = require('react-native');
|
|
5
|
+
var reactNativeSkia = require('@shopify/react-native-skia');
|
|
6
|
+
var d3Shape = require('d3-shape');
|
|
7
|
+
var d3Array = require('d3-array');
|
|
8
|
+
var d3Scale = require('d3-scale');
|
|
9
|
+
var reactNativeGestureHandler = require('react-native-gesture-handler');
|
|
10
|
+
var reactNativeReanimated = require('react-native-reanimated');
|
|
11
|
+
var react = require('react');
|
|
12
|
+
|
|
13
|
+
var __defProp = Object.defineProperty;
|
|
14
|
+
var __defProps = Object.defineProperties;
|
|
15
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
16
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
17
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
18
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
19
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
20
|
+
var __spreadValues = (a, b) => {
|
|
21
|
+
for (var prop in b || (b = {}))
|
|
22
|
+
if (__hasOwnProp.call(b, prop))
|
|
23
|
+
__defNormalProp(a, prop, b[prop]);
|
|
24
|
+
if (__getOwnPropSymbols)
|
|
25
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
26
|
+
if (__propIsEnum.call(b, prop))
|
|
27
|
+
__defNormalProp(a, prop, b[prop]);
|
|
28
|
+
}
|
|
29
|
+
return a;
|
|
30
|
+
};
|
|
31
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
32
|
+
function getCurve(curveType) {
|
|
33
|
+
let curve;
|
|
34
|
+
switch (curveType) {
|
|
35
|
+
case "curveBasis":
|
|
36
|
+
curve = d3Shape.curveBasis;
|
|
37
|
+
break;
|
|
38
|
+
case "curveBumpX":
|
|
39
|
+
curve = d3Shape.curveBumpX;
|
|
40
|
+
break;
|
|
41
|
+
case "curveLinear":
|
|
42
|
+
curve = d3Shape.curveLinear;
|
|
43
|
+
break;
|
|
44
|
+
case "curveMonotoneX":
|
|
45
|
+
curve = d3Shape.curveMonotoneX;
|
|
46
|
+
break;
|
|
47
|
+
case "natural":
|
|
48
|
+
curve = d3Shape.curveNatural;
|
|
49
|
+
break;
|
|
50
|
+
default:
|
|
51
|
+
curve = d3Shape.curveBasis;
|
|
52
|
+
console.warn(
|
|
53
|
+
"Invalid curve, falling back to default bezier (curveBasis)"
|
|
54
|
+
);
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
return curve;
|
|
58
|
+
}
|
|
59
|
+
function GenerateStringPath(curveType, data, canvas_width, canvas_height) {
|
|
60
|
+
const curve = getCurve(curveType);
|
|
61
|
+
const X_PADDING = Math.max(8, canvas_width * 0.05);
|
|
62
|
+
const CHART_HEIGHT = canvas_height;
|
|
63
|
+
const min_x = d3Array.min(data, (d) => {
|
|
64
|
+
return d.timestamp;
|
|
65
|
+
});
|
|
66
|
+
const max_x = d3Array.max(data, (d) => {
|
|
67
|
+
return d.timestamp;
|
|
68
|
+
});
|
|
69
|
+
const x_func = d3Scale.scaleTime().domain([min_x, max_x]).range([X_PADDING, canvas_width - X_PADDING]);
|
|
70
|
+
const min_y = d3Array.min(data, (d) => {
|
|
71
|
+
return d.price;
|
|
72
|
+
});
|
|
73
|
+
const max_y = d3Array.max(data, (d) => {
|
|
74
|
+
return d.price;
|
|
75
|
+
});
|
|
76
|
+
const y_padding = (max_y - min_y) * 0.1;
|
|
77
|
+
const y_func = d3Scale.scaleLinear().domain([min_y - y_padding, max_y + y_padding]).range([CHART_HEIGHT, 0]);
|
|
78
|
+
const str_path = d3Shape.line().x((d) => x_func(d.timestamp)).y((d) => y_func(d.price)).curve(curve)(data);
|
|
79
|
+
return {
|
|
80
|
+
str_path,
|
|
81
|
+
x_func,
|
|
82
|
+
y_func,
|
|
83
|
+
data,
|
|
84
|
+
x_range_min: X_PADDING,
|
|
85
|
+
x_range_max: canvas_width - X_PADDING
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
let path_config = null;
|
|
89
|
+
function GetYForX(x_pos, canvas_width, data, canvas_height, y_search_alogorithm) {
|
|
90
|
+
if (!path_config || path_config.canvas_width !== canvas_width || path_config.canvas_height !== canvas_height || path_config.data.length !== data.length) {
|
|
91
|
+
path_config = __spreadProps(__spreadValues({}, GenerateStringPath("curveBumpX", data, canvas_width, canvas_height)), {
|
|
92
|
+
canvas_width,
|
|
93
|
+
canvas_height
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
const { x_func, y_func, x_range_min, x_range_max } = path_config;
|
|
97
|
+
let clamped_x_pos = Math.max(x_range_min, Math.min(x_range_max, x_pos));
|
|
98
|
+
let res = searchStrategy(
|
|
99
|
+
y_search_alogorithm,
|
|
100
|
+
clamped_x_pos,
|
|
101
|
+
x_func,
|
|
102
|
+
data,
|
|
103
|
+
y_func
|
|
104
|
+
);
|
|
105
|
+
return res;
|
|
106
|
+
}
|
|
107
|
+
const searchStrategy = (search_strategy, clamped_x_pos, x_func, data, y_func) => {
|
|
108
|
+
let res;
|
|
109
|
+
switch (search_strategy) {
|
|
110
|
+
case "binarySearchWithInterpolation":
|
|
111
|
+
res = binarySearchWithInterpolation(clamped_x_pos, x_func, data, y_func);
|
|
112
|
+
break;
|
|
113
|
+
// might add more strategies later
|
|
114
|
+
// one might be using lookup tables
|
|
115
|
+
// as for less data points interpolation fails
|
|
116
|
+
default:
|
|
117
|
+
console.warn(
|
|
118
|
+
"invalid search strategy, falling back to binary with interpolation"
|
|
119
|
+
);
|
|
120
|
+
res = binarySearchWithInterpolation(clamped_x_pos, x_func, data, y_func);
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
return res;
|
|
124
|
+
};
|
|
125
|
+
const binarySearchWithInterpolation = (clamped_x_pos, x_func, data, y_func) => {
|
|
126
|
+
let timestamp = x_func.invert(clamped_x_pos).getTime();
|
|
127
|
+
let left_idx = 0;
|
|
128
|
+
if (timestamp <= data[0].timestamp) {
|
|
129
|
+
const p = data[0].price;
|
|
130
|
+
return { y_coord: y_func(p), real_price: p };
|
|
131
|
+
}
|
|
132
|
+
if (timestamp >= data[data.length - 1].timestamp) {
|
|
133
|
+
const p = data[data.length - 1].price;
|
|
134
|
+
return { y_coord: y_func(p), real_price: p };
|
|
135
|
+
}
|
|
136
|
+
let left = 0;
|
|
137
|
+
let right = data.length - 1;
|
|
138
|
+
while (left < right - 1) {
|
|
139
|
+
const mid = Math.floor((left + right) / 2);
|
|
140
|
+
if (data[mid].timestamp <= timestamp) {
|
|
141
|
+
left = mid;
|
|
142
|
+
} else {
|
|
143
|
+
right = mid;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (left >= data.length - 1) left = data.length - 2;
|
|
147
|
+
left_idx = left;
|
|
148
|
+
const left_point = data[left_idx];
|
|
149
|
+
const right_point = data[left_idx + 1];
|
|
150
|
+
const denominator = right_point.timestamp - left_point.timestamp;
|
|
151
|
+
const ratio = denominator !== 0 ? (timestamp - left_point.timestamp) / denominator : 0;
|
|
152
|
+
const y_val = left_point.price + ratio * (right_point.price - left_point.price);
|
|
153
|
+
let real_price = y_val;
|
|
154
|
+
let y_coord = y_func(y_val);
|
|
155
|
+
return { y_coord, real_price };
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
const StockCharts = ({
|
|
159
|
+
width,
|
|
160
|
+
height,
|
|
161
|
+
chartData,
|
|
162
|
+
priceTextStyles,
|
|
163
|
+
curveType = "curveBasis",
|
|
164
|
+
colors = ["#fff"],
|
|
165
|
+
cursorComponent,
|
|
166
|
+
curveStrokeWidth = 2,
|
|
167
|
+
curveFill = "stroke",
|
|
168
|
+
ySearch = "binarySearchWithInterpolation"
|
|
169
|
+
}) => {
|
|
170
|
+
const { str_path, x_func, y_func, data, x_range_min, x_range_max } = GenerateStringPath(curveType, chartData, width, height);
|
|
171
|
+
const skpath = reactNativeSkia.Skia.Path.MakeFromSVGString(str_path);
|
|
172
|
+
let init_x = x_func(data[0].timestamp);
|
|
173
|
+
let init_y = y_func(data[0].price);
|
|
174
|
+
const xPos = reactNativeReanimated.useSharedValue(init_x);
|
|
175
|
+
const yPos = reactNativeReanimated.useSharedValue(init_y);
|
|
176
|
+
const price_animated_val = reactNativeReanimated.useSharedValue(data[0].price);
|
|
177
|
+
const [priceText, setPriceText] = react.useState(data[0].price);
|
|
178
|
+
reactNativeReanimated.useDerivedValue(() => {
|
|
179
|
+
const txt = price_animated_val.value.toFixed(2);
|
|
180
|
+
reactNativeReanimated.runOnJS(setPriceText)(txt);
|
|
181
|
+
}, [price_animated_val]);
|
|
182
|
+
const updateY = (clamped_x) => {
|
|
183
|
+
let res_prices = GetYForX(clamped_x, width, data, height, ySearch);
|
|
184
|
+
yPos.value = res_prices.y_coord;
|
|
185
|
+
price_animated_val.value = reactNativeReanimated.withTiming(res_prices.real_price, {
|
|
186
|
+
duration: 100
|
|
187
|
+
});
|
|
188
|
+
};
|
|
189
|
+
const pan = reactNativeGestureHandler.Gesture.Pan().onUpdate((evt) => {
|
|
190
|
+
"worklet";
|
|
191
|
+
const raw_x = Number(evt.x);
|
|
192
|
+
const clamped = Math.max(x_range_min, Math.min(x_range_max, raw_x));
|
|
193
|
+
xPos.value = clamped;
|
|
194
|
+
reactNativeReanimated.runOnJS(updateY)(clamped);
|
|
195
|
+
});
|
|
196
|
+
if (!chartData || chartData.length === 0) {
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles.home__main, children: [
|
|
200
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.Text, { style: [styles.home__price, priceTextStyles], children: [
|
|
201
|
+
"$",
|
|
202
|
+
priceText
|
|
203
|
+
] }),
|
|
204
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNativeGestureHandler.GestureDetector, { gesture: pan, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
205
|
+
reactNativeSkia.Canvas,
|
|
206
|
+
{
|
|
207
|
+
style: {
|
|
208
|
+
width,
|
|
209
|
+
height
|
|
210
|
+
},
|
|
211
|
+
children: [
|
|
212
|
+
cursorComponent ? cursorComponent({ xPos, yPos }) : /* @__PURE__ */ jsxRuntime.jsx(Cursor, { xPos, yPos }),
|
|
213
|
+
skpath && /* @__PURE__ */ jsxRuntime.jsx(
|
|
214
|
+
reactNativeSkia.Path,
|
|
215
|
+
{
|
|
216
|
+
path: skpath,
|
|
217
|
+
style: curveFill,
|
|
218
|
+
strokeWidth: curveStrokeWidth,
|
|
219
|
+
color: "#fff",
|
|
220
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
221
|
+
reactNativeSkia.LinearGradient,
|
|
222
|
+
{
|
|
223
|
+
start: reactNativeSkia.vec(0, 0),
|
|
224
|
+
end: reactNativeSkia.vec(width, height),
|
|
225
|
+
colors
|
|
226
|
+
}
|
|
227
|
+
)
|
|
228
|
+
}
|
|
229
|
+
)
|
|
230
|
+
]
|
|
231
|
+
}
|
|
232
|
+
) })
|
|
233
|
+
] });
|
|
234
|
+
};
|
|
235
|
+
const Cursor = ({ xPos, yPos }) => {
|
|
236
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
237
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNativeSkia.Circle, { style: "fill", color: "#f69d69", cx: xPos, cy: yPos, r: 5 }),
|
|
238
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
239
|
+
reactNativeSkia.Circle,
|
|
240
|
+
{
|
|
241
|
+
style: "stroke",
|
|
242
|
+
color: "#f69d69",
|
|
243
|
+
cx: xPos,
|
|
244
|
+
cy: yPos,
|
|
245
|
+
r: 12,
|
|
246
|
+
strokeWidth: 2,
|
|
247
|
+
opacity: 0.65
|
|
248
|
+
}
|
|
249
|
+
),
|
|
250
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
251
|
+
reactNativeSkia.Circle,
|
|
252
|
+
{
|
|
253
|
+
style: "stroke",
|
|
254
|
+
color: "#f69d69",
|
|
255
|
+
cx: xPos,
|
|
256
|
+
cy: yPos,
|
|
257
|
+
r: 18,
|
|
258
|
+
strokeWidth: 2,
|
|
259
|
+
opacity: 0.65
|
|
260
|
+
}
|
|
261
|
+
)
|
|
262
|
+
] });
|
|
263
|
+
};
|
|
264
|
+
const styles = reactNative.StyleSheet.create({
|
|
265
|
+
home__main: {
|
|
266
|
+
flex: 1,
|
|
267
|
+
paddingVertical: 50,
|
|
268
|
+
alignItems: "center",
|
|
269
|
+
backgroundColor: "#181818",
|
|
270
|
+
paddingHorizontal: 20
|
|
271
|
+
},
|
|
272
|
+
home__price: {
|
|
273
|
+
color: "#000",
|
|
274
|
+
fontSize: 52
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
exports.GenerateStringPath = GenerateStringPath;
|
|
279
|
+
exports.GetYForX = GetYForX;
|
|
280
|
+
exports.StockCharts = StockCharts;
|
|
281
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/math.js","../src/rn.js"],"sourcesContent":["// FILE ka main goals kya hai ? =>\r\n// get the data\r\n// generate the skia-path for curve\r\n\r\nimport {\r\n curveBasis,\r\n curveBumpX,\r\n curveLinear,\r\n curveMonotoneX,\r\n curveNatural,\r\n line,\r\n} from \"d3-shape\";\r\n\r\nimport { max, min } from \"d3-array\";\r\nimport { scaleLinear, scaleTime } from \"d3-scale\";\r\n\r\nfunction getCurve(curveType) {\r\n let curve;\r\n\r\n // following are curves I believe are good matches for stock data\r\n switch (curveType) {\r\n case \"curveBasis\":\r\n curve = curveBasis;\r\n break;\r\n case \"curveBumpX\":\r\n curve = curveBumpX;\r\n break;\r\n case \"curveLinear\":\r\n curve = curveLinear;\r\n break;\r\n case \"curveMonotoneX\":\r\n curve = curveMonotoneX;\r\n break;\r\n case \"natural\":\r\n curve = curveNatural;\r\n break;\r\n default:\r\n curve = curveBasis;\r\n console.warn(\r\n \"Invalid curve, falling back to default bezier (curveBasis)\"\r\n );\r\n break;\r\n }\r\n return curve;\r\n}\r\n\r\nfunction GenerateStringPath(curveType, data, canvas_width, canvas_height) {\r\n const curve = getCurve(curveType);\r\n // const data = getPeriodData(period);\r\n\r\n const X_PADDING = Math.max(8, canvas_width * 0.05);\r\n // const CHART_HEIGHT = Math.round(canvas_width * 0.85);\r\n const CHART_HEIGHT = canvas_height;\r\n\r\n const min_x = min(data, (d) => {\r\n return d.timestamp;\r\n });\r\n const max_x = max(data, (d) => {\r\n return d.timestamp;\r\n });\r\n\r\n const x_func = scaleTime()\r\n .domain([min_x, max_x])\r\n .range([X_PADDING, canvas_width - X_PADDING]);\r\n // now we can call like x(someTimestampValue)\r\n // this is done while plotting the path like line().x((d) => x(d.timestamp))\r\n\r\n const min_y = min(data, (d) => {\r\n return d.price;\r\n });\r\n const max_y = max(data, (d) => {\r\n return d.price;\r\n });\r\n\r\n const y_padding = (max_y - min_y) * 0.1;\r\n\r\n const y_func = scaleLinear()\r\n .domain([min_y - y_padding, max_y + y_padding])\r\n .range([CHART_HEIGHT, 0]);\r\n\r\n const str_path = line()\r\n .x((d) => x_func(d.timestamp))\r\n .y((d) => y_func(d.price))\r\n .curve(curve)(data);\r\n\r\n return {\r\n str_path,\r\n x_func,\r\n y_func,\r\n data,\r\n x_range_min: X_PADDING,\r\n x_range_max: canvas_width - X_PADDING,\r\n };\r\n}\r\n\r\nlet path_config = null;\r\n\r\nfunction GetYForX(x_pos, canvas_width, data, canvas_height, y_search_alogorithm) {\r\n // IDEA BEHIND THIS FUNC. :\r\n // the curve is not linear so find two nearby points for the given X (timestamp)\r\n // then assume them as a linear line and get Y via linear interpolation\r\n // also cache the path configs\r\n\r\n if (\r\n !path_config || \r\n path_config.canvas_width !== canvas_width || \r\n path_config.canvas_height !== canvas_height ||\r\n path_config.data.length !== data.length\r\n ) {\r\n path_config = {\r\n ...GenerateStringPath(\"curveBumpX\", data, canvas_width, canvas_height),\r\n canvas_width,\r\n canvas_height\r\n };\r\n }\r\n\r\n const { x_func, y_func, x_range_min, x_range_max } = path_config;\r\n\r\n // keep x within bounds by clamping it\r\n let clamped_x_pos = Math.max(x_range_min, Math.min(x_range_max, x_pos));\r\n\r\n let res = searchStrategy(\r\n y_search_alogorithm,\r\n clamped_x_pos,\r\n x_func,\r\n data,\r\n y_func\r\n );\r\n\r\n return res;\r\n}\r\n\r\nconst searchStrategy = (\r\n search_strategy,\r\n clamped_x_pos,\r\n x_func,\r\n data,\r\n y_func\r\n) => {\r\n let res;\r\n switch (search_strategy) {\r\n case \"binarySearchWithInterpolation\":\r\n res = binarySearchWithInterpolation(clamped_x_pos, x_func, data, y_func);\r\n break;\r\n\r\n // might add more strategies later\r\n // one might be using lookup tables\r\n // as for less data points interpolation fails\r\n\r\n default:\r\n console.warn(\r\n \"invalid search strategy, falling back to binary with interpolation\"\r\n );\r\n res = binarySearchWithInterpolation(clamped_x_pos, x_func, data, y_func);\r\n break;\r\n }\r\n\r\n return res;\r\n};\r\n\r\nconst binarySearchWithInterpolation = (clamped_x_pos, x_func, data, y_func) => {\r\n let timestamp = x_func.invert(clamped_x_pos).getTime();\r\n\r\n let left_idx = 0;\r\n\r\n if (timestamp <= data[0].timestamp) {\r\n const p = data[0].price;\r\n return { y_coord: y_func(p), real_price: p };\r\n }\r\n if (timestamp >= data[data.length - 1].timestamp) {\r\n const p = data[data.length - 1].price;\r\n return { y_coord: y_func(p), real_price: p };\r\n }\r\n\r\n // Binary search (could have gone with linear search as well but lol why not better)\r\n let left = 0;\r\n let right = data.length - 1;\r\n\r\n while (left < right - 1) {\r\n const mid = Math.floor((left + right) / 2);\r\n if (data[mid].timestamp <= timestamp) {\r\n left = mid;\r\n } else {\r\n right = mid;\r\n }\r\n }\r\n\r\n if (left >= data.length - 1) left = data.length - 2;\r\n\r\n left_idx = left;\r\n\r\n const left_point = data[left_idx];\r\n const right_point = data[left_idx + 1];\r\n\r\n // do Linear interpolation here\r\n const denominator = right_point.timestamp - left_point.timestamp;\r\n const ratio =\r\n denominator !== 0 ? (timestamp - left_point.timestamp) / denominator : 0;\r\n const y_val =\r\n left_point.price + ratio * (right_point.price - left_point.price);\r\n\r\n let real_price = y_val;\r\n let y_coord = y_func(y_val);\r\n return { y_coord, real_price };\r\n};\r\n\r\nexport { GenerateStringPath, GetYForX };\r\n","import { Text, View, StyleSheet } from \"react-native\";\r\nimport {\r\n Canvas,\r\n LinearGradient,\r\n Path,\r\n vec,\r\n Skia,\r\n Circle,\r\n} from \"@shopify/react-native-skia\";\r\nimport { GenerateStringPath, GetYForX } from \"./math\";\r\nimport { Gesture, GestureDetector } from \"react-native-gesture-handler\";\r\nimport {\r\n useDerivedValue,\r\n useSharedValue,\r\n runOnJS,\r\n withTiming,\r\n} from \"react-native-reanimated\";\r\nimport { useState } from \"react\";\r\n\r\nexport const StockCharts = ({\r\n width,\r\n height,\r\n chartData,\r\n priceTextStyles,\r\n curveType = \"curveBasis\",\r\n colors = [\"#fff\"],\r\n cursorComponent,\r\n curveStrokeWidth = 2,\r\n curveFill = \"stroke\",\r\n ySearch = \"binarySearchWithInterpolation\",\r\n}) => {\r\n const { str_path, x_func, y_func, data, x_range_min, x_range_max } =\r\n GenerateStringPath(curveType, chartData, width, height);\r\n\r\n const skpath = Skia.Path.MakeFromSVGString(str_path);\r\n\r\n let init_x = x_func(data[0].timestamp);\r\n let init_y = y_func(data[0].price);\r\n\r\n const xPos = useSharedValue(init_x);\r\n const yPos = useSharedValue(init_y);\r\n const price_animated_val = useSharedValue(data[0].price);\r\n const [priceText, setPriceText] = useState(data[0].price);\r\n\r\n useDerivedValue(() => {\r\n const txt = price_animated_val.value.toFixed(2);\r\n runOnJS(setPriceText)(txt);\r\n }, [price_animated_val]);\r\n\r\n const updateY = (clamped_x) => {\r\n let res_prices = GetYForX(clamped_x, width, data, height, ySearch);\r\n yPos.value = res_prices.y_coord;\r\n\r\n price_animated_val.value = withTiming(res_prices.real_price, {\r\n duration: 100,\r\n });\r\n };\r\n\r\n const pan = Gesture.Pan().onUpdate((evt) => {\r\n \"worklet\";\r\n const raw_x = Number(evt.x);\r\n const clamped = Math.max(x_range_min, Math.min(x_range_max, raw_x));\r\n xPos.value = clamped;\r\n\r\n runOnJS(updateY)(clamped);\r\n });\r\n\r\n if (!chartData || chartData.length === 0) {\r\n return null; // or a fallback view in future , maybe :)\r\n }\r\n\r\n return (\r\n <View style={styles.home__main}>\r\n <Text style={[styles.home__price, priceTextStyles]}>${priceText}</Text>\r\n\r\n <GestureDetector gesture={pan}>\r\n <Canvas\r\n style={{\r\n width: width,\r\n height: height,\r\n }}\r\n >\r\n {cursorComponent ? (\r\n cursorComponent({ xPos, yPos })\r\n ) : (\r\n <Cursor xPos={xPos} yPos={yPos} />\r\n )}\r\n\r\n {skpath && (\r\n <Path\r\n path={skpath}\r\n style={curveFill} \r\n strokeWidth={curveStrokeWidth}\r\n color={\"#fff\"} // i forgot what's this :(\r\n >\r\n <LinearGradient\r\n start={vec(0, 0)}\r\n end={vec(width, height)}\r\n colors={colors}\r\n />\r\n </Path>\r\n )}\r\n </Canvas>\r\n </GestureDetector>\r\n </View>\r\n );\r\n};\r\n\r\nconst Cursor = ({ xPos, yPos }) => {\r\n return (\r\n <>\r\n <Circle style=\"fill\" color=\"#f69d69\" cx={xPos} cy={yPos} r={5} />\r\n <Circle\r\n style=\"stroke\"\r\n color=\"#f69d69\"\r\n cx={xPos}\r\n cy={yPos}\r\n r={12}\r\n strokeWidth={2}\r\n opacity={0.65}\r\n />\r\n <Circle\r\n style=\"stroke\"\r\n color=\"#f69d69\"\r\n cx={xPos}\r\n cy={yPos}\r\n r={18}\r\n strokeWidth={2}\r\n opacity={0.65}\r\n />\r\n </>\r\n );\r\n};\r\n\r\nconst styles = StyleSheet.create({\r\n home__main: {\r\n flex: 1,\r\n paddingVertical: 50,\r\n alignItems: \"center\",\r\n backgroundColor: \"#181818\",\r\n paddingHorizontal: 20,\r\n },\r\n home__price: {\r\n color: \"#000\",\r\n fontSize: 52,\r\n },\r\n});\r\n"],"names":["curveBasis","curveBumpX","curveLinear","curveMonotoneX","curveNatural","min","max","scaleTime","scaleLinear","line","Skia","useSharedValue","useState","useDerivedValue","runOnJS","withTiming","Gesture","jsxs","View","Text","jsx","GestureDetector","Canvas","Path","LinearGradient","vec","Fragment","Circle","StyleSheet"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "rn-cute-stocks",
|
|
3
|
+
"version": "1.0.1-beta.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"homepage": "https://github.com/DivyanshuShekhar55/rn-cute-stocks#readme",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/DivyanshuShekhar55/rn-cute-stocks/issues"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/DivyanshuShekhar55/rn-cute-stocks.git"
|
|
12
|
+
},
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"author": "Divyanshu Shekhar",
|
|
15
|
+
"type": "commonjs",
|
|
16
|
+
"main": "dist/index.js",
|
|
17
|
+
"module": "dist/esm/index.mjs",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"import": "./dist/esm/index.mjs",
|
|
21
|
+
"require": "./dist/index.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist"
|
|
26
|
+
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
29
|
+
"build:base": "rollup -c"
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"react": ">=19.0.0",
|
|
33
|
+
"react-native": ">=0.79.0",
|
|
34
|
+
"@shopify/react-native-skia": ">=2.0.0",
|
|
35
|
+
"react-native-reanimated": ">=4.0.0",
|
|
36
|
+
"react-native-gesture-handler": ">=2.0.0",
|
|
37
|
+
"d3-array": ">=3.0.0",
|
|
38
|
+
"d3-scale": ">=4.0.0",
|
|
39
|
+
"d3-shape": ">=3.0.0"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@rollup/plugin-alias": "^5.0.0",
|
|
43
|
+
"@rollup/plugin-node-resolve": "^15.0.0",
|
|
44
|
+
"@rollup/plugin-replace": "^5.0.0",
|
|
45
|
+
"@shopify/react-native-skia": "^1.0.0",
|
|
46
|
+
"d3-array": "^3.0.0",
|
|
47
|
+
"d3-scale": "^4.0.0",
|
|
48
|
+
"d3-shape": "^3.0.0",
|
|
49
|
+
"react": "^18.0.0",
|
|
50
|
+
"react-native": "^0.73.0",
|
|
51
|
+
"react-native-gesture-handler": "^2.0.0",
|
|
52
|
+
"react-native-reanimated": "^3.0.0",
|
|
53
|
+
"rollup": "^4.0.0",
|
|
54
|
+
"rollup-plugin-esbuild": "^6.0.0"
|
|
55
|
+
}
|
|
56
|
+
}
|