@easyv/charts 1.4.22 → 1.4.25
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/Axis.js +27 -12
- package/lib/components/Band.js +42 -2
- package/lib/components/CartesianChart.js +254 -27
- package/lib/components/ChartContainer.js +3 -2
- package/lib/components/Control.js +81 -0
- package/lib/components/Indicator.js +66 -5
- package/lib/components/Label.js +41 -1
- package/lib/components/Marquee.js +1 -1
- package/lib/components/index.js +8 -0
- package/lib/hooks/useAxes.js +5 -1
- package/lib/hooks/useCarouselAxisX.js +24 -12
- package/lib/hooks/useTooltip.js +1 -1
- package/package.json +1 -1
- package/src/components/Axis.tsx +223 -183
- package/src/components/Band.tsx +40 -5
- package/src/components/CartesianChart.js +319 -43
- package/src/components/ChartContainer.tsx +15 -8
- package/src/components/Control.jsx +51 -0
- package/src/components/Indicator.js +58 -10
- package/src/components/Label.js +33 -0
- package/src/components/Marquee.tsx +1 -1
- package/src/components/index.js +2 -0
- package/src/hooks/useAxes.js +9 -2
- package/src/hooks/useCarouselAxisX.js +35 -18
- package/src/hooks/useTooltip.ts +18 -18
package/src/components/Axis.tsx
CHANGED
|
@@ -8,11 +8,13 @@ import React, {
|
|
|
8
8
|
useContext,
|
|
9
9
|
CSSProperties,
|
|
10
10
|
MouseEventHandler,
|
|
11
|
+
forwardRef,
|
|
11
12
|
} from "react";
|
|
12
13
|
import { getTickCoord, getGridCoord, getFontStyle } from "../utils";
|
|
13
14
|
import { chartContext } from "../context";
|
|
14
15
|
import { Line } from "../element";
|
|
15
16
|
import TextOverflow from "./TextOverflow";
|
|
17
|
+
import { path } from "d3";
|
|
16
18
|
const defaultEvent = () => {};
|
|
17
19
|
const defaultAppearance = {
|
|
18
20
|
angle: 0,
|
|
@@ -250,201 +252,239 @@ const Label: (
|
|
|
250
252
|
};
|
|
251
253
|
|
|
252
254
|
export default memo(
|
|
253
|
-
(
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
255
|
+
forwardRef(
|
|
256
|
+
(
|
|
257
|
+
{
|
|
258
|
+
orientation,
|
|
259
|
+
scaler,
|
|
260
|
+
tickSize = defaultTickSize,
|
|
261
|
+
ticks,
|
|
262
|
+
formatter,
|
|
263
|
+
rotate,
|
|
264
|
+
triggerClick,
|
|
265
|
+
config: { on, label, axisLine, tickLine, gridLine, unit },
|
|
266
|
+
config,
|
|
267
|
+
positions,
|
|
268
|
+
xLineRange,
|
|
269
|
+
range,
|
|
270
|
+
axisType,
|
|
271
|
+
//断轴图相关
|
|
272
|
+
isClipAxis = false,
|
|
273
|
+
yLineRange,
|
|
274
|
+
clipAxisRange,
|
|
275
|
+
//控制图相关
|
|
276
|
+
isControlChart,
|
|
277
|
+
controlConfig,
|
|
278
|
+
controlEnd,
|
|
279
|
+
rawTicks,
|
|
280
|
+
}: any,
|
|
281
|
+
ref
|
|
282
|
+
) => {
|
|
283
|
+
if (!(on && ticks.length > 0)) return null;
|
|
284
|
+
const { width, height } = useContext(chartContext);
|
|
285
|
+
const x = orientation == "right" ? width : 0;
|
|
286
|
+
const y = orientation == "bottom" ? height : 0;
|
|
274
287
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
288
|
+
function drawAxisTickLine() {
|
|
289
|
+
const draw = (ticks: any, scaler: any) => {
|
|
290
|
+
return ticks.map((tick: string, index: number) => {
|
|
291
|
+
const coordinate = scaler(tick);
|
|
292
|
+
if (isNaN(coordinate)) return null;
|
|
293
|
+
const _tickSize = tickLine.tickSize || tickSize;
|
|
294
|
+
const gridCoord = getGridCoord({
|
|
295
|
+
orientation,
|
|
296
|
+
coordinate,
|
|
297
|
+
end:
|
|
298
|
+
orientation == "left" || orientation == "right"
|
|
299
|
+
? width
|
|
300
|
+
: height,
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
const x1 = gridCoord.x1;
|
|
304
|
+
const y1 = gridCoord.y1;
|
|
305
|
+
return (
|
|
306
|
+
!(
|
|
307
|
+
(orientation == "bottom" && (x1 < 0 || x1 > xLineRange)) ||
|
|
308
|
+
y1 < 0 ||
|
|
309
|
+
y1 > yLineRange
|
|
310
|
+
) && (
|
|
311
|
+
<Line
|
|
312
|
+
className="__easyv-tickLine"
|
|
313
|
+
key={index}
|
|
314
|
+
config={tickLine}
|
|
315
|
+
{...getTickCoord({
|
|
316
|
+
orientation,
|
|
317
|
+
coordinate,
|
|
318
|
+
tickSize: _tickSize,
|
|
319
|
+
})}
|
|
320
|
+
/>
|
|
321
|
+
)
|
|
322
|
+
);
|
|
286
323
|
});
|
|
324
|
+
};
|
|
287
325
|
|
|
288
|
-
|
|
289
|
-
const y1 = gridCoord.y1;
|
|
326
|
+
if (isClipAxis) {
|
|
290
327
|
return (
|
|
291
|
-
|
|
292
|
-
(
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
<Line
|
|
297
|
-
className="__easyv-tickLine"
|
|
298
|
-
key={index}
|
|
299
|
-
config={tickLine}
|
|
300
|
-
{...getTickCoord({
|
|
301
|
-
orientation,
|
|
302
|
-
coordinate,
|
|
303
|
-
tickSize: _tickSize,
|
|
304
|
-
})}
|
|
305
|
-
/>
|
|
306
|
-
)
|
|
328
|
+
<>
|
|
329
|
+
{ticks.map((ticks: any, index: number) => {
|
|
330
|
+
return draw(ticks, scaler[index]);
|
|
331
|
+
})}
|
|
332
|
+
</>
|
|
307
333
|
);
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
if (isClipAxis) {
|
|
312
|
-
return (
|
|
313
|
-
<>
|
|
314
|
-
{ticks.map((ticks: any, index: number) => {
|
|
315
|
-
return draw(ticks, scaler[index]);
|
|
316
|
-
})}
|
|
317
|
-
</>
|
|
318
|
-
);
|
|
319
|
-
} else {
|
|
320
|
-
return <>{draw(ticks, scaler)}</>;
|
|
334
|
+
} else {
|
|
335
|
+
return <>{draw(ticks, scaler)}</>;
|
|
336
|
+
}
|
|
321
337
|
}
|
|
322
|
-
}
|
|
323
338
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
339
|
+
function drawLabel() {
|
|
340
|
+
const draw = (ticks: any, scaler: any) => {
|
|
341
|
+
return ticks.map((tick: string, index: number) => {
|
|
342
|
+
const coordinate = scaler(tick);
|
|
343
|
+
if (isNaN(coordinate)) return null;
|
|
344
|
+
const _tickSize = tickLine.tickSize || tickSize;
|
|
345
|
+
const gridCoord = getGridCoord({
|
|
346
|
+
orientation,
|
|
347
|
+
coordinate,
|
|
348
|
+
end:
|
|
349
|
+
orientation == "left" || orientation == "right"
|
|
350
|
+
? width
|
|
351
|
+
: height,
|
|
352
|
+
});
|
|
353
|
+
const x1 = gridCoord.x1;
|
|
354
|
+
const y1 = gridCoord.y1;
|
|
355
|
+
return (
|
|
356
|
+
(!(
|
|
357
|
+
(orientation == "bottom" && (x1 < 0 || x1 > xLineRange)) ||
|
|
358
|
+
y1 < 0 ||
|
|
359
|
+
y1 > yLineRange
|
|
360
|
+
) ||
|
|
361
|
+
isControlChart) && (
|
|
362
|
+
<g key={index}>
|
|
363
|
+
{label && (
|
|
364
|
+
<Label
|
|
365
|
+
className="__easyv-label"
|
|
366
|
+
orientation={orientation}
|
|
367
|
+
coordinate={coordinate}
|
|
368
|
+
config={label}
|
|
369
|
+
label={tick}
|
|
370
|
+
tickSize={_tickSize}
|
|
371
|
+
formatter={formatter}
|
|
372
|
+
rotate={rotate}
|
|
373
|
+
onClick={triggerClick}
|
|
374
|
+
/>
|
|
375
|
+
)}
|
|
376
|
+
{gridLine && (
|
|
377
|
+
<Line
|
|
378
|
+
className="__easyv-gridLine"
|
|
379
|
+
config={gridLine}
|
|
380
|
+
{...gridCoord}
|
|
381
|
+
/>
|
|
382
|
+
)}
|
|
383
|
+
</g>
|
|
384
|
+
)
|
|
385
|
+
);
|
|
337
386
|
});
|
|
338
|
-
|
|
339
|
-
|
|
387
|
+
};
|
|
388
|
+
if (isClipAxis) {
|
|
340
389
|
return (
|
|
341
|
-
|
|
342
|
-
{
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
coordinate={coordinate}
|
|
347
|
-
config={label}
|
|
348
|
-
label={tick}
|
|
349
|
-
tickSize={_tickSize}
|
|
350
|
-
formatter={formatter}
|
|
351
|
-
rotate={rotate}
|
|
352
|
-
onClick={triggerClick}
|
|
353
|
-
/>
|
|
354
|
-
)}
|
|
355
|
-
{gridLine && (
|
|
356
|
-
<Line
|
|
357
|
-
className='__easyv-gridLine'
|
|
358
|
-
config={gridLine}
|
|
359
|
-
{...gridCoord}
|
|
360
|
-
/>
|
|
361
|
-
)}
|
|
362
|
-
</g>
|
|
390
|
+
<>
|
|
391
|
+
{ticks.map((ticks: any, index: number) => {
|
|
392
|
+
return draw(ticks, scaler[index]);
|
|
393
|
+
})}
|
|
394
|
+
</>
|
|
363
395
|
);
|
|
364
|
-
})
|
|
396
|
+
} else if (isControlChart && orientation == "bottom") {
|
|
397
|
+
return <>{draw(rawTicks, scaler)}</>;
|
|
398
|
+
} else {
|
|
399
|
+
return <>{draw(ticks, scaler)}</>;
|
|
400
|
+
}
|
|
365
401
|
}
|
|
366
|
-
if (isClipAxis) {
|
|
367
|
-
return (
|
|
368
|
-
<>
|
|
369
|
-
{ticks.map((ticks: any, index: number) => {
|
|
370
|
-
return draw(ticks, scaler[index]);
|
|
371
|
-
})}
|
|
372
|
-
</>
|
|
373
|
-
);
|
|
374
|
-
} else {
|
|
375
|
-
return <>{draw(ticks, scaler)}</>;
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
402
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
403
|
+
return (
|
|
404
|
+
<g>
|
|
405
|
+
{/* 绘制轴线和刻度 */}
|
|
406
|
+
{axisLine && tickLine && (
|
|
407
|
+
<g>
|
|
408
|
+
{axisLine &&
|
|
409
|
+
(positions && positions.length ? (
|
|
410
|
+
positions.map(({ x, y }: any, index: number) => (
|
|
411
|
+
<g
|
|
412
|
+
key={index}
|
|
413
|
+
transform={"translate(" + x + ", " + y + ")"}
|
|
414
|
+
>
|
|
415
|
+
<AxisLine
|
|
416
|
+
orientation={orientation}
|
|
417
|
+
config={axisLine}
|
|
418
|
+
range={range}
|
|
419
|
+
/>
|
|
420
|
+
{tickLine &&
|
|
421
|
+
ticks.map((tick: string, index: number) => {
|
|
422
|
+
const coordinate = scaler(tick);
|
|
423
|
+
if (isNaN(coordinate)) return null;
|
|
424
|
+
const _tickSize = tickLine.tickSize || tickSize;
|
|
425
|
+
const gridCoord = getGridCoord({
|
|
426
|
+
orientation,
|
|
427
|
+
coordinate,
|
|
428
|
+
end:
|
|
429
|
+
orientation == "left" || orientation == "right"
|
|
430
|
+
? width
|
|
431
|
+
: height,
|
|
432
|
+
});
|
|
433
|
+
const x1 = gridCoord.x1;
|
|
434
|
+
const y1 = gridCoord.y1;
|
|
435
|
+
return (
|
|
436
|
+
!(
|
|
437
|
+
(orientation == "bottom" &&
|
|
438
|
+
(x1 < 0 || x1 > xLineRange)) ||
|
|
439
|
+
y1 < 0 ||
|
|
440
|
+
y1 > yLineRange
|
|
441
|
+
) && (
|
|
442
|
+
<Line
|
|
443
|
+
className="__easyv-tickLine"
|
|
444
|
+
key={index}
|
|
445
|
+
config={tickLine}
|
|
446
|
+
{...getTickCoord({
|
|
447
|
+
orientation,
|
|
448
|
+
coordinate,
|
|
449
|
+
tickSize: _tickSize,
|
|
450
|
+
})}
|
|
451
|
+
/>
|
|
452
|
+
)
|
|
453
|
+
);
|
|
454
|
+
})}
|
|
455
|
+
</g>
|
|
456
|
+
))
|
|
457
|
+
) : (
|
|
458
|
+
<g transform={"translate(" + x + ", " + y + ")"}>
|
|
459
|
+
<AxisLine
|
|
460
|
+
orientation={orientation}
|
|
461
|
+
config={axisLine}
|
|
462
|
+
isClipAxis={isClipAxis}
|
|
463
|
+
clipAxisRange={clipAxisRange}
|
|
464
|
+
/>
|
|
465
|
+
{tickLine && drawAxisTickLine()}
|
|
425
466
|
</g>
|
|
426
|
-
))
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
{unit && <Unit config={unit} />}
|
|
467
|
+
))}
|
|
468
|
+
</g>
|
|
469
|
+
)}
|
|
470
|
+
{/* 绘制标签和网格线 */}
|
|
471
|
+
<svg
|
|
472
|
+
width={width}
|
|
473
|
+
style={{
|
|
474
|
+
overflow:
|
|
475
|
+
axisType !== "x" && isControlChart ? "visible" : "hidden",
|
|
476
|
+
}}
|
|
477
|
+
>
|
|
478
|
+
<g transform={"translate(" + x + ", " + y + ")"}>
|
|
479
|
+
{/* 用于控制图 */}
|
|
480
|
+
<g ref={ref as any}>
|
|
481
|
+
{label && gridLine && drawLabel()}
|
|
482
|
+
{unit && <Unit config={unit} />}
|
|
483
|
+
</g>
|
|
484
|
+
</g>
|
|
485
|
+
</svg>
|
|
446
486
|
</g>
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
487
|
+
);
|
|
488
|
+
}
|
|
489
|
+
)
|
|
450
490
|
);
|
package/src/components/Band.tsx
CHANGED
|
@@ -66,7 +66,15 @@ const getBorderRadius = ({
|
|
|
66
66
|
|
|
67
67
|
export default memo(
|
|
68
68
|
({
|
|
69
|
+
//控制图部分,主要是为了控制图的指示器,在悬浮的时候显示
|
|
69
70
|
triggerClick,
|
|
71
|
+
indicatorWidth,
|
|
72
|
+
setControlChartTooltipShow,
|
|
73
|
+
setControlChartTooltipX,
|
|
74
|
+
setControlChartTooltipXName,
|
|
75
|
+
isControlChart = false,
|
|
76
|
+
setControlChartIndicatorList,
|
|
77
|
+
|
|
70
78
|
config: {
|
|
71
79
|
pattern = {},
|
|
72
80
|
seriesIntervalWidth: paddingInner = 0,
|
|
@@ -84,6 +92,7 @@ export default memo(
|
|
|
84
92
|
bandLength = 0,
|
|
85
93
|
data,
|
|
86
94
|
xAxis: { scaler: xScaler, step, direction },
|
|
95
|
+
xAxis,
|
|
87
96
|
yAxis: { scaler: yScaler, isClipAxis, clipValue },
|
|
88
97
|
}: any) => {
|
|
89
98
|
if (!data.length) return null;
|
|
@@ -112,8 +121,7 @@ export default memo(
|
|
|
112
121
|
}: DataWithBoundType,
|
|
113
122
|
i: number
|
|
114
123
|
) => {
|
|
115
|
-
|
|
116
|
-
let y1:number, y2: number;
|
|
124
|
+
let y1: number, y2: number;
|
|
117
125
|
//断轴图相关,断轴图的scaler是一个数组,内含上断轴下断轴的scaler
|
|
118
126
|
if (isClipAxis) {
|
|
119
127
|
if (end > +clipValue) {
|
|
@@ -144,9 +152,9 @@ export default memo(
|
|
|
144
152
|
if (isClipAxis && end > +clipValue) {
|
|
145
153
|
let clipValueY2 = yScaler[0](clipValue); //上方
|
|
146
154
|
let clipValueY1 = yScaler[1](clipValue); //下方
|
|
147
|
-
let top = Math.abs((y2-clipValueY2)/(y1-y2))*100;
|
|
148
|
-
let bottom = Math.abs((y2-clipValueY1)/(y1-y2))*100;
|
|
149
|
-
|
|
155
|
+
let top = Math.abs((y2 - clipValueY2) / (y1 - y2)) * 100;
|
|
156
|
+
let bottom = Math.abs((y2 - clipValueY1) / (y1 - y2)) * 100;
|
|
157
|
+
|
|
150
158
|
//clip path属性
|
|
151
159
|
return `polygon(0% 0%, 0% 100%, 0 100%, 0 ${top}%, 100% ${top}%, 100% ${bottom}%, 0 ${bottom}%, 0 100%, 100% 100%, 100% 0%)`;
|
|
152
160
|
} else {
|
|
@@ -172,6 +180,33 @@ export default memo(
|
|
|
172
180
|
}}
|
|
173
181
|
{...attr}
|
|
174
182
|
onClick={triggerClick}
|
|
183
|
+
//enter和leave事件,用于控制图的提示框
|
|
184
|
+
onMouseEnter={() => {
|
|
185
|
+
if (isControlChart) {
|
|
186
|
+
setControlChartIndicatorList((v: any) => {
|
|
187
|
+
return v.map((item: any) => {
|
|
188
|
+
if (item.tick === data.x) {
|
|
189
|
+
return { ...item, isShow: true };
|
|
190
|
+
} else {
|
|
191
|
+
return item;
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
setControlChartTooltipShow(true);
|
|
196
|
+
setControlChartTooltipX(xScaler(x) - indicatorWidth / 2);
|
|
197
|
+
setControlChartTooltipXName(data.x);
|
|
198
|
+
}
|
|
199
|
+
}}
|
|
200
|
+
onMouseLeave={() => {
|
|
201
|
+
if (isControlChart) {
|
|
202
|
+
setControlChartIndicatorList((v: any) =>
|
|
203
|
+
v.map((item: any) => ({ ...item, isShow: false }))
|
|
204
|
+
);
|
|
205
|
+
setControlChartTooltipShow(false);
|
|
206
|
+
setControlChartTooltipXName(undefined);
|
|
207
|
+
setControlChartTooltipX(undefined);
|
|
208
|
+
}
|
|
209
|
+
}}
|
|
175
210
|
data-data={JSON.stringify(data)}
|
|
176
211
|
>
|
|
177
212
|
{headUrl && showHead && (
|