@easyv/charts 1.10.9 → 1.10.10
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/lib/components/Legend.js +51 -5
- package/lib/components/PieChart.js +5 -0
- package/lib/formatter/legend.js +111 -6
- package/lib/utils/index.js +116 -105
- package/package.json +2 -2
- package/src/components/Legend.js +63 -1
- package/src/components/PieChart.js +37 -32
- package/src/formatter/legend.js +134 -24
- package/src/utils/index.js +171 -155
|
@@ -186,7 +186,7 @@ const getArc = (
|
|
|
186
186
|
...rest
|
|
187
187
|
},
|
|
188
188
|
series_,
|
|
189
|
-
index
|
|
189
|
+
index,
|
|
190
190
|
) => {
|
|
191
191
|
const series =
|
|
192
192
|
series_.find((s) => s.fieldName == rest.data.s) ||
|
|
@@ -268,6 +268,7 @@ const Component = memo(
|
|
|
268
268
|
current,
|
|
269
269
|
} = {},
|
|
270
270
|
order,
|
|
271
|
+
columnsSeries,
|
|
271
272
|
series,
|
|
272
273
|
animation: {
|
|
273
274
|
on,
|
|
@@ -378,7 +379,7 @@ const Component = memo(
|
|
|
378
379
|
padAngle: _padAngle,
|
|
379
380
|
innerRadius,
|
|
380
381
|
outerRadius: scaler(arc.value),
|
|
381
|
-
})
|
|
382
|
+
}),
|
|
382
383
|
);
|
|
383
384
|
}
|
|
384
385
|
return _legendDataWithPercent.map((arc, index) => ({
|
|
@@ -410,7 +411,7 @@ const Component = memo(
|
|
|
410
411
|
type: "onClick",
|
|
411
412
|
});
|
|
412
413
|
},
|
|
413
|
-
[onEvent]
|
|
414
|
+
[onEvent],
|
|
414
415
|
);
|
|
415
416
|
|
|
416
417
|
const onMouseEnter = useCallback(
|
|
@@ -423,7 +424,7 @@ const Component = memo(
|
|
|
423
424
|
type: "onMouseEnter",
|
|
424
425
|
});
|
|
425
426
|
},
|
|
426
|
-
[onEvent, triggerOnRelative, onEmit]
|
|
427
|
+
[onEvent, triggerOnRelative, onEmit],
|
|
427
428
|
);
|
|
428
429
|
|
|
429
430
|
const onMouseLeave = useCallback(
|
|
@@ -437,7 +438,7 @@ const Component = memo(
|
|
|
437
438
|
type: "onMouseLeave",
|
|
438
439
|
});
|
|
439
440
|
},
|
|
440
|
-
[onEvent]
|
|
441
|
+
[onEvent],
|
|
441
442
|
);
|
|
442
443
|
|
|
443
444
|
useLayoutEffect(() => {
|
|
@@ -557,7 +558,7 @@ const Component = memo(
|
|
|
557
558
|
.innerRadius(centerRadius)
|
|
558
559
|
.outerRadius(centerRadius)(value);
|
|
559
560
|
const dashLength = Math.ceil(
|
|
560
|
-
(Math.PI * centerRadius * 2) / _arcs.length
|
|
561
|
+
(Math.PI * centerRadius * 2) / _arcs.length,
|
|
561
562
|
);
|
|
562
563
|
const pie = getColorList(series.color);
|
|
563
564
|
return (
|
|
@@ -600,7 +601,7 @@ const Component = memo(
|
|
|
600
601
|
</defs>
|
|
601
602
|
</Fragment>
|
|
602
603
|
);
|
|
603
|
-
}
|
|
604
|
+
},
|
|
604
605
|
)}
|
|
605
606
|
{label && (
|
|
606
607
|
<RingLabel
|
|
@@ -649,6 +650,8 @@ const Component = memo(
|
|
|
649
650
|
<Legend
|
|
650
651
|
{...legend}
|
|
651
652
|
height={chartHeight}
|
|
653
|
+
columnsSeries={columnsSeries}
|
|
654
|
+
data={data}
|
|
652
655
|
series={_arcs.map((arc) => ({
|
|
653
656
|
...arc,
|
|
654
657
|
percent: arc.percent.toFixed(legendPrecision),
|
|
@@ -697,7 +700,7 @@ const Component = memo(
|
|
|
697
700
|
outerRadius,
|
|
698
701
|
index: dataIndex,
|
|
699
702
|
},
|
|
700
|
-
index
|
|
703
|
+
index,
|
|
701
704
|
) => {
|
|
702
705
|
const current = index == currentIndex;
|
|
703
706
|
const prev = index == prevIndex.current;
|
|
@@ -706,14 +709,14 @@ const Component = memo(
|
|
|
706
709
|
const fillOpacity = animateColor
|
|
707
710
|
? 1
|
|
708
711
|
: current
|
|
709
|
-
|
|
710
|
-
|
|
712
|
+
? opacity / 100
|
|
713
|
+
: 1;
|
|
711
714
|
const deltaWidthen = offset * widthen;
|
|
712
715
|
const deltaHeighten = offset * heighten;
|
|
713
716
|
const path = arc
|
|
714
717
|
.innerRadius(innerRadius + deltaWidthen)
|
|
715
718
|
.outerRadius(outerRadius + deltaHeighten + deltaWidthen)(
|
|
716
|
-
value
|
|
719
|
+
value,
|
|
717
720
|
);
|
|
718
721
|
const pie = getColorList(series.color);
|
|
719
722
|
const currentPie = animateColor
|
|
@@ -726,15 +729,15 @@ const Component = memo(
|
|
|
726
729
|
//let offsetWidth=decorate2.radiusWidth/2 + radiusWidthAdd/2; //当前文字需生成在装饰物内,故而半径需要减小
|
|
727
730
|
let textArc = arc
|
|
728
731
|
.innerRadius(
|
|
729
|
-
outerRadius + (current ? gap : categoryText.gap)
|
|
732
|
+
outerRadius + (current ? gap : categoryText.gap),
|
|
730
733
|
)
|
|
731
734
|
.outerRadius(
|
|
732
|
-
outerRadius + (current ? gap : categoryText.gap)
|
|
735
|
+
outerRadius + (current ? gap : categoryText.gap),
|
|
733
736
|
)(value);
|
|
734
737
|
let lastA = textArc.lastIndexOf("A");
|
|
735
738
|
textPath = textArc.slice(
|
|
736
739
|
0,
|
|
737
|
-
lastA > 0 ? lastA : textArc.length
|
|
740
|
+
lastA > 0 ? lastA : textArc.length,
|
|
738
741
|
); //文字路径
|
|
739
742
|
categoryTextStyle = current
|
|
740
743
|
? animateCTS
|
|
@@ -779,7 +782,7 @@ const Component = memo(
|
|
|
779
782
|
.outerRadius(
|
|
780
783
|
outerRadius +
|
|
781
784
|
decorate2.radiusWidth +
|
|
782
|
-
(current ? radiusWidthAdd : 0)
|
|
785
|
+
(current ? radiusWidthAdd : 0),
|
|
783
786
|
)(value)}
|
|
784
787
|
stroke={show ? color : "none"}
|
|
785
788
|
strokeWidth={show ? strokeWidth : "0"}
|
|
@@ -843,7 +846,7 @@ const Component = memo(
|
|
|
843
846
|
</defs>
|
|
844
847
|
</Fragment>
|
|
845
848
|
);
|
|
846
|
-
}
|
|
849
|
+
},
|
|
847
850
|
)}
|
|
848
851
|
{label && (
|
|
849
852
|
<Label
|
|
@@ -918,6 +921,8 @@ const Component = memo(
|
|
|
918
921
|
<Legend
|
|
919
922
|
{...legend}
|
|
920
923
|
height={chartHeight}
|
|
924
|
+
data={data}
|
|
925
|
+
columnsSeries={columnsSeries}
|
|
921
926
|
series={_arcs.map((arc) => ({
|
|
922
927
|
...arc,
|
|
923
928
|
percent: arc.percent.toFixed(legendPrecision),
|
|
@@ -928,7 +933,7 @@ const Component = memo(
|
|
|
928
933
|
/>
|
|
929
934
|
</div>
|
|
930
935
|
);
|
|
931
|
-
}
|
|
936
|
+
},
|
|
932
937
|
);
|
|
933
938
|
|
|
934
939
|
const Current = ({
|
|
@@ -979,7 +984,7 @@ const Current = ({
|
|
|
979
984
|
//数据容错,当data都为零那么需要进行以下容错
|
|
980
985
|
if (judge == 0) {
|
|
981
986
|
_data.forEach((d) => {
|
|
982
|
-
(d.percent = 0), (d.value = 0);
|
|
987
|
+
((d.percent = 0), (d.value = 0));
|
|
983
988
|
});
|
|
984
989
|
}
|
|
985
990
|
|
|
@@ -1143,7 +1148,7 @@ const Label = ({
|
|
|
1143
1148
|
}) => {
|
|
1144
1149
|
const _arcs = useMemo(
|
|
1145
1150
|
() => getDataWithPercent(arcs, precision),
|
|
1146
|
-
[arcs, precision]
|
|
1151
|
+
[arcs, precision],
|
|
1147
1152
|
);
|
|
1148
1153
|
//数据做出容错
|
|
1149
1154
|
if (judge == 0) {
|
|
@@ -1171,14 +1176,14 @@ const Label = ({
|
|
|
1171
1176
|
outerRadius,
|
|
1172
1177
|
index: actualIndex,
|
|
1173
1178
|
},
|
|
1174
|
-
index
|
|
1179
|
+
index,
|
|
1175
1180
|
) => {
|
|
1176
1181
|
const [x, y] = arc.centroid();
|
|
1177
1182
|
const midAngle = Math.atan2(y, x);
|
|
1178
1183
|
|
|
1179
1184
|
const [x1, y1] = getCoord(
|
|
1180
1185
|
midAngle,
|
|
1181
|
-
maxRadius ? maxRadius : outerRadius
|
|
1186
|
+
maxRadius ? maxRadius : outerRadius,
|
|
1182
1187
|
);
|
|
1183
1188
|
|
|
1184
1189
|
const radius = (maxRadius ? maxRadius : outerRadius) + distance;
|
|
@@ -1223,8 +1228,8 @@ const Label = ({
|
|
|
1223
1228
|
lineColor
|
|
1224
1229
|
? lineColor
|
|
1225
1230
|
: type == "pure"
|
|
1226
|
-
|
|
1227
|
-
|
|
1231
|
+
? pure
|
|
1232
|
+
: stops[0].color
|
|
1228
1233
|
}
|
|
1229
1234
|
fill="none"
|
|
1230
1235
|
/>
|
|
@@ -1253,8 +1258,8 @@ const Label = ({
|
|
|
1253
1258
|
align == "left"
|
|
1254
1259
|
? "flex-start"
|
|
1255
1260
|
: align == "center"
|
|
1256
|
-
|
|
1257
|
-
|
|
1261
|
+
? "center"
|
|
1262
|
+
: "flex-end",
|
|
1258
1263
|
justifyContent: "center",
|
|
1259
1264
|
}}
|
|
1260
1265
|
>
|
|
@@ -1315,7 +1320,7 @@ const Label = ({
|
|
|
1315
1320
|
</g>
|
|
1316
1321
|
)
|
|
1317
1322
|
);
|
|
1318
|
-
}
|
|
1323
|
+
},
|
|
1319
1324
|
)}
|
|
1320
1325
|
</g>
|
|
1321
1326
|
);
|
|
@@ -1376,7 +1381,7 @@ const RingLabel = ({
|
|
|
1376
1381
|
}) => {
|
|
1377
1382
|
const _arcs = useMemo(
|
|
1378
1383
|
() => getDataWithPercent(arcs, precision),
|
|
1379
|
-
[arcs, precision]
|
|
1384
|
+
[arcs, precision],
|
|
1380
1385
|
);
|
|
1381
1386
|
|
|
1382
1387
|
//数据做出容错
|
|
@@ -1406,14 +1411,14 @@ const RingLabel = ({
|
|
|
1406
1411
|
outerRadius,
|
|
1407
1412
|
index: actualIndex,
|
|
1408
1413
|
},
|
|
1409
|
-
index
|
|
1414
|
+
index,
|
|
1410
1415
|
) => {
|
|
1411
1416
|
const [x, y] = arc.centroid();
|
|
1412
1417
|
const midAngle = Math.atan2(y, x);
|
|
1413
1418
|
|
|
1414
1419
|
const [x1, y1] = getCoord(
|
|
1415
1420
|
midAngle,
|
|
1416
|
-
maxRadius ? maxRadius : outerRadius
|
|
1421
|
+
maxRadius ? maxRadius : outerRadius,
|
|
1417
1422
|
);
|
|
1418
1423
|
|
|
1419
1424
|
const radius = (maxRadius ? maxRadius : outerRadius) + distance;
|
|
@@ -1456,8 +1461,8 @@ const RingLabel = ({
|
|
|
1456
1461
|
lineColor
|
|
1457
1462
|
? lineColor
|
|
1458
1463
|
: type == "pure"
|
|
1459
|
-
|
|
1460
|
-
|
|
1464
|
+
? pure
|
|
1465
|
+
: stops[0].color
|
|
1461
1466
|
}
|
|
1462
1467
|
fill="none"
|
|
1463
1468
|
/>
|
|
@@ -1546,7 +1551,7 @@ const RingLabel = ({
|
|
|
1546
1551
|
</g>
|
|
1547
1552
|
)
|
|
1548
1553
|
);
|
|
1549
|
-
}
|
|
1554
|
+
},
|
|
1550
1555
|
)}
|
|
1551
1556
|
</g>
|
|
1552
1557
|
);
|
package/src/formatter/legend.js
CHANGED
|
@@ -42,6 +42,48 @@ export const pieLegendFormatter = (series, props) => {
|
|
|
42
42
|
translate: { x: percentX, y: percentY },
|
|
43
43
|
},
|
|
44
44
|
} = props;
|
|
45
|
+
const fieldColumnKeys = props.fieldColumnKeys ?? [];
|
|
46
|
+
const fieldsColumnWidths = props.fieldsColumnWidths ?? [];
|
|
47
|
+
//获取文本所占宽度
|
|
48
|
+
function getStringWidth(text, fontStyle = "14px sans-serif") {
|
|
49
|
+
const canvas = document.createElement("canvas");
|
|
50
|
+
const ctx = canvas.getContext("2d");
|
|
51
|
+
ctx.font = fontStyle;
|
|
52
|
+
return ctx.measureText(text).width;
|
|
53
|
+
}
|
|
54
|
+
const alignToJustify = (align) =>
|
|
55
|
+
align == "left" ? "flex-start" : align == "right" ? "flex-end" : "center";
|
|
56
|
+
const alignToTextAlign = (align) =>
|
|
57
|
+
align === "left" ? "left" : align === "right" ? "right" : "center";
|
|
58
|
+
if (fieldColumnKeys.length > 0) {
|
|
59
|
+
//处理除name、value、percent外的列
|
|
60
|
+
series.fieldsData = fieldColumnKeys
|
|
61
|
+
.map((key, fieldsColumnIndex) => {
|
|
62
|
+
if (!series.fields?.[key] || !series.data?.hasOwnProperty(key)) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
...series.fields[key],
|
|
67
|
+
value: series.data[key],
|
|
68
|
+
fieldsColumnIndex,
|
|
69
|
+
};
|
|
70
|
+
})
|
|
71
|
+
.filter(Boolean);
|
|
72
|
+
} else {
|
|
73
|
+
series.fieldsData = Object.entries(series.fields || {}).reduce(
|
|
74
|
+
(arr, [key, config]) => {
|
|
75
|
+
if (series.data.hasOwnProperty(key)) {
|
|
76
|
+
arr.push({
|
|
77
|
+
...config,
|
|
78
|
+
value: series.data[key],
|
|
79
|
+
fieldsColumnIndex: arr.length,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return arr;
|
|
83
|
+
},
|
|
84
|
+
[],
|
|
85
|
+
);
|
|
86
|
+
}
|
|
45
87
|
const {
|
|
46
88
|
type: seriesColorType,
|
|
47
89
|
pure,
|
|
@@ -56,6 +98,43 @@ export const pieLegendFormatter = (series, props) => {
|
|
|
56
98
|
if (showName) columns.push(`${props.nameMaxWidth}px`);
|
|
57
99
|
if (showValue) columns.push(`${props.valueMaxWidth + valueGap}px`);
|
|
58
100
|
if (showPercent) columns.push(`${props.percentMaxWidth + percentGap}px`);
|
|
101
|
+
if (series.fieldsData.length > 0) {
|
|
102
|
+
//网格布局新增的各列宽度
|
|
103
|
+
series.fieldsData.forEach((item) => {
|
|
104
|
+
const idx = item.fieldsColumnIndex ?? 0;
|
|
105
|
+
const measured = getStringWidth(
|
|
106
|
+
item.value,
|
|
107
|
+
`${item.font.fontSize}px ${item.font.fontFamily}`,
|
|
108
|
+
);
|
|
109
|
+
const suf = item.suffix;
|
|
110
|
+
const suffixWidth =
|
|
111
|
+
suf?.show && suf?.text != null && String(suf.text) !== ""
|
|
112
|
+
? getStringWidth(
|
|
113
|
+
String(suf.text),
|
|
114
|
+
`${suf.fontSize ?? item.font?.fontSize}px ${item.font.fontFamily}`,
|
|
115
|
+
)
|
|
116
|
+
: 0;
|
|
117
|
+
const tx = Math.max(0, Number(item.translate?.x) || 0);
|
|
118
|
+
const stx =
|
|
119
|
+
suf?.show && suf?.text != null && String(suf.text) !== ""
|
|
120
|
+
? Math.max(0, Number(suf.translate?.x) || 0)
|
|
121
|
+
: 0;
|
|
122
|
+
const flowW = measured + suffixWidth + tx + stx;
|
|
123
|
+
let colW;
|
|
124
|
+
if (fieldsColumnWidths.length > idx && fieldsColumnWidths[idx] > 0) {
|
|
125
|
+
colW = Math.max(
|
|
126
|
+
Number(fieldsColumnWidths[idx]) || 0,
|
|
127
|
+
Number(item.maxWidth) || 0,
|
|
128
|
+
flowW,
|
|
129
|
+
);
|
|
130
|
+
} else {
|
|
131
|
+
const fromConfig = Number(item.maxWidth) || 0;
|
|
132
|
+
colW = Math.max(flowW, fromConfig);
|
|
133
|
+
}
|
|
134
|
+
columns.push(`${colW}px`);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
59
138
|
return (
|
|
60
139
|
<>
|
|
61
140
|
{icon && (
|
|
@@ -76,6 +155,7 @@ export const pieLegendFormatter = (series, props) => {
|
|
|
76
155
|
style={{
|
|
77
156
|
width: `calc( 100% + ${textMarginLeft + valueGap + percentGap}px )`,
|
|
78
157
|
gridTemplateColumns: columns.join(" "),
|
|
158
|
+
overflowX: "visible",
|
|
79
159
|
}}
|
|
80
160
|
>
|
|
81
161
|
{showName && (
|
|
@@ -101,18 +181,8 @@ export const pieLegendFormatter = (series, props) => {
|
|
|
101
181
|
transform: `translate(${valueX}px,${valueY}px)`,
|
|
102
182
|
color: valueSameColor ? _color : valueFont.color,
|
|
103
183
|
alignItems: "center",
|
|
104
|
-
justifyContent:
|
|
105
|
-
|
|
106
|
-
? "flex-start"
|
|
107
|
-
: valueAlign == "right"
|
|
108
|
-
? "flex-end"
|
|
109
|
-
: "center",
|
|
110
|
-
textAlign:
|
|
111
|
-
valueAlign === "left"
|
|
112
|
-
? "left"
|
|
113
|
-
: valueAlign === "right"
|
|
114
|
-
? "right"
|
|
115
|
-
: "center",
|
|
184
|
+
justifyContent: alignToJustify(valueAlign ?? "center"),
|
|
185
|
+
textAlign: alignToTextAlign(valueAlign),
|
|
116
186
|
}}
|
|
117
187
|
>
|
|
118
188
|
<span>
|
|
@@ -134,29 +204,69 @@ export const pieLegendFormatter = (series, props) => {
|
|
|
134
204
|
{showPercent && (
|
|
135
205
|
<span
|
|
136
206
|
style={{
|
|
207
|
+
display: "flex",
|
|
137
208
|
whiteSpace: "nowrap",
|
|
138
209
|
...getFontStyle(percentFont),
|
|
139
210
|
marginLeft: percentGap,
|
|
140
211
|
transform: `translate(${percentX}px,${percentY}px)`,
|
|
141
212
|
color: percentSameColor ? _color : percentFont.color,
|
|
142
213
|
alignItems: "center",
|
|
143
|
-
justifyContent:
|
|
144
|
-
|
|
145
|
-
? "flex-start"
|
|
146
|
-
: percentAlign == "right"
|
|
147
|
-
? "flex-end"
|
|
148
|
-
: "center",
|
|
149
|
-
textAlign:
|
|
150
|
-
percentAlign === "left"
|
|
151
|
-
? "left"
|
|
152
|
-
: percentAlign === "right"
|
|
153
|
-
? "right"
|
|
154
|
-
: "center",
|
|
214
|
+
justifyContent: alignToJustify(percentAlign),
|
|
215
|
+
textAlign: alignToTextAlign(percentAlign),
|
|
155
216
|
}}
|
|
156
217
|
>
|
|
157
218
|
{percent + "%"}
|
|
158
219
|
</span>
|
|
159
220
|
)}
|
|
221
|
+
{series.fieldsData?.map(
|
|
222
|
+
(
|
|
223
|
+
item,
|
|
224
|
+
index, //渲染网格布局新增的各列
|
|
225
|
+
) => (
|
|
226
|
+
<span
|
|
227
|
+
key={fieldColumnKeys[item.fieldsColumnIndex ?? index] ?? index}
|
|
228
|
+
style={{
|
|
229
|
+
display: "flex",
|
|
230
|
+
boxSizing: "border-box",
|
|
231
|
+
width: "100%",
|
|
232
|
+
minWidth: 0,
|
|
233
|
+
alignItems: "center",
|
|
234
|
+
justifyContent: alignToJustify(item.align ?? "center"),
|
|
235
|
+
textAlign: alignToTextAlign(item.align ?? "center"),
|
|
236
|
+
overflow: "visible",
|
|
237
|
+
...getFontStyle(item.font),
|
|
238
|
+
color: item.sameColor ? _color : item.font.color,
|
|
239
|
+
}}
|
|
240
|
+
>
|
|
241
|
+
<span
|
|
242
|
+
style={{
|
|
243
|
+
display: "inline-flex",
|
|
244
|
+
alignItems: "center",
|
|
245
|
+
flexWrap: "nowrap",
|
|
246
|
+
whiteSpace: "nowrap",
|
|
247
|
+
marginLeft: item.translate?.x ?? 0,
|
|
248
|
+
marginTop: item.translate?.y ?? 0,
|
|
249
|
+
}}
|
|
250
|
+
>
|
|
251
|
+
<span style={{ whiteSpace: "nowrap" }}>{item.value}</span>
|
|
252
|
+
{item.suffix?.show &&
|
|
253
|
+
item.suffix?.text != null &&
|
|
254
|
+
String(item.suffix.text) !== "" && (
|
|
255
|
+
<span
|
|
256
|
+
style={{
|
|
257
|
+
whiteSpace: "nowrap",
|
|
258
|
+
fontSize: item.suffix.fontSize,
|
|
259
|
+
marginLeft: item.suffix.translate?.x ?? 0,
|
|
260
|
+
marginTop: item.suffix.translate?.y ?? 0,
|
|
261
|
+
}}
|
|
262
|
+
>
|
|
263
|
+
{item.suffix.text}
|
|
264
|
+
</span>
|
|
265
|
+
)}
|
|
266
|
+
</span>
|
|
267
|
+
</span>
|
|
268
|
+
),
|
|
269
|
+
)}
|
|
160
270
|
</div>
|
|
161
271
|
</>
|
|
162
272
|
);
|