@easyv/charts 1.10.8 → 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/CartesianChart.js +33 -16
- package/lib/components/Legend.js +51 -5
- package/lib/components/Line.js +5 -5
- package/lib/components/PieChart.js +5 -0
- package/lib/formatter/legend.js +111 -6
- package/lib/hooks/useAxes.js +10 -5
- package/lib/hooks/useCarouselAxisX.js +18 -16
- package/lib/utils/index.js +116 -105
- package/package.json +1 -1
- package/src/components/CartesianChart.js +38 -20
- package/src/components/Legend.js +63 -1
- package/src/components/Line.js +61 -38
- package/src/components/PieChart.js +37 -32
- package/src/formatter/legend.js +134 -24
- package/src/hooks/useAxes.js +18 -8
- package/src/hooks/useCarouselAxisX.js +320 -318
- package/src/utils/index.js +171 -155
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
|
);
|
package/src/hooks/useAxes.js
CHANGED
|
@@ -372,8 +372,12 @@ export default ({
|
|
|
372
372
|
clipAxisRange,
|
|
373
373
|
lengthWithoutPaddingOuter,
|
|
374
374
|
step: [
|
|
375
|
-
|
|
376
|
-
|
|
375
|
+
clipAxisAllTicks[0].length > 0
|
|
376
|
+
? lengthWithoutPaddingOuter / clipAxisAllTicks[0].length
|
|
377
|
+
: 0,
|
|
378
|
+
clipAxisAllTicks[1].length > 0
|
|
379
|
+
? lengthWithoutPaddingOuter / clipAxisAllTicks[1].length
|
|
380
|
+
: 0,
|
|
377
381
|
],
|
|
378
382
|
allTicks: clipAxisAllTicks,
|
|
379
383
|
ticks: clipAxisTicks,
|
|
@@ -454,16 +458,22 @@ export default ({
|
|
|
454
458
|
// }
|
|
455
459
|
// }
|
|
456
460
|
// }
|
|
457
|
-
|
|
461
|
+
const tickLen = allTicks.length;
|
|
462
|
+
let step =
|
|
463
|
+
tickLen > 0 ? lengthWithoutPaddingOuter / tickLen : 0;
|
|
458
464
|
const controlCfg = {
|
|
459
465
|
controlStep: 0,
|
|
460
466
|
controlDragScaler: null,
|
|
461
467
|
};
|
|
462
468
|
if (isC) {
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
.
|
|
466
|
-
|
|
469
|
+
if (tickLen > 0 && cPercent > 0) {
|
|
470
|
+
controlCfg.controlStep = step / cPercent;
|
|
471
|
+
controlCfg.controlDragScaler = scaler
|
|
472
|
+
.copy()
|
|
473
|
+
.range([start / cPercent, end / cPercent]);
|
|
474
|
+
} else {
|
|
475
|
+
controlCfg.controlDragScaler = scaler.copy();
|
|
476
|
+
}
|
|
467
477
|
const {
|
|
468
478
|
start: start_,
|
|
469
479
|
end: end_,
|
|
@@ -480,7 +490,7 @@ export default ({
|
|
|
480
490
|
scaler = scales[type]().domain(newDomain).range(range);
|
|
481
491
|
scaler.type = type;
|
|
482
492
|
const controlOuter = len - outer;
|
|
483
|
-
step = controlOuter /
|
|
493
|
+
step = tickLen > 0 ? controlOuter / tickLen : 0;
|
|
484
494
|
}
|
|
485
495
|
tmp.set(axisType, {
|
|
486
496
|
...item,
|