@easyv/charts 1.4.34 → 1.4.36
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 +7 -7
- package/lib/components/Band.js +28 -26
- package/lib/components/CartesianChart.js +208 -175
- package/lib/components/Control.js +78 -30
- package/lib/components/Indicator.js +30 -34
- package/lib/components/Label.js +1 -41
- package/lib/hooks/useAxes.js +43 -12
- package/lib/hooks/useCarouselAxisX.js +15 -16
- package/lib/hooks/useFilterData.js +21 -1
- package/package.json +1 -1
- package/src/components/Axis.tsx +6 -7
- package/src/components/Band.tsx +27 -34
- package/src/components/CartesianChart.js +186 -196
- package/src/components/Control.jsx +87 -43
- package/src/components/Indicator.js +17 -20
- package/src/components/Label.js +1 -34
- package/src/components/Tooltip.js +0 -1
- package/src/hooks/useAxes.js +34 -16
- package/src/hooks/useCarouselAxisX.js +14 -18
- package/src/hooks/useFilterData.js +7 -1
package/src/components/Band.tsx
CHANGED
|
@@ -69,12 +69,8 @@ export default memo(
|
|
|
69
69
|
//控制图部分,主要是为了控制图的指示器,在悬浮的时候显示
|
|
70
70
|
triggerClick,
|
|
71
71
|
indicatorWidth,
|
|
72
|
-
setControlChartTooltipShow,
|
|
73
|
-
setControlChartTooltipX,
|
|
74
|
-
setControlChartTooltipXName,
|
|
75
72
|
isControlChart = false,
|
|
76
|
-
|
|
77
|
-
|
|
73
|
+
setCtlTip,
|
|
78
74
|
config: {
|
|
79
75
|
pattern = {},
|
|
80
76
|
seriesIntervalWidth: paddingInner = 0,
|
|
@@ -91,12 +87,12 @@ export default memo(
|
|
|
91
87
|
},
|
|
92
88
|
bandLength = 0,
|
|
93
89
|
data,
|
|
94
|
-
xAxis: { scaler:
|
|
95
|
-
xAxis,
|
|
90
|
+
xAxis: { scaler: normalScaler, step:normalStep, controlStep, direction, controlDragScaler },
|
|
96
91
|
yAxis: { scaler: yScaler, isClipAxis, clipValue },
|
|
97
92
|
}: any) => {
|
|
98
93
|
if (!data.length) return null;
|
|
99
|
-
|
|
94
|
+
const step = isControlChart?controlStep:normalStep;
|
|
95
|
+
const xScaler = isControlChart?controlDragScaler:normalScaler;
|
|
100
96
|
const { seriesWidth, seriesStep, seriesStart } = getSeriesInfo({
|
|
101
97
|
step,
|
|
102
98
|
bandLength,
|
|
@@ -105,7 +101,6 @@ export default memo(
|
|
|
105
101
|
});
|
|
106
102
|
|
|
107
103
|
const _data = showHighlight ? getHighlightData(data, extent) : data;
|
|
108
|
-
|
|
109
104
|
const isVertical = direction === "vertical";
|
|
110
105
|
const borderStr = `${border.borderColor} solid ${border.borderWidth}px`;
|
|
111
106
|
return (
|
|
@@ -135,9 +130,7 @@ export default memo(
|
|
|
135
130
|
y1 = yScaler(isVertical ? end : start);
|
|
136
131
|
y2 = yScaler(isVertical ? start : end);
|
|
137
132
|
}
|
|
138
|
-
|
|
139
|
-
const positionX =
|
|
140
|
-
xScaler(x) - step / 2 + seriesStart + index * seriesStep;
|
|
133
|
+
const positionX = xScaler(x) - step / 2 + seriesStart + index * seriesStep;
|
|
141
134
|
|
|
142
135
|
let showHead, headUrl, headWidth, headHeight, headTranslate;
|
|
143
136
|
if (headDecorate) {
|
|
@@ -176,36 +169,35 @@ export default memo(
|
|
|
176
169
|
style={{
|
|
177
170
|
overflow: "visible",
|
|
178
171
|
position: "relative",
|
|
172
|
+
pointerEvents:isControlChart?"auto":"none",
|
|
179
173
|
cursor: "pointer",
|
|
180
174
|
}}
|
|
181
175
|
{...attr}
|
|
182
176
|
onClick={triggerClick}
|
|
183
177
|
//enter和leave事件,用于控制图的提示框
|
|
184
178
|
onMouseEnter={() => {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
setControlChartTooltipXName(data.x);
|
|
198
|
-
}
|
|
179
|
+
setCtlTip((pre:any)=>({
|
|
180
|
+
show:true,
|
|
181
|
+
x:xScaler(x),
|
|
182
|
+
xName:data.x,
|
|
183
|
+
indicatorList:pre.indicatorList.map((item:any)=>{
|
|
184
|
+
if (item.tick === data.x) {
|
|
185
|
+
return { ...item, isShow: true };
|
|
186
|
+
} else {
|
|
187
|
+
return item;
|
|
188
|
+
}
|
|
189
|
+
})
|
|
190
|
+
}))
|
|
199
191
|
}}
|
|
200
192
|
onMouseLeave={() => {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}
|
|
193
|
+
setCtlTip((pre:any)=>({
|
|
194
|
+
show:false,
|
|
195
|
+
x:undefined,
|
|
196
|
+
xName:undefined,
|
|
197
|
+
indicatorList:pre.indicatorList.map((item:any)=>{
|
|
198
|
+
return { ...item, isShow:false }
|
|
199
|
+
})
|
|
200
|
+
}))
|
|
209
201
|
}}
|
|
210
202
|
data-data={JSON.stringify(data)}
|
|
211
203
|
>
|
|
@@ -214,6 +206,7 @@ export default memo(
|
|
|
214
206
|
style={{
|
|
215
207
|
position: "absolute",
|
|
216
208
|
background: `url(${
|
|
209
|
+
//@ts-ignore
|
|
217
210
|
window.appConfig.ASSETS_URL + headUrl
|
|
218
211
|
}) 0 0/100% 100%`,
|
|
219
212
|
width: headWidth,
|
|
@@ -8,10 +8,9 @@ import React, {
|
|
|
8
8
|
useRef,
|
|
9
9
|
useContext,
|
|
10
10
|
useCallback,
|
|
11
|
-
useEffect
|
|
12
|
-
forwardRef,
|
|
11
|
+
useEffect
|
|
13
12
|
} from "react";
|
|
14
|
-
import { useAxes, useTooltip, useCarouselAxisX,useAiData } from "../hooks";
|
|
13
|
+
import { useAxes, useTooltip, useCarouselAxisX, useAiData } from "../hooks";
|
|
15
14
|
import { chartContext } from "../context";
|
|
16
15
|
import {
|
|
17
16
|
ChartContainer,
|
|
@@ -30,7 +29,6 @@ import {
|
|
|
30
29
|
BaseLine,
|
|
31
30
|
Control,
|
|
32
31
|
} from ".";
|
|
33
|
-
import { getMousePos } from "../utils";
|
|
34
32
|
|
|
35
33
|
const Chart = memo(
|
|
36
34
|
({
|
|
@@ -58,7 +56,6 @@ const Chart = memo(
|
|
|
58
56
|
config: { auto, manual, indicator = {} } = {},
|
|
59
57
|
} = {},
|
|
60
58
|
brush,
|
|
61
|
-
isControlChart = false,
|
|
62
59
|
control = null,
|
|
63
60
|
},
|
|
64
61
|
style,
|
|
@@ -74,25 +71,49 @@ const Chart = memo(
|
|
|
74
71
|
height: chartHeight,
|
|
75
72
|
triggerOnRelative,
|
|
76
73
|
onEmit,
|
|
77
|
-
} =
|
|
74
|
+
} = context;
|
|
75
|
+
const xLineRange = chartWidth;
|
|
76
|
+
let yLineRange = chartHeight;
|
|
77
|
+
//获取控制条相关的参数
|
|
78
|
+
let isControl = false;
|
|
79
|
+
let controlWidth = 0;
|
|
80
|
+
let controlBarWidth = 0;
|
|
81
|
+
let dragPercent = 1;
|
|
82
|
+
let controlHeight = 0;
|
|
83
|
+
if(control){
|
|
84
|
+
const { height, margin:{ left, right }, drag:{ width:dragWidth } } = control;
|
|
85
|
+
isControl = true;
|
|
86
|
+
controlHeight = height;
|
|
87
|
+
controlWidth = width-left-right;
|
|
88
|
+
dragPercent = dragWidth/100;
|
|
89
|
+
controlBarWidth = controlWidth*dragPercent;
|
|
90
|
+
}
|
|
91
|
+
const [controlInfo, setControlInfo] = useState({ isC:isControl, cWidth:controlWidth, cHeight:controlHeight, cBarWidth:controlBarWidth, cPercent:dragPercent });
|
|
92
|
+
const { cWidth, cHeight, cBarWidth, cPercent } = controlInfo;
|
|
93
|
+
yLineRange -= cHeight;
|
|
94
|
+
useEffect(()=>{
|
|
95
|
+
setControlInfo({
|
|
96
|
+
isC:isControl,
|
|
97
|
+
cWidth:controlWidth,
|
|
98
|
+
cHeight:controlHeight,
|
|
99
|
+
cBarWidth:controlBarWidth,
|
|
100
|
+
cPercent:dragPercent
|
|
101
|
+
});
|
|
102
|
+
},[JSON.stringify(control)]);
|
|
103
|
+
|
|
78
104
|
const svg = useRef();
|
|
79
105
|
const axes = useAxes({
|
|
80
106
|
axes: axesConfig,
|
|
81
107
|
context,
|
|
82
|
-
|
|
83
|
-
control,
|
|
108
|
+
controlInfo
|
|
84
109
|
});
|
|
85
110
|
const aiData = aiFormatter?aiFormatter(originData, axes, series):useAiData(originData, axes, series);
|
|
86
111
|
const axisX = useCarouselAxisX(
|
|
87
112
|
axes.get("x"),
|
|
88
113
|
animation,
|
|
89
114
|
isHover,
|
|
90
|
-
|
|
91
|
-
control
|
|
115
|
+
controlInfo
|
|
92
116
|
);
|
|
93
|
-
const xLineRange = width - marginLeft - marginRight;
|
|
94
|
-
const yLineRange = height - marginTop - marginBottom;
|
|
95
|
-
|
|
96
117
|
useEffect(()=>{
|
|
97
118
|
if(aiData.length){
|
|
98
119
|
if(!window.aiData){
|
|
@@ -118,7 +139,7 @@ const Chart = memo(
|
|
|
118
139
|
marginLeft,
|
|
119
140
|
marginTop,
|
|
120
141
|
width: chartWidth,
|
|
121
|
-
height:
|
|
142
|
+
height: yLineRange,
|
|
122
143
|
axisX,
|
|
123
144
|
isHover,
|
|
124
145
|
config: tooltipConfig,
|
|
@@ -137,12 +158,12 @@ const Chart = memo(
|
|
|
137
158
|
|
|
138
159
|
const isVertical = axisX.direction === "vertical";
|
|
139
160
|
|
|
140
|
-
const indicatorWidth = (indicator.width * axisX.step) / 100;
|
|
161
|
+
const indicatorWidth = (indicator.width * (control?axisX.controlStep:axisX.step)) / 100;
|
|
141
162
|
const position = axisX.scaler(tickName) - indicatorWidth / 2;
|
|
142
163
|
const indicatorAttr = isVertical
|
|
143
164
|
? { width: chartWidth, height: indicatorWidth, y: position }
|
|
144
165
|
: {
|
|
145
|
-
height:
|
|
166
|
+
height: yLineRange,
|
|
146
167
|
width: indicatorWidth,
|
|
147
168
|
x: position,
|
|
148
169
|
};
|
|
@@ -165,148 +186,130 @@ const Chart = memo(
|
|
|
165
186
|
const seriesEl = useRef(null);
|
|
166
187
|
const axisElList = useRef([]);
|
|
167
188
|
const curControlPercent = useRef(0);
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
let movementX = 0;
|
|
172
|
-
let rawTranslateX = 0;
|
|
173
|
-
let percent = 0;
|
|
174
|
-
const controlWidth = (xLineRange * control.drag.width) / 100;
|
|
175
|
-
const range = (num) => {
|
|
176
|
-
let _num = num;
|
|
177
|
-
const min = 0;
|
|
178
|
-
const max = xLineRange - controlWidth;
|
|
179
|
-
_num = Math.max(_num, min);
|
|
180
|
-
_num = Math.min(_num, max);
|
|
181
|
-
return _num;
|
|
182
|
-
};
|
|
183
|
-
const setControlTranslate = (x) => {
|
|
184
|
-
const moveLen = range(x);
|
|
185
|
-
controlEl.current.style.transform = `translateX(${moveLen}px)`;
|
|
186
|
-
//计算出当前位移的百分比
|
|
187
|
-
percent = moveLen / (xLineRange - controlWidth);
|
|
188
|
-
curControlPercent.current = percent;
|
|
189
|
-
seriesEl.current.style.transform = `translate(${
|
|
190
|
-
-(axisX.controlEnd - axisX.end) * percent
|
|
191
|
-
}px,${marginTop}px)`;
|
|
192
|
-
axisElList.current[2].style.transform = `translate(${
|
|
193
|
-
-(axisX.controlEnd - axisX.end) * percent
|
|
194
|
-
}px,${0}px)`;
|
|
195
|
-
};
|
|
196
|
-
const mouseDownHandle = (e) => {
|
|
197
|
-
const mouseMoveHandle = (e) => {
|
|
198
|
-
//当前位移的距离
|
|
199
|
-
if (isDragging) {
|
|
200
|
-
movementX += e.movementX;
|
|
201
|
-
setControlTranslate(movementX + rawTranslateX);
|
|
202
|
-
}
|
|
203
|
-
};
|
|
204
|
-
const mouseUpHandle = (e) => {
|
|
205
|
-
rawTranslateX = range(movementX + rawTranslateX);
|
|
206
|
-
movementX = 0;
|
|
207
|
-
isDragging = false;
|
|
208
|
-
document.removeEventListener("mousemove", mouseMoveHandle);
|
|
209
|
-
document.removeEventListener("mouseup", mouseUpHandle);
|
|
210
|
-
};
|
|
211
|
-
document.addEventListener("mousemove", mouseMoveHandle);
|
|
212
|
-
document.addEventListener("mouseup", mouseUpHandle);
|
|
213
|
-
isDragging = true;
|
|
214
|
-
};
|
|
189
|
+
const controlTimer = useRef(); //控制条的动画计时器
|
|
190
|
+
const ctlBarX = useRef(0); //控制条的滑块偏移值
|
|
191
|
+
const isWorking = useRef(false); //控制条是否正在进行各种操作
|
|
215
192
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
193
|
+
const range = (num) => {
|
|
194
|
+
let _num = num;
|
|
195
|
+
const min = 0;
|
|
196
|
+
const max = cWidth - cBarWidth;
|
|
197
|
+
_num = Math.max(_num, min);
|
|
198
|
+
_num = Math.min(_num, max);
|
|
199
|
+
return _num;
|
|
200
|
+
};
|
|
201
|
+
//设置滑块和图表主体的偏移值
|
|
202
|
+
const setControlTranslate = (x, needSave) => {
|
|
203
|
+
const { controlEnd, start } = axisX;
|
|
204
|
+
const moveLen = range(x);
|
|
205
|
+
if(needSave) ctlBarX.current = moveLen;
|
|
206
|
+
controlEl.current.style.transform = `translate(${moveLen}px,0)`;
|
|
207
|
+
//计算出当前位移的百分比
|
|
208
|
+
const percent = moveLen / (cWidth - cBarWidth);
|
|
209
|
+
const translateX = -(controlEnd + start/cPercent - chartWidth) * percent;
|
|
210
|
+
curControlPercent.current = percent;
|
|
211
|
+
seriesEl.current.style.transform = `translate(${translateX}px,${marginTop}px)`;
|
|
212
|
+
axisElList.current[2].style.transform = `translate(${translateX}px,${0}px)`;
|
|
213
|
+
};
|
|
214
|
+
//设置控制条是否正在进行拖拽/缩放操作
|
|
215
|
+
const setWorking=(bool)=>{
|
|
216
|
+
isWorking.current = bool;
|
|
217
|
+
}
|
|
218
|
+
useEffect(() => {
|
|
219
|
+
if (controlEl.current && control) {
|
|
220
|
+
let isEnter = false; //控制条轮播动画是否处于暂停状态
|
|
227
221
|
const { show, duration, interval, hover } = animation;
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
timeGap = timestamp - initTime;
|
|
249
|
-
if (timeGap < (interval + duration) * 1000) {
|
|
250
|
-
if (timeGap < duration * 1000) {
|
|
251
|
-
const p = timeGap / (duration * 1000);
|
|
252
|
-
let nextIndex = index + 1;
|
|
253
|
-
let v;
|
|
254
|
-
if (nextIndex < animatePos.length) {
|
|
255
|
-
v =
|
|
256
|
-
p * (animatePos[nextIndex] - animatePos[index]) +
|
|
257
|
-
animatePos[index];
|
|
258
|
-
} else {
|
|
259
|
-
nextIndex = 0;
|
|
260
|
-
v = (1 - p) * animatePos[index];
|
|
222
|
+
const startAnimate=()=>{
|
|
223
|
+
const loopInterval = interval*1000, tranDuration = duration*1000;
|
|
224
|
+
let loopTime, timeGap, toRight=true;
|
|
225
|
+
const transition=(timeStamp)=>{
|
|
226
|
+
if(!loopTime)loopTime=timeStamp;
|
|
227
|
+
if(!isEnter && !isWorking.current){
|
|
228
|
+
if(timeStamp-loopTime<tranDuration){
|
|
229
|
+
const percent = Math.min(1,(timeStamp-loopTime)/tranDuration);
|
|
230
|
+
if(toRight){
|
|
231
|
+
setControlTranslate(cBarWidth*percent+ctlBarX.current);
|
|
232
|
+
}else{
|
|
233
|
+
setControlTranslate(ctlBarX.current*(1-percent));
|
|
234
|
+
}
|
|
235
|
+
controlTimer.current = requestAnimationFrame(transition);
|
|
236
|
+
}else{
|
|
237
|
+
loopTime = timeStamp;
|
|
238
|
+
if(toRight){
|
|
239
|
+
setControlTranslate(cBarWidth+ctlBarX.current, true);
|
|
240
|
+
}else{
|
|
241
|
+
setControlTranslate(0,true);
|
|
261
242
|
}
|
|
262
|
-
|
|
243
|
+
controlTimer.current = requestAnimationFrame(loop);
|
|
263
244
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
initTime = 0;
|
|
268
|
-
animationId = window.requestAnimationFrame(animation);
|
|
245
|
+
}else{
|
|
246
|
+
loopTime = timeStamp-timeGap;
|
|
247
|
+
controlTimer.current = requestAnimationFrame(transition);
|
|
269
248
|
}
|
|
270
|
-
|
|
271
|
-
|
|
249
|
+
timeGap = timeStamp - loopTime;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const loop=(timeStamp)=>{
|
|
253
|
+
if(!loopTime)loopTime=timeStamp;
|
|
254
|
+
if(!isEnter && !isWorking.current){
|
|
255
|
+
if(timeStamp-loopTime<loopInterval){
|
|
256
|
+
controlTimer.current = requestAnimationFrame(loop);
|
|
257
|
+
}else{
|
|
258
|
+
loopTime = timeStamp;
|
|
259
|
+
if(ctlBarX.current==cWidth - cBarWidth) toRight=false;
|
|
260
|
+
else toRight=true;
|
|
261
|
+
controlTimer.current = requestAnimationFrame(transition);
|
|
262
|
+
}
|
|
263
|
+
}else{
|
|
264
|
+
loopTime = timeStamp-timeGap;
|
|
265
|
+
controlTimer.current = requestAnimationFrame(loop);
|
|
266
|
+
}
|
|
267
|
+
timeGap = timeStamp - loopTime;
|
|
268
|
+
}
|
|
269
|
+
controlTimer.current = requestAnimationFrame(loop);
|
|
270
|
+
}
|
|
271
|
+
const mouseenter = () => {
|
|
272
|
+
isEnter = true;
|
|
273
|
+
};
|
|
274
|
+
const mouseleave = () => {
|
|
275
|
+
isEnter = false;
|
|
276
|
+
};
|
|
277
|
+
if(hover){
|
|
278
|
+
svg.current.addEventListener("mouseenter",mouseenter);
|
|
279
|
+
svg.current.addEventListener("mouseleave",mouseleave);
|
|
280
|
+
controlEl.current.addEventListener("mouseenter",mouseenter);
|
|
281
|
+
controlEl.current.addEventListener("mouseleave",mouseleave);
|
|
282
|
+
}
|
|
283
|
+
if(show){
|
|
284
|
+
startAnimate();
|
|
272
285
|
}
|
|
273
|
-
controlEl.current.addEventListener("mousedown", mouseDownHandle);
|
|
274
|
-
|
|
275
286
|
return () => {
|
|
276
|
-
|
|
277
|
-
svg.current.removeEventListener(
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
);
|
|
281
|
-
svg.current.removeEventListener(
|
|
282
|
-
"mouseleave",
|
|
283
|
-
setAnimationHoverStopFalse
|
|
284
|
-
);
|
|
285
|
-
|
|
286
|
-
window.cancelAnimationFrame(animationId);
|
|
287
|
+
svg.current.removeEventListener("mouseenter",mouseenter);
|
|
288
|
+
svg.current.removeEventListener("mouseleave",mouseleave);
|
|
289
|
+
controlEl.current.removeEventListener("mouseenter",mouseenter);
|
|
290
|
+
controlEl.current.removeEventListener("mouseleave",mouseleave);
|
|
291
|
+
cancelAnimationFrame(controlTimer.current);
|
|
287
292
|
};
|
|
288
293
|
}
|
|
289
294
|
}, [JSON.stringify(animation), control]);
|
|
290
|
-
|
|
291
|
-
const
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
})
|
|
309
|
-
);
|
|
295
|
+
//初始化控制图提示框状态的函数
|
|
296
|
+
const initCtlTip = ()=>{
|
|
297
|
+
return {
|
|
298
|
+
show:false,
|
|
299
|
+
xName:"",
|
|
300
|
+
x:undefined,
|
|
301
|
+
indicatorList:axisX.ticks.map((tick) => {
|
|
302
|
+
return {
|
|
303
|
+
tick: tick,
|
|
304
|
+
isShow: false,
|
|
305
|
+
};
|
|
306
|
+
})
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
const [ctlTip, setCtlTip] = useState(initCtlTip);
|
|
310
|
+
const { show:showCtl, xName:ctlXName, x:ctlX, indicatorList:ctlIndicatorList } = ctlTip;
|
|
311
|
+
const controlChartTooltipData = ctlXName && originData.filter((d) => d.x === ctlXName);
|
|
312
|
+
|
|
310
313
|
return (
|
|
311
314
|
<>
|
|
312
315
|
<ChartContainer
|
|
@@ -334,7 +337,7 @@ const Chart = memo(
|
|
|
334
337
|
>
|
|
335
338
|
<svg width="100%" height="100%">
|
|
336
339
|
<Background
|
|
337
|
-
length={isVertical ? chartWidth :
|
|
340
|
+
length={isVertical ? chartWidth : yLineRange}
|
|
338
341
|
axis={axisX}
|
|
339
342
|
config={background}
|
|
340
343
|
bandLength={bandLength}
|
|
@@ -344,7 +347,6 @@ const Chart = memo(
|
|
|
344
347
|
)}
|
|
345
348
|
{[...axes.values()].reverse().map((item, index) => {
|
|
346
349
|
const config = item.axisType == "x" ? axisX : item;
|
|
347
|
-
|
|
348
350
|
return (
|
|
349
351
|
<Axis
|
|
350
352
|
ref={(d) => {
|
|
@@ -353,30 +355,13 @@ const Chart = memo(
|
|
|
353
355
|
triggerClick={onInteraction}
|
|
354
356
|
xLineRange={xLineRange}
|
|
355
357
|
yLineRange={yLineRange}
|
|
356
|
-
|
|
357
|
-
controlConfig={control}
|
|
358
|
+
controlInfo={controlInfo}
|
|
358
359
|
{...config}
|
|
359
360
|
key={index}
|
|
360
361
|
/>
|
|
361
362
|
);
|
|
362
363
|
})}
|
|
363
|
-
{
|
|
364
|
-
{isControlChart && control && (
|
|
365
|
-
<Control
|
|
366
|
-
ref={controlEl}
|
|
367
|
-
props={{
|
|
368
|
-
control,
|
|
369
|
-
axes,
|
|
370
|
-
series,
|
|
371
|
-
xLineRange,
|
|
372
|
-
yLineRange,
|
|
373
|
-
marginTop,
|
|
374
|
-
axisX,
|
|
375
|
-
bandLength,
|
|
376
|
-
}}
|
|
377
|
-
></Control>
|
|
378
|
-
)}
|
|
379
|
-
{showTooltip && !isControlChart && (
|
|
364
|
+
{showTooltip && !control && (
|
|
380
365
|
<Indicator {...indicator} {...indicatorAttr} />
|
|
381
366
|
)}
|
|
382
367
|
|
|
@@ -408,33 +393,27 @@ const Chart = memo(
|
|
|
408
393
|
>
|
|
409
394
|
{/* 控制图指示器部分 */}
|
|
410
395
|
<g>
|
|
411
|
-
{
|
|
412
|
-
|
|
396
|
+
{control &&
|
|
397
|
+
ctlIndicatorList.map((item, index) => {
|
|
413
398
|
const x = axisX.scaler(item.tick);
|
|
414
399
|
return (
|
|
415
400
|
<Indicator
|
|
416
401
|
key={index}
|
|
417
402
|
{...indicator}
|
|
418
403
|
{...{
|
|
419
|
-
height:
|
|
404
|
+
height: yLineRange,
|
|
420
405
|
width: indicatorWidth,
|
|
421
406
|
x: x - indicatorWidth / 2,
|
|
422
407
|
}}
|
|
423
|
-
isControlChart={
|
|
408
|
+
isControlChart={!!control}
|
|
424
409
|
xName={item.tick}
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
}
|
|
428
|
-
setControlChartTooltipX={setControlChartTooltipX}
|
|
429
|
-
setControlChartTooltipShow={setControlChartTooltipShow}
|
|
430
|
-
controlChartIndicatorList={controlChartIndicatorList}
|
|
431
|
-
setControlChartIndicatorList={
|
|
432
|
-
setControlChartIndicatorList
|
|
433
|
-
}
|
|
410
|
+
setCtlTip={setCtlTip}
|
|
411
|
+
ctlIndicatorList={ctlIndicatorList}
|
|
434
412
|
/>
|
|
435
413
|
);
|
|
436
414
|
})}
|
|
437
415
|
</g>
|
|
416
|
+
{/**绘制图表主体 */}
|
|
438
417
|
{series.map(({ Component, yOrZ, ...config }, index) => {
|
|
439
418
|
const yAxis = axes.get(yOrZ);
|
|
440
419
|
return (
|
|
@@ -447,15 +426,10 @@ const Chart = memo(
|
|
|
447
426
|
xAxis={axisX}
|
|
448
427
|
yAxis={yAxis}
|
|
449
428
|
// 控制图部分,主要是为了,当鼠标悬浮在指示器上时,显示对应的tooltip
|
|
450
|
-
isControlChart={
|
|
451
|
-
setControlChartTooltipXName={setControlChartTooltipXName}
|
|
452
|
-
setControlChartTooltipX={setControlChartTooltipX}
|
|
453
|
-
setControlChartTooltipShow={setControlChartTooltipShow}
|
|
429
|
+
isControlChart={!!control}
|
|
454
430
|
indicatorWidth={indicatorWidth}
|
|
455
431
|
triggerClick={onInteraction}
|
|
456
|
-
|
|
457
|
-
setControlChartIndicatorList
|
|
458
|
-
}
|
|
432
|
+
setCtlTip={setCtlTip}
|
|
459
433
|
/>
|
|
460
434
|
)
|
|
461
435
|
);
|
|
@@ -503,8 +477,27 @@ const Chart = memo(
|
|
|
503
477
|
);
|
|
504
478
|
})}
|
|
505
479
|
</ChartContainer>
|
|
480
|
+
{/* 控制条逻辑 */}
|
|
481
|
+
{control && (
|
|
482
|
+
<Control
|
|
483
|
+
ref={controlEl}
|
|
484
|
+
actions={{
|
|
485
|
+
setX:setControlTranslate,
|
|
486
|
+
setWorking,
|
|
487
|
+
setControlInfo
|
|
488
|
+
}}
|
|
489
|
+
props={{
|
|
490
|
+
control,
|
|
491
|
+
axes,
|
|
492
|
+
series,
|
|
493
|
+
width,
|
|
494
|
+
top:chartHeight+marginTop,
|
|
495
|
+
bandLength,
|
|
496
|
+
}}
|
|
497
|
+
></Control>
|
|
498
|
+
)}
|
|
506
499
|
<Legend {...legend} filterData={filterData} series={series} />
|
|
507
|
-
{showTooltip && !
|
|
500
|
+
{showTooltip && !control && (
|
|
508
501
|
<Tooltip
|
|
509
502
|
isVertical={isVertical}
|
|
510
503
|
{...tooltip}
|
|
@@ -519,18 +512,15 @@ const Chart = memo(
|
|
|
519
512
|
/>
|
|
520
513
|
)}
|
|
521
514
|
|
|
522
|
-
{
|
|
515
|
+
{showCtl && !!control && (
|
|
523
516
|
<Tooltip
|
|
524
517
|
isVertical={isVertical}
|
|
525
518
|
{...tooltip}
|
|
526
519
|
data={controlChartTooltipData}
|
|
527
|
-
x={
|
|
528
|
-
controlChartTooltipX -
|
|
529
|
-
(axisX.controlEnd - axisX.end) * curControlPercent.current
|
|
530
|
-
}
|
|
520
|
+
x={ ctlX -(axisX.controlEnd + axisX.start/cPercent - chartWidth) * curControlPercent.current}
|
|
531
521
|
marginLeft={marginLeft}
|
|
532
522
|
marginTop={marginTop}
|
|
533
|
-
tickName={
|
|
523
|
+
tickName={ctlXName}
|
|
534
524
|
series={series}
|
|
535
525
|
width={width}
|
|
536
526
|
height={height}
|