@easyv/charts 1.8.23 → 1.8.24
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 +68 -62
- package/lib/components/PieChart.js +2 -0
- package/lib/components/pieTooltip.js +19 -21
- package/package.json +1 -1
- package/src/components/Legend.js +222 -135
- package/src/components/PieChart.js +2 -0
- package/src/components/PieTooltip.jsx +279 -198
package/src/components/Legend.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 图例
|
|
3
3
|
*/
|
|
4
|
-
import React, { memo, useCallback, useState, useEffect, useRef } from
|
|
5
|
-
import { getIcon, sortPie } from
|
|
6
|
-
import TextOverflow from
|
|
4
|
+
import React, { memo, useCallback, useState, useEffect, useRef } from "react";
|
|
5
|
+
import { getIcon, sortPie } from "../utils";
|
|
6
|
+
import TextOverflow from "./TextOverflow";
|
|
7
7
|
|
|
8
8
|
const defaultFont = {
|
|
9
|
-
fontStyle:
|
|
10
|
-
fontWeight:
|
|
9
|
+
fontStyle: "normal",
|
|
10
|
+
fontWeight: "normal",
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
export default memo(
|
|
@@ -17,14 +17,14 @@ export default memo(
|
|
|
17
17
|
config,
|
|
18
18
|
config: {
|
|
19
19
|
show,
|
|
20
|
-
order =
|
|
20
|
+
order = "",
|
|
21
21
|
interactive,
|
|
22
|
-
LegendType
|
|
22
|
+
LegendType, //类型
|
|
23
23
|
maxWidth,
|
|
24
24
|
textOverflow,
|
|
25
25
|
speed,
|
|
26
26
|
layout: {
|
|
27
|
-
alignment =
|
|
27
|
+
alignment = "right center",
|
|
28
28
|
gridTemplateColumns,
|
|
29
29
|
gridGap: { gridColumnGap, gridRowGap },
|
|
30
30
|
translate: { x, y },
|
|
@@ -35,7 +35,8 @@ export default memo(
|
|
|
35
35
|
},
|
|
36
36
|
filterData,
|
|
37
37
|
formatter,
|
|
38
|
-
judge
|
|
38
|
+
judge,
|
|
39
|
+
pieClick,
|
|
39
40
|
}) => {
|
|
40
41
|
if (!show) return null;
|
|
41
42
|
|
|
@@ -47,7 +48,8 @@ export default memo(
|
|
|
47
48
|
// 初始化行高
|
|
48
49
|
useEffect(() => {
|
|
49
50
|
if (ref_container.current) {
|
|
50
|
-
const rowHeight =
|
|
51
|
+
const rowHeight =
|
|
52
|
+
ref_container.current.querySelector("li").clientHeight + gridRowGap;
|
|
51
53
|
setScrollStep(rowHeight);
|
|
52
54
|
}
|
|
53
55
|
}, [gridRowGap]);
|
|
@@ -64,12 +66,12 @@ export default memo(
|
|
|
64
66
|
|
|
65
67
|
// 清除定时器
|
|
66
68
|
return () => clearInterval(timer);
|
|
67
|
-
}, [scrollStep, loop.show, loop.interval])
|
|
68
|
-
|
|
69
|
+
}, [scrollStep, loop.show, loop.interval]);
|
|
70
|
+
|
|
69
71
|
const handleAutoScroll = () => {
|
|
70
72
|
const table = ref_container.current;
|
|
71
73
|
if (!table) return;
|
|
72
|
-
|
|
74
|
+
|
|
73
75
|
// 如果已经滚动到了底部,则返回顶部
|
|
74
76
|
if (ref_scrollTop.current + table.clientHeight >= table.scrollHeight) {
|
|
75
77
|
ref_scrollTop.current = 0;
|
|
@@ -78,11 +80,11 @@ export default memo(
|
|
|
78
80
|
ref_scrollTop.current += scrollStep;
|
|
79
81
|
}
|
|
80
82
|
|
|
81
|
-
table.scrollTo({ top: ref_scrollTop.current, behavior:
|
|
83
|
+
table.scrollTo({ top: ref_scrollTop.current, behavior: "smooth" });
|
|
82
84
|
};
|
|
83
85
|
|
|
84
86
|
const _series = sortPie(series, order);
|
|
85
|
-
const [_alignment, position] = alignment.split(
|
|
87
|
+
const [_alignment, position] = alignment.split(" ");
|
|
86
88
|
const length = _series.length;
|
|
87
89
|
|
|
88
90
|
const onClick = useCallback(
|
|
@@ -90,168 +92,249 @@ export default memo(
|
|
|
90
92
|
const { dataset } = e.currentTarget;
|
|
91
93
|
const { name } = dataset;
|
|
92
94
|
filterData && interactive && filterData(name);
|
|
95
|
+
pieClick && pieClick(e);
|
|
93
96
|
},
|
|
94
|
-
[interactive, filterData]
|
|
97
|
+
[interactive, filterData, pieClick]
|
|
95
98
|
);
|
|
96
99
|
|
|
97
100
|
if (judge == 0) {
|
|
98
101
|
_series.forEach((d) => {
|
|
99
|
-
d.percent=0
|
|
100
|
-
})
|
|
102
|
+
d.percent = 0;
|
|
103
|
+
});
|
|
101
104
|
}
|
|
102
105
|
|
|
103
106
|
// 计算最大宽度
|
|
104
107
|
const valueFont = config.value?.font || {};
|
|
105
108
|
const percentFont = config.percent?.font || {};
|
|
106
|
-
const valueSuffix = config.value?.suffix?.text ||
|
|
109
|
+
const valueSuffix = config.value?.suffix?.text || "";
|
|
107
110
|
const valueSplitConfig = config.value?.splitConfig || {};
|
|
108
111
|
const getValueStr = (item) => {
|
|
109
|
-
let valueStr = (item.data?.y ?? item.value ??
|
|
112
|
+
let valueStr = (item.data?.y ?? item.value ?? "") + (valueSuffix || "");
|
|
110
113
|
if (valueSplitConfig.show && valueSplitConfig.separator) {
|
|
111
|
-
valueStr = valueStr
|
|
114
|
+
valueStr = valueStr
|
|
115
|
+
.toString()
|
|
116
|
+
.replace(/\B(?=(\d{3})+(?!\d))/g, valueSplitConfig.separator);
|
|
112
117
|
}
|
|
113
118
|
return valueStr;
|
|
114
119
|
};
|
|
115
120
|
const valueMaxWidth = Math.max(
|
|
116
|
-
..._series.map(
|
|
121
|
+
..._series.map((item) =>
|
|
122
|
+
parseFloat(
|
|
123
|
+
getCanvasTextWidth(
|
|
124
|
+
getValueStr(item),
|
|
125
|
+
valueFont.letterSpacing || 0,
|
|
126
|
+
`${valueFont.fontSize || 12}px ${valueFont.fontFamily || "Arial"}`
|
|
127
|
+
)
|
|
128
|
+
)
|
|
129
|
+
)
|
|
117
130
|
);
|
|
118
131
|
const percentMaxWidth = Math.max(
|
|
119
|
-
..._series.map(item => {
|
|
120
|
-
const percentStr =
|
|
121
|
-
|
|
132
|
+
..._series.map((item) => {
|
|
133
|
+
const percentStr =
|
|
134
|
+
(item.percent !== undefined ? item.percent : item.data?.percent) +
|
|
135
|
+
"%";
|
|
136
|
+
return parseFloat(
|
|
137
|
+
getCanvasTextWidth(
|
|
138
|
+
percentStr,
|
|
139
|
+
percentFont.letterSpacing || 0,
|
|
140
|
+
`${percentFont.fontSize || 12}px ${
|
|
141
|
+
percentFont.fontFamily || "Arial"
|
|
142
|
+
}`
|
|
143
|
+
)
|
|
144
|
+
);
|
|
122
145
|
})
|
|
123
146
|
);
|
|
124
147
|
const nameMaxWidth = config.name?.maxWidth || 80;
|
|
125
148
|
|
|
126
|
-
const stylePieOrAxis=formatter
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
149
|
+
const stylePieOrAxis = formatter
|
|
150
|
+
? {
|
|
151
|
+
display: "flex",
|
|
152
|
+
alignContent:
|
|
153
|
+
alignment.split(" ")[0] == "center" &&
|
|
154
|
+
(alignment.split(" ")[1] == "left" ||
|
|
155
|
+
alignment.split(" ")[1] == "right")
|
|
156
|
+
? alignment.split(" ")[1] == "left"
|
|
157
|
+
? "flex-start"
|
|
158
|
+
: "flex-end"
|
|
159
|
+
: alignment.split(" ")[0] == "left"
|
|
160
|
+
? "flex-start"
|
|
161
|
+
: alignment.split(" ")[0] == "center"
|
|
162
|
+
? "center"
|
|
163
|
+
: "flex-end",
|
|
164
|
+
flexDirection: "column",
|
|
165
|
+
position: "absolute",
|
|
166
|
+
...getPosition(position, _alignment, x, y),
|
|
167
|
+
height: loop.show ? height : "auto",
|
|
168
|
+
overflowY: loop.show ? "scroll" : "auto",
|
|
169
|
+
}
|
|
170
|
+
: {
|
|
171
|
+
display: "flex",
|
|
172
|
+
flexWrap: "wrap",
|
|
173
|
+
alignContent:
|
|
174
|
+
alignment.split(" ")[0] == "center" &&
|
|
175
|
+
(alignment.split(" ")[1] == "left" ||
|
|
176
|
+
alignment.split(" ")[1] == "right")
|
|
177
|
+
? alignment.split(" ")[1] == "left"
|
|
178
|
+
? "flex-start"
|
|
179
|
+
: "flex-end"
|
|
180
|
+
: alignment.split(" ")[0] == "left"
|
|
181
|
+
? "flex-start"
|
|
182
|
+
: alignment.split(" ")[0] == "center"
|
|
183
|
+
? "center"
|
|
184
|
+
: "flex-end",
|
|
185
|
+
flexDirection: "column",
|
|
186
|
+
position: "absolute",
|
|
187
|
+
...getPosition(position, _alignment, x, y),
|
|
188
|
+
height: loop.show ? height : "auto",
|
|
189
|
+
overflowY: loop.show ? "scroll" : "auto",
|
|
190
|
+
};
|
|
191
|
+
return LegendType == "FixedWidth" ? (
|
|
146
192
|
<div
|
|
147
|
-
className=
|
|
193
|
+
className="__easyv-legend-wrapper"
|
|
148
194
|
style={{
|
|
149
|
-
position:
|
|
150
|
-
display:
|
|
195
|
+
position: "absolute",
|
|
196
|
+
display: "flex",
|
|
151
197
|
...getPosition(position, _alignment, x, y),
|
|
152
|
-
height: loop.show ? height :
|
|
153
|
-
overflowY: loop.show ?
|
|
198
|
+
height: loop.show ? height : "auto",
|
|
199
|
+
overflowY: loop.show ? "scroll" : "auto",
|
|
154
200
|
}}
|
|
155
201
|
ref={ref_container}
|
|
156
202
|
>
|
|
157
203
|
<ul
|
|
158
204
|
style={{
|
|
159
|
-
display:
|
|
160
|
-
gridGap: gridRowGap +
|
|
161
|
-
gridTemplateColumns:formatter
|
|
162
|
-
|
|
205
|
+
display: "grid",
|
|
206
|
+
gridGap: gridRowGap + "px " + gridColumnGap + "px",
|
|
207
|
+
gridTemplateColumns: formatter
|
|
208
|
+
? `${nameMaxWidth}px ${valueMaxWidth}px ${percentMaxWidth}px`
|
|
209
|
+
: "repeat(" + Math.min(gridTemplateColumns, length) + ", 1fr)", //饼图或者柱状图配合不同的图例显示格式
|
|
163
210
|
}}
|
|
164
211
|
>
|
|
165
|
-
{_series.map((series,
|
|
166
|
-
const { type, name, displayName, icon, selected } = series;
|
|
212
|
+
{_series.map((series, i) => {
|
|
213
|
+
const { type, name, displayName, icon, selected, index } = series;
|
|
167
214
|
const _icon = getIcon(type, icon, series?.config?.line?.type);
|
|
168
215
|
return (
|
|
169
216
|
<li
|
|
170
|
-
key={
|
|
217
|
+
key={i}
|
|
171
218
|
onClick={onClick}
|
|
172
|
-
data-name={name}
|
|
219
|
+
data-name={displayName || name}
|
|
220
|
+
data-index={index}
|
|
173
221
|
style={{
|
|
174
|
-
display:
|
|
222
|
+
display: "flex",
|
|
175
223
|
opacity: selected === false ? opacity / 100 : 1,
|
|
176
|
-
alignItems:
|
|
224
|
+
alignItems: "center",
|
|
177
225
|
cursor: "pointer",
|
|
178
226
|
gap: _icon.gap,
|
|
179
227
|
}}
|
|
180
228
|
>
|
|
181
229
|
{formatter ? (
|
|
182
|
-
formatter(series, {
|
|
230
|
+
formatter(series, {
|
|
231
|
+
...config,
|
|
232
|
+
valueMaxWidth,
|
|
233
|
+
percentMaxWidth,
|
|
234
|
+
nameMaxWidth,
|
|
235
|
+
})
|
|
183
236
|
) : (
|
|
184
237
|
<>
|
|
185
238
|
<span style={_icon} />
|
|
186
|
-
<TextOverflow
|
|
239
|
+
<TextOverflow
|
|
240
|
+
type={textOverflow}
|
|
241
|
+
value={displayName || name}
|
|
242
|
+
style={{
|
|
187
243
|
...font,
|
|
188
|
-
width:maxWidth,
|
|
189
|
-
fontStyle: italic ?
|
|
190
|
-
fontWeight: bold ?
|
|
191
|
-
}}
|
|
192
|
-
|
|
244
|
+
width: maxWidth,
|
|
245
|
+
fontStyle: italic ? "italic" : "normal",
|
|
246
|
+
fontWeight: bold ? "bold" : "normal",
|
|
247
|
+
}}
|
|
248
|
+
speed={speed}
|
|
249
|
+
></TextOverflow>
|
|
193
250
|
</>
|
|
194
251
|
)}
|
|
195
252
|
</li>
|
|
196
253
|
);
|
|
197
254
|
})}
|
|
198
255
|
</ul>
|
|
199
|
-
</div
|
|
200
|
-
|
|
256
|
+
</div>
|
|
257
|
+
) : (
|
|
258
|
+
<div
|
|
259
|
+
className="__easyv-legend-wrapper"
|
|
201
260
|
style={stylePieOrAxis}
|
|
202
261
|
ref={ref_container}
|
|
203
262
|
>
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
style={{
|
|
209
|
-
display: 'flex',
|
|
210
|
-
width: 'fit-content',
|
|
211
|
-
justifyContent:alignment.split(" ")[0]=="left"?"flex-start":alignment.split(" ")[0]=="center"?"center":"flex-end",
|
|
212
|
-
marginBottom:"0px",
|
|
213
|
-
gap:`${gridRowGap}px ${gridColumnGap}px`,
|
|
214
|
-
marginBottom:gridRowGap+"px"
|
|
215
|
-
}}
|
|
216
|
-
>
|
|
217
|
-
{_series.map((series, index) => {
|
|
218
|
-
if(Math.floor(index/gridTemplateColumns)==indexs){
|
|
219
|
-
const { type, name, displayName, icon, selected } = series;
|
|
220
|
-
const _icon = getIcon(type, icon, series?.config?.line?.type);
|
|
221
|
-
return (
|
|
222
|
-
<li
|
|
223
|
-
key={index}
|
|
224
|
-
onClick={onClick}
|
|
225
|
-
data-name={name}
|
|
263
|
+
{[...Array(Math.ceil(series.length / gridTemplateColumns))].map(
|
|
264
|
+
(_, indexs) => (
|
|
265
|
+
<ul
|
|
266
|
+
key={indexs}
|
|
226
267
|
style={{
|
|
227
|
-
display:
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
268
|
+
display: "flex",
|
|
269
|
+
width: "fit-content",
|
|
270
|
+
justifyContent:
|
|
271
|
+
alignment.split(" ")[0] == "left"
|
|
272
|
+
? "flex-start"
|
|
273
|
+
: alignment.split(" ")[0] == "center"
|
|
274
|
+
? "center"
|
|
275
|
+
: "flex-end",
|
|
276
|
+
marginBottom: "0px",
|
|
277
|
+
gap: `${gridRowGap}px ${gridColumnGap}px`,
|
|
278
|
+
marginBottom: gridRowGap + "px",
|
|
232
279
|
}}
|
|
233
280
|
>
|
|
234
|
-
{
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
281
|
+
{_series.map((series, i) => {
|
|
282
|
+
if (Math.floor(i / gridTemplateColumns) == indexs) {
|
|
283
|
+
const { type, name, displayName, icon, selected, index } =
|
|
284
|
+
series;
|
|
285
|
+
const _icon = getIcon(type, icon, series?.config?.line?.type);
|
|
286
|
+
return (
|
|
287
|
+
<li
|
|
288
|
+
key={i}
|
|
289
|
+
onClick={onClick}
|
|
290
|
+
data-name={displayName || name}
|
|
291
|
+
data-index={index}
|
|
292
|
+
style={{
|
|
293
|
+
display: "flex",
|
|
294
|
+
opacity: selected === false ? opacity / 100 : 1,
|
|
295
|
+
alignItems: "center",
|
|
296
|
+
cursor: "pointer",
|
|
297
|
+
gap: _icon.gap,
|
|
298
|
+
}}
|
|
299
|
+
>
|
|
300
|
+
{formatter ? (
|
|
301
|
+
formatter(series, {
|
|
302
|
+
...config,
|
|
303
|
+
valueMaxWidth,
|
|
304
|
+
percentMaxWidth,
|
|
305
|
+
nameMaxWidth,
|
|
306
|
+
})
|
|
307
|
+
) : (
|
|
308
|
+
<>
|
|
309
|
+
<span style={_icon} />
|
|
310
|
+
<TextOverflow
|
|
311
|
+
ShowType={LegendType}
|
|
312
|
+
type="ellipsis"
|
|
313
|
+
value={displayName || name}
|
|
314
|
+
style={{
|
|
315
|
+
...font,
|
|
316
|
+
fontStyle: italic ? "italic" : "normal",
|
|
317
|
+
fontWeight: bold ? "bold" : "normal",
|
|
318
|
+
minWidth: getCanvasTextWidth(
|
|
319
|
+
displayName
|
|
320
|
+
? displayName.substring(0, 5) ||
|
|
321
|
+
name.substring(0, 5)
|
|
322
|
+
: "",
|
|
323
|
+
font.letterSpacing,
|
|
324
|
+
`${font.fontSize}px ${font.fontFamily}`
|
|
325
|
+
),
|
|
326
|
+
}}
|
|
327
|
+
speed={speed}
|
|
328
|
+
></TextOverflow>
|
|
329
|
+
</>
|
|
330
|
+
)}
|
|
331
|
+
</li>
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
})}
|
|
335
|
+
</ul>
|
|
336
|
+
)
|
|
337
|
+
)}
|
|
255
338
|
</div>
|
|
256
339
|
);
|
|
257
340
|
}
|
|
@@ -259,38 +342,42 @@ const stylePieOrAxis=formatter?{
|
|
|
259
342
|
|
|
260
343
|
const getPosition = (position, alignment, x = 0, y = 0) => {
|
|
261
344
|
switch (position) {
|
|
262
|
-
case
|
|
345
|
+
case "top":
|
|
263
346
|
return {
|
|
264
|
-
left: alignment ==
|
|
265
|
-
right: alignment ==
|
|
347
|
+
left: alignment == "left" ? 5 : alignment == "center" ? "50%" : "",
|
|
348
|
+
right: alignment == "right" ? 10 : "",
|
|
266
349
|
top: 5,
|
|
267
|
-
transform: `translate3d(calc(${
|
|
350
|
+
transform: `translate3d(calc(${
|
|
351
|
+
alignment == "center" ? "-50%" : "0px"
|
|
352
|
+
} + ${x}px), ${y}px, 0px)`,
|
|
268
353
|
};
|
|
269
|
-
case
|
|
354
|
+
case "right":
|
|
270
355
|
return {
|
|
271
|
-
top:
|
|
356
|
+
top: "50%",
|
|
272
357
|
right: 10,
|
|
273
|
-
transform: `translate3d(${x}px, calc(-50% + ${y}px), 0px)
|
|
358
|
+
transform: `translate3d(${x}px, calc(-50% + ${y}px), 0px)`,
|
|
274
359
|
};
|
|
275
|
-
case
|
|
360
|
+
case "left":
|
|
276
361
|
return {
|
|
277
|
-
top:
|
|
362
|
+
top: "50%",
|
|
278
363
|
left: 5,
|
|
279
|
-
transform: `translate3d(${x}px, calc(-50% + ${y}px), 0px)
|
|
364
|
+
transform: `translate3d(${x}px, calc(-50% + ${y}px), 0px)`,
|
|
280
365
|
};
|
|
281
366
|
default: // bottom
|
|
282
367
|
return {
|
|
283
|
-
left: alignment ==
|
|
284
|
-
right: alignment ==
|
|
368
|
+
left: alignment == "left" ? 5 : alignment == "center" ? "50%" : "",
|
|
369
|
+
right: alignment == "right" ? 10 : "",
|
|
285
370
|
bottom: 5,
|
|
286
|
-
transform: `translate3d(calc(${
|
|
371
|
+
transform: `translate3d(calc(${
|
|
372
|
+
alignment == "center" ? "-50%" : "0px"
|
|
373
|
+
} + ${x}px), ${y}px, 0px)`,
|
|
287
374
|
};
|
|
288
375
|
}
|
|
289
376
|
};
|
|
290
|
-
const getCanvasTextWidth=(text,letterSpacing, font =
|
|
291
|
-
const canvas = document.createElement(
|
|
292
|
-
const ctx = canvas.getContext(
|
|
377
|
+
const getCanvasTextWidth = (text, letterSpacing, font = "16px Arial") => {
|
|
378
|
+
const canvas = document.createElement("canvas");
|
|
379
|
+
const ctx = canvas.getContext("2d");
|
|
293
380
|
ctx.font = font;
|
|
294
|
-
return ctx.measureText(text).width+
|
|
381
|
+
return ctx.measureText(text).width + text.length * letterSpacing + "px";
|
|
295
382
|
// return ctx.measureText(text).width+(text.length-1)*letterSpacing+"px";//-1有bug
|
|
296
|
-
}
|
|
383
|
+
};
|
|
@@ -653,6 +653,7 @@ const Component = memo(
|
|
|
653
653
|
...arc,
|
|
654
654
|
percent: arc.percent.toFixed(legendPrecision),
|
|
655
655
|
}))}
|
|
656
|
+
pieClick={onClick}
|
|
656
657
|
formatter={formatter}
|
|
657
658
|
judge={judgeData}
|
|
658
659
|
/>
|
|
@@ -921,6 +922,7 @@ const Component = memo(
|
|
|
921
922
|
...arc,
|
|
922
923
|
percent: arc.percent.toFixed(legendPrecision),
|
|
923
924
|
}))}
|
|
925
|
+
pieClick={onClick}
|
|
924
926
|
formatter={formatter}
|
|
925
927
|
judge={judgeData}
|
|
926
928
|
/>
|