@obitrain/charts 0.10.0 → 0.10.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/README.md +79 -0
- package/lib/commonjs/Charts/BottomAxis/AxisLine.js +5 -5
- package/lib/commonjs/Charts/BottomAxis/AxisLine.js.map +1 -1
- package/lib/commonjs/Charts/BottomAxis/BottomAxis.js +3 -3
- package/lib/commonjs/Charts/BottomAxis/BottomAxis.js.map +1 -1
- package/lib/commonjs/Charts/BottomAxis/Tick.js +2 -2
- package/lib/commonjs/Charts/BottomAxis/Tick.js.map +1 -1
- package/lib/commonjs/Charts/BottomAxis/index.js +3 -3
- package/lib/commonjs/Charts/Cursor.js +5 -6
- package/lib/commonjs/Charts/Cursor.js.map +1 -1
- package/lib/commonjs/Charts/Linechart/index.js +2 -0
- package/lib/commonjs/Charts/Linechart/index.js.map +1 -1
- package/lib/commonjs/Charts/ZoomableLinechart/ScalablePath.js +4 -11
- package/lib/commonjs/Charts/ZoomableLinechart/ScalablePath.js.map +1 -1
- package/lib/commonjs/Charts/ZoomableLinechart/index.js +1 -1
- package/lib/commonjs/Charts/gesture.js +28 -34
- package/lib/commonjs/Charts/gesture.js.map +1 -1
- package/lib/commonjs/Charts/graphUtils.js +25 -22
- package/lib/commonjs/Charts/graphUtils.js.map +1 -1
- package/lib/commonjs/Charts/index.js +13 -13
- package/lib/commonjs/Charts/index.js.map +1 -1
- package/lib/commonjs/Charts/maths.js.map +1 -1
- package/lib/commonjs/dateUtils.js +11 -15
- package/lib/commonjs/dateUtils.js.map +1 -1
- package/lib/commonjs/index.js +6 -6
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/Charts/BottomAxis/AxisLine.js +5 -5
- package/lib/module/Charts/BottomAxis/AxisLine.js.map +1 -1
- package/lib/module/Charts/BottomAxis/BottomAxis.js +3 -3
- package/lib/module/Charts/BottomAxis/BottomAxis.js.map +1 -1
- package/lib/module/Charts/BottomAxis/Tick.js +2 -2
- package/lib/module/Charts/BottomAxis/Tick.js.map +1 -1
- package/lib/module/Charts/BottomAxis/index.js +3 -3
- package/lib/module/Charts/BottomAxis/index.js.map +1 -1
- package/lib/module/Charts/Cursor.js +5 -6
- package/lib/module/Charts/Cursor.js.map +1 -1
- package/lib/module/Charts/Linechart/index.js +2 -0
- package/lib/module/Charts/Linechart/index.js.map +1 -1
- package/lib/module/Charts/ZoomableLinechart/ScalablePath.js +4 -11
- package/lib/module/Charts/ZoomableLinechart/ScalablePath.js.map +1 -1
- package/lib/module/Charts/ZoomableLinechart/index.js +1 -1
- package/lib/module/Charts/ZoomableLinechart/index.js.map +1 -1
- package/lib/module/Charts/gesture.js +29 -35
- package/lib/module/Charts/gesture.js.map +1 -1
- package/lib/module/Charts/graphUtils.js +26 -22
- package/lib/module/Charts/graphUtils.js.map +1 -1
- package/lib/module/Charts/index.js +7 -7
- package/lib/module/Charts/index.js.map +1 -1
- package/lib/module/Charts/maths.js.map +1 -1
- package/lib/module/dateUtils.js +10 -14
- package/lib/module/dateUtils.js.map +1 -1
- package/lib/module/index.js +3 -3
- package/lib/module/index.js.map +1 -1
- package/lib/module/package.json +1 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/src/Charts/BottomAxis/AxisLine.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/Charts/BottomAxis/BottomAxis.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/Charts/BottomAxis/Tick.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/Charts/BottomAxis/index.d.ts.map +1 -0
- package/lib/typescript/{src → commonjs/src}/Charts/Cursor.d.ts +1 -1
- package/lib/typescript/commonjs/src/Charts/Cursor.d.ts.map +1 -0
- package/lib/typescript/{src → commonjs/src}/Charts/Linechart/index.d.ts +10 -4
- package/lib/typescript/commonjs/src/Charts/Linechart/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/Charts/ZoomableLinechart/ScalablePath.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/Charts/ZoomableLinechart/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/Charts/gesture.d.ts.map +1 -0
- package/lib/typescript/{src → commonjs/src}/Charts/graphUtils.d.ts +5 -3
- package/lib/typescript/commonjs/src/Charts/graphUtils.d.ts.map +1 -0
- package/lib/typescript/{src → commonjs/src}/Charts/index.d.ts +4 -3
- package/lib/typescript/commonjs/src/Charts/index.d.ts.map +1 -0
- package/lib/typescript/{src → commonjs/src}/Charts/maths.d.ts +1 -2
- package/lib/typescript/commonjs/src/Charts/maths.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/Charts/types.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/dateUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/textUtils.d.ts.map +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/src/Charts/BottomAxis/AxisLine.d.ts +15 -0
- package/lib/typescript/module/src/Charts/BottomAxis/AxisLine.d.ts.map +1 -0
- package/lib/typescript/module/src/Charts/BottomAxis/BottomAxis.d.ts +17 -0
- package/lib/typescript/module/src/Charts/BottomAxis/BottomAxis.d.ts.map +1 -0
- package/lib/typescript/module/src/Charts/BottomAxis/Tick.d.ts +14 -0
- package/lib/typescript/module/src/Charts/BottomAxis/Tick.d.ts.map +1 -0
- package/lib/typescript/module/src/Charts/BottomAxis/index.d.ts +4 -0
- package/lib/typescript/module/src/Charts/BottomAxis/index.d.ts.map +1 -0
- package/lib/typescript/module/src/Charts/Cursor.d.ts +14 -0
- package/lib/typescript/module/src/Charts/Cursor.d.ts.map +1 -0
- package/lib/typescript/module/src/Charts/Linechart/index.d.ts +31 -0
- package/lib/typescript/module/src/Charts/Linechart/index.d.ts.map +1 -0
- package/lib/typescript/module/src/Charts/ZoomableLinechart/ScalablePath.d.ts +14 -0
- package/lib/typescript/module/src/Charts/ZoomableLinechart/ScalablePath.d.ts.map +1 -0
- package/lib/typescript/module/src/Charts/ZoomableLinechart/index.d.ts +23 -0
- package/lib/typescript/module/src/Charts/ZoomableLinechart/index.d.ts.map +1 -0
- package/lib/typescript/module/src/Charts/gesture.d.ts +54 -0
- package/lib/typescript/module/src/Charts/gesture.d.ts.map +1 -0
- package/lib/typescript/module/src/Charts/graphUtils.d.ts +45 -0
- package/lib/typescript/module/src/Charts/graphUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/Charts/index.d.ts +15 -0
- package/lib/typescript/module/src/Charts/index.d.ts.map +1 -0
- package/lib/typescript/module/src/Charts/maths.d.ts +18 -0
- package/lib/typescript/module/src/Charts/maths.d.ts.map +1 -0
- package/lib/typescript/module/src/Charts/types.d.ts +14 -0
- package/lib/typescript/module/src/Charts/types.d.ts.map +1 -0
- package/lib/typescript/module/src/dateUtils.d.ts +37 -0
- package/lib/typescript/module/src/dateUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/index.d.ts +5 -0
- package/lib/typescript/module/src/index.d.ts.map +1 -0
- package/lib/typescript/module/src/textUtils.d.ts +3 -0
- package/lib/typescript/module/src/textUtils.d.ts.map +1 -0
- package/package.json +53 -41
- package/src/Charts/BottomAxis/AxisLine.tsx +4 -4
- package/src/Charts/BottomAxis/BottomAxis.tsx +1 -1
- package/src/Charts/BottomAxis/Tick.tsx +10 -13
- package/src/Charts/Cursor.tsx +15 -16
- package/src/Charts/Linechart/index.tsx +8 -4
- package/src/Charts/ZoomableLinechart/ScalablePath.tsx +9 -17
- package/src/Charts/gesture.ts +40 -39
- package/src/Charts/graphUtils.ts +32 -27
- package/src/Charts/index.tsx +22 -3
- package/src/Charts/maths.ts +5 -3
- package/src/dateUtils.ts +9 -16
- package/lib/typescript/src/Charts/BottomAxis/AxisLine.d.ts.map +0 -1
- package/lib/typescript/src/Charts/BottomAxis/BottomAxis.d.ts.map +0 -1
- package/lib/typescript/src/Charts/BottomAxis/Tick.d.ts.map +0 -1
- package/lib/typescript/src/Charts/BottomAxis/index.d.ts.map +0 -1
- package/lib/typescript/src/Charts/Cursor.d.ts.map +0 -1
- package/lib/typescript/src/Charts/Linechart/index.d.ts.map +0 -1
- package/lib/typescript/src/Charts/ZoomableLinechart/ScalablePath.d.ts.map +0 -1
- package/lib/typescript/src/Charts/ZoomableLinechart/index.d.ts.map +0 -1
- package/lib/typescript/src/Charts/gesture.d.ts.map +0 -1
- package/lib/typescript/src/Charts/graphUtils.d.ts.map +0 -1
- package/lib/typescript/src/Charts/index.d.ts.map +0 -1
- package/lib/typescript/src/Charts/maths.d.ts.map +0 -1
- package/lib/typescript/src/Charts/types.d.ts.map +0 -1
- package/lib/typescript/src/dateUtils.d.ts.map +0 -1
- package/lib/typescript/src/index.d.ts.map +0 -1
- package/lib/typescript/src/textUtils.d.ts.map +0 -1
- /package/lib/typescript/{src → commonjs/src}/Charts/BottomAxis/AxisLine.d.ts +0 -0
- /package/lib/typescript/{src → commonjs/src}/Charts/BottomAxis/BottomAxis.d.ts +0 -0
- /package/lib/typescript/{src → commonjs/src}/Charts/BottomAxis/Tick.d.ts +0 -0
- /package/lib/typescript/{src → commonjs/src}/Charts/BottomAxis/index.d.ts +0 -0
- /package/lib/typescript/{src → commonjs/src}/Charts/ZoomableLinechart/ScalablePath.d.ts +0 -0
- /package/lib/typescript/{src → commonjs/src}/Charts/ZoomableLinechart/index.d.ts +0 -0
- /package/lib/typescript/{src → commonjs/src}/Charts/gesture.d.ts +0 -0
- /package/lib/typescript/{src → commonjs/src}/Charts/types.d.ts +0 -0
- /package/lib/typescript/{src → commonjs/src}/dateUtils.d.ts +0 -0
- /package/lib/typescript/{src → commonjs/src}/index.d.ts +0 -0
- /package/lib/typescript/{src → commonjs/src}/textUtils.d.ts +0 -0
package/package.json
CHANGED
|
@@ -1,12 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@obitrain/charts",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.2",
|
|
4
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",
|
|
5
|
+
"main": "lib/commonjs/index.js",
|
|
6
|
+
"module": "lib/module/index.js",
|
|
7
|
+
"types": "lib/typescript/commonjs/src/index.d.ts",
|
|
8
8
|
"react-native": "src/index",
|
|
9
9
|
"source": "src/index",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"source": "./src/index.tsx",
|
|
13
|
+
"import": {
|
|
14
|
+
"types": "./lib/typescript/module/src/index.d.ts",
|
|
15
|
+
"default": "./lib/module/index.js"
|
|
16
|
+
},
|
|
17
|
+
"require": {
|
|
18
|
+
"types": "./lib/typescript/commonjs/src/index.d.ts",
|
|
19
|
+
"default": "./lib/commonjs/index.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"./package.json": "./package.json"
|
|
23
|
+
},
|
|
10
24
|
"files": [
|
|
11
25
|
"src",
|
|
12
26
|
"lib",
|
|
@@ -25,6 +39,7 @@
|
|
|
25
39
|
"!**/__mocks__",
|
|
26
40
|
"!**/.*"
|
|
27
41
|
],
|
|
42
|
+
"sideEffects": false,
|
|
28
43
|
"scripts": {
|
|
29
44
|
"example": "yarn workspace obi-chart-example",
|
|
30
45
|
"test": "jest",
|
|
@@ -32,9 +47,8 @@
|
|
|
32
47
|
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
33
48
|
"clean": "del-cli lib",
|
|
34
49
|
"prepare": "bob build",
|
|
35
|
-
"release": "./bin/release.sh",
|
|
36
50
|
"gifs": "./bin/capture-gifs.sh",
|
|
37
|
-
"check-deps": "
|
|
51
|
+
"check-deps": "rnx-align-deps --diff-mode allow-subset package.json"
|
|
38
52
|
},
|
|
39
53
|
"keywords": [
|
|
40
54
|
"react-native",
|
|
@@ -55,6 +69,10 @@
|
|
|
55
69
|
"access": "public",
|
|
56
70
|
"registry": "https://registry.npmjs.org/"
|
|
57
71
|
},
|
|
72
|
+
"dependencies": {
|
|
73
|
+
"@types/d3-scale": "^4.0.5",
|
|
74
|
+
"@types/d3-shape": "^3.1.3"
|
|
75
|
+
},
|
|
58
76
|
"devDependencies": {
|
|
59
77
|
"@commitlint/config-conventional": "^17.0.2",
|
|
60
78
|
"@evilmartians/lefthook": "^1.5.0",
|
|
@@ -65,11 +83,8 @@
|
|
|
65
83
|
"@react-native/eslint-config": "^0.86.0",
|
|
66
84
|
"@react-native/jest-preset": "^0.86.0",
|
|
67
85
|
"@react-native/metro-config": "^0.86.0",
|
|
68
|
-
"@release-it/conventional-changelog": "^5.0.0",
|
|
69
86
|
"@rnx-kit/align-deps": "^4.0.6",
|
|
70
87
|
"@shopify/react-native-skia": "2.6.2",
|
|
71
|
-
"@types/d3-scale": "^4.0.5",
|
|
72
|
-
"@types/d3-shape": "^3.1.3",
|
|
73
88
|
"@types/jest": "^29.2.1",
|
|
74
89
|
"@types/react": "^19.2.0",
|
|
75
90
|
"commitlint": "^17.0.2",
|
|
@@ -91,23 +106,17 @@
|
|
|
91
106
|
"react-native-reanimated": "~4.5.1",
|
|
92
107
|
"react-native-worklets": "^0.10.1",
|
|
93
108
|
"react-test-renderer": "19.2.3",
|
|
94
|
-
"release-it": "^15.0.0",
|
|
95
109
|
"typescript": "^5.0.2"
|
|
96
110
|
},
|
|
97
111
|
"peerDependencies": {
|
|
98
112
|
"@shopify/react-native-skia": ">=2.0.0 <3.0.0",
|
|
99
113
|
"d3-scale": ">=4.0.2 <5.0.0",
|
|
100
114
|
"d3-shape": ">=3.2.0 <4.0.0",
|
|
101
|
-
"react": "
|
|
102
|
-
"react-native": "^0.
|
|
103
|
-
"react-native-gesture-handler": "^
|
|
104
|
-
"react-native-reanimated": "^
|
|
105
|
-
"react-native-worklets": ">=0.
|
|
106
|
-
},
|
|
107
|
-
"peerDependenciesMeta": {
|
|
108
|
-
"react-native-worklets": {
|
|
109
|
-
"optional": true
|
|
110
|
-
}
|
|
115
|
+
"react": "^16.9.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
|
|
116
|
+
"react-native": "^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",
|
|
117
|
+
"react-native-gesture-handler": "^2.26.0 || ^2.28.0 || ^2.29.1 || ^2.30.0 || ^2.31.1 || ~2.32.0 || ^3.1.0",
|
|
118
|
+
"react-native-reanimated": "^4.0.0 || ~4.5.1",
|
|
119
|
+
"react-native-worklets": ">=0.5.0"
|
|
111
120
|
},
|
|
112
121
|
"workspaces": [
|
|
113
122
|
"example"
|
|
@@ -122,6 +131,17 @@
|
|
|
122
131
|
},
|
|
123
132
|
"jest": {
|
|
124
133
|
"preset": "@react-native/jest-preset",
|
|
134
|
+
"moduleNameMapper": {
|
|
135
|
+
"^react-native-worklets$": "react-native-worklets/src/mock"
|
|
136
|
+
},
|
|
137
|
+
"setupFiles": [
|
|
138
|
+
"<rootDir>/jest.setup.js",
|
|
139
|
+
"@shopify/react-native-skia/jestSetup.js",
|
|
140
|
+
"react-native-gesture-handler/jestSetup.js"
|
|
141
|
+
],
|
|
142
|
+
"transformIgnorePatterns": [
|
|
143
|
+
"node_modules/(?!((jest-)?react-native|@react-native(-community)?|@shopify/react-native-skia|react-native-reanimated|react-native-worklets|react-native-gesture-handler|d3-.*|internmap)/)"
|
|
144
|
+
],
|
|
125
145
|
"modulePathIgnorePatterns": [
|
|
126
146
|
"<rootDir>/example/node_modules",
|
|
127
147
|
"<rootDir>/lib/"
|
|
@@ -132,24 +152,6 @@
|
|
|
132
152
|
"@commitlint/config-conventional"
|
|
133
153
|
]
|
|
134
154
|
},
|
|
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
155
|
"eslintConfig": {
|
|
154
156
|
"root": true,
|
|
155
157
|
"extends": [
|
|
@@ -185,8 +187,18 @@
|
|
|
185
187
|
"source": "src",
|
|
186
188
|
"output": "lib",
|
|
187
189
|
"targets": [
|
|
188
|
-
|
|
189
|
-
|
|
190
|
+
[
|
|
191
|
+
"commonjs",
|
|
192
|
+
{
|
|
193
|
+
"esm": true
|
|
194
|
+
}
|
|
195
|
+
],
|
|
196
|
+
[
|
|
197
|
+
"module",
|
|
198
|
+
{
|
|
199
|
+
"esm": true
|
|
200
|
+
}
|
|
201
|
+
],
|
|
190
202
|
[
|
|
191
203
|
"typescript",
|
|
192
204
|
{
|
|
@@ -207,7 +219,7 @@
|
|
|
207
219
|
"react-native@0.86"
|
|
208
220
|
],
|
|
209
221
|
"production": [
|
|
210
|
-
"react-native
|
|
222
|
+
"react-native@>=0.79"
|
|
211
223
|
]
|
|
212
224
|
},
|
|
213
225
|
"capabilities": [
|
|
@@ -27,12 +27,12 @@ const AxisLine: FC<AxisLineProps> = function (props) {
|
|
|
27
27
|
const p1 = useDerivedValue(() => {
|
|
28
28
|
const p1X = getPositionWl(0, focalX.value, scale.value, offsetX.value);
|
|
29
29
|
return vec(p1X, offsetY);
|
|
30
|
-
}
|
|
30
|
+
});
|
|
31
31
|
|
|
32
32
|
const p2 = useDerivedValue(() => {
|
|
33
|
-
const
|
|
34
|
-
return vec(
|
|
35
|
-
}
|
|
33
|
+
const p2X = getPositionWl(width, focalX.value, scale.value, offsetX.value);
|
|
34
|
+
return vec(p2X, offsetY);
|
|
35
|
+
});
|
|
36
36
|
|
|
37
37
|
return <Line {...{ p1, p2, color, strokeWidth }} />;
|
|
38
38
|
};
|
|
@@ -21,7 +21,7 @@ export type BottomAxisProps = {
|
|
|
21
21
|
const BottomAxis: FC<BottomAxisProps> = function (props) {
|
|
22
22
|
const { labels, scale, focalX, offsetX, style, width, font } = props;
|
|
23
23
|
const offsetY = props.offsetY ?? 0;
|
|
24
|
-
const tickInterval = width / (labels.length - 1);
|
|
24
|
+
const tickInterval = labels.length > 1 ? width / (labels.length - 1) : 0;
|
|
25
25
|
|
|
26
26
|
return (
|
|
27
27
|
<Canvas style={style}>
|
|
@@ -22,19 +22,16 @@ export type TickProps = {
|
|
|
22
22
|
export const Tick: React.FC<TickProps> = (props) => {
|
|
23
23
|
const { label, scale, focalX, offsetX, initPosition, font } = props;
|
|
24
24
|
const offsetY = props.offsetY ?? 0;
|
|
25
|
-
const transform = useDerivedValue(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
],
|
|
36
|
-
[initPosition, offsetX]
|
|
37
|
-
);
|
|
25
|
+
const transform = useDerivedValue(() => [
|
|
26
|
+
{
|
|
27
|
+
translateX: getPositionWl(
|
|
28
|
+
initPosition,
|
|
29
|
+
focalX.value,
|
|
30
|
+
scale.value,
|
|
31
|
+
offsetX.value
|
|
32
|
+
),
|
|
33
|
+
},
|
|
34
|
+
]);
|
|
38
35
|
const width = font
|
|
39
36
|
.getGlyphWidths(font.getGlyphIDs(label))
|
|
40
37
|
.reduce((a, b) => a + b, 0);
|
package/src/Charts/Cursor.tsx
CHANGED
|
@@ -10,7 +10,7 @@ export type CursorProps = {
|
|
|
10
10
|
positionX: SharedValue<number>;
|
|
11
11
|
size?: number;
|
|
12
12
|
color?: string;
|
|
13
|
-
currentValue?: SharedValue<number> | SharedValue<undefined>;
|
|
13
|
+
currentValue?: SharedValue<number> | SharedValue<number | undefined>;
|
|
14
14
|
translateY?: SharedValue<number | undefined>;
|
|
15
15
|
};
|
|
16
16
|
|
|
@@ -23,23 +23,22 @@ const Cursor: FC<CursorProps> = function ({
|
|
|
23
23
|
size = CURSOR_SIZE,
|
|
24
24
|
}) {
|
|
25
25
|
if (currentValue !== undefined && translateY !== undefined) {
|
|
26
|
-
console.warn('
|
|
26
|
+
console.warn('currentValue has no effect when translateY is set');
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
});
|
|
29
|
+
const derivedTranslateY = useDerivedValue(() => {
|
|
30
|
+
const _commands = commands?.value;
|
|
31
|
+
if (_commands === undefined) {
|
|
32
|
+
return 0;
|
|
33
|
+
}
|
|
34
|
+
const _value = getYForX(_commands, positionX.value) ?? 0;
|
|
35
|
+
if (translateY === undefined && currentValue !== undefined) {
|
|
36
|
+
currentValue.value = _value;
|
|
37
|
+
}
|
|
38
|
+
return _value;
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const _translateY = translateY ?? derivedTranslateY;
|
|
43
42
|
|
|
44
43
|
const transform = useDerivedValue(() => [
|
|
45
44
|
{ translateX: positionX.value },
|
|
@@ -10,19 +10,23 @@ export type LinePath = {
|
|
|
10
10
|
id?: string;
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
path?: SkPath | SharedValue<SkPath>;
|
|
15
|
-
paths?: LinePath[];
|
|
13
|
+
type LineChartBaseProps = {
|
|
16
14
|
height: number;
|
|
17
15
|
width: number;
|
|
18
16
|
style?: StyleProp<ViewStyle>;
|
|
19
|
-
color?: string;
|
|
20
17
|
offsetY?: number;
|
|
21
18
|
offsetX?: number;
|
|
22
19
|
background?: React.ReactNode;
|
|
23
20
|
children?: React.ReactNode;
|
|
24
21
|
};
|
|
25
22
|
|
|
23
|
+
// Require at least one of `path` / `paths` at compile time
|
|
24
|
+
export type LineChartProps = LineChartBaseProps &
|
|
25
|
+
(
|
|
26
|
+
| { path: SkPath | SharedValue<SkPath>; paths?: LinePath[]; color?: string }
|
|
27
|
+
| { paths: LinePath[]; path?: SkPath | SharedValue<SkPath>; color?: string }
|
|
28
|
+
);
|
|
29
|
+
|
|
26
30
|
const LineChart: FC<LineChartProps> = function (props) {
|
|
27
31
|
const {
|
|
28
32
|
width,
|
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Path,
|
|
3
|
-
Skia,
|
|
4
|
-
type PathCommand,
|
|
5
|
-
type SkPath,
|
|
6
|
-
} from '@shopify/react-native-skia';
|
|
1
|
+
import { Path, Skia, type SkPath } from '@shopify/react-native-skia';
|
|
7
2
|
import { type FC } from 'react';
|
|
8
3
|
import { useDerivedValue, type SharedValue } from 'react-native-reanimated';
|
|
9
|
-
import { scaleCommands } from '../graphUtils';
|
|
10
4
|
|
|
11
5
|
export type ScalablePathProps = {
|
|
12
6
|
path: SharedValue<SkPath>;
|
|
@@ -21,17 +15,15 @@ const ScalablePath: FC<ScalablePathProps> = function (props) {
|
|
|
21
15
|
const { path, scale, focalX, offsetX, pathProps, color = 'red' } = props;
|
|
22
16
|
|
|
23
17
|
const animatedPath = useDerivedValue(() => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const _path = Skia.Path.MakeFromCmds(_cmds);
|
|
32
|
-
if (!_path) throw new Error('Path is null');
|
|
18
|
+
// Affine equivalent of getPositionWl: x' = scale * x + focalX * (1 - scale) + offsetX
|
|
19
|
+
const _path = path.value.copy();
|
|
20
|
+
_path.transform(
|
|
21
|
+
Skia.Matrix()
|
|
22
|
+
.translate(focalX.value * (1 - scale.value) + offsetX.value, 0)
|
|
23
|
+
.scale(scale.value, 1)
|
|
24
|
+
);
|
|
33
25
|
return _path;
|
|
34
|
-
}
|
|
26
|
+
});
|
|
35
27
|
|
|
36
28
|
return (
|
|
37
29
|
<Path
|
package/src/Charts/gesture.ts
CHANGED
|
@@ -2,13 +2,12 @@ import { clamp } from '@shopify/react-native-skia';
|
|
|
2
2
|
import { useCallback } from 'react';
|
|
3
3
|
import { Gesture, type PanGesture, type PinchGesture } from 'react-native-gesture-handler';
|
|
4
4
|
import {
|
|
5
|
-
runOnJS,
|
|
6
5
|
useAnimatedReaction,
|
|
7
|
-
useDerivedValue,
|
|
8
6
|
useSharedValue,
|
|
9
7
|
withTiming,
|
|
10
8
|
type SharedValue,
|
|
11
9
|
} from 'react-native-reanimated';
|
|
10
|
+
import { scheduleOnRN } from 'react-native-worklets';
|
|
12
11
|
import type { DataPoint } from './types';
|
|
13
12
|
|
|
14
13
|
/**
|
|
@@ -75,11 +74,6 @@ export const useScalableGesture = (props: AxisGestureProps): ScalableGesture =>
|
|
|
75
74
|
startScale,
|
|
76
75
|
]);
|
|
77
76
|
|
|
78
|
-
const animateFocalPoint = (newFocalX: number) => {
|
|
79
|
-
'worklet';
|
|
80
|
-
focalX.value = withTiming(newFocalX, { duration: 300 }); // Smooth transition with duration
|
|
81
|
-
};
|
|
82
|
-
|
|
83
77
|
const panGesture = Gesture.Pan()
|
|
84
78
|
.onUpdate((event) => {
|
|
85
79
|
const newOffsetX = lastOffsetX.value + event.translationX;
|
|
@@ -105,15 +99,12 @@ export const useScalableGesture = (props: AxisGestureProps): ScalableGesture =>
|
|
|
105
99
|
let newOffset;
|
|
106
100
|
|
|
107
101
|
if (leftBound > startOffset) {
|
|
108
|
-
// console.log(`Left Boundary reached`);
|
|
109
102
|
newOffset = offsetX.value - leftBound + startOffset;
|
|
110
|
-
} else if (rightBound < width) {
|
|
111
|
-
// console.log(`Right Boundary reached`);
|
|
103
|
+
} else if (rightBound < width + startOffset) {
|
|
112
104
|
newOffset = offsetX.value + width - rightBound + startOffset;
|
|
113
105
|
} else {
|
|
114
106
|
newOffset = offsetX.value;
|
|
115
107
|
}
|
|
116
|
-
if (newOffset === undefined) throw new Error('newOffset is undefined');
|
|
117
108
|
|
|
118
109
|
offsetX.value = withTiming(newOffset, { duration: 300 });
|
|
119
110
|
lastOffsetX.value = newOffset;
|
|
@@ -121,13 +112,15 @@ export const useScalableGesture = (props: AxisGestureProps): ScalableGesture =>
|
|
|
121
112
|
|
|
122
113
|
const pinchGesture = Gesture.Pinch()
|
|
123
114
|
.onUpdate((event) => {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
115
|
+
// Rebase offsetX so moving the focal point doesn't shift the content
|
|
116
|
+
offsetX.value += (focalX.value - event.focalX) * (1 - scale.value);
|
|
117
|
+
focalX.value = event.focalX;
|
|
118
|
+
scale.value = clamp(lastScale.value * event.scale, 1, Infinity);
|
|
127
119
|
})
|
|
128
120
|
.onEnd(() => {
|
|
129
121
|
lastScale.value = scale.value;
|
|
130
122
|
lastFocalX.value = focalX.value;
|
|
123
|
+
lastOffsetX.value = offsetX.value;
|
|
131
124
|
});
|
|
132
125
|
|
|
133
126
|
return {
|
|
@@ -165,12 +158,11 @@ export const useUpdateAxis = function (props: UpdateAxisProps) {
|
|
|
165
158
|
currentIndex.value !== i
|
|
166
159
|
) {
|
|
167
160
|
currentIndex.value = i;
|
|
168
|
-
if (onScaleChange !== undefined)
|
|
161
|
+
if (onScaleChange !== undefined) scheduleOnRN(onScaleChange, i);
|
|
169
162
|
break;
|
|
170
163
|
}
|
|
171
164
|
}
|
|
172
|
-
}
|
|
173
|
-
[]
|
|
165
|
+
}
|
|
174
166
|
);
|
|
175
167
|
|
|
176
168
|
return { currentIndex };
|
|
@@ -221,34 +213,43 @@ export const useCursorGesture = function (props: UseCursorGestureProps) {
|
|
|
221
213
|
isContinuous = true,
|
|
222
214
|
} = props;
|
|
223
215
|
|
|
224
|
-
|
|
225
|
-
|
|
216
|
+
if (!isContinuous && points === undefined)
|
|
217
|
+
console.warn('Points must be defined for non-continuous mode');
|
|
226
218
|
|
|
227
|
-
const
|
|
228
|
-
|
|
229
|
-
xPosition.value = clamp(event.x, 0, width);
|
|
230
|
-
yPosition.value = clamp(event.y, 0, height);
|
|
231
|
-
})
|
|
232
|
-
.onUpdate((event) => {
|
|
233
|
-
xPosition.value = clamp(event.x, 0, width);
|
|
234
|
-
yPosition.value = clamp(event.y, 0, height);
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
const tapGesture = Gesture.Tap().onBegin((event) => {
|
|
238
|
-
xPosition.value = clamp(event.x, 0, width);
|
|
239
|
-
yPosition.value = clamp(event.y, 0, height);
|
|
240
|
-
});
|
|
219
|
+
const xPosition = useSharedValue(0);
|
|
220
|
+
const yPosition = useSharedValue(height);
|
|
241
221
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
222
|
+
const setPosition = (x: number, y: number) => {
|
|
223
|
+
'worklet';
|
|
224
|
+
yPosition.value = clamp(y, 0, height);
|
|
225
|
+
if (isContinuous || points === undefined) {
|
|
226
|
+
xPosition.value = clamp(x, 0, width);
|
|
246
227
|
return;
|
|
247
228
|
}
|
|
248
|
-
const _closestDot = getClosestPoint(
|
|
229
|
+
const _closestDot = getClosestPoint(clamp(x, 0, width), points.value);
|
|
249
230
|
if (closestDataPoint !== undefined) closestDataPoint.value = _closestDot;
|
|
250
231
|
xPosition.value = _closestDot.x;
|
|
251
|
-
}
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
const panGesture = Gesture.Pan()
|
|
235
|
+
.onBegin((event) => setPosition(event.x, event.y))
|
|
236
|
+
.onUpdate((event) => setPosition(event.x, event.y));
|
|
237
|
+
|
|
238
|
+
const tapGesture = Gesture.Tap().onBegin((event) =>
|
|
239
|
+
setPosition(event.x, event.y)
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
// Re-snap the cursor when the data points change (e.g. switching graphs)
|
|
243
|
+
useAnimatedReaction(
|
|
244
|
+
() => points?.value,
|
|
245
|
+
(_points) => {
|
|
246
|
+
if (isContinuous || _points === undefined || _points.length === 0)
|
|
247
|
+
return;
|
|
248
|
+
const _closestDot = getClosestPoint(xPosition.value, _points);
|
|
249
|
+
if (closestDataPoint !== undefined) closestDataPoint.value = _closestDot;
|
|
250
|
+
xPosition.value = _closestDot.x;
|
|
251
|
+
}
|
|
252
|
+
);
|
|
252
253
|
|
|
253
254
|
return { panGesture, tapGesture, xPosition, yPosition };
|
|
254
255
|
};
|
package/src/Charts/graphUtils.ts
CHANGED
|
@@ -15,7 +15,7 @@ import { getPositionWl } from './gesture';
|
|
|
15
15
|
import { getYForX } from './maths';
|
|
16
16
|
import type { AnimatedDot, DataPoint } from './types';
|
|
17
17
|
|
|
18
|
-
export type
|
|
18
|
+
export type BuildGraphConfig = {
|
|
19
19
|
minX?: number;
|
|
20
20
|
maxX?: number;
|
|
21
21
|
minY?: number;
|
|
@@ -24,8 +24,11 @@ export type Config = {
|
|
|
24
24
|
curve?: shape.CurveFactory | shape.CurveFactoryLineOnly;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
+
/** @deprecated Use {@link BuildGraphConfig} instead */
|
|
28
|
+
export type Config = BuildGraphConfig;
|
|
29
|
+
|
|
27
30
|
export type GraphData = {
|
|
28
|
-
data: [number, number][];
|
|
31
|
+
data: [x: number, y: number][];
|
|
29
32
|
minY: number;
|
|
30
33
|
maxY: number;
|
|
31
34
|
path: string;
|
|
@@ -36,38 +39,40 @@ export type GraphData = {
|
|
|
36
39
|
};
|
|
37
40
|
|
|
38
41
|
export const buildGraph = function (
|
|
39
|
-
data: [number, number][],
|
|
42
|
+
data: [x: number, y: number][],
|
|
40
43
|
width: number,
|
|
41
44
|
height: number,
|
|
42
|
-
config?:
|
|
45
|
+
config?: BuildGraphConfig
|
|
43
46
|
): GraphData {
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
if (data.length === 0)
|
|
48
|
+
throw new Error('buildGraph requires at least one data point');
|
|
49
|
+
|
|
50
|
+
const minX = config?.minX ?? Math.min(...data.map((d) => d[0]));
|
|
51
|
+
const maxX = config?.maxX ?? Math.max(...data.map((d) => d[0]));
|
|
46
52
|
const scaleX = scaleLinear().domain([minX, maxX]).range([0, width]);
|
|
47
53
|
|
|
48
|
-
const minY = config?.minY ?? Math.min(...data.map((
|
|
49
|
-
const maxY = config?.maxY ?? Math.max(...data.map((
|
|
54
|
+
const minY = config?.minY ?? Math.min(...data.map((d) => d[1]));
|
|
55
|
+
const maxY = config?.maxY ?? Math.max(...data.map((d) => d[1]));
|
|
50
56
|
const scaleY = scaleLinear().domain([minY, maxY]).range([height, 0]);
|
|
51
57
|
|
|
52
|
-
const fmtValues = data.map((x) => [x[1], x[0]] as [number, number]);
|
|
53
|
-
|
|
54
58
|
const path = shape
|
|
55
|
-
.line()
|
|
56
|
-
.x(([
|
|
57
|
-
.y(([y]) => scaleY(y))
|
|
58
|
-
.curve(config?.curve ?? shape.curveBasis)(
|
|
59
|
+
.line<[number, number]>()
|
|
60
|
+
.x(([x]) => scaleX(x))
|
|
61
|
+
.y(([, y]) => scaleY(y))
|
|
62
|
+
.curve(config?.curve ?? shape.curveBasis)(data);
|
|
63
|
+
if (path === null) throw new Error('Failed to build the line path');
|
|
59
64
|
|
|
60
|
-
const dataPoints =
|
|
65
|
+
const dataPoints = data.map(([x, y]) => ({
|
|
61
66
|
x: scaleX(x),
|
|
62
67
|
y: scaleY(y),
|
|
63
68
|
value: y,
|
|
64
69
|
}));
|
|
65
70
|
|
|
66
71
|
const skiaPath = Skia.Path.MakeFromSVGString(path);
|
|
67
|
-
if (skiaPath == null) throw new Error('
|
|
72
|
+
if (skiaPath == null) throw new Error('Failed to parse the SVG path');
|
|
68
73
|
|
|
69
74
|
return {
|
|
70
|
-
data
|
|
75
|
+
data,
|
|
71
76
|
minY,
|
|
72
77
|
maxY,
|
|
73
78
|
path,
|
|
@@ -136,7 +141,6 @@ export const scaleCommands = function (
|
|
|
136
141
|
];
|
|
137
142
|
}
|
|
138
143
|
if (commandType === PathVerb.Close) return command;
|
|
139
|
-
if (commandType === PathVerb.Move) return command;
|
|
140
144
|
throw new Error(`Unsupported command type ${commandType}`);
|
|
141
145
|
});
|
|
142
146
|
};
|
|
@@ -173,25 +177,26 @@ export const useDotsTransition = function (props: UseDotAnimationProps) {
|
|
|
173
177
|
() => ({
|
|
174
178
|
_currentGraph: currentGraph.value,
|
|
175
179
|
_currentCommands: path.value.toCmds(),
|
|
180
|
+
// Track the animating x values so y stays glued to the curve
|
|
181
|
+
// even when the path is swapped instantly or tweens on another duration
|
|
182
|
+
_xs: dots.map((d) => d.x.value),
|
|
176
183
|
}),
|
|
177
184
|
({ _currentGraph, _currentCommands }) => {
|
|
178
185
|
const newDataPoints = dataPoints[_currentGraph];
|
|
179
186
|
if (newDataPoints === undefined)
|
|
180
187
|
throw new Error('Data points cannot be undefined');
|
|
181
|
-
dots.
|
|
188
|
+
dots.forEach((_dot, i) => {
|
|
182
189
|
const _newDot = newDataPoints[i];
|
|
183
190
|
if (!_newDot) {
|
|
184
191
|
_dot.opacity.value = opacityWl(0);
|
|
185
192
|
return;
|
|
186
|
-
} else {
|
|
187
|
-
_dot.x.value = translateWl(_newDot.x);
|
|
188
|
-
const newY = getYForX(_currentCommands, _dot.x.value);
|
|
189
|
-
if (newY !== undefined) {
|
|
190
|
-
_dot.y.value = newY;
|
|
191
|
-
}
|
|
192
|
-
// _dot.y.value = withTiming(newDots[i]!.y, { duration: 1000 });
|
|
193
|
-
_dot.opacity.value = opacityWl(1);
|
|
194
193
|
}
|
|
194
|
+
_dot.x.value = translateWl(_newDot.x);
|
|
195
|
+
const newY = getYForX(_currentCommands, _dot.x.value);
|
|
196
|
+
if (newY !== undefined) {
|
|
197
|
+
_dot.y.value = newY;
|
|
198
|
+
}
|
|
199
|
+
_dot.opacity.value = opacityWl(1);
|
|
195
200
|
});
|
|
196
201
|
}
|
|
197
202
|
);
|
package/src/Charts/index.tsx
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
export { AxisLine, BottomAxis, Tick } from './BottomAxis';
|
|
2
|
+
export type {
|
|
3
|
+
AxisLineProps,
|
|
4
|
+
BottomAxisProps,
|
|
5
|
+
TickProps,
|
|
6
|
+
} from './BottomAxis';
|
|
2
7
|
export { Cursor } from './Cursor';
|
|
3
8
|
export type { CursorProps } from './Cursor';
|
|
4
9
|
export { LineChart } from './Linechart';
|
|
5
10
|
export type { LineChartProps, LinePath } from './Linechart';
|
|
6
11
|
export { ScalablePath, ZoomableLineChart } from './ZoomableLinechart';
|
|
7
|
-
export type {
|
|
12
|
+
export type {
|
|
13
|
+
ScalablePathProps,
|
|
14
|
+
ZoomableLineChartProps,
|
|
15
|
+
} from './ZoomableLinechart';
|
|
8
16
|
export {
|
|
9
17
|
getClosestPoint,
|
|
10
18
|
getPositionWl,
|
|
@@ -12,7 +20,12 @@ export {
|
|
|
12
20
|
useScalableGesture,
|
|
13
21
|
useUpdateAxis,
|
|
14
22
|
} from './gesture';
|
|
15
|
-
export type {
|
|
23
|
+
export type {
|
|
24
|
+
AxisGestureProps,
|
|
25
|
+
ScalableGesture,
|
|
26
|
+
UpdateAxisProps,
|
|
27
|
+
UseCursorGestureProps,
|
|
28
|
+
} from './gesture';
|
|
16
29
|
export {
|
|
17
30
|
buildGraph,
|
|
18
31
|
defaultOpacityTransitionWl,
|
|
@@ -20,7 +33,13 @@ export {
|
|
|
20
33
|
scaleCommands,
|
|
21
34
|
useDotsTransition,
|
|
22
35
|
} from './graphUtils';
|
|
23
|
-
export type {
|
|
36
|
+
export type {
|
|
37
|
+
BuildGraphConfig,
|
|
38
|
+
// eslint-disable-next-line deprecation/deprecation
|
|
39
|
+
Config,
|
|
40
|
+
GraphData,
|
|
41
|
+
UseDotAnimationProps,
|
|
42
|
+
} from './graphUtils';
|
|
24
43
|
export {
|
|
25
44
|
commandsToBezier,
|
|
26
45
|
cubicBezierYForX,
|