@easyv/charts 1.4.21 → 1.4.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/.babelrc +8 -8
- package/.husky/commit-msg +3 -3
- package/CHANGELOG.md +18 -18
- package/commitlint.config.js +1 -1
- package/lib/components/AnimateData.js +8 -16
- package/lib/components/Axis.js +106 -138
- package/lib/components/Background.js +18 -26
- package/lib/components/Band.js +105 -91
- package/lib/components/BaseLine.js +33 -46
- package/lib/components/Brush.js +29 -46
- package/lib/components/Carousel.js +13 -40
- package/lib/components/CartesianChart.js +292 -113
- package/lib/components/Chart.js +23 -36
- package/lib/components/ChartContainer.js +21 -29
- package/lib/components/ConicalGradient.js +56 -89
- package/lib/components/Control.js +65 -0
- package/lib/components/ExtentData.js +9 -17
- package/lib/components/FilterData.js +16 -27
- package/lib/components/Indicator.js +66 -12
- package/lib/components/Label.js +128 -118
- package/lib/components/Legend.js +41 -66
- package/lib/components/Lighter.js +21 -50
- package/lib/components/Line.js +39 -59
- package/lib/components/LinearGradient.js +16 -22
- package/lib/components/Mapping.js +9 -34
- package/lib/components/Marquee.js +14 -30
- package/lib/components/PieChart.js +312 -406
- package/lib/components/StackData.js +8 -18
- package/lib/components/StereoBar.js +65 -105
- package/lib/components/TextOverflow.js +8 -21
- package/lib/components/Tooltip.js +41 -55
- package/lib/components/index.js +7 -27
- package/lib/context/index.js +0 -2
- package/lib/css/index.module.css +42 -42
- package/lib/css/piechart.module.css +26 -26
- package/lib/element/ConicGradient.js +29 -35
- package/lib/element/Line.js +9 -13
- package/lib/element/index.js +0 -2
- package/lib/formatter/index.js +0 -2
- package/lib/formatter/legend.js +30 -41
- package/lib/hooks/index.js +0 -9
- package/lib/hooks/useAiData.js +12 -20
- package/lib/hooks/useAnimateData.js +8 -21
- package/lib/hooks/useAxes.js +69 -115
- package/lib/hooks/useCarouselAxisX.js +47 -68
- package/lib/hooks/useExtentData.js +14 -46
- package/lib/hooks/useFilterData.js +13 -34
- package/lib/hooks/useStackData.js +12 -35
- package/lib/hooks/useTooltip.js +37 -54
- package/lib/index.js +0 -15
- package/lib/utils/index.js +95 -247
- package/package.json +55 -55
- package/src/components/Axis.tsx +223 -183
- package/src/components/Background.tsx +61 -61
- package/src/components/Band.tsx +274 -239
- package/src/components/Brush.js +159 -159
- package/src/components/CartesianChart.js +320 -44
- package/src/components/Chart.js +99 -99
- package/src/components/ChartContainer.tsx +71 -64
- package/src/components/ConicalGradient.js +258 -258
- package/src/components/Control.jsx +51 -0
- package/src/components/ExtentData.js +17 -17
- package/src/components/Indicator.js +61 -13
- package/src/components/Label.js +275 -242
- package/src/components/Legend.js +165 -165
- package/src/components/Lighter.jsx +173 -173
- package/src/components/Line.js +150 -150
- package/src/components/LinearGradient.js +29 -29
- package/src/components/PieChart.js +8 -4
- package/src/components/StereoBar.tsx +307 -307
- package/src/components/index.js +57 -55
- 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 +67 -67
- package/src/hooks/useAxes.js +9 -2
- package/src/hooks/useCarouselAxisX.js +35 -18
- package/src/hooks/useFilterData.js +72 -72
- package/src/hooks/useStackData.js +101 -101
- package/src/hooks/useTooltip.ts +100 -100
- package/src/index.js +6 -6
- package/src/types/index.d.ts +67 -67
- package/src/utils/index.js +757 -757
- package/tsconfig.json +23 -23
|
@@ -1,67 +1,67 @@
|
|
|
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
|
-
* @returns 改变后的数据
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
export default (data: DataType[], dataAnimation: DataAnimation) => {
|
|
12
|
-
const [animateData, setAnimateData] = useState<DataType[]>([]);
|
|
13
|
-
|
|
14
|
-
useEffect(() => {
|
|
15
|
-
let animateRef: any = null;
|
|
16
|
-
if (
|
|
17
|
-
dataAnimation &&
|
|
18
|
-
dataAnimation.show &&
|
|
19
|
-
dataAnimation.duration &&
|
|
20
|
-
data.length
|
|
21
|
-
) {
|
|
22
|
-
animateRef = animate({
|
|
23
|
-
autoplay: true,
|
|
24
|
-
repeat: 0,
|
|
25
|
-
from: 0,
|
|
26
|
-
to: 1,
|
|
27
|
-
duration: dataAnimation.duration * 1000,
|
|
28
|
-
ease: linear,
|
|
29
|
-
onUpdate: (v: number) => {
|
|
30
|
-
setAnimateData((oldData: DataType[]) => {
|
|
31
|
-
const oldLength = oldData.length;
|
|
32
|
-
const newLength = data.length;
|
|
33
|
-
if (oldLength >= newLength) {
|
|
34
|
-
return oldData.map(({ y }: DataType, i: number) => {
|
|
35
|
-
const current: DataType = data[i] || { y: 0 };
|
|
36
|
-
const delta: number = current.y - y;
|
|
37
|
-
return {
|
|
38
|
-
...current,
|
|
39
|
-
y: y + delta * v,
|
|
40
|
-
};
|
|
41
|
-
});
|
|
42
|
-
} else {
|
|
43
|
-
return data.map((current: DataType, i: number) => {
|
|
44
|
-
const oldCurrent: DataType = oldData[i] || { y: 0 };
|
|
45
|
-
const delta = oldCurrent.y - current.y;
|
|
46
|
-
return {
|
|
47
|
-
...current,
|
|
48
|
-
y:oldCurrent.y + delta * v,
|
|
49
|
-
};
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
},
|
|
54
|
-
onComplete: () => {
|
|
55
|
-
setAnimateData(data);
|
|
56
|
-
},
|
|
57
|
-
});
|
|
58
|
-
} else {
|
|
59
|
-
setAnimateData(data);
|
|
60
|
-
}
|
|
61
|
-
return () => {
|
|
62
|
-
animateRef && animateRef.stop();
|
|
63
|
-
};
|
|
64
|
-
}, [data, dataAnimation]);
|
|
65
|
-
|
|
66
|
-
return animateData;
|
|
67
|
-
};
|
|
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
|
+
* @returns 改变后的数据
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export default (data: DataType[], dataAnimation: DataAnimation) => {
|
|
12
|
+
const [animateData, setAnimateData] = useState<DataType[]>([]);
|
|
13
|
+
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
let animateRef: any = null;
|
|
16
|
+
if (
|
|
17
|
+
dataAnimation &&
|
|
18
|
+
dataAnimation.show &&
|
|
19
|
+
dataAnimation.duration &&
|
|
20
|
+
data.length
|
|
21
|
+
) {
|
|
22
|
+
animateRef = animate({
|
|
23
|
+
autoplay: true,
|
|
24
|
+
repeat: 0,
|
|
25
|
+
from: 0,
|
|
26
|
+
to: 1,
|
|
27
|
+
duration: dataAnimation.duration * 1000,
|
|
28
|
+
ease: linear,
|
|
29
|
+
onUpdate: (v: number) => {
|
|
30
|
+
setAnimateData((oldData: DataType[]) => {
|
|
31
|
+
const oldLength = oldData.length;
|
|
32
|
+
const newLength = data.length;
|
|
33
|
+
if (oldLength >= newLength) {
|
|
34
|
+
return oldData.map(({ y }: DataType, i: number) => {
|
|
35
|
+
const current: DataType = data[i] || { y: 0 };
|
|
36
|
+
const delta: number = current.y - y;
|
|
37
|
+
return {
|
|
38
|
+
...current,
|
|
39
|
+
y: y + delta * v,
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
} else {
|
|
43
|
+
return data.map((current: DataType, i: number) => {
|
|
44
|
+
const oldCurrent: DataType = oldData[i] || { y: 0 };
|
|
45
|
+
const delta = oldCurrent.y - current.y;
|
|
46
|
+
return {
|
|
47
|
+
...current,
|
|
48
|
+
y:oldCurrent.y + delta * v,
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
},
|
|
54
|
+
onComplete: () => {
|
|
55
|
+
setAnimateData(data);
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
} else {
|
|
59
|
+
setAnimateData(data);
|
|
60
|
+
}
|
|
61
|
+
return () => {
|
|
62
|
+
animateRef && animateRef.stop();
|
|
63
|
+
};
|
|
64
|
+
}, [data, dataAnimation]);
|
|
65
|
+
|
|
66
|
+
return animateData;
|
|
67
|
+
};
|
package/src/hooks/useAxes.js
CHANGED
|
@@ -58,7 +58,12 @@ const scales = {
|
|
|
58
58
|
* @returns {Map} 返回所有轴
|
|
59
59
|
*/
|
|
60
60
|
|
|
61
|
-
export default ({
|
|
61
|
+
export default ({
|
|
62
|
+
axes,
|
|
63
|
+
context: { width, height }, //是否为控制图
|
|
64
|
+
isControlChart,
|
|
65
|
+
control: controlConfig,
|
|
66
|
+
}) => {
|
|
62
67
|
const _axes = useMemo(() => {
|
|
63
68
|
const tmp = new Map();
|
|
64
69
|
const xAxisPositions = [];
|
|
@@ -321,7 +326,7 @@ export default ({ axes, context: { width, height } }) => {
|
|
|
321
326
|
const { start, end, direction, _paddingOuter, length } =
|
|
322
327
|
getChartsConfig(orientation, width, height, paddingOuter);
|
|
323
328
|
|
|
324
|
-
|
|
329
|
+
let range =
|
|
325
330
|
direction === "horizontal"
|
|
326
331
|
? [start, end]
|
|
327
332
|
: direction === "vertical"
|
|
@@ -380,7 +385,9 @@ export default ({ axes, context: { width, height } }) => {
|
|
|
380
385
|
...item,
|
|
381
386
|
count: _count,
|
|
382
387
|
isClipAxis: _isClipAxis,
|
|
388
|
+
range,
|
|
383
389
|
scaler,
|
|
390
|
+
domain,
|
|
384
391
|
length,
|
|
385
392
|
direction,
|
|
386
393
|
start,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { useEffect, useState } from
|
|
2
|
-
import { animate, linear } from
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import { animate, linear } from "popmotion";
|
|
3
3
|
|
|
4
4
|
const initialState = {
|
|
5
5
|
currentIndex: null,
|
|
6
|
-
flag: false,
|
|
6
|
+
flag: false, //表示是否为首次加载,true表示首次加载,不需要立刻执行动画,false表示可以执行轮播动画
|
|
7
7
|
};
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -13,7 +13,13 @@ const initialState = {
|
|
|
13
13
|
* @returns {Map} 返回经过改变后的x轴,主要是ticks和scaler的range发生了改变
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
export default (
|
|
16
|
+
export default (
|
|
17
|
+
axis,
|
|
18
|
+
config,
|
|
19
|
+
isHover,
|
|
20
|
+
isControlChart = false,
|
|
21
|
+
controlConfig = null
|
|
22
|
+
) => {
|
|
17
23
|
const { show, interval, duration, hover } = config;
|
|
18
24
|
const time = duration + interval;
|
|
19
25
|
|
|
@@ -29,6 +35,12 @@ export default (axis, config, isHover) => {
|
|
|
29
35
|
} = axis;
|
|
30
36
|
const tickLength = ticks.length;
|
|
31
37
|
|
|
38
|
+
const _end =
|
|
39
|
+
isControlChart && controlConfig
|
|
40
|
+
? end / (controlConfig.drag.width / 100)
|
|
41
|
+
: end;
|
|
42
|
+
const controlDragScaler = scaler.copy().range([start, end]);
|
|
43
|
+
|
|
32
44
|
const [state, setState] = useState({
|
|
33
45
|
scaler,
|
|
34
46
|
step,
|
|
@@ -46,9 +58,9 @@ export default (axis, config, isHover) => {
|
|
|
46
58
|
setStatus(initialState);
|
|
47
59
|
}
|
|
48
60
|
}, [show, time, tickCount, tickLength]);
|
|
49
|
-
useEffect(()=>{
|
|
61
|
+
useEffect(() => {
|
|
50
62
|
let handler;
|
|
51
|
-
if(!(hover && isHover) && show && time && tickLength > tickCount){
|
|
63
|
+
if (!(hover && isHover) && show && time && tickLength > tickCount) {
|
|
52
64
|
handler = setInterval(() => {
|
|
53
65
|
setStatus(({ currentIndex }) => {
|
|
54
66
|
const tmp = +currentIndex + 1;
|
|
@@ -62,7 +74,7 @@ export default (axis, config, isHover) => {
|
|
|
62
74
|
return () => {
|
|
63
75
|
handler && clearInterval(handler);
|
|
64
76
|
};
|
|
65
|
-
},[show, time, tickCount, tickLength, hover, isHover])
|
|
77
|
+
}, [show, time, tickCount, tickLength, hover, isHover]);
|
|
66
78
|
|
|
67
79
|
useEffect(() => {
|
|
68
80
|
let animation;
|
|
@@ -74,7 +86,7 @@ export default (axis, config, isHover) => {
|
|
|
74
86
|
setState({
|
|
75
87
|
step,
|
|
76
88
|
ticks: _ticks,
|
|
77
|
-
scaler: scaler.copy().domain(_ticks).range([start,
|
|
89
|
+
scaler: scaler.copy().domain(_ticks).range([start, _end]),
|
|
78
90
|
});
|
|
79
91
|
} else {
|
|
80
92
|
animation = animate({
|
|
@@ -95,7 +107,7 @@ export default (axis, config, isHover) => {
|
|
|
95
107
|
ticks: _ticks,
|
|
96
108
|
scaler: scaler
|
|
97
109
|
.copy()
|
|
98
|
-
.range([start,
|
|
110
|
+
.range([start, _end + step])
|
|
99
111
|
.domain(_ticks),
|
|
100
112
|
};
|
|
101
113
|
});
|
|
@@ -107,7 +119,7 @@ export default (axis, config, isHover) => {
|
|
|
107
119
|
...axis,
|
|
108
120
|
scaler: scaler
|
|
109
121
|
.copy()
|
|
110
|
-
.range([start + step * v,
|
|
122
|
+
.range([start + step * v, _end + step + step * v]),
|
|
111
123
|
};
|
|
112
124
|
});
|
|
113
125
|
},
|
|
@@ -118,17 +130,17 @@ export default (axis, config, isHover) => {
|
|
|
118
130
|
return {
|
|
119
131
|
...axis,
|
|
120
132
|
ticks: _ticks,
|
|
121
|
-
scaler: scaler.copy().range([start,
|
|
133
|
+
scaler: scaler.copy().range([start, _end]).domain(_ticks),
|
|
122
134
|
};
|
|
123
135
|
});
|
|
124
136
|
},
|
|
125
137
|
});
|
|
126
138
|
}
|
|
127
139
|
} else {
|
|
128
|
-
const _ticks = scaler.type ==
|
|
140
|
+
const _ticks = scaler.type == "linear" ? scaler.domain() : allTicks;
|
|
129
141
|
setState({
|
|
130
142
|
step,
|
|
131
|
-
scaler: scaler.copy().domain(_ticks).range([start,
|
|
143
|
+
scaler: scaler.copy().domain(_ticks).range([start, _end]),
|
|
132
144
|
ticks,
|
|
133
145
|
});
|
|
134
146
|
}
|
|
@@ -140,16 +152,21 @@ export default (axis, config, isHover) => {
|
|
|
140
152
|
allTicks,
|
|
141
153
|
scaler,
|
|
142
154
|
start,
|
|
143
|
-
|
|
155
|
+
_end,
|
|
144
156
|
step,
|
|
145
157
|
ticks,
|
|
146
158
|
lengthWithoutPaddingOuter,
|
|
147
159
|
status,
|
|
148
160
|
duration,
|
|
149
161
|
]);
|
|
162
|
+
|
|
150
163
|
return {
|
|
151
164
|
...axis,
|
|
152
165
|
...state,
|
|
166
|
+
rawTicks: axis.ticks,
|
|
167
|
+
controlDragScaler,
|
|
168
|
+
controlEnd: _end,
|
|
169
|
+
isControlChart,
|
|
153
170
|
};
|
|
154
171
|
};
|
|
155
172
|
|
|
@@ -157,11 +174,11 @@ const getTicks = (ticks, currentIndex, length) => {
|
|
|
157
174
|
const _currentIndex = +currentIndex;
|
|
158
175
|
const ticksLength = ticks.length;
|
|
159
176
|
if (ticksLength <= length) return ticks;
|
|
160
|
-
const
|
|
161
|
-
if (ticksLength <
|
|
177
|
+
const _end = _currentIndex + length;
|
|
178
|
+
if (ticksLength < _end) {
|
|
162
179
|
const prev = ticks.slice(_currentIndex, ticksLength);
|
|
163
|
-
const next = ticks.slice(0,
|
|
180
|
+
const next = ticks.slice(0, _end - ticksLength);
|
|
164
181
|
return [...prev, ...next];
|
|
165
182
|
}
|
|
166
|
-
return ticks.slice(_currentIndex,
|
|
183
|
+
return ticks.slice(_currentIndex, _end);
|
|
167
184
|
};
|
|
@@ -1,72 +1,72 @@
|
|
|
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
|
-
setSelected(getInitialSelected(series));
|
|
57
|
-
}, [series]);
|
|
58
|
-
|
|
59
|
-
return [
|
|
60
|
-
{
|
|
61
|
-
series: _series,
|
|
62
|
-
data: _data.map(d=>{
|
|
63
|
-
return {
|
|
64
|
-
...d,
|
|
65
|
-
y:parseFloat(d.y),
|
|
66
|
-
showY:d.y
|
|
67
|
-
}
|
|
68
|
-
}),
|
|
69
|
-
},
|
|
70
|
-
onClick,
|
|
71
|
-
];
|
|
72
|
-
};
|
|
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
|
+
setSelected(getInitialSelected(series));
|
|
57
|
+
}, [series]);
|
|
58
|
+
|
|
59
|
+
return [
|
|
60
|
+
{
|
|
61
|
+
series: _series,
|
|
62
|
+
data: _data.map(d=>{
|
|
63
|
+
return {
|
|
64
|
+
...d,
|
|
65
|
+
y:parseFloat(d.y),
|
|
66
|
+
showY:d.y
|
|
67
|
+
}
|
|
68
|
+
}),
|
|
69
|
+
},
|
|
70
|
+
onClick,
|
|
71
|
+
];
|
|
72
|
+
};
|
|
@@ -1,101 +1,101 @@
|
|
|
1
|
-
import { useMemo } from 'react';
|
|
2
|
-
import { group } from 'd3v7';
|
|
3
|
-
import {
|
|
4
|
-
dataYOrZ,
|
|
5
|
-
seriesYOrZ,
|
|
6
|
-
getCurrentStack,
|
|
7
|
-
getStacks,
|
|
8
|
-
resetStacks,
|
|
9
|
-
} from '../utils';
|
|
10
|
-
|
|
11
|
-
const getSeriesMap = (series) => {
|
|
12
|
-
const seriesMap = new Map();
|
|
13
|
-
series.forEach(({ name, ...rest }) => {
|
|
14
|
-
seriesMap.set(name, {
|
|
15
|
-
...rest,
|
|
16
|
-
name,
|
|
17
|
-
data: [],
|
|
18
|
-
});
|
|
19
|
-
});
|
|
20
|
-
return seriesMap;
|
|
21
|
-
};
|
|
22
|
-
const resetStackData = (series) => {
|
|
23
|
-
series.forEach((series) => {
|
|
24
|
-
series.data = [];
|
|
25
|
-
});
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
const setStackData = (data, series, stacks) => {
|
|
29
|
-
const dataMap = group(data, (d) => d.x);
|
|
30
|
-
|
|
31
|
-
dataMap.forEach((value) => {
|
|
32
|
-
resetStacks(stacks);
|
|
33
|
-
for (let i = 0, j = value.length; i < j; i++) {
|
|
34
|
-
const d = value[i];
|
|
35
|
-
const currentSeries = series.get(d.s);
|
|
36
|
-
if (d && d.y !== undefined && !isNaN(d.y)) {
|
|
37
|
-
const currentStack = getCurrentStack(currentSeries, stacks);
|
|
38
|
-
if (currentSeries && currentStack) {
|
|
39
|
-
if (d.y >= 0) {
|
|
40
|
-
currentSeries.data.push({
|
|
41
|
-
data: d,
|
|
42
|
-
index: currentStack.index,
|
|
43
|
-
bound: [currentStack.positive, currentStack.positive + d.y],
|
|
44
|
-
});
|
|
45
|
-
currentStack.positive += d.y;
|
|
46
|
-
} else {
|
|
47
|
-
currentSeries.data.push({
|
|
48
|
-
data: d,
|
|
49
|
-
index: currentStack.index,
|
|
50
|
-
bound: [currentStack.negative, currentStack.negative + d.y],
|
|
51
|
-
});
|
|
52
|
-
currentStack.negative += d.y;
|
|
53
|
-
}
|
|
54
|
-
} else {
|
|
55
|
-
currentSeries.data.push({
|
|
56
|
-
data: d,
|
|
57
|
-
bound: [0, d.y],
|
|
58
|
-
index: 0,
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
dataMap.clear();
|
|
65
|
-
return series;
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* 计算堆叠数据
|
|
70
|
-
* @param {Array} data 数据
|
|
71
|
-
* @param {Map} series 系列
|
|
72
|
-
* @returns {Array} 返回堆叠后的数据,由一开始的{x, y, s}变成{data: {x, y, s}, bound: [start, end], index}
|
|
73
|
-
*/
|
|
74
|
-
|
|
75
|
-
export default ({ data, series }) => {
|
|
76
|
-
const _series = useMemo(() => {
|
|
77
|
-
const stacks = getStacks(series);
|
|
78
|
-
const _series = getSeriesMap(series);
|
|
79
|
-
return { stacks, series: seriesYOrZ(_series) };
|
|
80
|
-
}, [series]);
|
|
81
|
-
|
|
82
|
-
const _data = useMemo(() => dataYOrZ(data, _series.series), [data, _series]);
|
|
83
|
-
|
|
84
|
-
const tmp = useMemo(() => {
|
|
85
|
-
const { y: dataY, z: dataZ } = _data;
|
|
86
|
-
const {
|
|
87
|
-
stacks,
|
|
88
|
-
series: { y: seriesY, z: seriesZ },
|
|
89
|
-
} = _series;
|
|
90
|
-
resetStackData(seriesY);
|
|
91
|
-
resetStackData(seriesZ);
|
|
92
|
-
setStackData(dataY, seriesY, stacks);
|
|
93
|
-
setStackData(dataZ, seriesZ, stacks);
|
|
94
|
-
|
|
95
|
-
return {
|
|
96
|
-
bandLength: stacks.filter((item) => item.type == 'band').length,
|
|
97
|
-
series: [...seriesY.values(), ...seriesZ.values()],
|
|
98
|
-
};
|
|
99
|
-
}, [_data, _series]);
|
|
100
|
-
return tmp;
|
|
101
|
-
};
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { group } from 'd3v7';
|
|
3
|
+
import {
|
|
4
|
+
dataYOrZ,
|
|
5
|
+
seriesYOrZ,
|
|
6
|
+
getCurrentStack,
|
|
7
|
+
getStacks,
|
|
8
|
+
resetStacks,
|
|
9
|
+
} from '../utils';
|
|
10
|
+
|
|
11
|
+
const getSeriesMap = (series) => {
|
|
12
|
+
const seriesMap = new Map();
|
|
13
|
+
series.forEach(({ name, ...rest }) => {
|
|
14
|
+
seriesMap.set(name, {
|
|
15
|
+
...rest,
|
|
16
|
+
name,
|
|
17
|
+
data: [],
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
return seriesMap;
|
|
21
|
+
};
|
|
22
|
+
const resetStackData = (series) => {
|
|
23
|
+
series.forEach((series) => {
|
|
24
|
+
series.data = [];
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const setStackData = (data, series, stacks) => {
|
|
29
|
+
const dataMap = group(data, (d) => d.x);
|
|
30
|
+
|
|
31
|
+
dataMap.forEach((value) => {
|
|
32
|
+
resetStacks(stacks);
|
|
33
|
+
for (let i = 0, j = value.length; i < j; i++) {
|
|
34
|
+
const d = value[i];
|
|
35
|
+
const currentSeries = series.get(d.s);
|
|
36
|
+
if (d && d.y !== undefined && !isNaN(d.y)) {
|
|
37
|
+
const currentStack = getCurrentStack(currentSeries, stacks);
|
|
38
|
+
if (currentSeries && currentStack) {
|
|
39
|
+
if (d.y >= 0) {
|
|
40
|
+
currentSeries.data.push({
|
|
41
|
+
data: d,
|
|
42
|
+
index: currentStack.index,
|
|
43
|
+
bound: [currentStack.positive, currentStack.positive + d.y],
|
|
44
|
+
});
|
|
45
|
+
currentStack.positive += d.y;
|
|
46
|
+
} else {
|
|
47
|
+
currentSeries.data.push({
|
|
48
|
+
data: d,
|
|
49
|
+
index: currentStack.index,
|
|
50
|
+
bound: [currentStack.negative, currentStack.negative + d.y],
|
|
51
|
+
});
|
|
52
|
+
currentStack.negative += d.y;
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
currentSeries.data.push({
|
|
56
|
+
data: d,
|
|
57
|
+
bound: [0, d.y],
|
|
58
|
+
index: 0,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
dataMap.clear();
|
|
65
|
+
return series;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* 计算堆叠数据
|
|
70
|
+
* @param {Array} data 数据
|
|
71
|
+
* @param {Map} series 系列
|
|
72
|
+
* @returns {Array} 返回堆叠后的数据,由一开始的{x, y, s}变成{data: {x, y, s}, bound: [start, end], index}
|
|
73
|
+
*/
|
|
74
|
+
|
|
75
|
+
export default ({ data, series }) => {
|
|
76
|
+
const _series = useMemo(() => {
|
|
77
|
+
const stacks = getStacks(series);
|
|
78
|
+
const _series = getSeriesMap(series);
|
|
79
|
+
return { stacks, series: seriesYOrZ(_series) };
|
|
80
|
+
}, [series]);
|
|
81
|
+
|
|
82
|
+
const _data = useMemo(() => dataYOrZ(data, _series.series), [data, _series]);
|
|
83
|
+
|
|
84
|
+
const tmp = useMemo(() => {
|
|
85
|
+
const { y: dataY, z: dataZ } = _data;
|
|
86
|
+
const {
|
|
87
|
+
stacks,
|
|
88
|
+
series: { y: seriesY, z: seriesZ },
|
|
89
|
+
} = _series;
|
|
90
|
+
resetStackData(seriesY);
|
|
91
|
+
resetStackData(seriesZ);
|
|
92
|
+
setStackData(dataY, seriesY, stacks);
|
|
93
|
+
setStackData(dataZ, seriesZ, stacks);
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
bandLength: stacks.filter((item) => item.type == 'band').length,
|
|
97
|
+
series: [...seriesY.values(), ...seriesZ.values()],
|
|
98
|
+
};
|
|
99
|
+
}, [_data, _series]);
|
|
100
|
+
return tmp;
|
|
101
|
+
};
|