@easyv/charts 1.5.29 → 1.5.30
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/.babelrc +8 -8
- package/.husky/commit-msg +3 -3
- package/CHANGELOG.md +18 -18
- package/commitlint.config.js +1 -1
- package/lib/components/Background.js +2 -2
- package/lib/components/ConicalGradient.js +21 -21
- package/lib/components/Lighter.js +2 -2
- package/lib/components/LinearGradient.js +2 -2
- package/lib/css/index.module.css +42 -42
- package/lib/css/piechart.module.css +26 -26
- package/lib/hooks/useAnimateData.js +6 -6
- package/lib/hooks/useAxes.js +29 -6
- package/lib/hooks/useExtentData.js +19 -4
- package/lib/hooks/useFilterData.js +5 -5
- package/lib/hooks/useStackData.js +5 -5
- package/lib/hooks/useTooltip.js +11 -11
- package/package.json +55 -55
- package/src/components/Background.tsx +61 -61
- package/src/components/Band.tsx +271 -271
- package/src/components/Brush.js +159 -159
- package/src/components/Chart.js +135 -135
- package/src/components/ChartContainer.tsx +71 -71
- package/src/components/ConicalGradient.js +258 -258
- package/src/components/Control.jsx +236 -236
- package/src/components/ExtentData.js +18 -18
- package/src/components/Indicator.js +58 -58
- package/src/components/Label.js +242 -242
- package/src/components/Legend.js +166 -166
- package/src/components/Lighter.jsx +173 -173
- package/src/components/Line.js +153 -153
- package/src/components/LinearGradient.js +29 -29
- package/src/components/PieTooltip.jsx +160 -160
- package/src/components/StereoBar.tsx +307 -307
- package/src/components/index.js +59 -59
- package/src/context/index.js +2 -2
- package/src/css/index.module.css +42 -42
- package/src/css/piechart.module.css +26 -26
- package/src/element/ConicGradient.jsx +55 -55
- package/src/element/Line.tsx +33 -33
- package/src/element/index.ts +3 -3
- package/src/formatter/index.js +1 -1
- package/src/formatter/legend.js +92 -92
- package/src/hooks/index.js +20 -20
- package/src/hooks/useAnimateData.ts +68 -68
- package/src/hooks/useAxes.js +86 -32
- package/src/hooks/useExtentData.js +52 -16
- package/src/hooks/useFilterData.js +78 -78
- package/src/hooks/useStackData.js +102 -102
- package/src/hooks/useTooltip.ts +104 -104
- package/src/index.js +6 -6
- package/src/types/index.d.ts +68 -68
- package/src/utils/index.js +762 -762
- package/tsconfig.json +23 -23
package/src/hooks/index.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import useFilterData from './useFilterData';
|
|
2
|
-
import useStackData from './useStackData';
|
|
3
|
-
import useAxes from './useAxes';
|
|
4
|
-
import useTooltip from './useTooltip';
|
|
5
|
-
import useAnimateData from './useAnimateData';
|
|
6
|
-
import useCarouselAxisX from './useCarouselAxisX';
|
|
7
|
-
import useExtentData from './useExtentData';
|
|
8
|
-
import { useAiData, useAiDataOfPie } from './useAiData';
|
|
9
|
-
|
|
10
|
-
export {
|
|
11
|
-
useFilterData,
|
|
12
|
-
useStackData,
|
|
13
|
-
useAxes,
|
|
14
|
-
useTooltip,
|
|
15
|
-
useAnimateData,
|
|
16
|
-
useCarouselAxisX,
|
|
17
|
-
useExtentData,
|
|
18
|
-
useAiData,
|
|
19
|
-
useAiDataOfPie
|
|
20
|
-
};
|
|
1
|
+
import useFilterData from './useFilterData';
|
|
2
|
+
import useStackData from './useStackData';
|
|
3
|
+
import useAxes from './useAxes';
|
|
4
|
+
import useTooltip from './useTooltip';
|
|
5
|
+
import useAnimateData from './useAnimateData';
|
|
6
|
+
import useCarouselAxisX from './useCarouselAxisX';
|
|
7
|
+
import useExtentData from './useExtentData';
|
|
8
|
+
import { useAiData, useAiDataOfPie } from './useAiData';
|
|
9
|
+
|
|
10
|
+
export {
|
|
11
|
+
useFilterData,
|
|
12
|
+
useStackData,
|
|
13
|
+
useAxes,
|
|
14
|
+
useTooltip,
|
|
15
|
+
useAnimateData,
|
|
16
|
+
useCarouselAxisX,
|
|
17
|
+
useExtentData,
|
|
18
|
+
useAiData,
|
|
19
|
+
useAiDataOfPie
|
|
20
|
+
};
|
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
import { useEffect, useState } from 'react';
|
|
2
|
-
import { animate, easeIn, easeOut, linear } from 'popmotion';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* 图表数据动画
|
|
6
|
-
* @param {Array} data data列表
|
|
7
|
-
* @param {boolean} dataAnimation 是否开启数据增长动画
|
|
8
|
-
* @param {boolean} active 是否处于活跃状态,false为休眠
|
|
9
|
-
* @returns 改变后的数据
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
export default (data: DataType[], dataAnimation: DataAnimation, active:boolean) => {
|
|
13
|
-
const [animateData, setAnimateData] = useState<DataType[]>([]);
|
|
14
|
-
useEffect(() => {
|
|
15
|
-
let animateRef: any = null;
|
|
16
|
-
if (
|
|
17
|
-
dataAnimation &&
|
|
18
|
-
dataAnimation.show &&
|
|
19
|
-
dataAnimation.duration &&
|
|
20
|
-
data.length &&
|
|
21
|
-
active
|
|
22
|
-
) {
|
|
23
|
-
animateRef = animate({
|
|
24
|
-
autoplay: true,
|
|
25
|
-
repeat: 0,
|
|
26
|
-
from: 0,
|
|
27
|
-
to: 1,
|
|
28
|
-
duration: dataAnimation.duration * 1000,
|
|
29
|
-
ease: linear,
|
|
30
|
-
onUpdate: (v: number) => {
|
|
31
|
-
setAnimateData((oldData: DataType[]) => {
|
|
32
|
-
const oldLength = oldData.length;
|
|
33
|
-
const newLength = data.length;
|
|
34
|
-
if (oldLength >= newLength) {
|
|
35
|
-
return oldData.map(({ y }: DataType, i: number) => {
|
|
36
|
-
const current: DataType = data[i] || { y: 0 };
|
|
37
|
-
const delta: number = current.y - y;
|
|
38
|
-
return {
|
|
39
|
-
...current,
|
|
40
|
-
y: y + delta * v,
|
|
41
|
-
};
|
|
42
|
-
});
|
|
43
|
-
} else {
|
|
44
|
-
return data.map((current: DataType, i: number) => {
|
|
45
|
-
const oldCurrent: DataType = oldData[i] || { y: 0 };
|
|
46
|
-
const delta = oldCurrent.y - current.y;
|
|
47
|
-
return {
|
|
48
|
-
...current,
|
|
49
|
-
y:oldCurrent.y + delta * v,
|
|
50
|
-
};
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
},
|
|
55
|
-
onComplete: () => {
|
|
56
|
-
setAnimateData(data);
|
|
57
|
-
},
|
|
58
|
-
});
|
|
59
|
-
} else {
|
|
60
|
-
setAnimateData(data);
|
|
61
|
-
}
|
|
62
|
-
return () => {
|
|
63
|
-
animateRef && animateRef.stop();
|
|
64
|
-
};
|
|
65
|
-
}, [data, dataAnimation, active]);
|
|
66
|
-
|
|
67
|
-
return animateData;
|
|
68
|
-
};
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
import { animate, easeIn, easeOut, linear } from 'popmotion';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 图表数据动画
|
|
6
|
+
* @param {Array} data data列表
|
|
7
|
+
* @param {boolean} dataAnimation 是否开启数据增长动画
|
|
8
|
+
* @param {boolean} active 是否处于活跃状态,false为休眠
|
|
9
|
+
* @returns 改变后的数据
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export default (data: DataType[], dataAnimation: DataAnimation, active:boolean) => {
|
|
13
|
+
const [animateData, setAnimateData] = useState<DataType[]>([]);
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
let animateRef: any = null;
|
|
16
|
+
if (
|
|
17
|
+
dataAnimation &&
|
|
18
|
+
dataAnimation.show &&
|
|
19
|
+
dataAnimation.duration &&
|
|
20
|
+
data.length &&
|
|
21
|
+
active
|
|
22
|
+
) {
|
|
23
|
+
animateRef = animate({
|
|
24
|
+
autoplay: true,
|
|
25
|
+
repeat: 0,
|
|
26
|
+
from: 0,
|
|
27
|
+
to: 1,
|
|
28
|
+
duration: dataAnimation.duration * 1000,
|
|
29
|
+
ease: linear,
|
|
30
|
+
onUpdate: (v: number) => {
|
|
31
|
+
setAnimateData((oldData: DataType[]) => {
|
|
32
|
+
const oldLength = oldData.length;
|
|
33
|
+
const newLength = data.length;
|
|
34
|
+
if (oldLength >= newLength) {
|
|
35
|
+
return oldData.map(({ y }: DataType, i: number) => {
|
|
36
|
+
const current: DataType = data[i] || { y: 0 };
|
|
37
|
+
const delta: number = current.y - y;
|
|
38
|
+
return {
|
|
39
|
+
...current,
|
|
40
|
+
y: y + delta * v,
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
} else {
|
|
44
|
+
return data.map((current: DataType, i: number) => {
|
|
45
|
+
const oldCurrent: DataType = oldData[i] || { y: 0 };
|
|
46
|
+
const delta = oldCurrent.y - current.y;
|
|
47
|
+
return {
|
|
48
|
+
...current,
|
|
49
|
+
y:oldCurrent.y + delta * v,
|
|
50
|
+
};
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
},
|
|
55
|
+
onComplete: () => {
|
|
56
|
+
setAnimateData(data);
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
} else {
|
|
60
|
+
setAnimateData(data);
|
|
61
|
+
}
|
|
62
|
+
return () => {
|
|
63
|
+
animateRef && animateRef.stop();
|
|
64
|
+
};
|
|
65
|
+
}, [data, dataAnimation, active]);
|
|
66
|
+
|
|
67
|
+
return animateData;
|
|
68
|
+
};
|
package/src/hooks/useAxes.js
CHANGED
|
@@ -14,26 +14,49 @@ const getCount = (num) => {
|
|
|
14
14
|
return i;
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
const getNewDomain = (
|
|
18
|
-
|
|
17
|
+
const getNewDomain = (
|
|
18
|
+
domain,
|
|
19
|
+
mode,
|
|
20
|
+
step,
|
|
21
|
+
extent = {},
|
|
22
|
+
numericalRangeModel = "value",
|
|
23
|
+
percentageExtent = { max: 100, min: 100 }
|
|
24
|
+
) => {
|
|
25
|
+
let { min: defaultBottom = "", max: defaultTop = "" } = extent;
|
|
26
|
+
const { min: defaultPercentageMin = 100, max: defaultPercentageMax = 100 } =
|
|
27
|
+
percentageExtent;
|
|
28
|
+
let bottom = defaultBottom,
|
|
29
|
+
top = defaultTop;
|
|
30
|
+
|
|
19
31
|
let newDomain = [];
|
|
20
32
|
//能进入这个函数,说明extent中min和max至少有一个是缺失的,如果max存在,意味着纵轴上限被固定
|
|
21
33
|
let min = domain[0],
|
|
22
34
|
max = domain[1];
|
|
23
35
|
let minCount = Math.pow(10, getCount(min)),
|
|
24
36
|
maxCount = Math.pow(10, getCount(max));
|
|
37
|
+
|
|
38
|
+
//轴标签,范围模式,百分比模式
|
|
39
|
+
if (numericalRangeModel == "percentage") {
|
|
40
|
+
let _max = defaultPercentageMax === "" ? 100 : defaultPercentageMax;
|
|
41
|
+
let _min = defaultPercentageMin === "" ? 100 : defaultPercentageMin;
|
|
42
|
+
bottom = (min * _min) / 100;
|
|
43
|
+
top = (max * _max) / 100;
|
|
44
|
+
}
|
|
45
|
+
|
|
25
46
|
switch (mode) {
|
|
26
47
|
case "count":
|
|
27
|
-
newDomain[0] =
|
|
28
|
-
|
|
48
|
+
newDomain[0] =
|
|
49
|
+
bottom != "" ? bottom : Math.floor(domain[0] / minCount) * minCount;
|
|
50
|
+
newDomain[1] =
|
|
51
|
+
top != "" ? top : Math.ceil(domain[1] / maxCount) * maxCount;
|
|
29
52
|
break;
|
|
30
53
|
case "step":
|
|
31
|
-
if(
|
|
54
|
+
if (defaultTop != "") {
|
|
32
55
|
newDomain = [domain[1], domain[1]];
|
|
33
56
|
while (newDomain[0] > domain[0]) {
|
|
34
57
|
newDomain[0] -= step;
|
|
35
58
|
}
|
|
36
|
-
}else{
|
|
59
|
+
} else {
|
|
37
60
|
newDomain = [domain[0], domain[0]];
|
|
38
61
|
while (newDomain[1] < domain[1]) {
|
|
39
62
|
newDomain[1] += step;
|
|
@@ -70,19 +93,26 @@ const scales = {
|
|
|
70
93
|
|
|
71
94
|
export default ({
|
|
72
95
|
axes,
|
|
73
|
-
context: { width:chartWidth, height:chartHeight },
|
|
74
|
-
controlInfo,
|
|
96
|
+
context: { width: chartWidth, height: chartHeight },
|
|
97
|
+
controlInfo, //是否为控制图
|
|
75
98
|
}) => {
|
|
76
99
|
const { isC, cHeight, cWidth, cPercent } = controlInfo;
|
|
77
100
|
const width = chartWidth;
|
|
78
101
|
const height = chartHeight - cHeight;
|
|
102
|
+
|
|
79
103
|
const _axes = useMemo(() => {
|
|
80
104
|
const tmp = new Map();
|
|
81
105
|
const xAxisPositions = [];
|
|
82
106
|
axes.forEach((item) => {
|
|
83
107
|
const {
|
|
84
108
|
config: {
|
|
85
|
-
label: {
|
|
109
|
+
label: {
|
|
110
|
+
extent,
|
|
111
|
+
percentageExtent,
|
|
112
|
+
numericalRangeModel = "value",
|
|
113
|
+
showLast = false,
|
|
114
|
+
decimal = 0,
|
|
115
|
+
},
|
|
86
116
|
},
|
|
87
117
|
type,
|
|
88
118
|
orientation,
|
|
@@ -104,7 +134,7 @@ export default ({
|
|
|
104
134
|
bottomClipAxisStep,
|
|
105
135
|
topClipAxisStep,
|
|
106
136
|
clipValue,
|
|
107
|
-
clipPosition
|
|
137
|
+
clipPosition,
|
|
108
138
|
} = item;
|
|
109
139
|
//如果是断轴类型,输出一套完全不同的values
|
|
110
140
|
/**
|
|
@@ -146,7 +176,7 @@ export default ({
|
|
|
146
176
|
* @param {*} scales
|
|
147
177
|
* @param {*} type 轴类型
|
|
148
178
|
* @param {*} domain 数据的范围
|
|
149
|
-
* @param {*}
|
|
179
|
+
* @param {*} 屏幕坐标的范围
|
|
150
180
|
* @returns
|
|
151
181
|
*/
|
|
152
182
|
function setScaler(scales, type, domain, range) {
|
|
@@ -209,7 +239,10 @@ export default ({
|
|
|
209
239
|
break;
|
|
210
240
|
case "step":
|
|
211
241
|
let newStep = +step;
|
|
212
|
-
newStep =
|
|
242
|
+
newStep =
|
|
243
|
+
(newDomain[1] - newDomain[0]) / newStep > 30
|
|
244
|
+
? Math.ceil((newDomain[1] - newDomain[0]) / 30)
|
|
245
|
+
: newStep;
|
|
213
246
|
_ticks = getYTicksByStep(newDomain[1], newDomain[0], newStep);
|
|
214
247
|
break;
|
|
215
248
|
}
|
|
@@ -333,32 +366,41 @@ export default ({
|
|
|
333
366
|
});
|
|
334
367
|
} else {
|
|
335
368
|
//计算真正需要的tickCount,如果domain区间太小,不能完全按照count来,需要减少count数
|
|
336
|
-
const tickCount =
|
|
337
|
-
|
|
369
|
+
const tickCount =
|
|
370
|
+
type == "ordinal" ? _count : getTickCount(domain, _count, decimal);
|
|
371
|
+
const { start, end, direction, _paddingOuter, length } =
|
|
372
|
+
getChartsConfig(orientation, width, height, paddingOuter);
|
|
338
373
|
let range =
|
|
339
374
|
direction === "horizontal"
|
|
340
375
|
? [start, end]
|
|
341
376
|
: direction === "vertical"
|
|
342
377
|
? [end, start]
|
|
343
378
|
: [0, 0];
|
|
344
|
-
if(reverse)range = [range[1],range[0]];
|
|
379
|
+
if (reverse) range = [range[1], range[0]];
|
|
345
380
|
let newDomain = domain;
|
|
346
|
-
const fixedDomain = extent && extent.min!="" && extent.max!="";
|
|
381
|
+
const fixedDomain = extent && extent.min != "" && extent.max != ""; //判断配置项中是否强制了最大最小值,如果已经被强制了,就不计算newDomain
|
|
347
382
|
if (type !== "ordinal" && !isNaN(domain[1]) && !auto && !fixedDomain) {
|
|
348
|
-
newDomain = getNewDomain(
|
|
383
|
+
newDomain = getNewDomain(
|
|
384
|
+
domain,
|
|
385
|
+
mode,
|
|
386
|
+
_step,
|
|
387
|
+
extent,
|
|
388
|
+
numericalRangeModel,
|
|
389
|
+
percentageExtent
|
|
390
|
+
);
|
|
349
391
|
}
|
|
350
392
|
let scaler = scales[type]().domain(newDomain).range(range);
|
|
351
393
|
|
|
352
394
|
scaler.type = type;
|
|
353
395
|
if (type !== "ordinal") scaler.clamp(true);
|
|
354
|
-
|
|
396
|
+
|
|
355
397
|
const allTicks = ticks
|
|
356
398
|
? ticks
|
|
357
399
|
: scaler.ticks
|
|
358
400
|
? scaler.ticks(tickCount)
|
|
359
401
|
: scaler.domain();
|
|
360
402
|
let _ticks = allTicks;
|
|
361
|
-
|
|
403
|
+
|
|
362
404
|
if (type === "ordinal") {
|
|
363
405
|
if (carousel === false || isC) {
|
|
364
406
|
_ticks = getTicksOfAxis(_ticks, +tickCount, showLast);
|
|
@@ -371,7 +413,10 @@ export default ({
|
|
|
371
413
|
break;
|
|
372
414
|
case "step":
|
|
373
415
|
let newStep = +_step;
|
|
374
|
-
newStep =
|
|
416
|
+
newStep =
|
|
417
|
+
(newDomain[1] - newDomain[0]) / newStep > 30
|
|
418
|
+
? Math.ceil((newDomain[1] - newDomain[0]) / 30)
|
|
419
|
+
: newStep;
|
|
375
420
|
_ticks = getYTicksByStep(newDomain[1], newDomain[0], newStep);
|
|
376
421
|
break;
|
|
377
422
|
}
|
|
@@ -396,22 +441,31 @@ export default ({
|
|
|
396
441
|
}
|
|
397
442
|
let step = lengthWithoutPaddingOuter / allTicks.length;
|
|
398
443
|
const controlCfg = {
|
|
399
|
-
controlStep:0,
|
|
400
|
-
controlDragScaler:null
|
|
401
|
-
}
|
|
402
|
-
if(isC){
|
|
444
|
+
controlStep: 0,
|
|
445
|
+
controlDragScaler: null,
|
|
446
|
+
};
|
|
447
|
+
if (isC) {
|
|
403
448
|
controlCfg.controlStep = step / cPercent;
|
|
404
|
-
controlCfg.controlDragScaler = scaler
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
:
|
|
409
|
-
|
|
410
|
-
:
|
|
449
|
+
controlCfg.controlDragScaler = scaler
|
|
450
|
+
.copy()
|
|
451
|
+
.range([start / cPercent, end / cPercent]);
|
|
452
|
+
const {
|
|
453
|
+
start: start_,
|
|
454
|
+
end: end_,
|
|
455
|
+
direction: direction_,
|
|
456
|
+
_paddingOuter: outer,
|
|
457
|
+
length: len,
|
|
458
|
+
} = getChartsConfig(orientation, cWidth, height, paddingOuter);
|
|
459
|
+
let range =
|
|
460
|
+
direction_ === "horizontal"
|
|
461
|
+
? [start_, end_]
|
|
462
|
+
: direction_ === "vertical"
|
|
463
|
+
? [end_, start_]
|
|
464
|
+
: [0, 0];
|
|
411
465
|
scaler = scales[type]().domain(newDomain).range(range);
|
|
412
466
|
scaler.type = type;
|
|
413
467
|
const controlOuter = len - outer;
|
|
414
|
-
step = controlOuter/allTicks.length;
|
|
468
|
+
step = controlOuter / allTicks.length;
|
|
415
469
|
}
|
|
416
470
|
tmp.set(axisType, {
|
|
417
471
|
...item,
|
|
@@ -10,13 +10,17 @@ import {
|
|
|
10
10
|
|
|
11
11
|
//扩张系数,用于扩大数据的最大最小值范围,达到图表尽量居中显示的效果
|
|
12
12
|
const extentRatio = 0;
|
|
13
|
-
const extentRange = (value, type)=>{
|
|
14
|
-
if(value>=0){
|
|
15
|
-
return type=="min"
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
const extentRange = (value, type) => {
|
|
14
|
+
if (value >= 0) {
|
|
15
|
+
return type == "min"
|
|
16
|
+
? value * (1 - extentRatio)
|
|
17
|
+
: value * (1 + extentRatio);
|
|
18
|
+
} else {
|
|
19
|
+
return type == "min"
|
|
20
|
+
? value * (1 + extentRatio)
|
|
21
|
+
: value * (1 - extentRatio);
|
|
18
22
|
}
|
|
19
|
-
}
|
|
23
|
+
};
|
|
20
24
|
const stackData = (data, series) => {
|
|
21
25
|
const dataMap = group(data, (d) => d.x);
|
|
22
26
|
const stacks = getStacks(series);
|
|
@@ -48,7 +52,10 @@ const stackData = (data, series) => {
|
|
|
48
52
|
max = Math.max(...arr, max);
|
|
49
53
|
});
|
|
50
54
|
dataMap.clear();
|
|
51
|
-
return [
|
|
55
|
+
return [
|
|
56
|
+
extentRange(min || 0, "min"),
|
|
57
|
+
extentRange(max == undefined ? (min || 0) + 100 : max, "max"),
|
|
58
|
+
];
|
|
52
59
|
};
|
|
53
60
|
|
|
54
61
|
/**
|
|
@@ -68,20 +75,35 @@ export default ({ axes, series, data }) => {
|
|
|
68
75
|
const x = useMemo(() => [...group(data, (d) => d.x).keys()], [data]);
|
|
69
76
|
const y = stackData(dataY, _series.y);
|
|
70
77
|
const z = stackData(dataZ, _series.z);
|
|
71
|
-
const xAxis = axes.find(d=>d.axisType=="x");
|
|
72
|
-
if(xAxis){
|
|
73
|
-
const {
|
|
74
|
-
|
|
75
|
-
|
|
78
|
+
const xAxis = axes.find((d) => d.axisType == "x");
|
|
79
|
+
if (xAxis) {
|
|
80
|
+
const {
|
|
81
|
+
config: {
|
|
82
|
+
label: {
|
|
83
|
+
autoSort,
|
|
84
|
+
format: { type },
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
} = xAxis;
|
|
88
|
+
if (type == "date" && autoSort) {
|
|
89
|
+
x.sort((a, b) => (a > b ? 1 : -1));
|
|
76
90
|
// const groupBySeries = group(data, (d) => d.s);
|
|
77
91
|
// data=[...groupBySeries].flatMap(d=>{
|
|
78
92
|
// return d[1].sort((a,b)=>a.x>b.x?1:-1)
|
|
79
93
|
// });
|
|
80
94
|
}
|
|
81
95
|
}
|
|
96
|
+
// console.log("nononon", axes);
|
|
82
97
|
//clipAxisMode如果是auto根据clipDifferenceValue设置clipValue
|
|
83
98
|
return axes.map((item) => {
|
|
84
|
-
const {
|
|
99
|
+
const {
|
|
100
|
+
axisType,
|
|
101
|
+
domain,
|
|
102
|
+
type,
|
|
103
|
+
config: {
|
|
104
|
+
label: { percentageExtent, numericalRangeModel },
|
|
105
|
+
},
|
|
106
|
+
} = item;
|
|
85
107
|
switch (axisType) {
|
|
86
108
|
case "x":
|
|
87
109
|
return {
|
|
@@ -116,19 +138,33 @@ export default ({ axes, series, data }) => {
|
|
|
116
138
|
}
|
|
117
139
|
return {
|
|
118
140
|
...item,
|
|
119
|
-
domain: domain
|
|
141
|
+
domain: domain
|
|
142
|
+
? getDomain(y, domain, numericalRangeModel, percentageExtent)
|
|
143
|
+
: y,
|
|
120
144
|
};
|
|
121
145
|
}
|
|
122
146
|
|
|
123
147
|
case "z":
|
|
124
148
|
return {
|
|
125
149
|
...item,
|
|
126
|
-
domain: domain
|
|
150
|
+
domain: domain
|
|
151
|
+
? getDomain(z, domain, numericalRangeModel, percentageExtent)
|
|
152
|
+
: z,
|
|
127
153
|
};
|
|
128
154
|
}
|
|
129
155
|
});
|
|
130
156
|
};
|
|
131
157
|
|
|
132
|
-
const getDomain = (
|
|
158
|
+
const getDomain = (
|
|
159
|
+
[min1, max1],
|
|
160
|
+
{ min, max },
|
|
161
|
+
numericalRangeModel = "value",
|
|
162
|
+
percentageExtent
|
|
163
|
+
) => {
|
|
164
|
+
if (numericalRangeModel == "percentage" && percentageExtent) {
|
|
165
|
+
const _min = percentageExtent.min == "" ? 100 : +percentageExtent.min;
|
|
166
|
+
const _max = percentageExtent.max == "" ? 100 : +percentageExtent.max;
|
|
167
|
+
return [(min1 * _min) / 100, (max1 * _max) / 100];
|
|
168
|
+
}
|
|
133
169
|
return [min !== "" ? +min : min1, max !== "" ? +max : max1];
|
|
134
170
|
};
|
|
@@ -1,78 +1,78 @@
|
|
|
1
|
-
import { useState, useCallback, useEffect, useMemo } from 'react';
|
|
2
|
-
|
|
3
|
-
const getInitialSelected = (series) => {
|
|
4
|
-
const status = new Map();
|
|
5
|
-
for (let [name] of series.entries()) {
|
|
6
|
-
status.set(name, true);
|
|
7
|
-
}
|
|
8
|
-
return status;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
const getSelected = (selected, name) => {
|
|
12
|
-
const tmp = new Map();
|
|
13
|
-
selected.forEach((value, key) => {
|
|
14
|
-
if (name == key) {
|
|
15
|
-
tmp.set(key, !value);
|
|
16
|
-
} else {
|
|
17
|
-
tmp.set(key, value);
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
return tmp;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* 图例点击状态管理
|
|
25
|
-
* @param {Array} data 数据
|
|
26
|
-
* @param {Map} series 系列
|
|
27
|
-
* @returns {Array} 返回筛选后的数据和是否选中状态,及控制选中函数
|
|
28
|
-
*/
|
|
29
|
-
|
|
30
|
-
export default ({ data, series }) => {
|
|
31
|
-
const [selected, setSelected] = useState(getInitialSelected(series));
|
|
32
|
-
|
|
33
|
-
const _series = useMemo(() => {
|
|
34
|
-
const tmp = new Map();
|
|
35
|
-
series.forEach((currentSeries, key) => {
|
|
36
|
-
const value = selected.get(key);
|
|
37
|
-
tmp.set(key, {
|
|
38
|
-
...currentSeries,
|
|
39
|
-
selected: value,
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
return tmp;
|
|
43
|
-
}, [selected, series]);
|
|
44
|
-
|
|
45
|
-
const _data = useMemo(() => {
|
|
46
|
-
return data.filter(({ s }) => {
|
|
47
|
-
return s && _series.get(s) && _series.get(s).selected;
|
|
48
|
-
});
|
|
49
|
-
}, [data, _series]);
|
|
50
|
-
|
|
51
|
-
const onClick = useCallback((name) => {
|
|
52
|
-
setSelected((selected) => getSelected(selected, name));
|
|
53
|
-
}, []);
|
|
54
|
-
|
|
55
|
-
useEffect(() => {
|
|
56
|
-
const map = getInitialSelected(series);
|
|
57
|
-
for(let [ key ] of map.entries()){
|
|
58
|
-
if(selected.has(key)){
|
|
59
|
-
map.set(key, selected.get(key));
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
setSelected(map);
|
|
63
|
-
}, [series]);
|
|
64
|
-
|
|
65
|
-
return [
|
|
66
|
-
{
|
|
67
|
-
series: _series,
|
|
68
|
-
data: _data.map(d=>{
|
|
69
|
-
return {
|
|
70
|
-
...d,
|
|
71
|
-
y:parseFloat(d.y),
|
|
72
|
-
showY:d.y
|
|
73
|
-
}
|
|
74
|
-
}),
|
|
75
|
-
},
|
|
76
|
-
onClick,
|
|
77
|
-
];
|
|
78
|
-
};
|
|
1
|
+
import { useState, useCallback, useEffect, useMemo } from 'react';
|
|
2
|
+
|
|
3
|
+
const getInitialSelected = (series) => {
|
|
4
|
+
const status = new Map();
|
|
5
|
+
for (let [name] of series.entries()) {
|
|
6
|
+
status.set(name, true);
|
|
7
|
+
}
|
|
8
|
+
return status;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const getSelected = (selected, name) => {
|
|
12
|
+
const tmp = new Map();
|
|
13
|
+
selected.forEach((value, key) => {
|
|
14
|
+
if (name == key) {
|
|
15
|
+
tmp.set(key, !value);
|
|
16
|
+
} else {
|
|
17
|
+
tmp.set(key, value);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
return tmp;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* 图例点击状态管理
|
|
25
|
+
* @param {Array} data 数据
|
|
26
|
+
* @param {Map} series 系列
|
|
27
|
+
* @returns {Array} 返回筛选后的数据和是否选中状态,及控制选中函数
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
export default ({ data, series }) => {
|
|
31
|
+
const [selected, setSelected] = useState(getInitialSelected(series));
|
|
32
|
+
|
|
33
|
+
const _series = useMemo(() => {
|
|
34
|
+
const tmp = new Map();
|
|
35
|
+
series.forEach((currentSeries, key) => {
|
|
36
|
+
const value = selected.get(key);
|
|
37
|
+
tmp.set(key, {
|
|
38
|
+
...currentSeries,
|
|
39
|
+
selected: value,
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
return tmp;
|
|
43
|
+
}, [selected, series]);
|
|
44
|
+
|
|
45
|
+
const _data = useMemo(() => {
|
|
46
|
+
return data.filter(({ s }) => {
|
|
47
|
+
return s && _series.get(s) && _series.get(s).selected;
|
|
48
|
+
});
|
|
49
|
+
}, [data, _series]);
|
|
50
|
+
|
|
51
|
+
const onClick = useCallback((name) => {
|
|
52
|
+
setSelected((selected) => getSelected(selected, name));
|
|
53
|
+
}, []);
|
|
54
|
+
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
const map = getInitialSelected(series);
|
|
57
|
+
for(let [ key ] of map.entries()){
|
|
58
|
+
if(selected.has(key)){
|
|
59
|
+
map.set(key, selected.get(key));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
setSelected(map);
|
|
63
|
+
}, [series]);
|
|
64
|
+
|
|
65
|
+
return [
|
|
66
|
+
{
|
|
67
|
+
series: _series,
|
|
68
|
+
data: _data.map(d=>{
|
|
69
|
+
return {
|
|
70
|
+
...d,
|
|
71
|
+
y:parseFloat(d.y),
|
|
72
|
+
showY:d.y
|
|
73
|
+
}
|
|
74
|
+
}),
|
|
75
|
+
},
|
|
76
|
+
onClick,
|
|
77
|
+
];
|
|
78
|
+
};
|