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