@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 @@
1
+ {"version":3,"file":"textUtils.d.ts","sourceRoot":"","sources":["../../../src/textUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,WAAW,EACjB,MAAM,yBAAyB,CAAC;AAOjC,eAAO,MAAM,oBAAoB,GAC/B,YAAW,MAAU,KACpB,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAO3C,CAAC"}
package/package.json ADDED
@@ -0,0 +1,226 @@
1
+ {
2
+ "name": "@obitrain/charts",
3
+ "version": "0.9.2",
4
+ "description": "Charting library for React Native",
5
+ "main": "lib/commonjs/index",
6
+ "module": "lib/module/index",
7
+ "types": "lib/typescript/src/index.d.ts",
8
+ "react-native": "src/index",
9
+ "source": "src/index",
10
+ "files": [
11
+ "src",
12
+ "lib",
13
+ "android",
14
+ "ios",
15
+ "cpp",
16
+ "*.podspec",
17
+ "!ios/build",
18
+ "!android/build",
19
+ "!android/gradle",
20
+ "!android/gradlew",
21
+ "!android/gradlew.bat",
22
+ "!android/local.properties",
23
+ "!**/__tests__",
24
+ "!**/__fixtures__",
25
+ "!**/__mocks__",
26
+ "!**/.*"
27
+ ],
28
+ "scripts": {
29
+ "example": "yarn workspace obi-chart-example",
30
+ "test": "jest",
31
+ "typecheck": "tsc --noEmit",
32
+ "lint": "eslint \"**/*.{js,ts,tsx}\"",
33
+ "clean": "del-cli lib",
34
+ "prepare": "bob build",
35
+ "release": "./bin/release.sh",
36
+ "gifs": "./bin/capture-gifs.sh",
37
+ "check-deps": "npx @rnx-kit/align-deps@latest --diff-mode allow-subset package.json"
38
+ },
39
+ "keywords": [
40
+ "react-native",
41
+ "ios",
42
+ "android"
43
+ ],
44
+ "repository": {
45
+ "type": "git",
46
+ "url": "git+https://github.com/Obitrain/obi-chart.git"
47
+ },
48
+ "author": "Julien Brayere <julien.brayere@obitrain.com> (https://github.com/Andarius)",
49
+ "license": "MIT",
50
+ "bugs": {
51
+ "url": "https://github.com/Obitrain/obi-chart/issues"
52
+ },
53
+ "homepage": "https://github.com/Obitrain/obi-chart#readme",
54
+ "publishConfig": {
55
+ "access": "public",
56
+ "registry": "https://registry.npmjs.org/"
57
+ },
58
+ "devDependencies": {
59
+ "@commitlint/config-conventional": "^17.0.2",
60
+ "@evilmartians/lefthook": "^1.5.0",
61
+ "@react-native-community/cli": "^20.1.0",
62
+ "@react-native-community/cli-platform-android": "^20.1.0",
63
+ "@react-native-community/cli-platform-ios": "^20.1.0",
64
+ "@react-native/babel-preset": "^0.86.0",
65
+ "@react-native/eslint-config": "^0.86.0",
66
+ "@react-native/jest-preset": "^0.86.0",
67
+ "@react-native/metro-config": "^0.86.0",
68
+ "@release-it/conventional-changelog": "^5.0.0",
69
+ "@rnx-kit/align-deps": "^4.0.6",
70
+ "@shopify/react-native-skia": "2.6.2",
71
+ "@types/d3-scale": "^4.0.5",
72
+ "@types/d3-shape": "^3.1.3",
73
+ "@types/jest": "^29.2.1",
74
+ "@types/react": "^19.2.0",
75
+ "commitlint": "^17.0.2",
76
+ "d3-scale": "^4.0.2",
77
+ "d3-shape": "^3.2.0",
78
+ "del-cli": "^5.0.0",
79
+ "eslint": "^8.19.0",
80
+ "eslint-config-prettier": "^8.5.0",
81
+ "eslint-plugin-deprecation": "^3.0.0",
82
+ "eslint-plugin-ft-flow": "^2.0.3",
83
+ "eslint-plugin-prettier": "^4.2.1",
84
+ "eslint-plugin-react": "^7.32.2",
85
+ "jest": "^29.2.1",
86
+ "prettier": "^2.0.5",
87
+ "react": "^16.9.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
88
+ "react-native": "^0.86.0",
89
+ "react-native-builder-bob": "^0.40.17",
90
+ "react-native-gesture-handler": "~2.32.0",
91
+ "react-native-reanimated": "~4.5.1",
92
+ "react-native-worklets": "^0.10.1",
93
+ "react-test-renderer": "19.2.3",
94
+ "release-it": "^15.0.0",
95
+ "typescript": "^5.0.2"
96
+ },
97
+ "peerDependencies": {
98
+ "@shopify/react-native-skia": ">=2.0.0 <3.0.0",
99
+ "d3-scale": ">=4.0.2 <5.0.0",
100
+ "d3-shape": ">=3.2.0 <4.0.0",
101
+ "react": "16.9.0 || 16.11.0 || 16.13.1 || 17.0.1 || 17.0.2 || 18.0.0 || 18.1.0 || 18.2.0 || ^18.2.0 || 18.3.1 || 19.0.0 || 19.1.0 || 19.1.4 || ^16.9.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || 19.2.3",
102
+ "react-native": "^0.61.5 || ^0.62.3 || ^0.63.2 || ^0.64.2 || ^0.65.0 || ^0.66.0 || ^0.67.0 || ^0.68.0 || ^0.69.0 || ^0.70.0 || ^0.71.0 || ^0.72.0 || ^0.73.0 || ^0.74.0 || ^0.75.0 || ^0.76.0 || ^0.77.0 || ^0.78.0 || ^0.79.0 || ^0.80.0 || ^0.81.6 || ^0.82.0 || ^0.83.0 || ^0.84.0 || ^0.85.0 || ^0.86.0 || ^0.87.0",
103
+ "react-native-gesture-handler": "^1.9.0 || ^1.10.3 || ^2.3.2 || ^2.5.0 || ^2.6.0 || ^2.9.0 || ^2.12.0 || ^2.14.0 || ^2.18.1 || ^2.20.0 || ^2.22.0 || ^2.24.0 || ^2.26.0 || ^2.28.0 || ^2.29.1 || ^2.30.0 || ^2.31.1 || ~2.32.0 || ^3.1.0",
104
+ "react-native-reanimated": "^1.13.3 || ^2.1.0 || ^2.2.1 || ^2.2.3 || ^2.2.4 || ^2.5.0 || ^2.9.0 || ^2.10.0 || ^2.14.1 || ^3.3.0 || ^3.6.0 || ^3.9.0 || ^3.15.0 || ^3.16.1 || ^3.16.7 || ^3.17.0 || ^3.17.5 || ^3.18.0 || ^3.19.0 || ^4.2.0 || ~4.2.0 || ^4.2.2 || ^4.4.3 || ~4.5.1 || ^4.5.3",
105
+ "react-native-worklets": ">=0.10.0"
106
+ },
107
+ "peerDependenciesMeta": {
108
+ "react-native-worklets": {
109
+ "optional": true
110
+ }
111
+ },
112
+ "workspaces": [
113
+ "example"
114
+ ],
115
+ "resolutions": {
116
+ "react": "19.2.3",
117
+ "react-dom": "19.2.3"
118
+ },
119
+ "packageManager": "yarn@3.6.1",
120
+ "engines": {
121
+ "node": ">= 20.19.4"
122
+ },
123
+ "jest": {
124
+ "preset": "@react-native/jest-preset",
125
+ "modulePathIgnorePatterns": [
126
+ "<rootDir>/example/node_modules",
127
+ "<rootDir>/lib/"
128
+ ]
129
+ },
130
+ "commitlint": {
131
+ "extends": [
132
+ "@commitlint/config-conventional"
133
+ ]
134
+ },
135
+ "release-it": {
136
+ "git": {
137
+ "commitMessage": "chore: release ${version}",
138
+ "tagName": "v${version}"
139
+ },
140
+ "npm": {
141
+ "publish": true,
142
+ "skipChecks": true
143
+ },
144
+ "github": {
145
+ "release": true
146
+ },
147
+ "plugins": {
148
+ "@release-it/conventional-changelog": {
149
+ "preset": "angular"
150
+ }
151
+ }
152
+ },
153
+ "eslintConfig": {
154
+ "root": true,
155
+ "extends": [
156
+ "@react-native",
157
+ "prettier"
158
+ ],
159
+ "rules": {
160
+ "react/react-in-jsx-scope": "off",
161
+ "prettier/prettier": [
162
+ "error",
163
+ {
164
+ "quoteProps": "consistent",
165
+ "singleQuote": true,
166
+ "tabWidth": 2,
167
+ "trailingComma": "es5",
168
+ "useTabs": false
169
+ }
170
+ ]
171
+ }
172
+ },
173
+ "eslintIgnore": [
174
+ "node_modules/",
175
+ "lib/"
176
+ ],
177
+ "prettier": {
178
+ "quoteProps": "consistent",
179
+ "singleQuote": true,
180
+ "tabWidth": 2,
181
+ "trailingComma": "es5",
182
+ "useTabs": false
183
+ },
184
+ "react-native-builder-bob": {
185
+ "source": "src",
186
+ "output": "lib",
187
+ "targets": [
188
+ "commonjs",
189
+ "module",
190
+ [
191
+ "typescript",
192
+ {
193
+ "project": "tsconfig.build.json"
194
+ }
195
+ ]
196
+ ]
197
+ },
198
+ "rnx-kit": {
199
+ "kitType": "library",
200
+ "alignDeps": {
201
+ "presets": [
202
+ "microsoft/react-native",
203
+ "./align-deps-preset.js"
204
+ ],
205
+ "requirements": {
206
+ "development": [
207
+ "react-native@0.86"
208
+ ],
209
+ "production": [
210
+ "react-native@*"
211
+ ]
212
+ },
213
+ "capabilities": [
214
+ "animation",
215
+ "babel-preset-react-native",
216
+ "core",
217
+ "core-android",
218
+ "core-ios",
219
+ "gestures",
220
+ "jest",
221
+ "react",
222
+ "react-test-renderer"
223
+ ]
224
+ }
225
+ }
226
+ }
@@ -0,0 +1,40 @@
1
+ import { Line, vec, type Color } from '@shopify/react-native-skia';
2
+ import { type FC } from 'react';
3
+ import { StyleSheet } from 'react-native';
4
+ import { useDerivedValue, type SharedValue } from 'react-native-reanimated';
5
+ import { getPositionWl } from '../gesture';
6
+
7
+ export type AxisLineProps = {
8
+ width: number;
9
+ focalX: SharedValue<number>;
10
+ scale: SharedValue<number>;
11
+ offsetX: SharedValue<number>;
12
+ strokeWidth?: number;
13
+ offsetY?: number;
14
+ color?: Color;
15
+ };
16
+
17
+ const AxisLine: FC<AxisLineProps> = function (props) {
18
+ const {
19
+ width,
20
+ focalX,
21
+ scale,
22
+ offsetX,
23
+ offsetY = 0,
24
+ strokeWidth = StyleSheet.hairlineWidth,
25
+ color = 'black',
26
+ } = props;
27
+ const p1 = useDerivedValue(() => {
28
+ const p1X = getPositionWl(0, focalX.value, scale.value, offsetX.value);
29
+ return vec(p1X, offsetY);
30
+ }, []);
31
+
32
+ const p2 = useDerivedValue(() => {
33
+ const p1X = getPositionWl(width, focalX.value, scale.value, offsetX.value);
34
+ return vec(p1X, offsetY);
35
+ }, [width]);
36
+
37
+ return <Line {...{ p1, p2, color, strokeWidth }} />;
38
+ };
39
+
40
+ export { AxisLine };
@@ -0,0 +1,41 @@
1
+ // ChartUtilsScreen.tsx
2
+ import { Canvas, type SkFont } from '@shopify/react-native-skia';
3
+ import { type FC } from 'react';
4
+ import { type StyleProp, type ViewStyle } from 'react-native';
5
+ import type { SharedValue } from 'react-native-reanimated';
6
+ import { AxisLine } from './AxisLine';
7
+ import { Tick } from './Tick';
8
+
9
+ export type BottomAxisProps = {
10
+ labels: string[];
11
+ width: number;
12
+ // tickInterval: number;
13
+ scale: SharedValue<number>;
14
+ focalX: SharedValue<number>;
15
+ offsetX: SharedValue<number>;
16
+ offsetY?: number;
17
+ style?: StyleProp<ViewStyle>;
18
+ font: SkFont;
19
+ };
20
+
21
+ const BottomAxis: FC<BottomAxisProps> = function (props) {
22
+ const { labels, scale, focalX, offsetX, style, width, font } = props;
23
+ const offsetY = props.offsetY ?? 0;
24
+ const tickInterval = width / (labels.length - 1);
25
+
26
+ return (
27
+ <Canvas style={style}>
28
+ <AxisLine {...{ width, offsetY, focalX, scale, offsetX }} />
29
+ {labels.map((_label, i) => (
30
+ <Tick
31
+ key={i}
32
+ label={_label}
33
+ initPosition={tickInterval * i}
34
+ {...{ offsetX, offsetY, focalX, scale, font }}
35
+ />
36
+ ))}
37
+ </Canvas>
38
+ );
39
+ };
40
+
41
+ export { BottomAxis };
@@ -0,0 +1,54 @@
1
+ import {
2
+ Group,
3
+ Line,
4
+ Text,
5
+ vec,
6
+ type SkFont,
7
+ } from '@shopify/react-native-skia';
8
+ import React from 'react';
9
+ import { useDerivedValue, type SharedValue } from 'react-native-reanimated';
10
+ import { getPositionWl } from '../gesture';
11
+
12
+ export type TickProps = {
13
+ initPosition: number;
14
+ label: string;
15
+ scale: SharedValue<number>;
16
+ focalX: SharedValue<number>;
17
+ offsetX: SharedValue<number>;
18
+ offsetY?: number;
19
+ font: SkFont;
20
+ };
21
+
22
+ export const Tick: React.FC<TickProps> = (props) => {
23
+ const { label, scale, focalX, offsetX, initPosition, font } = props;
24
+ const offsetY = props.offsetY ?? 0;
25
+ const transform = useDerivedValue(
26
+ () => [
27
+ {
28
+ translateX: getPositionWl(
29
+ initPosition,
30
+ focalX.value,
31
+ scale.value,
32
+ offsetX.value
33
+ ),
34
+ },
35
+ ],
36
+ [initPosition, offsetX]
37
+ );
38
+ const width = font
39
+ .getGlyphWidths(font.getGlyphIDs(label))
40
+ .reduce((a, b) => a + b, 0);
41
+
42
+ return (
43
+ <Group transform={transform}>
44
+ <Line color="black" p1={vec(0, offsetY)} p2={vec(0, offsetY + 10)} />
45
+ <Text
46
+ text={label}
47
+ color="black"
48
+ x={-width / 2}
49
+ y={offsetY + 23}
50
+ font={font}
51
+ />
52
+ </Group>
53
+ );
54
+ };
@@ -0,0 +1,3 @@
1
+ export { AxisLine, type AxisLineProps } from './AxisLine';
2
+ export { BottomAxis, type BottomAxisProps } from './BottomAxis';
3
+ export { Tick, type TickProps } from './Tick';
@@ -0,0 +1,51 @@
1
+ import { Circle, type PathCommand } from '@shopify/react-native-skia';
2
+ import type { FC } from 'react';
3
+ import { useDerivedValue, type SharedValue } from 'react-native-reanimated';
4
+ import { getYForX } from './maths';
5
+
6
+ const CURSOR_SIZE = 10;
7
+
8
+ export type CursorProps = {
9
+ commands?: SharedValue<PathCommand[]>;
10
+ positionX: SharedValue<number>;
11
+ size?: number;
12
+ color?: string;
13
+ currentValue?: SharedValue<number> | SharedValue<undefined>;
14
+ translateY?: SharedValue<number | undefined>;
15
+ };
16
+
17
+ const Cursor: FC<CursorProps> = function ({
18
+ commands,
19
+ positionX,
20
+ color,
21
+ currentValue,
22
+ translateY,
23
+ size = CURSOR_SIZE,
24
+ }) {
25
+ if (currentValue !== undefined && translateY !== undefined) {
26
+ console.warn('Current value as no effect when translateY is set');
27
+ }
28
+
29
+ const _translateY = translateY
30
+ ? translateY
31
+ : // eslint-disable-next-line react-hooks/rules-of-hooks
32
+ useDerivedValue(() => {
33
+ const _commands = commands?.value;
34
+ if (_commands === undefined) {
35
+ return 0;
36
+ }
37
+ const _value = getYForX(_commands, positionX.value) ?? 0;
38
+ if (currentValue !== undefined) {
39
+ currentValue.value = _value;
40
+ }
41
+ return _value;
42
+ });
43
+
44
+ const transform = useDerivedValue(() => [
45
+ { translateX: positionX.value },
46
+ { translateY: _translateY.value ?? 0 },
47
+ ]);
48
+ return <Circle transform={transform} cx={0} cy={0} r={size} color={color} />;
49
+ };
50
+
51
+ export { Cursor };
@@ -0,0 +1,79 @@
1
+ import { Canvas, Group, Path, type SkPath } from '@shopify/react-native-skia';
2
+ import type { FC } from 'react';
3
+ import React from 'react';
4
+ import type { StyleProp, ViewStyle } from 'react-native';
5
+ import type { SharedValue } from 'react-native-reanimated';
6
+
7
+ export type LinePath = {
8
+ path: SkPath | SharedValue<SkPath>;
9
+ color: string;
10
+ id?: string;
11
+ };
12
+
13
+ export type LineChartProps = {
14
+ path?: SkPath | SharedValue<SkPath>;
15
+ paths?: LinePath[];
16
+ height: number;
17
+ width: number;
18
+ style?: StyleProp<ViewStyle>;
19
+ color?: string;
20
+ offsetY?: number;
21
+ offsetX?: number;
22
+ background?: React.ReactNode;
23
+ children?: React.ReactNode;
24
+ };
25
+
26
+ const LineChart: FC<LineChartProps> = function (props) {
27
+ const {
28
+ width,
29
+ height,
30
+ style,
31
+ path,
32
+ children,
33
+ color,
34
+ paths,
35
+ background,
36
+ offsetX = 0,
37
+ offsetY = 0,
38
+ } = props;
39
+
40
+ const _paths: LinePath[] =
41
+ paths !== undefined
42
+ ? paths
43
+ : path !== undefined
44
+ ? [{ path: path, color: color ?? 'red' }]
45
+ : [];
46
+ if (_paths.length === 0) {
47
+ console.warn('Specify either a path or multiple paths.');
48
+ return null;
49
+ // throw new Error('Specify either a path or multiple paths.');
50
+ }
51
+ return (
52
+ <Canvas
53
+ style={[
54
+ {
55
+ width,
56
+ height,
57
+ },
58
+ style,
59
+ ]}
60
+ >
61
+ <Group transform={[{ translateY: offsetY }, { translateX: offsetX }]}>
62
+ {background}
63
+ {_paths.map((_path, i) => (
64
+ <Path
65
+ key={`${_path.id ?? i}`}
66
+ style="stroke"
67
+ {..._path}
68
+ strokeWidth={2}
69
+ strokeJoin="round"
70
+ strokeCap="round"
71
+ />
72
+ ))}
73
+ {children}
74
+ </Group>
75
+ </Canvas>
76
+ );
77
+ };
78
+
79
+ export { LineChart };
@@ -0,0 +1,49 @@
1
+ import {
2
+ Path,
3
+ Skia,
4
+ type PathCommand,
5
+ type SkPath,
6
+ } from '@shopify/react-native-skia';
7
+ import { type FC } from 'react';
8
+ import { useDerivedValue, type SharedValue } from 'react-native-reanimated';
9
+ import { scaleCommands } from '../graphUtils';
10
+
11
+ export type ScalablePathProps = {
12
+ path: SharedValue<SkPath>;
13
+ scale: SharedValue<number>;
14
+ focalX: SharedValue<number>;
15
+ offsetX: SharedValue<number>;
16
+ color?: string;
17
+ pathProps?: Omit<React.ComponentProps<typeof Path>, 'color'>;
18
+ };
19
+
20
+ const ScalablePath: FC<ScalablePathProps> = function (props) {
21
+ const { path, scale, focalX, offsetX, pathProps, color = 'red' } = props;
22
+
23
+ const animatedPath = useDerivedValue(() => {
24
+ let _cmds: PathCommand[] = [];
25
+ try {
26
+ _cmds = scaleCommands(path.value?.toCmds() ?? [], scale, focalX, offsetX);
27
+ } catch (e) {
28
+ console.error('Got error while scaling path: ', typeof e);
29
+ _cmds = [];
30
+ }
31
+ const _path = Skia.Path.MakeFromCmds(_cmds);
32
+ if (!_path) throw new Error('Path is null');
33
+ return _path;
34
+ }, [scale]);
35
+
36
+ return (
37
+ <Path
38
+ style="stroke"
39
+ path={animatedPath}
40
+ strokeWidth={2}
41
+ strokeJoin="round"
42
+ strokeCap="round"
43
+ color={color}
44
+ {...pathProps}
45
+ />
46
+ );
47
+ };
48
+
49
+ export { ScalablePath };
@@ -0,0 +1,47 @@
1
+ import { Canvas, Group, type SkPath } from '@shopify/react-native-skia';
2
+ import type { FC } from 'react';
3
+ import React from 'react';
4
+ import type { StyleProp, ViewStyle } from 'react-native';
5
+
6
+ import type { SharedValue } from 'react-native-reanimated';
7
+ import { ScalablePath, type ScalablePathProps } from './ScalablePath';
8
+
9
+ export { ScalablePath };
10
+ export type { ScalablePathProps };
11
+
12
+ export type ZoomableLineChartProps = {
13
+ height: number;
14
+ width: number;
15
+ offsetX: SharedValue<number>;
16
+ scale: SharedValue<number>;
17
+ focalX: SharedValue<number>;
18
+ offsetY?: number;
19
+
20
+ style?: StyleProp<ViewStyle>;
21
+ path: SharedValue<SkPath>;
22
+ children?: React.ReactNode;
23
+ color?: string;
24
+ };
25
+
26
+ const ZoomableLineChart: FC<ZoomableLineChartProps> = function (props) {
27
+ const { width, height, style, children, offsetY = 0, ...rest } = props;
28
+
29
+ return (
30
+ <Canvas
31
+ style={[
32
+ {
33
+ width,
34
+ height,
35
+ },
36
+ style,
37
+ ]}
38
+ >
39
+ <Group transform={[{ translateY: offsetY }]}>
40
+ <ScalablePath {...rest} />
41
+ {children}
42
+ </Group>
43
+ </Canvas>
44
+ );
45
+ };
46
+
47
+ export { ZoomableLineChart };