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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gifted-charts-core",
3
- "version": "0.0.42",
3
+ "version": "0.0.44",
4
4
  "description": "Mathematical and logical utilities used by react-gifted-charts and react-native-gifted-charts",
5
5
  "main": "./src/index.js",
6
6
  "files": [
@@ -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;
@@ -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 _w = __read(useState(-1), 2), selectedIndex = _w[0], setSelectedIndex = _w[1]; // at the start, nothing is selected
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 _x = __read(useState((_d = props.initialAngle) !== null && _d !== void 0 ? _d : (props.semiCircle ? -pi : 0)), 2), startAngle = _x[0], setStartAngle = _x[1];
27
- var _y = __read(useState(0), 2), total = _y[0], setTotal = _y[1];
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, _z = props.inwardExtraLengthForFocused, inwardExtraLengthForFocused = _z === void 0 ? 0 : _z;
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 = (_e = props.strokeWidth) !== null && _e !== void 0 ? _e : 0;
70
- var innerRadius = (_f = props.innerRadius) !== null && _f !== void 0 ? _f : radius / 2.5;
71
- var innerCircleColor = (_h = (_g = props.innerCircleColor) !== null && _g !== void 0 ? _g : props.backgroundColor) !== null && _h !== void 0 ? _h : 'white';
72
- var innerCircleBorderWidth = (_j = props.innerCircleBorderWidth) !== null && _j !== void 0 ? _j : (props.innerCircleBorderColor ? strokeWidth || 2 : 0);
73
- var innerCircleBorderColor = (_k = props.innerCircleBorderColor) !== null && _k !== void 0 ? _k : 'lightgray';
74
- var shiftInnerCenterX = (_l = props.shiftInnerCenterX) !== null && _l !== void 0 ? _l : 0;
75
- var shiftInnerCenterY = (_m = props.shiftInnerCenterY) !== null && _m !== void 0 ? _m : 0;
76
- var tiltAngle = (_o = props.tiltAngle) !== null && _o !== void 0 ? _o : '55deg';
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((_p = props.textSize) !== null && _p !== void 0 ? _p : 0, radius);
84
- var paddingHorizontal = ((_q = props.paddingHorizontal) !== null && _q !== void 0 ? _q : props.labelsPosition === 'onBorder')
85
- ? ((_r = props.textBackgroundRadius) !== null && _r !== void 0 ? _r : textSize) * 2 + 6
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 = ((_s = props.paddingVertical) !== null && _s !== void 0 ? _s : props.labelsPosition === 'onBorder')
88
- ? ((_t = props.textBackgroundRadius) !== null && _t !== void 0 ? _t : textSize) * 2 + 6
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 ? (_u = props.startAngle) !== null && _u !== void 0 ? _u : 0 : startAngle,
97
- endAngle: (_v = props.endAngle) !== null && _v !== void 0 ? _v : startAngle + (semiCircle ? Math.PI : Math.PI * 2),
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
  };
@@ -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 ? props.startAngle ?? 0 : startAngle,
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
  }
@@ -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
- curvedEdges?: boolean;
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;
@@ -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
- curvedEdges?: boolean
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
@@ -7,6 +7,7 @@ export declare enum chartTypes {
7
7
  LINE_BI_COLOR = 2
8
8
  }
9
9
  export declare const defaultCurvature = 0.2;
10
+ export declare const defaultAnimationDuration = 800;
10
11
  export declare enum yAxisSides {
11
12
  LEFT = 0,
12
13
  RIGHT = 1
@@ -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
@@ -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'