@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.
- package/LICENSE +21 -0
- package/README.md +125 -0
- package/lib/commonjs/Charts/BottomAxis/AxisLine.js +38 -0
- package/lib/commonjs/Charts/BottomAxis/AxisLine.js.map +1 -0
- package/lib/commonjs/Charts/BottomAxis/BottomAxis.js +45 -0
- package/lib/commonjs/Charts/BottomAxis/BottomAxis.js.map +1 -0
- package/lib/commonjs/Charts/BottomAxis/Tick.js +43 -0
- package/lib/commonjs/Charts/BottomAxis/Tick.js.map +1 -0
- package/lib/commonjs/Charts/BottomAxis/index.js +27 -0
- package/lib/commonjs/Charts/BottomAxis/index.js.map +1 -0
- package/lib/commonjs/Charts/Cursor.js +50 -0
- package/lib/commonjs/Charts/Cursor.js.map +1 -0
- package/lib/commonjs/Charts/Linechart/index.js +55 -0
- package/lib/commonjs/Charts/Linechart/index.js.map +1 -0
- package/lib/commonjs/Charts/ZoomableLinechart/ScalablePath.js +43 -0
- package/lib/commonjs/Charts/ZoomableLinechart/ScalablePath.js.map +1 -0
- package/lib/commonjs/Charts/ZoomableLinechart/index.js +43 -0
- package/lib/commonjs/Charts/ZoomableLinechart/index.js.map +1 -0
- package/lib/commonjs/Charts/gesture.js +185 -0
- package/lib/commonjs/Charts/gesture.js.map +1 -0
- package/lib/commonjs/Charts/graphUtils.js +131 -0
- package/lib/commonjs/Charts/graphUtils.js.map +1 -0
- package/lib/commonjs/Charts/index.js +151 -0
- package/lib/commonjs/Charts/index.js.map +1 -0
- package/lib/commonjs/Charts/maths.js +195 -0
- package/lib/commonjs/Charts/maths.js.map +1 -0
- package/lib/commonjs/Charts/types.js +6 -0
- package/lib/commonjs/Charts/types.js.map +1 -0
- package/lib/commonjs/dateUtils.js +151 -0
- package/lib/commonjs/dateUtils.js.map +1 -0
- package/lib/commonjs/index.js +39 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/textUtils.js +21 -0
- package/lib/commonjs/textUtils.js.map +1 -0
- package/lib/module/Charts/BottomAxis/AxisLine.js +34 -0
- package/lib/module/Charts/BottomAxis/AxisLine.js.map +1 -0
- package/lib/module/Charts/BottomAxis/BottomAxis.js +40 -0
- package/lib/module/Charts/BottomAxis/BottomAxis.js.map +1 -0
- package/lib/module/Charts/BottomAxis/Tick.js +37 -0
- package/lib/module/Charts/BottomAxis/Tick.js.map +1 -0
- package/lib/module/Charts/BottomAxis/index.js +6 -0
- package/lib/module/Charts/BottomAxis/index.js.map +1 -0
- package/lib/module/Charts/Cursor.js +46 -0
- package/lib/module/Charts/Cursor.js.map +1 -0
- package/lib/module/Charts/Linechart/index.js +50 -0
- package/lib/module/Charts/Linechart/index.js.map +1 -0
- package/lib/module/Charts/ZoomableLinechart/ScalablePath.js +39 -0
- package/lib/module/Charts/ZoomableLinechart/ScalablePath.js.map +1 -0
- package/lib/module/Charts/ZoomableLinechart/index.js +33 -0
- package/lib/module/Charts/ZoomableLinechart/index.js.map +1 -0
- package/lib/module/Charts/gesture.js +176 -0
- package/lib/module/Charts/gesture.js.map +1 -0
- package/lib/module/Charts/graphUtils.js +121 -0
- package/lib/module/Charts/graphUtils.js.map +1 -0
- package/lib/module/Charts/index.js +10 -0
- package/lib/module/Charts/index.js.map +1 -0
- package/lib/module/Charts/maths.js +187 -0
- package/lib/module/Charts/maths.js.map +1 -0
- package/lib/module/Charts/types.js +4 -0
- package/lib/module/Charts/types.js.map +1 -0
- package/lib/module/dateUtils.js +142 -0
- package/lib/module/dateUtils.js.map +1 -0
- package/lib/module/index.js +6 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/textUtils.js +16 -0
- package/lib/module/textUtils.js.map +1 -0
- package/lib/typescript/src/Charts/BottomAxis/AxisLine.d.ts +15 -0
- package/lib/typescript/src/Charts/BottomAxis/AxisLine.d.ts.map +1 -0
- package/lib/typescript/src/Charts/BottomAxis/BottomAxis.d.ts +17 -0
- package/lib/typescript/src/Charts/BottomAxis/BottomAxis.d.ts.map +1 -0
- package/lib/typescript/src/Charts/BottomAxis/Tick.d.ts +14 -0
- package/lib/typescript/src/Charts/BottomAxis/Tick.d.ts.map +1 -0
- package/lib/typescript/src/Charts/BottomAxis/index.d.ts +4 -0
- package/lib/typescript/src/Charts/BottomAxis/index.d.ts.map +1 -0
- package/lib/typescript/src/Charts/Cursor.d.ts +14 -0
- package/lib/typescript/src/Charts/Cursor.d.ts.map +1 -0
- package/lib/typescript/src/Charts/Linechart/index.d.ts +25 -0
- package/lib/typescript/src/Charts/Linechart/index.d.ts.map +1 -0
- package/lib/typescript/src/Charts/ZoomableLinechart/ScalablePath.d.ts +14 -0
- package/lib/typescript/src/Charts/ZoomableLinechart/ScalablePath.d.ts.map +1 -0
- package/lib/typescript/src/Charts/ZoomableLinechart/index.d.ts +23 -0
- package/lib/typescript/src/Charts/ZoomableLinechart/index.d.ts.map +1 -0
- package/lib/typescript/src/Charts/gesture.d.ts +54 -0
- package/lib/typescript/src/Charts/gesture.d.ts.map +1 -0
- package/lib/typescript/src/Charts/graphUtils.d.ts +43 -0
- package/lib/typescript/src/Charts/graphUtils.d.ts.map +1 -0
- package/lib/typescript/src/Charts/index.d.ts +14 -0
- package/lib/typescript/src/Charts/index.d.ts.map +1 -0
- package/lib/typescript/src/Charts/maths.d.ts +19 -0
- package/lib/typescript/src/Charts/maths.d.ts.map +1 -0
- package/lib/typescript/src/Charts/types.d.ts +14 -0
- package/lib/typescript/src/Charts/types.d.ts.map +1 -0
- package/lib/typescript/src/dateUtils.d.ts +37 -0
- package/lib/typescript/src/dateUtils.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +5 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/textUtils.d.ts +3 -0
- package/lib/typescript/src/textUtils.d.ts.map +1 -0
- package/package.json +226 -0
- package/src/Charts/BottomAxis/AxisLine.tsx +40 -0
- package/src/Charts/BottomAxis/BottomAxis.tsx +41 -0
- package/src/Charts/BottomAxis/Tick.tsx +54 -0
- package/src/Charts/BottomAxis/index.tsx +3 -0
- package/src/Charts/Cursor.tsx +51 -0
- package/src/Charts/Linechart/index.tsx +79 -0
- package/src/Charts/ZoomableLinechart/ScalablePath.tsx +49 -0
- package/src/Charts/ZoomableLinechart/index.tsx +47 -0
- package/src/Charts/gesture.ts +254 -0
- package/src/Charts/graphUtils.ts +198 -0
- package/src/Charts/index.tsx +32 -0
- package/src/Charts/maths.ts +245 -0
- package/src/Charts/types.ts +16 -0
- package/src/dateUtils.ts +163 -0
- package/src/index.tsx +4 -0
- 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,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 };
|