gifted-charts-core 0.0.42 → 0.0.44
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/package.json +1 -1
- package/src/PieChart/index.d.ts +13 -0
- package/src/PieChart/index.js +173 -21
- package/src/PieChart/index.ts +243 -5
- package/src/PieChart/types.d.ts +4 -2
- package/src/PieChart/types.ts +4 -2
- package/src/utils/constants.d.ts +1 -0
- package/src/utils/constants.js +1 -1
- package/src/utils/constants.ts +4 -4
package/package.json
CHANGED
package/src/PieChart/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type pieDataItem, type PieChartPropsType } from './types';
|
|
2
2
|
import { type ColorValue } from 'react-native';
|
|
3
|
+
import { LabelsPosition } from '../utils/types';
|
|
3
4
|
interface IusePieChart {
|
|
4
5
|
radius: number;
|
|
5
6
|
extraRadiusForFocused: number;
|
|
@@ -29,6 +30,18 @@ interface IusePieChart {
|
|
|
29
30
|
isDataShifted: boolean;
|
|
30
31
|
paddingHorizontal: number;
|
|
31
32
|
paddingVertical: number;
|
|
33
|
+
isAnimated: boolean;
|
|
34
|
+
animationDuration: number;
|
|
35
|
+
initial: string;
|
|
36
|
+
dInitial: string[];
|
|
37
|
+
dFinal: string[];
|
|
38
|
+
isAnimating: boolean;
|
|
39
|
+
getStartCaps: (index: number, item: pieDataItem) => string;
|
|
40
|
+
getEndCaps: (index: number, item: pieDataItem) => string;
|
|
41
|
+
getTextCoordinates: (index: number, labelPos?: LabelsPosition) => {
|
|
42
|
+
x: number;
|
|
43
|
+
y: number;
|
|
44
|
+
};
|
|
32
45
|
}
|
|
33
46
|
interface IPieChartPropsType extends PieChartPropsType {
|
|
34
47
|
pro?: boolean;
|
package/src/PieChart/index.js
CHANGED
|
@@ -16,15 +16,16 @@ var __read = (this && this.__read) || function (o, n) {
|
|
|
16
16
|
};
|
|
17
17
|
import { useEffect, useState } from 'react';
|
|
18
18
|
import { getTextSizeForPieLabels } from '../utils';
|
|
19
|
+
import { defaultAnimationDuration } from '../utils/constants';
|
|
19
20
|
export var usePieChart = function (props) {
|
|
20
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
|
|
21
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
|
|
21
22
|
var radius = (_a = props.radius) !== null && _a !== void 0 ? _a : 120;
|
|
22
23
|
var extraRadiusForFocused = (_b = props.extraRadiusForFocused) !== null && _b !== void 0 ? _b : (((_c = props.focusOnPress) !== null && _c !== void 0 ? _c : props.sectionAutoFocus) ? radius / 10 : 0);
|
|
23
24
|
var pi = props.semiCircle ? Math.PI / 2 : Math.PI;
|
|
24
|
-
var
|
|
25
|
+
var _x = __read(useState(-1), 2), selectedIndex = _x[0], setSelectedIndex = _x[1]; // at the start, nothing is selected
|
|
25
26
|
// because we're going to use a useEffect, we need startAngle and total to be state variables
|
|
26
|
-
var
|
|
27
|
-
var
|
|
27
|
+
var _y = __read(useState((_d = props.initialAngle) !== null && _d !== void 0 ? _d : (props.semiCircle ? -pi : 0)), 2), startAngle = _y[0], setStartAngle = _y[1];
|
|
28
|
+
var _z = __read(useState(0), 2), total = _z[0], setTotal = _z[1];
|
|
28
29
|
useEffect(function () {
|
|
29
30
|
var _a;
|
|
30
31
|
// Update the total, this could be use to replace the forEach : const newTotal = props.data.reduce((acc, item) => acc + item.value, 0);
|
|
@@ -63,38 +64,179 @@ export var usePieChart = function (props) {
|
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
66
|
}, [selectedIndex]);
|
|
66
|
-
var pro = props.pro, data = props.data, donut = props.donut, isThreeD = props.isThreeD, semiCircle = props.semiCircle,
|
|
67
|
+
var pro = props.pro, data = props.data, donut = props.donut, isThreeD = props.isThreeD, semiCircle = props.semiCircle, _0 = props.inwardExtraLengthForFocused, inwardExtraLengthForFocused = _0 === void 0 ? 0 : _0, _1 = props.isAnimated, isAnimated = _1 === void 0 ? false : _1, edgesRadius = props.edgesRadius, _2 = props.endAngle, endAngle = _2 === void 0 ? (_e = props.endAngle) !== null && _e !== void 0 ? _e : startAngle + Math.PI * (semiCircle ? 1 : 2) : _2;
|
|
67
68
|
var canvasWidth = radius * 2;
|
|
68
69
|
var canvasHeight = isThreeD ? radius * 2.3 : radius * 2;
|
|
69
|
-
var strokeWidth = (
|
|
70
|
-
var innerRadius = (
|
|
71
|
-
var innerCircleColor = (
|
|
72
|
-
var innerCircleBorderWidth = (
|
|
73
|
-
var innerCircleBorderColor = (
|
|
74
|
-
var shiftInnerCenterX = (
|
|
75
|
-
var shiftInnerCenterY = (
|
|
76
|
-
var tiltAngle = (
|
|
70
|
+
var strokeWidth = (_f = props.strokeWidth) !== null && _f !== void 0 ? _f : 0;
|
|
71
|
+
var innerRadius = (_g = props.innerRadius) !== null && _g !== void 0 ? _g : radius / 2.5;
|
|
72
|
+
var innerCircleColor = (_j = (_h = props.innerCircleColor) !== null && _h !== void 0 ? _h : props.backgroundColor) !== null && _j !== void 0 ? _j : 'white';
|
|
73
|
+
var innerCircleBorderWidth = (_k = props.innerCircleBorderWidth) !== null && _k !== void 0 ? _k : (props.innerCircleBorderColor ? strokeWidth || 2 : 0);
|
|
74
|
+
var innerCircleBorderColor = (_l = props.innerCircleBorderColor) !== null && _l !== void 0 ? _l : 'lightgray';
|
|
75
|
+
var shiftInnerCenterX = (_m = props.shiftInnerCenterX) !== null && _m !== void 0 ? _m : 0;
|
|
76
|
+
var shiftInnerCenterY = (_o = props.shiftInnerCenterY) !== null && _o !== void 0 ? _o : 0;
|
|
77
|
+
var tiltAngle = (_p = props.tiltAngle) !== null && _p !== void 0 ? _p : '55deg';
|
|
77
78
|
var isDataShifted = false;
|
|
78
79
|
data.forEach(function (item) {
|
|
79
80
|
if (item.shiftX || item.shiftY) {
|
|
80
81
|
isDataShifted = true;
|
|
81
82
|
}
|
|
82
83
|
});
|
|
83
|
-
var textSize = getTextSizeForPieLabels((
|
|
84
|
-
var paddingHorizontal = ((
|
|
85
|
-
? ((
|
|
84
|
+
var textSize = getTextSizeForPieLabels((_q = props.textSize) !== null && _q !== void 0 ? _q : 0, radius);
|
|
85
|
+
var paddingHorizontal = ((_r = props.paddingHorizontal) !== null && _r !== void 0 ? _r : props.labelsPosition === 'onBorder')
|
|
86
|
+
? ((_s = props.textBackgroundRadius) !== null && _s !== void 0 ? _s : textSize) * 2 + 6
|
|
86
87
|
: 0;
|
|
87
|
-
var paddingVertical = ((
|
|
88
|
-
? ((
|
|
88
|
+
var paddingVertical = ((_t = props.paddingVertical) !== null && _t !== void 0 ? _t : props.labelsPosition === 'onBorder')
|
|
89
|
+
? ((_u = props.textBackgroundRadius) !== null && _u !== void 0 ? _u : textSize) * 2 + 6
|
|
89
90
|
: 0;
|
|
91
|
+
/********************************** PRO **********************/
|
|
92
|
+
var startAngleForPro = (_v = props.startAngle) !== null && _v !== void 0 ? _v : 0;
|
|
93
|
+
var animationDuration = (_w = props.animationDuration) !== null && _w !== void 0 ? _w : defaultAnimationDuration;
|
|
94
|
+
var _3 = __read(useState(isAnimated), 2), isAnimating = _3[0], setIsAnimating = _3[1];
|
|
95
|
+
useEffect(function () {
|
|
96
|
+
if (isAnimated) {
|
|
97
|
+
setIsAnimating(true);
|
|
98
|
+
setTimeout(function () { return setIsAnimating(false); }, animationDuration);
|
|
99
|
+
}
|
|
100
|
+
}, []);
|
|
101
|
+
var endAngleLocal = 0;
|
|
102
|
+
var addValues = function (index) {
|
|
103
|
+
if (index < 0)
|
|
104
|
+
return 0;
|
|
105
|
+
var sum = 0;
|
|
106
|
+
for (var i = 0; i <= index; i++)
|
|
107
|
+
sum += data[i].value;
|
|
108
|
+
return sum;
|
|
109
|
+
};
|
|
110
|
+
var labelsPosition = props.labelsPosition
|
|
111
|
+
? props.labelsPosition
|
|
112
|
+
: donut || props.centerLabelComponent
|
|
113
|
+
? 'outward'
|
|
114
|
+
: 'mid';
|
|
115
|
+
var getCoordinates = function (index, additionalValue, addInOnlyStart, addInOnlyEnd) {
|
|
116
|
+
var addedValue = addValues(index - 1) + (addInOnlyEnd ? 0 : additionalValue !== null && additionalValue !== void 0 ? additionalValue : 0);
|
|
117
|
+
var angle = (addedValue / total) * endAngleLocal + startAngleForPro;
|
|
118
|
+
var startInnerX = radius + Math.cos(angle) * innerRadius;
|
|
119
|
+
var startInnerY = radius - Math.sin(angle) * innerRadius;
|
|
120
|
+
var startOuterX = radius + Math.cos(angle) * radius;
|
|
121
|
+
var startOuterY = radius - Math.sin(angle) * radius;
|
|
122
|
+
var value = addValues(index - 1) +
|
|
123
|
+
data[index].value +
|
|
124
|
+
(addInOnlyStart ? 0 : additionalValue !== null && additionalValue !== void 0 ? additionalValue : 0);
|
|
125
|
+
angle = (value / total) * endAngleLocal + startAngleForPro;
|
|
126
|
+
var endOuterX = radius + Math.cos(angle) * radius;
|
|
127
|
+
var endOuterY = radius - Math.sin(angle) * radius;
|
|
128
|
+
var endInnerX = radius + Math.cos(angle) * innerRadius;
|
|
129
|
+
var endInnerY = radius - Math.sin(angle) * innerRadius;
|
|
130
|
+
return {
|
|
131
|
+
startInnerX: startInnerX,
|
|
132
|
+
startInnerY: startInnerY,
|
|
133
|
+
startOuterX: startOuterX,
|
|
134
|
+
startOuterY: startOuterY,
|
|
135
|
+
endOuterX: endOuterX,
|
|
136
|
+
endOuterY: endOuterY,
|
|
137
|
+
endInnerX: endInnerX,
|
|
138
|
+
endInnerY: endInnerY
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
var getTextCoordinates = function (index, labelPos) {
|
|
142
|
+
var value = addValues(index - 1) + data[index].value / 2;
|
|
143
|
+
var angle = (value / total) * endAngleLocal + startAngleForPro;
|
|
144
|
+
var labelPosition = labelPos || labelsPosition;
|
|
145
|
+
var x = radius +
|
|
146
|
+
Math.cos(angle) *
|
|
147
|
+
radius *
|
|
148
|
+
(labelPosition === 'inward'
|
|
149
|
+
? 0.25
|
|
150
|
+
: labelPosition === 'mid'
|
|
151
|
+
? 0.5
|
|
152
|
+
: labelPosition === 'outward'
|
|
153
|
+
? 0.75
|
|
154
|
+
: 1);
|
|
155
|
+
var y = radius -
|
|
156
|
+
Math.sin(angle) *
|
|
157
|
+
radius *
|
|
158
|
+
(labelPosition === 'inward'
|
|
159
|
+
? 0.25
|
|
160
|
+
: labelPosition === 'mid'
|
|
161
|
+
? 0.5
|
|
162
|
+
: labelPosition === 'outward'
|
|
163
|
+
? 0.75
|
|
164
|
+
: 1);
|
|
165
|
+
return { x: x, y: y };
|
|
166
|
+
};
|
|
167
|
+
var initial = '';
|
|
168
|
+
var getInitial = function (item) {
|
|
169
|
+
if (item.isStartEdgeCurved || item.startEdgeRadius) {
|
|
170
|
+
var _a = getCoordinates(0, (radius - innerRadius) / (radius / 20)), startInnerX = _a.startInnerX, startInnerY = _a.startInnerY, startOuterX = _a.startOuterX, startOuterY = _a.startOuterY;
|
|
171
|
+
return "M".concat(startInnerX, ",").concat(startInnerY, " L").concat(startOuterX, ",").concat(startOuterY, " ");
|
|
172
|
+
}
|
|
173
|
+
return "M".concat(radius + innerRadius, ",").concat(radius, " h").concat(radius - innerRadius, " ");
|
|
174
|
+
};
|
|
175
|
+
var getPath = function (index) {
|
|
176
|
+
var _a;
|
|
177
|
+
var _b = getCoordinates(index), endOuterX = _b.endOuterX, endOuterY = _b.endOuterY;
|
|
178
|
+
var isLargeArc = data[index].value / total > 0.5 ? 1 : 0;
|
|
179
|
+
var arc = "A".concat(radius + ((_a = props.strokeWidth) !== null && _a !== void 0 ? _a : 0) / 2, ",").concat(radius, " 0 ").concat(isLargeArc, " 0 ");
|
|
180
|
+
var path = "".concat(arc, " ").concat(endOuterX, ", ").concat(endOuterY, "\n L").concat(radius, ",").concat(radius, " ");
|
|
181
|
+
initial = "M".concat(radius, ",").concat(radius, " L").concat(endOuterX, ",").concat(endOuterY);
|
|
182
|
+
return path;
|
|
183
|
+
};
|
|
184
|
+
var getDonutPath = function (index, item) {
|
|
185
|
+
var _a;
|
|
186
|
+
var additionalForStart = item.isStartEdgeCurved || item.startEdgeRadius
|
|
187
|
+
? (radius - innerRadius) / (radius / 20)
|
|
188
|
+
: 0;
|
|
189
|
+
var additionalForEnd = item.isEndEdgeCurved || item.endEdgeRadius
|
|
190
|
+
? (radius - innerRadius) / (radius / -20)
|
|
191
|
+
: 0;
|
|
192
|
+
var cropAtEnd = !!(index === data.length - 1 &&
|
|
193
|
+
(item.isEndEdgeCurved || item.endEdgeRadius));
|
|
194
|
+
var _b = getCoordinates(index, cropAtEnd ? additionalForEnd : additionalForStart, !cropAtEnd, cropAtEnd), startInnerX = _b.startInnerX, startInnerY = _b.startInnerY, endOuterX = _b.endOuterX, endOuterY = _b.endOuterY, endInnerX = _b.endInnerX, endInnerY = _b.endInnerY;
|
|
195
|
+
var isLargeArc = data[index].value / total > 0.5 ? 1 : 0;
|
|
196
|
+
var innerArc = "A".concat(innerRadius, ",").concat(innerRadius, " 0 ").concat(isLargeArc, " 1 ");
|
|
197
|
+
var outerArc = "A".concat(radius + ((_a = props.strokeWidth) !== null && _a !== void 0 ? _a : 0) / 2, ",").concat(radius, " 0 ").concat(isLargeArc, " 0 ");
|
|
198
|
+
var path = "".concat(outerArc, " ").concat(endOuterX, ", ").concat(endOuterY, "\n L").concat(endInnerX, ",").concat(endInnerY, " M").concat(endInnerX, ",").concat(endInnerY, " ").concat(innerArc, " ").concat(startInnerX, ",").concat(startInnerY);
|
|
199
|
+
initial = "M".concat(endInnerX, ",").concat(endInnerY, " L").concat(endOuterX, ",").concat(endOuterY, " ");
|
|
200
|
+
return path;
|
|
201
|
+
};
|
|
202
|
+
var getStartCaps = function (index, item) {
|
|
203
|
+
var _a, _b;
|
|
204
|
+
var edgeRadius = (_b = (_a = item.startEdgeRadius) !== null && _a !== void 0 ? _a : edgesRadius) !== null && _b !== void 0 ? _b : 1;
|
|
205
|
+
var additional = (item.isStartEdgeCurved || item.startEdgeRadius
|
|
206
|
+
? (radius - innerRadius) / (radius / 20)
|
|
207
|
+
: 0) +
|
|
208
|
+
strokeWidth / 2;
|
|
209
|
+
var _c = getCoordinates(index, additional), startInnerX = _c.startInnerX, startInnerY = _c.startInnerY, startOuterX = _c.startOuterX, startOuterY = _c.startOuterY;
|
|
210
|
+
var path = "M".concat(startInnerX, ",").concat(startInnerY, " A").concat(edgeRadius, ",").concat(edgeRadius, " 0 0 0 ").concat(startOuterX, ",").concat(startOuterY);
|
|
211
|
+
return path;
|
|
212
|
+
};
|
|
213
|
+
var getEndCaps = function (index, item) {
|
|
214
|
+
var _a, _b;
|
|
215
|
+
var edgeRadius = (_b = (_a = item.endEdgeRadius) !== null && _a !== void 0 ? _a : edgesRadius) !== null && _b !== void 0 ? _b : 1;
|
|
216
|
+
var additional = (item.isEndEdgeCurved || item.endEdgeRadius
|
|
217
|
+
? (radius - innerRadius) / (radius / 20)
|
|
218
|
+
: 0) -
|
|
219
|
+
strokeWidth / 2;
|
|
220
|
+
var _c = getCoordinates(index, -additional), endInnerX = _c.endInnerX, endInnerY = _c.endInnerY, endOuterX = _c.endOuterX, endOuterY = _c.endOuterY;
|
|
221
|
+
var path = "M".concat(endInnerX, ",").concat(endInnerY, " A").concat(edgeRadius, ",").concat(edgeRadius, " 0 0 1 ").concat(endOuterX, ",").concat(endOuterY);
|
|
222
|
+
return path;
|
|
223
|
+
};
|
|
224
|
+
var dInitial = data.map(function (item, index) {
|
|
225
|
+
return "".concat(initial || getInitial(item), " ").concat(donut ? getDonutPath(index, item) : getPath(index));
|
|
226
|
+
});
|
|
227
|
+
endAngleLocal = endAngle;
|
|
228
|
+
initial = '';
|
|
229
|
+
var dFinal = data.map(function (item, index) {
|
|
230
|
+
return "".concat(initial || getInitial(item), " ").concat(donut ? getDonutPath(index, item) : getPath(index));
|
|
231
|
+
});
|
|
90
232
|
return {
|
|
91
233
|
radius: radius,
|
|
92
234
|
extraRadiusForFocused: extraRadiusForFocused,
|
|
93
235
|
pi: pi,
|
|
94
236
|
selectedIndex: selectedIndex,
|
|
95
237
|
setSelectedIndex: setSelectedIndex,
|
|
96
|
-
startAngle: pro ?
|
|
97
|
-
endAngle:
|
|
238
|
+
startAngle: pro ? startAngleForPro : startAngle,
|
|
239
|
+
endAngle: endAngle,
|
|
98
240
|
setStartAngle: setStartAngle,
|
|
99
241
|
total: total,
|
|
100
242
|
setTotal: setTotal,
|
|
@@ -115,6 +257,16 @@ export var usePieChart = function (props) {
|
|
|
115
257
|
tiltAngle: tiltAngle,
|
|
116
258
|
isDataShifted: isDataShifted,
|
|
117
259
|
paddingHorizontal: paddingHorizontal,
|
|
118
|
-
paddingVertical: paddingVertical
|
|
260
|
+
paddingVertical: paddingVertical,
|
|
261
|
+
isAnimated: isAnimated,
|
|
262
|
+
animationDuration: animationDuration / 1000,
|
|
263
|
+
// PRO
|
|
264
|
+
initial: initial,
|
|
265
|
+
dInitial: dInitial,
|
|
266
|
+
dFinal: dFinal,
|
|
267
|
+
isAnimating: isAnimating,
|
|
268
|
+
getStartCaps: getStartCaps,
|
|
269
|
+
getEndCaps: getEndCaps,
|
|
270
|
+
getTextCoordinates: getTextCoordinates
|
|
119
271
|
};
|
|
120
272
|
};
|
package/src/PieChart/index.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { useEffect, useState } from 'react'
|
|
|
2
2
|
import { type pieDataItem, type PieChartPropsType } from './types'
|
|
3
3
|
import { getTextSizeForPieLabels } from '../utils'
|
|
4
4
|
import { type ColorValue } from 'react-native'
|
|
5
|
+
import { defaultAnimationDuration } from '../utils/constants'
|
|
6
|
+
import { LabelsPosition } from '../utils/types'
|
|
5
7
|
|
|
6
8
|
interface IusePieChart {
|
|
7
9
|
radius: number
|
|
@@ -32,6 +34,18 @@ interface IusePieChart {
|
|
|
32
34
|
isDataShifted: boolean
|
|
33
35
|
paddingHorizontal: number
|
|
34
36
|
paddingVertical: number
|
|
37
|
+
isAnimated: boolean
|
|
38
|
+
animationDuration: number
|
|
39
|
+
initial: string
|
|
40
|
+
dInitial: string[]
|
|
41
|
+
dFinal: string[]
|
|
42
|
+
isAnimating: boolean
|
|
43
|
+
getStartCaps: (index: number, item: pieDataItem) => string
|
|
44
|
+
getEndCaps: (index: number, item: pieDataItem) => string
|
|
45
|
+
getTextCoordinates: (
|
|
46
|
+
index: number,
|
|
47
|
+
labelPos?: LabelsPosition
|
|
48
|
+
) => { x: number; y: number }
|
|
35
49
|
}
|
|
36
50
|
|
|
37
51
|
interface IPieChartPropsType extends PieChartPropsType {
|
|
@@ -100,7 +114,10 @@ export const usePieChart = (props: IPieChartPropsType): IusePieChart => {
|
|
|
100
114
|
donut,
|
|
101
115
|
isThreeD,
|
|
102
116
|
semiCircle,
|
|
103
|
-
inwardExtraLengthForFocused = 0
|
|
117
|
+
inwardExtraLengthForFocused = 0,
|
|
118
|
+
isAnimated = false,
|
|
119
|
+
edgesRadius,
|
|
120
|
+
endAngle = props.endAngle ?? startAngle + Math.PI * (semiCircle ? 1 : 2)
|
|
104
121
|
} = props
|
|
105
122
|
|
|
106
123
|
const canvasWidth = radius * 2
|
|
@@ -137,15 +154,224 @@ export const usePieChart = (props: IPieChartPropsType): IusePieChart => {
|
|
|
137
154
|
? (props.textBackgroundRadius ?? textSize) * 2 + 6
|
|
138
155
|
: 0
|
|
139
156
|
|
|
157
|
+
/********************************** PRO **********************/
|
|
158
|
+
|
|
159
|
+
const startAngleForPro = props.startAngle ?? 0
|
|
160
|
+
const animationDuration = props.animationDuration ?? defaultAnimationDuration
|
|
161
|
+
|
|
162
|
+
const [isAnimating, setIsAnimating] = useState(isAnimated)
|
|
163
|
+
|
|
164
|
+
useEffect(() => {
|
|
165
|
+
if (isAnimated) {
|
|
166
|
+
setIsAnimating(true)
|
|
167
|
+
setTimeout(() => setIsAnimating(false), animationDuration)
|
|
168
|
+
}
|
|
169
|
+
}, [])
|
|
170
|
+
|
|
171
|
+
let endAngleLocal = 0
|
|
172
|
+
|
|
173
|
+
const addValues = (index: number) => {
|
|
174
|
+
if (index < 0) return 0
|
|
175
|
+
let sum = 0
|
|
176
|
+
for (let i = 0; i <= index; i++) sum += data[i].value
|
|
177
|
+
return sum
|
|
178
|
+
}
|
|
179
|
+
const labelsPosition = props.labelsPosition
|
|
180
|
+
? props.labelsPosition
|
|
181
|
+
: donut || props.centerLabelComponent
|
|
182
|
+
? 'outward'
|
|
183
|
+
: 'mid'
|
|
184
|
+
|
|
185
|
+
const getCoordinates = (
|
|
186
|
+
index: number,
|
|
187
|
+
additionalValue?: number,
|
|
188
|
+
addInOnlyStart?: boolean,
|
|
189
|
+
addInOnlyEnd?: boolean
|
|
190
|
+
) => {
|
|
191
|
+
const addedValue =
|
|
192
|
+
addValues(index - 1) + (addInOnlyEnd ? 0 : additionalValue ?? 0)
|
|
193
|
+
let angle = (addedValue / total) * endAngleLocal + startAngleForPro
|
|
194
|
+
const startInnerX = radius + Math.cos(angle) * innerRadius
|
|
195
|
+
const startInnerY = radius - Math.sin(angle) * innerRadius
|
|
196
|
+
const startOuterX = radius + Math.cos(angle) * radius
|
|
197
|
+
const startOuterY = radius - Math.sin(angle) * radius
|
|
198
|
+
|
|
199
|
+
const value =
|
|
200
|
+
addValues(index - 1) +
|
|
201
|
+
data[index].value +
|
|
202
|
+
(addInOnlyStart ? 0 : additionalValue ?? 0)
|
|
203
|
+
angle = (value / total) * endAngleLocal + startAngleForPro
|
|
204
|
+
|
|
205
|
+
const endOuterX = radius + Math.cos(angle) * radius
|
|
206
|
+
const endOuterY = radius - Math.sin(angle) * radius
|
|
207
|
+
|
|
208
|
+
const endInnerX = radius + Math.cos(angle) * innerRadius
|
|
209
|
+
const endInnerY = radius - Math.sin(angle) * innerRadius
|
|
210
|
+
|
|
211
|
+
return {
|
|
212
|
+
startInnerX,
|
|
213
|
+
startInnerY,
|
|
214
|
+
startOuterX,
|
|
215
|
+
startOuterY,
|
|
216
|
+
endOuterX,
|
|
217
|
+
endOuterY,
|
|
218
|
+
endInnerX,
|
|
219
|
+
endInnerY
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const getTextCoordinates = (index: number, labelPos?: LabelsPosition) => {
|
|
224
|
+
const value = addValues(index - 1) + data[index].value / 2
|
|
225
|
+
const angle = (value / total) * endAngleLocal + startAngleForPro
|
|
226
|
+
|
|
227
|
+
const labelPosition: LabelsPosition = labelPos || labelsPosition
|
|
228
|
+
|
|
229
|
+
let x =
|
|
230
|
+
radius +
|
|
231
|
+
Math.cos(angle) *
|
|
232
|
+
radius *
|
|
233
|
+
(labelPosition === 'inward'
|
|
234
|
+
? 0.25
|
|
235
|
+
: labelPosition === 'mid'
|
|
236
|
+
? 0.5
|
|
237
|
+
: labelPosition === 'outward'
|
|
238
|
+
? 0.75
|
|
239
|
+
: 1)
|
|
240
|
+
let y =
|
|
241
|
+
radius -
|
|
242
|
+
Math.sin(angle) *
|
|
243
|
+
radius *
|
|
244
|
+
(labelPosition === 'inward'
|
|
245
|
+
? 0.25
|
|
246
|
+
: labelPosition === 'mid'
|
|
247
|
+
? 0.5
|
|
248
|
+
: labelPosition === 'outward'
|
|
249
|
+
? 0.75
|
|
250
|
+
: 1)
|
|
251
|
+
|
|
252
|
+
return { x, y }
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
var initial = ''
|
|
256
|
+
const getInitial = (item: pieDataItem) => {
|
|
257
|
+
if (item.isStartEdgeCurved || item.startEdgeRadius) {
|
|
258
|
+
const { startInnerX, startInnerY, startOuterX, startOuterY } =
|
|
259
|
+
getCoordinates(0, (radius - innerRadius) / (radius / 20))
|
|
260
|
+
|
|
261
|
+
return `M${startInnerX},${startInnerY} L${startOuterX},${startOuterY} `
|
|
262
|
+
}
|
|
263
|
+
return `M${radius + innerRadius},${radius} h${radius - innerRadius} `
|
|
264
|
+
}
|
|
265
|
+
const getPath = (index: number) => {
|
|
266
|
+
const { endOuterX, endOuterY } = getCoordinates(index)
|
|
267
|
+
|
|
268
|
+
const isLargeArc = data[index].value / total > 0.5 ? 1 : 0
|
|
269
|
+
|
|
270
|
+
const arc = `A${
|
|
271
|
+
radius + (props.strokeWidth ?? 0) / 2
|
|
272
|
+
},${radius} 0 ${isLargeArc} 0 `
|
|
273
|
+
const path = `${arc} ${endOuterX}, ${endOuterY}
|
|
274
|
+
L${radius},${radius} `
|
|
275
|
+
|
|
276
|
+
initial = `M${radius},${radius} L${endOuterX},${endOuterY}`
|
|
277
|
+
|
|
278
|
+
return path
|
|
279
|
+
}
|
|
280
|
+
const getDonutPath = (index: number, item: pieDataItem) => {
|
|
281
|
+
const additionalForStart =
|
|
282
|
+
item.isStartEdgeCurved || item.startEdgeRadius
|
|
283
|
+
? (radius - innerRadius) / (radius / 20)
|
|
284
|
+
: 0
|
|
285
|
+
|
|
286
|
+
const additionalForEnd =
|
|
287
|
+
item.isEndEdgeCurved || item.endEdgeRadius
|
|
288
|
+
? (radius - innerRadius) / (radius / -20)
|
|
289
|
+
: 0
|
|
290
|
+
|
|
291
|
+
const cropAtEnd = !!(
|
|
292
|
+
index === data.length - 1 &&
|
|
293
|
+
(item.isEndEdgeCurved || item.endEdgeRadius)
|
|
294
|
+
)
|
|
295
|
+
const {
|
|
296
|
+
startInnerX,
|
|
297
|
+
startInnerY,
|
|
298
|
+
endOuterX,
|
|
299
|
+
endOuterY,
|
|
300
|
+
endInnerX,
|
|
301
|
+
endInnerY
|
|
302
|
+
} = getCoordinates(
|
|
303
|
+
index,
|
|
304
|
+
cropAtEnd ? additionalForEnd : additionalForStart,
|
|
305
|
+
!cropAtEnd,
|
|
306
|
+
cropAtEnd
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
const isLargeArc = data[index].value / total > 0.5 ? 1 : 0
|
|
310
|
+
|
|
311
|
+
const innerArc = `A${innerRadius},${innerRadius} 0 ${isLargeArc} 1 `
|
|
312
|
+
const outerArc = `A${
|
|
313
|
+
radius + (props.strokeWidth ?? 0) / 2
|
|
314
|
+
},${radius} 0 ${isLargeArc} 0 `
|
|
315
|
+
const path = `${outerArc} ${endOuterX}, ${endOuterY}
|
|
316
|
+
L${endInnerX},${endInnerY} M${endInnerX},${endInnerY} ${innerArc} ${startInnerX},${startInnerY}`
|
|
317
|
+
|
|
318
|
+
initial = `M${endInnerX},${endInnerY} L${endOuterX},${endOuterY} `
|
|
319
|
+
|
|
320
|
+
return path
|
|
321
|
+
}
|
|
322
|
+
const getStartCaps = (index: number, item: pieDataItem) => {
|
|
323
|
+
const edgeRadius = item.startEdgeRadius ?? edgesRadius ?? 1
|
|
324
|
+
const additional =
|
|
325
|
+
(item.isStartEdgeCurved || item.startEdgeRadius
|
|
326
|
+
? (radius - innerRadius) / (radius / 20)
|
|
327
|
+
: 0) +
|
|
328
|
+
strokeWidth / 2
|
|
329
|
+
const { startInnerX, startInnerY, startOuterX, startOuterY } =
|
|
330
|
+
getCoordinates(index, additional)
|
|
331
|
+
|
|
332
|
+
const path = `M${startInnerX},${startInnerY} A${edgeRadius},${edgeRadius} 0 0 0 ${startOuterX},${startOuterY}`
|
|
333
|
+
return path
|
|
334
|
+
}
|
|
335
|
+
const getEndCaps = (index: number, item: pieDataItem) => {
|
|
336
|
+
const edgeRadius = item.endEdgeRadius ?? edgesRadius ?? 1
|
|
337
|
+
const additional =
|
|
338
|
+
(item.isEndEdgeCurved || item.endEdgeRadius
|
|
339
|
+
? (radius - innerRadius) / (radius / 20)
|
|
340
|
+
: 0) -
|
|
341
|
+
strokeWidth / 2
|
|
342
|
+
const { endInnerX, endInnerY, endOuterX, endOuterY } = getCoordinates(
|
|
343
|
+
index,
|
|
344
|
+
-additional
|
|
345
|
+
)
|
|
346
|
+
|
|
347
|
+
const path = `M${endInnerX},${endInnerY} A${edgeRadius},${edgeRadius} 0 0 1 ${endOuterX},${endOuterY}`
|
|
348
|
+
return path
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
const dInitial = data.map(
|
|
352
|
+
(item, index) =>
|
|
353
|
+
`${initial || getInitial(item)} ${
|
|
354
|
+
donut ? getDonutPath(index, item) : getPath(index)
|
|
355
|
+
}`
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
endAngleLocal = endAngle
|
|
359
|
+
initial = ''
|
|
360
|
+
const dFinal = data.map(
|
|
361
|
+
(item, index) =>
|
|
362
|
+
`${initial || getInitial(item)} ${
|
|
363
|
+
donut ? getDonutPath(index, item) : getPath(index)
|
|
364
|
+
}`
|
|
365
|
+
)
|
|
366
|
+
|
|
140
367
|
return {
|
|
141
368
|
radius,
|
|
142
369
|
extraRadiusForFocused,
|
|
143
370
|
pi,
|
|
144
371
|
selectedIndex,
|
|
145
372
|
setSelectedIndex,
|
|
146
|
-
startAngle: pro ?
|
|
147
|
-
endAngle
|
|
148
|
-
props.endAngle ?? startAngle + (semiCircle ? Math.PI : Math.PI * 2),
|
|
373
|
+
startAngle: pro ? startAngleForPro : startAngle,
|
|
374
|
+
endAngle,
|
|
149
375
|
setStartAngle,
|
|
150
376
|
total,
|
|
151
377
|
setTotal,
|
|
@@ -166,6 +392,18 @@ export const usePieChart = (props: IPieChartPropsType): IusePieChart => {
|
|
|
166
392
|
tiltAngle,
|
|
167
393
|
isDataShifted,
|
|
168
394
|
paddingHorizontal,
|
|
169
|
-
paddingVertical
|
|
395
|
+
paddingVertical,
|
|
396
|
+
isAnimated,
|
|
397
|
+
animationDuration: animationDuration / 1000,
|
|
398
|
+
|
|
399
|
+
// PRO
|
|
400
|
+
|
|
401
|
+
initial,
|
|
402
|
+
dInitial,
|
|
403
|
+
dFinal,
|
|
404
|
+
isAnimating,
|
|
405
|
+
getStartCaps,
|
|
406
|
+
getEndCaps,
|
|
407
|
+
getTextCoordinates
|
|
170
408
|
}
|
|
171
409
|
}
|
package/src/PieChart/types.d.ts
CHANGED
|
@@ -49,11 +49,13 @@ export interface PieChartPropsType {
|
|
|
49
49
|
pieInnerComponentWidth?: number;
|
|
50
50
|
paddingHorizontal?: number;
|
|
51
51
|
paddingVertical?: number;
|
|
52
|
-
isAnimated?: boolean;
|
|
53
52
|
startAngle?: number;
|
|
54
53
|
endAngle?: number;
|
|
55
|
-
|
|
54
|
+
curvedStartEdges?: boolean;
|
|
55
|
+
curvedEndEdges?: boolean;
|
|
56
56
|
edgesRadius?: number;
|
|
57
|
+
isAnimated?: boolean;
|
|
58
|
+
animationDuration?: number;
|
|
57
59
|
}
|
|
58
60
|
export interface pieDataItem {
|
|
59
61
|
value: number;
|
package/src/PieChart/types.ts
CHANGED
|
@@ -52,11 +52,13 @@ export interface PieChartPropsType {
|
|
|
52
52
|
pieInnerComponentWidth?: number
|
|
53
53
|
paddingHorizontal?: number
|
|
54
54
|
paddingVertical?: number
|
|
55
|
-
isAnimated?: boolean
|
|
56
55
|
startAngle?: number
|
|
57
56
|
endAngle?: number
|
|
58
|
-
|
|
57
|
+
curvedStartEdges?: boolean
|
|
58
|
+
curvedEndEdges?: boolean
|
|
59
59
|
edgesRadius?: number
|
|
60
|
+
isAnimated?: boolean
|
|
61
|
+
animationDuration?: number
|
|
60
62
|
}
|
|
61
63
|
export interface pieDataItem {
|
|
62
64
|
value: number
|
package/src/utils/constants.d.ts
CHANGED
package/src/utils/constants.js
CHANGED
|
@@ -8,7 +8,7 @@ export var chartTypes;
|
|
|
8
8
|
})(chartTypes || (chartTypes = {}));
|
|
9
9
|
export var defaultCurvature = 0.2;
|
|
10
10
|
var defaultCurveType = CurveType.CUBIC;
|
|
11
|
-
var defaultAnimationDuration = 800;
|
|
11
|
+
export var defaultAnimationDuration = 800;
|
|
12
12
|
var defaultScrollEventThrottle = 0;
|
|
13
13
|
var defaultEndReachedOffset = 80;
|
|
14
14
|
// Bar and Line chart Specific
|
package/src/utils/constants.ts
CHANGED
|
@@ -7,12 +7,12 @@ import { type FontStyle } from 'react-native-svg'
|
|
|
7
7
|
export enum chartTypes {
|
|
8
8
|
BAR,
|
|
9
9
|
LINE,
|
|
10
|
-
LINE_BI_COLOR
|
|
10
|
+
LINE_BI_COLOR
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export const defaultCurvature = 0.2
|
|
14
14
|
const defaultCurveType = CurveType.CUBIC
|
|
15
|
-
const defaultAnimationDuration = 800
|
|
15
|
+
export const defaultAnimationDuration = 800
|
|
16
16
|
const defaultScrollEventThrottle = 0
|
|
17
17
|
const defaultEndReachedOffset = 80
|
|
18
18
|
|
|
@@ -20,13 +20,13 @@ const defaultEndReachedOffset = 80
|
|
|
20
20
|
|
|
21
21
|
export enum yAxisSides {
|
|
22
22
|
LEFT,
|
|
23
|
-
RIGHT
|
|
23
|
+
RIGHT
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
export enum loc {
|
|
27
27
|
IN,
|
|
28
28
|
UP,
|
|
29
|
-
DOWN
|
|
29
|
+
DOWN
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
export const SEGMENT_START = 'segmentStart'
|