st-comp 0.0.30 → 0.0.31
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/bundle.js +6524 -6487
- package/lib/bundle.umd.cjs +37 -37
- package/lib/style.css +1 -1
- package/package.json +1 -1
- package/packages/Kline/index.vue +1 -6
- package/packages/Kline/option.ts +133 -106
- package/packages/Kline/utils.ts +261 -223
- package/src/pages/Kline/api.ts +15 -1
- package/src/pages/Kline/components/SingleCycleSingleVariety.vue +206 -88
package/packages/Kline/utils.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type { EChartsType, ElementEvent } from
|
|
1
|
+
import type { EChartsType, ElementEvent } from "echarts";
|
|
2
2
|
import type {
|
|
3
3
|
KlineDataType,
|
|
4
4
|
WarningConfigType,
|
|
5
5
|
PositionConfigType,
|
|
6
6
|
ConditionConfigType,
|
|
7
7
|
GraphicEvent,
|
|
8
|
-
} from
|
|
8
|
+
} from "./type.d.ts";
|
|
9
9
|
|
|
10
10
|
// ------------------普通工具函数---------------------
|
|
11
11
|
|
|
@@ -15,10 +15,10 @@ import type {
|
|
|
15
15
|
* @param {Object} option 配置选项
|
|
16
16
|
*/
|
|
17
17
|
export const printConsole = (message: string, option?: { type?: string; color?: string }) => {
|
|
18
|
-
const { type =
|
|
19
|
-
let isShow = localStorage.getItem(
|
|
20
|
-
isShow && console[type](`%c${message}`, `color:${color}`)
|
|
21
|
-
}
|
|
18
|
+
const { type = "log", color = "black" } = option ?? {};
|
|
19
|
+
let isShow = localStorage.getItem("st-kline-console-show") === "true" ? true : false;
|
|
20
|
+
isShow && console[type](`%c${message}`, `color:${color}`);
|
|
21
|
+
};
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* @description: 格式化数字:保留后三位小数
|
|
@@ -26,8 +26,8 @@ export const printConsole = (message: string, option?: { type?: string; color?:
|
|
|
26
26
|
* @return {*}
|
|
27
27
|
*/
|
|
28
28
|
export const formatValue = (value: number) => {
|
|
29
|
-
return value || value === 0 ? Math.round(value * 1000) / 1000 : null
|
|
30
|
-
}
|
|
29
|
+
return value || value === 0 ? Math.round(value * 1000) / 1000 : null;
|
|
30
|
+
};
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
33
|
* @description: 格式化价格:万 || 亿 || 万亿
|
|
@@ -36,47 +36,47 @@ export const formatValue = (value: number) => {
|
|
|
36
36
|
*/
|
|
37
37
|
export const formatPrice = (value: number) => {
|
|
38
38
|
if (value >= 1000000000000) {
|
|
39
|
-
return `${(value / 1000000000000).toFixed(2)}
|
|
39
|
+
return `${(value / 1000000000000).toFixed(2)}万亿`;
|
|
40
40
|
} else if (value >= 100000000) {
|
|
41
|
-
return `${(value / 100000000).toFixed(2)}
|
|
41
|
+
return `${(value / 100000000).toFixed(2)}亿`;
|
|
42
42
|
} else if (value >= 10000) {
|
|
43
|
-
return `${(value / 10000).toFixed(2)}
|
|
43
|
+
return `${(value / 10000).toFixed(2)}万`;
|
|
44
44
|
} else {
|
|
45
|
-
return value.toFixed(2)
|
|
45
|
+
return value.toFixed(2);
|
|
46
46
|
}
|
|
47
|
-
}
|
|
47
|
+
};
|
|
48
48
|
|
|
49
49
|
// -----------------额外画线工具函数-------------------
|
|
50
50
|
interface InfoType {
|
|
51
|
-
info: any
|
|
52
|
-
config: WarningConfigType | PositionConfigType | ConditionConfigType
|
|
53
|
-
event: GraphicEvent
|
|
51
|
+
info: any;
|
|
52
|
+
config: WarningConfigType | PositionConfigType | ConditionConfigType;
|
|
53
|
+
event: GraphicEvent;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
// 单条线的配置-预警线
|
|
57
57
|
interface warningParamsType {
|
|
58
|
-
y: number
|
|
59
|
-
text: string
|
|
60
|
-
info: InfoType
|
|
61
|
-
gridLeft: number
|
|
62
|
-
gridRight: number
|
|
63
|
-
echartsWidth: number
|
|
64
|
-
echartsInstance: EChartsType
|
|
58
|
+
y: number;
|
|
59
|
+
text: string;
|
|
60
|
+
info: InfoType;
|
|
61
|
+
gridLeft: number;
|
|
62
|
+
gridRight: number;
|
|
63
|
+
echartsWidth: number;
|
|
64
|
+
echartsInstance: EChartsType;
|
|
65
65
|
}
|
|
66
66
|
export const getWarningItem = (params: warningParamsType) => {
|
|
67
67
|
// 1.解构入参
|
|
68
|
-
const { y, text, info, gridLeft, gridRight, echartsWidth, echartsInstance } = params
|
|
69
|
-
const { config, event } = info
|
|
68
|
+
const { y, text, info, gridLeft, gridRight, echartsWidth, echartsInstance } = params;
|
|
69
|
+
const { config, event } = info;
|
|
70
70
|
|
|
71
|
-
let dragStart = 0 // 拖拽开始坐标
|
|
71
|
+
let dragStart = 0; // 拖拽开始坐标
|
|
72
72
|
|
|
73
73
|
// -----------------------------------return-------------------------------------------
|
|
74
74
|
return {
|
|
75
|
-
type:
|
|
76
|
-
draggable: config.draggable ?
|
|
75
|
+
type: "group",
|
|
76
|
+
draggable: config.draggable ? "vertical" : false,
|
|
77
77
|
children: [
|
|
78
78
|
{
|
|
79
|
-
type:
|
|
79
|
+
type: "line",
|
|
80
80
|
info,
|
|
81
81
|
shape: {
|
|
82
82
|
x1: gridLeft,
|
|
@@ -92,18 +92,18 @@ export const getWarningItem = (params: warningParamsType) => {
|
|
|
92
92
|
z: 10,
|
|
93
93
|
},
|
|
94
94
|
{
|
|
95
|
-
type:
|
|
95
|
+
type: "group",
|
|
96
96
|
x: echartsWidth,
|
|
97
97
|
y: y - 5,
|
|
98
98
|
children: [
|
|
99
99
|
{
|
|
100
|
-
type:
|
|
100
|
+
type: "text",
|
|
101
101
|
left: -1 * gridRight,
|
|
102
102
|
info,
|
|
103
103
|
style: {
|
|
104
104
|
fill: config.textColor,
|
|
105
105
|
text,
|
|
106
|
-
stroke:
|
|
106
|
+
stroke: "#000",
|
|
107
107
|
lineWidth: 1,
|
|
108
108
|
opacity: 1,
|
|
109
109
|
},
|
|
@@ -115,83 +115,83 @@ export const getWarningItem = (params: warningParamsType) => {
|
|
|
115
115
|
// 事件:鼠标滑入
|
|
116
116
|
onmouseover: (params: ElementEvent) => {
|
|
117
117
|
if (event.onmouseover instanceof Function) {
|
|
118
|
-
event.onmouseover(params, info)
|
|
118
|
+
event.onmouseover(params, info);
|
|
119
119
|
}
|
|
120
120
|
},
|
|
121
121
|
// 事件:鼠标滑出
|
|
122
122
|
onmouseout: (params: ElementEvent) => {
|
|
123
123
|
if (event.onmouseout instanceof Function) {
|
|
124
|
-
event.onmouseout(params, info)
|
|
124
|
+
event.onmouseout(params, info);
|
|
125
125
|
}
|
|
126
126
|
},
|
|
127
127
|
// 事件:开始拖拽
|
|
128
128
|
ondragstart: (params: ElementEvent) => {
|
|
129
129
|
if (event.ondragstart instanceof Function && config.draggable) {
|
|
130
|
-
dragStart = params.offsetY // 记录拖拽开始坐标
|
|
131
|
-
event.ondragstart(params, info)
|
|
130
|
+
dragStart = params.offsetY; // 记录拖拽开始坐标
|
|
131
|
+
event.ondragstart(params, info);
|
|
132
132
|
}
|
|
133
133
|
},
|
|
134
134
|
// 事件:结束拖拽
|
|
135
135
|
ondragend: (params: ElementEvent) => {
|
|
136
136
|
if (event.ondragend instanceof Function && config.draggable) {
|
|
137
|
-
const dragEnd = params.offsetY // 记录结束拖拽坐标
|
|
138
|
-
const dragInterval = dragEnd - dragStart // 拖拽偏移量
|
|
137
|
+
const dragEnd = params.offsetY; // 记录结束拖拽坐标
|
|
138
|
+
const dragInterval = dragEnd - dragStart; // 拖拽偏移量
|
|
139
139
|
if (dragInterval === 0) {
|
|
140
|
-
return
|
|
140
|
+
return;
|
|
141
141
|
}
|
|
142
|
-
const yAxisValue = echartsInstance.convertFromPixel({ yAxisIndex: 0 }, y + dragInterval)
|
|
143
|
-
event.ondragend(params, info, yAxisValue)
|
|
142
|
+
const yAxisValue = echartsInstance.convertFromPixel({ yAxisIndex: 0 }, y + dragInterval);
|
|
143
|
+
event.ondragend(params, info, yAxisValue);
|
|
144
144
|
}
|
|
145
145
|
},
|
|
146
|
-
}
|
|
147
|
-
}
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
148
|
|
|
149
149
|
// 单条线的配置-持仓线
|
|
150
150
|
interface positionParamsType {
|
|
151
|
-
y: number
|
|
152
|
-
text: string
|
|
153
|
-
info: InfoType
|
|
154
|
-
gridLeft: number
|
|
155
|
-
gridRight: number
|
|
156
|
-
echartsWidth: number
|
|
157
|
-
echartsInstance: EChartsType
|
|
151
|
+
y: number;
|
|
152
|
+
text: string;
|
|
153
|
+
info: InfoType;
|
|
154
|
+
gridLeft: number;
|
|
155
|
+
gridRight: number;
|
|
156
|
+
echartsWidth: number;
|
|
157
|
+
echartsInstance: EChartsType;
|
|
158
158
|
}
|
|
159
159
|
export const getPositionItem = (params: positionParamsType) => {
|
|
160
160
|
// 1.解构入参
|
|
161
|
-
const { y, text, info, gridLeft, gridRight, echartsWidth, echartsInstance } = params
|
|
162
|
-
const { config, event } = info
|
|
161
|
+
const { y, text, info, gridLeft, gridRight, echartsWidth, echartsInstance } = params;
|
|
162
|
+
const { config, event } = info;
|
|
163
163
|
|
|
164
|
-
let dragStart = 0 // 拖拽开始坐标
|
|
164
|
+
let dragStart = 0; // 拖拽开始坐标
|
|
165
165
|
|
|
166
166
|
// --------------------默认鼠标滑入/滑出展示事件: 展示持仓线文本--------------------------
|
|
167
167
|
const defaultOnMouseOver = (params: ElementEvent) => {
|
|
168
|
-
let groupItem: any = null
|
|
169
|
-
if (params.target.type ===
|
|
170
|
-
groupItem = params.target.parent
|
|
171
|
-
} else if (params.target.type ===
|
|
172
|
-
groupItem = params.target.parent.parent.parent
|
|
168
|
+
let groupItem: any = null;
|
|
169
|
+
if (params.target.type === "line") {
|
|
170
|
+
groupItem = params.target.parent;
|
|
171
|
+
} else if (params.target.type === "tspan") {
|
|
172
|
+
groupItem = params.target.parent.parent.parent;
|
|
173
173
|
}
|
|
174
174
|
// 处理持仓线鼠标滑入时展示
|
|
175
|
-
groupItem.children()[1].children()[0].animate(
|
|
176
|
-
}
|
|
175
|
+
groupItem.children()[1].children()[0].animate("style", false).when(200, { opacity: 1 }).start();
|
|
176
|
+
};
|
|
177
177
|
const defaultOnMouseOut = (params: ElementEvent) => {
|
|
178
|
-
let groupItem: any = null
|
|
179
|
-
if (params.target.type ===
|
|
180
|
-
groupItem = params.target.parent
|
|
181
|
-
} else if (params.target.type ===
|
|
182
|
-
groupItem = params.target.parent.parent.parent
|
|
178
|
+
let groupItem: any = null;
|
|
179
|
+
if (params.target.type === "line") {
|
|
180
|
+
groupItem = params.target.parent;
|
|
181
|
+
} else if (params.target.type === "tspan") {
|
|
182
|
+
groupItem = params.target.parent.parent.parent;
|
|
183
183
|
}
|
|
184
184
|
// 处理持仓线鼠标滑出时展示
|
|
185
|
-
groupItem.children()[1].children()[0].animate(
|
|
186
|
-
}
|
|
185
|
+
groupItem.children()[1].children()[0].animate("style", false).when(200, { opacity: 0 }).start();
|
|
186
|
+
};
|
|
187
187
|
|
|
188
188
|
// -----------------------------------return-------------------------------------------
|
|
189
189
|
return {
|
|
190
|
-
type:
|
|
191
|
-
draggable: config.draggable ?
|
|
190
|
+
type: "group",
|
|
191
|
+
draggable: config.draggable ? "vertical" : false, // 是否支持拖拽
|
|
192
192
|
children: [
|
|
193
193
|
{
|
|
194
|
-
type:
|
|
194
|
+
type: "line",
|
|
195
195
|
info,
|
|
196
196
|
shape: {
|
|
197
197
|
x1: gridLeft,
|
|
@@ -206,18 +206,18 @@ export const getPositionItem = (params: positionParamsType) => {
|
|
|
206
206
|
z: 10,
|
|
207
207
|
},
|
|
208
208
|
{
|
|
209
|
-
type:
|
|
209
|
+
type: "group",
|
|
210
210
|
x: echartsWidth / 2,
|
|
211
211
|
y: y - 5,
|
|
212
212
|
children: [
|
|
213
213
|
{
|
|
214
|
-
type:
|
|
215
|
-
left:
|
|
214
|
+
type: "text",
|
|
215
|
+
left: "center",
|
|
216
216
|
info,
|
|
217
217
|
style: {
|
|
218
218
|
fill: config.textColor,
|
|
219
219
|
text,
|
|
220
|
-
stroke:
|
|
220
|
+
stroke: "#000",
|
|
221
221
|
lineWidth: 1,
|
|
222
222
|
opacity: 0, //隐藏文本
|
|
223
223
|
},
|
|
@@ -229,120 +229,120 @@ export const getPositionItem = (params: positionParamsType) => {
|
|
|
229
229
|
// 事件:鼠标滑入
|
|
230
230
|
onmouseover: (params: ElementEvent) => {
|
|
231
231
|
if (event.onmouseover instanceof Function) {
|
|
232
|
-
event.onmouseover(params, info)
|
|
232
|
+
event.onmouseover(params, info);
|
|
233
233
|
} else {
|
|
234
|
-
defaultOnMouseOver(params)
|
|
234
|
+
defaultOnMouseOver(params);
|
|
235
235
|
}
|
|
236
236
|
},
|
|
237
237
|
// 事件:鼠标滑出
|
|
238
238
|
onmouseout: (params: ElementEvent) => {
|
|
239
239
|
if (event.onmouseout instanceof Function) {
|
|
240
|
-
event.onmouseout(params, info)
|
|
240
|
+
event.onmouseout(params, info);
|
|
241
241
|
} else {
|
|
242
|
-
defaultOnMouseOut(params)
|
|
242
|
+
defaultOnMouseOut(params);
|
|
243
243
|
}
|
|
244
244
|
},
|
|
245
245
|
// 事件:开始拖拽
|
|
246
246
|
ondragstart: (params: ElementEvent) => {
|
|
247
247
|
if (event.ondragstart instanceof Function && config.draggable) {
|
|
248
|
-
dragStart = params.offsetY // 记录拖拽开始坐标
|
|
249
|
-
event.ondragstart(params, info)
|
|
248
|
+
dragStart = params.offsetY; // 记录拖拽开始坐标
|
|
249
|
+
event.ondragstart(params, info);
|
|
250
250
|
}
|
|
251
251
|
},
|
|
252
252
|
// 事件:结束拖拽
|
|
253
253
|
ondragend: (params: ElementEvent) => {
|
|
254
254
|
if (event.ondragend instanceof Function && config.draggable) {
|
|
255
|
-
const dragEnd = params.offsetY // 记录结束拖拽坐标
|
|
256
|
-
const dragInterval = dragEnd - dragStart // 拖拽偏移量
|
|
255
|
+
const dragEnd = params.offsetY; // 记录结束拖拽坐标
|
|
256
|
+
const dragInterval = dragEnd - dragStart; // 拖拽偏移量
|
|
257
257
|
if (dragInterval === 0) {
|
|
258
|
-
return
|
|
258
|
+
return;
|
|
259
259
|
}
|
|
260
|
-
const yAxisValue = echartsInstance.convertFromPixel({ yAxisIndex: 0 }, y + dragInterval)
|
|
261
|
-
event.ondragend(params, info, yAxisValue)
|
|
260
|
+
const yAxisValue = echartsInstance.convertFromPixel({ yAxisIndex: 0 }, y + dragInterval);
|
|
261
|
+
event.ondragend(params, info, yAxisValue);
|
|
262
262
|
}
|
|
263
263
|
},
|
|
264
|
-
}
|
|
265
|
-
}
|
|
264
|
+
};
|
|
265
|
+
};
|
|
266
266
|
|
|
267
267
|
// 单条线的配置-条件单
|
|
268
268
|
interface conditionParamsType {
|
|
269
|
-
y: number
|
|
270
|
-
text: string
|
|
271
|
-
profitY: number
|
|
272
|
-
profitText: string
|
|
273
|
-
lossY: number
|
|
274
|
-
lossText: string
|
|
275
|
-
info: InfoType
|
|
276
|
-
gridLeft: number
|
|
277
|
-
gridRight: number
|
|
278
|
-
echartsWidth: number
|
|
279
|
-
echartsInstance: EChartsType
|
|
269
|
+
y: number;
|
|
270
|
+
text: string;
|
|
271
|
+
profitY: number;
|
|
272
|
+
profitText: string;
|
|
273
|
+
lossY: number;
|
|
274
|
+
lossText: string;
|
|
275
|
+
info: InfoType;
|
|
276
|
+
gridLeft: number;
|
|
277
|
+
gridRight: number;
|
|
278
|
+
echartsWidth: number;
|
|
279
|
+
echartsInstance: EChartsType;
|
|
280
280
|
}
|
|
281
281
|
export const getConditionItem = (params: conditionParamsType) => {
|
|
282
282
|
// 1.解构入参
|
|
283
283
|
const { y, text, profitY, profitText, lossY, lossText, info, gridLeft, gridRight, echartsWidth, echartsInstance } =
|
|
284
|
-
params
|
|
285
|
-
const { config, event } = info
|
|
284
|
+
params;
|
|
285
|
+
const { config, event } = info;
|
|
286
286
|
|
|
287
|
-
let dragStart = 0 // 拖拽开始坐标
|
|
287
|
+
let dragStart = 0; // 拖拽开始坐标
|
|
288
288
|
|
|
289
289
|
// --------------------默认鼠标滑入/滑出展示事件: alt展示盈亏线---------------------------
|
|
290
290
|
// 键盘按下事件函数
|
|
291
|
-
let handleKeyDown: any = null
|
|
291
|
+
let handleKeyDown: any = null;
|
|
292
292
|
// 键盘弹起函数
|
|
293
|
-
let handleKeyUp: any = null
|
|
293
|
+
let handleKeyUp: any = null;
|
|
294
294
|
// [展示/隐藏]盈亏线
|
|
295
295
|
const handleProfitLossShow = (groupItem: any, show: boolean) => {
|
|
296
|
-
groupItem.children()[2]?.animate(
|
|
297
|
-
groupItem.children()[3].children()[0]?.animate(
|
|
298
|
-
groupItem.children()[4]?.animate(
|
|
299
|
-
groupItem.children()[5].children()[0]?.animate(
|
|
300
|
-
}
|
|
296
|
+
groupItem.children()[2]?.animate("style", false).when(200, { opacity: ~~show }).start();
|
|
297
|
+
groupItem.children()[3].children()[0]?.animate("style", false).when(200, { opacity: ~~show }).start();
|
|
298
|
+
groupItem.children()[4]?.animate("style", false).when(200, { opacity: ~~show }).start();
|
|
299
|
+
groupItem.children()[5].children()[0]?.animate("style", false).when(200, { opacity: ~~show }).start();
|
|
300
|
+
};
|
|
301
301
|
// 默认的鼠标滑入事件
|
|
302
302
|
const defaultOnMouseOver = (params: ElementEvent) => {
|
|
303
|
-
let groupItem: any = null
|
|
304
|
-
if (params.target.type ===
|
|
305
|
-
groupItem = params.target.parent
|
|
306
|
-
} else if (params.target.type ===
|
|
307
|
-
groupItem = params.target.parent.parent.parent
|
|
303
|
+
let groupItem: any = null;
|
|
304
|
+
if (params.target.type === "line") {
|
|
305
|
+
groupItem = params.target.parent;
|
|
306
|
+
} else if (params.target.type === "tspan") {
|
|
307
|
+
groupItem = params.target.parent.parent.parent;
|
|
308
308
|
}
|
|
309
309
|
// 处理持仓线鼠标滑入+按下alt时展示
|
|
310
|
-
handleKeyDown = e => {
|
|
311
|
-
e.preventDefault()
|
|
312
|
-
if (e.code ===
|
|
313
|
-
handleProfitLossShow(groupItem, true)
|
|
310
|
+
handleKeyDown = (e) => {
|
|
311
|
+
e.preventDefault();
|
|
312
|
+
if (e.code === "AltLeft" || e.code === "AltRight") {
|
|
313
|
+
handleProfitLossShow(groupItem, true);
|
|
314
314
|
}
|
|
315
|
-
}
|
|
316
|
-
handleKeyUp = e => {
|
|
317
|
-
if (e.code ===
|
|
318
|
-
handleProfitLossShow(groupItem, false)
|
|
315
|
+
};
|
|
316
|
+
handleKeyUp = (e) => {
|
|
317
|
+
if (e.code === "AltLeft" || e.code === "AltRight") {
|
|
318
|
+
handleProfitLossShow(groupItem, false);
|
|
319
319
|
}
|
|
320
|
-
}
|
|
321
|
-
window.addEventListener(
|
|
322
|
-
window.addEventListener(
|
|
323
|
-
}
|
|
320
|
+
};
|
|
321
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
322
|
+
window.addEventListener("keyup", handleKeyUp);
|
|
323
|
+
};
|
|
324
324
|
// 默认的鼠标滑出事件
|
|
325
325
|
const defaultOnMouseOut = (params: ElementEvent) => {
|
|
326
|
-
let groupItem: any = null
|
|
327
|
-
if (params.target.type ===
|
|
328
|
-
groupItem = params.target.parent
|
|
329
|
-
} else if (params.target.type ===
|
|
330
|
-
groupItem = params.target.parent.parent.parent
|
|
326
|
+
let groupItem: any = null;
|
|
327
|
+
if (params.target.type === "line") {
|
|
328
|
+
groupItem = params.target.parent;
|
|
329
|
+
} else if (params.target.type === "tspan") {
|
|
330
|
+
groupItem = params.target.parent.parent.parent;
|
|
331
331
|
}
|
|
332
332
|
// 处理持仓线鼠标滑出时展示
|
|
333
|
-
handleProfitLossShow(groupItem, false)
|
|
334
|
-
window.removeEventListener(
|
|
335
|
-
window.removeEventListener(
|
|
336
|
-
}
|
|
333
|
+
handleProfitLossShow(groupItem, false);
|
|
334
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
335
|
+
window.removeEventListener("keyup", handleKeyUp);
|
|
336
|
+
};
|
|
337
337
|
|
|
338
338
|
// -----------------------------------return-------------------------------------------
|
|
339
339
|
return {
|
|
340
|
-
type:
|
|
341
|
-
draggable: config.draggable ?
|
|
340
|
+
type: "group",
|
|
341
|
+
draggable: config.draggable ? "vertical" : false, // 是否支持拖拽
|
|
342
342
|
children: [
|
|
343
343
|
// 条件单-主线
|
|
344
344
|
{
|
|
345
|
-
type:
|
|
345
|
+
type: "line",
|
|
346
346
|
info,
|
|
347
347
|
shape: {
|
|
348
348
|
x1: gridLeft,
|
|
@@ -358,18 +358,18 @@ export const getConditionItem = (params: conditionParamsType) => {
|
|
|
358
358
|
},
|
|
359
359
|
// 条件单-文本内容
|
|
360
360
|
{
|
|
361
|
-
type:
|
|
361
|
+
type: "group",
|
|
362
362
|
x: echartsWidth / 2,
|
|
363
363
|
y: y - 5,
|
|
364
364
|
children: [
|
|
365
365
|
{
|
|
366
|
-
type:
|
|
367
|
-
left:
|
|
366
|
+
type: "text",
|
|
367
|
+
left: "center",
|
|
368
368
|
info,
|
|
369
369
|
style: {
|
|
370
370
|
fill: config.textColor, // 填充色
|
|
371
371
|
text: text,
|
|
372
|
-
stroke:
|
|
372
|
+
stroke: "#000", // 线条颜色
|
|
373
373
|
lineWidth: 1,
|
|
374
374
|
opacity: 1, //直接展示文本
|
|
375
375
|
},
|
|
@@ -379,7 +379,7 @@ export const getConditionItem = (params: conditionParamsType) => {
|
|
|
379
379
|
},
|
|
380
380
|
// 条件单-止盈线
|
|
381
381
|
{
|
|
382
|
-
type:
|
|
382
|
+
type: "line",
|
|
383
383
|
info,
|
|
384
384
|
shape: {
|
|
385
385
|
x1: gridLeft,
|
|
@@ -397,18 +397,18 @@ export const getConditionItem = (params: conditionParamsType) => {
|
|
|
397
397
|
},
|
|
398
398
|
// 条件单-止盈线文本内容
|
|
399
399
|
{
|
|
400
|
-
type:
|
|
400
|
+
type: "group",
|
|
401
401
|
x: echartsWidth / 2,
|
|
402
402
|
y: profitY - 5,
|
|
403
403
|
children: [
|
|
404
404
|
{
|
|
405
|
-
type:
|
|
406
|
-
left:
|
|
405
|
+
type: "text",
|
|
406
|
+
left: "center",
|
|
407
407
|
info,
|
|
408
408
|
style: {
|
|
409
409
|
fill: (config as ConditionConfigType).profitTextColor,
|
|
410
410
|
text: profitText,
|
|
411
|
-
stroke:
|
|
411
|
+
stroke: "#000",
|
|
412
412
|
lineWidth: 1,
|
|
413
413
|
opacity: 0,
|
|
414
414
|
},
|
|
@@ -418,7 +418,7 @@ export const getConditionItem = (params: conditionParamsType) => {
|
|
|
418
418
|
},
|
|
419
419
|
// 条件单-止损线
|
|
420
420
|
{
|
|
421
|
-
type:
|
|
421
|
+
type: "line",
|
|
422
422
|
info,
|
|
423
423
|
shape: {
|
|
424
424
|
x1: gridLeft,
|
|
@@ -436,18 +436,18 @@ export const getConditionItem = (params: conditionParamsType) => {
|
|
|
436
436
|
},
|
|
437
437
|
// 条件单-止损线文本内容
|
|
438
438
|
{
|
|
439
|
-
type:
|
|
439
|
+
type: "group",
|
|
440
440
|
x: echartsWidth / 2,
|
|
441
441
|
y: lossY - 5,
|
|
442
442
|
children: [
|
|
443
443
|
{
|
|
444
|
-
type:
|
|
445
|
-
left:
|
|
444
|
+
type: "text",
|
|
445
|
+
left: "center",
|
|
446
446
|
info,
|
|
447
447
|
style: {
|
|
448
448
|
fill: (config as ConditionConfigType).lossTextColor,
|
|
449
449
|
text: lossText,
|
|
450
|
-
stroke:
|
|
450
|
+
stroke: "#000",
|
|
451
451
|
lineWidth: 1,
|
|
452
452
|
opacity: 0,
|
|
453
453
|
},
|
|
@@ -459,40 +459,40 @@ export const getConditionItem = (params: conditionParamsType) => {
|
|
|
459
459
|
// 事件:鼠标滑入
|
|
460
460
|
onmouseover: (params: ElementEvent) => {
|
|
461
461
|
if (event.onmouseover instanceof Function) {
|
|
462
|
-
event.onmouseover(params, info)
|
|
462
|
+
event.onmouseover(params, info);
|
|
463
463
|
} else {
|
|
464
|
-
defaultOnMouseOver(params)
|
|
464
|
+
defaultOnMouseOver(params);
|
|
465
465
|
}
|
|
466
466
|
},
|
|
467
467
|
// 事件:鼠标滑出
|
|
468
468
|
onmouseout: (params: ElementEvent) => {
|
|
469
469
|
if (event.onmouseout instanceof Function) {
|
|
470
|
-
event.onmouseout(params, info)
|
|
470
|
+
event.onmouseout(params, info);
|
|
471
471
|
} else {
|
|
472
|
-
defaultOnMouseOut(params)
|
|
472
|
+
defaultOnMouseOut(params);
|
|
473
473
|
}
|
|
474
474
|
},
|
|
475
475
|
// 事件:开始拖拽
|
|
476
476
|
ondragstart: (params: ElementEvent) => {
|
|
477
477
|
if (event.ondragstart instanceof Function && config.draggable) {
|
|
478
|
-
dragStart = params.offsetY // 记录拖拽开始坐标
|
|
479
|
-
event.ondragstart(params, info)
|
|
478
|
+
dragStart = params.offsetY; // 记录拖拽开始坐标
|
|
479
|
+
event.ondragstart(params, info);
|
|
480
480
|
}
|
|
481
481
|
},
|
|
482
482
|
// 事件:结束拖拽
|
|
483
483
|
ondragend: (params: ElementEvent) => {
|
|
484
484
|
if (event.ondragend instanceof Function && config.draggable) {
|
|
485
|
-
const dragEnd = params.offsetY // 记录结束拖拽坐标
|
|
486
|
-
const dragInterval = dragEnd - dragStart // 拖拽偏移量
|
|
485
|
+
const dragEnd = params.offsetY; // 记录结束拖拽坐标
|
|
486
|
+
const dragInterval = dragEnd - dragStart; // 拖拽偏移量
|
|
487
487
|
if (dragInterval === 0) {
|
|
488
|
-
return
|
|
488
|
+
return;
|
|
489
489
|
}
|
|
490
|
-
const yAxisValue = echartsInstance.convertFromPixel({ yAxisIndex: 0 }, y + dragInterval)
|
|
491
|
-
event.ondragend(params, info, yAxisValue)
|
|
490
|
+
const yAxisValue = echartsInstance.convertFromPixel({ yAxisIndex: 0 }, y + dragInterval);
|
|
491
|
+
event.ondragend(params, info, yAxisValue);
|
|
492
492
|
}
|
|
493
493
|
},
|
|
494
|
-
}
|
|
495
|
-
}
|
|
494
|
+
};
|
|
495
|
+
};
|
|
496
496
|
|
|
497
497
|
// -----------------点位处理工具函数--------------------
|
|
498
498
|
|
|
@@ -504,26 +504,26 @@ export const getConditionItem = (params: conditionParamsType) => {
|
|
|
504
504
|
*/
|
|
505
505
|
const handleTradeType = (
|
|
506
506
|
data: {
|
|
507
|
-
direction?: string
|
|
508
|
-
tradeAction?: string
|
|
509
|
-
tradeType?: string
|
|
507
|
+
direction?: string;
|
|
508
|
+
tradeAction?: string;
|
|
509
|
+
tradeType?: string;
|
|
510
510
|
},
|
|
511
511
|
type: string
|
|
512
512
|
) => {
|
|
513
|
-
const { direction =
|
|
514
|
-
if (type ===
|
|
515
|
-
const key = tradeType ?? direction + tradeAction
|
|
513
|
+
const { direction = "", tradeAction = "", tradeType = "" } = data;
|
|
514
|
+
if (type === "sellBuy") {
|
|
515
|
+
const key = tradeType ?? direction + tradeAction;
|
|
516
516
|
const keyMap = new Map([
|
|
517
|
-
[
|
|
518
|
-
[
|
|
519
|
-
[
|
|
520
|
-
[
|
|
521
|
-
])
|
|
522
|
-
return keyMap.get(key)
|
|
523
|
-
} else if (type ===
|
|
524
|
-
return tradeType ?? direction + tradeAction
|
|
517
|
+
["开多", "买"],
|
|
518
|
+
["平多", "卖"],
|
|
519
|
+
["开空", "卖"],
|
|
520
|
+
["平空", "买"],
|
|
521
|
+
]);
|
|
522
|
+
return keyMap.get(key);
|
|
523
|
+
} else if (type === "openClose") {
|
|
524
|
+
return tradeType ?? direction + tradeAction;
|
|
525
525
|
}
|
|
526
|
-
}
|
|
526
|
+
};
|
|
527
527
|
|
|
528
528
|
/**
|
|
529
529
|
* @description: 返回买卖点配置
|
|
@@ -532,30 +532,48 @@ const handleTradeType = (
|
|
|
532
532
|
const handleSellBuyConfig = (data: any[], originData: KlineDataType) => {
|
|
533
533
|
return data.reduce((result, next) => {
|
|
534
534
|
// 1.获取交易类型
|
|
535
|
-
const tradeType = handleTradeType(next,
|
|
535
|
+
const tradeType = handleTradeType(next, "sellBuy");
|
|
536
536
|
/**
|
|
537
537
|
* 2.获取标注图标
|
|
538
538
|
* 因为传入参数数据时,已经对数据进行了合并处理,不会出现例如: 两个平空数据于一条K线上,这种情况,所以
|
|
539
539
|
* 简单判断该条K线上是否有多个数据即可判断出是否是买卖同时存在,如果同时存在图标变成T
|
|
540
540
|
*/
|
|
541
|
-
let symbol =
|
|
541
|
+
let symbol = "image://" + new URL(`./images/${tradeType === "买" ? "buy" : "sell"}.svg`, import.meta.url).href;
|
|
542
542
|
if (data.filter((item: any) => item.time === next.time).length > 1) {
|
|
543
|
-
symbol =
|
|
543
|
+
symbol = "image://" + new URL("./images/t.svg", import.meta.url).href;
|
|
544
544
|
}
|
|
545
545
|
// 3.获取对应Y轴值
|
|
546
|
-
const originDataItem = originData.find((item: any) => item[0] === next.time) ?? []
|
|
547
|
-
const yAxisValue = originDataItem[2]
|
|
546
|
+
const originDataItem = originData.find((item: any) => item[0] === next.time) ?? [];
|
|
547
|
+
const yAxisValue = originDataItem[2];
|
|
548
|
+
// 5.连线逻辑处理
|
|
549
|
+
const markLineTarget =
|
|
550
|
+
next?.markLineTarget?.map((target: { time: string; name: string; lineStyle: any }) => {
|
|
551
|
+
const startX = next.time;
|
|
552
|
+
const startY = yAxisValue + "";
|
|
553
|
+
const endX = target.time;
|
|
554
|
+
const endY = originData.find((item: any) => item[0] === target.time)[3];
|
|
555
|
+
return [
|
|
556
|
+
{
|
|
557
|
+
coord: [startX, startY],
|
|
558
|
+
lineStyle: target.lineStyle,
|
|
559
|
+
},
|
|
560
|
+
{
|
|
561
|
+
coord: [endX, endY],
|
|
562
|
+
},
|
|
563
|
+
];
|
|
564
|
+
}) ?? null;
|
|
548
565
|
result.push({
|
|
549
566
|
symbol, // 图标
|
|
550
567
|
symbolSize: 25, // 图标大小
|
|
551
568
|
animation: false, // 是否展示动画
|
|
552
|
-
coord: [next.time +
|
|
569
|
+
coord: [next.time + "", yAxisValue], // X轴[时间],Y轴[最高价]
|
|
553
570
|
symbolRotate: 0, // 旋转角度
|
|
554
|
-
symbolOffset: [0,
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
}
|
|
571
|
+
symbolOffset: [0, "-7"], // 偏移距离
|
|
572
|
+
markLineTarget,
|
|
573
|
+
});
|
|
574
|
+
return result;
|
|
575
|
+
}, []);
|
|
576
|
+
};
|
|
559
577
|
|
|
560
578
|
/**
|
|
561
579
|
* @description: 返回开平点配置
|
|
@@ -564,39 +582,59 @@ const handleSellBuyConfig = (data: any[], originData: KlineDataType) => {
|
|
|
564
582
|
const handleOpenCloseConfig = (data: any[], originData: KlineDataType) => {
|
|
565
583
|
return data.reduce((result, next, index) => {
|
|
566
584
|
// 1.获取交易类型
|
|
567
|
-
const tradeType = handleTradeType(next,
|
|
585
|
+
const tradeType = handleTradeType(next, "openClose");
|
|
568
586
|
// 2.确定位置
|
|
569
|
-
const position = tradeType ===
|
|
587
|
+
const position = tradeType === "开多" || tradeType === "开空" ? "top" : "bottom";
|
|
570
588
|
// 3.获取对应Y轴值
|
|
571
|
-
const originDataItem = originData.find((item: any) => item[0] === next.time) ?? []
|
|
572
|
-
const yAxisValue = position ===
|
|
589
|
+
const originDataItem = originData.find((item: any) => item[0] === next.time) ?? [];
|
|
590
|
+
const yAxisValue = position === "top" ? originDataItem[2] : originDataItem[3];
|
|
573
591
|
// 4.计算偏移量,避免点位重叠
|
|
574
|
-
let offset = 7
|
|
592
|
+
let offset = 7;
|
|
575
593
|
offset +=
|
|
576
594
|
data.slice(0, index).filter((item: any) => {
|
|
577
|
-
const itemTradeType = handleTradeType(item,
|
|
578
|
-
const itemPosition = itemTradeType ===
|
|
579
|
-
return itemPosition === position && item.time === next.time
|
|
580
|
-
}).length * 7
|
|
595
|
+
const itemTradeType = handleTradeType(item, "openClose");
|
|
596
|
+
const itemPosition = itemTradeType === "开多" || itemTradeType === "开空" ? "top" : "bottom";
|
|
597
|
+
return itemPosition === position && item.time === next.time;
|
|
598
|
+
}).length * 7;
|
|
599
|
+
// 5.连线逻辑处理
|
|
600
|
+
const markLineTarget =
|
|
601
|
+
next?.markLineTarget?.map((target: { time: string; name: string; lineStyle: any }) => {
|
|
602
|
+
const startX = next.time;
|
|
603
|
+
const startY = yAxisValue + "";
|
|
604
|
+
const endX = target.time;
|
|
605
|
+
const endY = originData.find((item: any) => item[0] === target.time)[3];
|
|
606
|
+
return [
|
|
607
|
+
{
|
|
608
|
+
coord: [startX, startY],
|
|
609
|
+
lineStyle: target.lineStyle,
|
|
610
|
+
},
|
|
611
|
+
{
|
|
612
|
+
coord: [endX, endY],
|
|
613
|
+
},
|
|
614
|
+
];
|
|
615
|
+
}) ?? null;
|
|
581
616
|
result.push({
|
|
582
|
-
symbol:
|
|
617
|
+
symbol: "triangle", // 图标
|
|
583
618
|
symbolSize: [10, 12], // 图标大小
|
|
584
619
|
animation: false, // 是否展示动画
|
|
585
|
-
coord: [next.time +
|
|
586
|
-
symbolRotate: position ===
|
|
587
|
-
symbolOffset: [0, `${position ===
|
|
588
|
-
itemStyle: { color: position ===
|
|
620
|
+
coord: [next.time + "", yAxisValue], // X轴[时间],Y轴[最高价||最低价]
|
|
621
|
+
symbolRotate: position === "top" ? 180 : 0, //标注旋转角度
|
|
622
|
+
symbolOffset: [0, `${position === "top" ? offset * -1 : offset}`], //标注偏移距离
|
|
623
|
+
itemStyle: { color: position === "top" ? "#FF0000" : "#389e0d" }, // 图标颜色
|
|
589
624
|
// 文本
|
|
590
625
|
label: {
|
|
591
626
|
show: true, // 是否展示
|
|
592
627
|
position,
|
|
593
|
-
color:
|
|
594
|
-
formatter: `${tradeType} ${position ===
|
|
628
|
+
color: "#fff",
|
|
629
|
+
formatter: `${tradeType} ${position === "top" ? "+" : "-"} ${next.amount}手 ${
|
|
630
|
+
next.part ? `(${next.part}份)` : ""
|
|
631
|
+
}`,
|
|
595
632
|
},
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
}
|
|
633
|
+
markLineTarget,
|
|
634
|
+
});
|
|
635
|
+
return result;
|
|
636
|
+
}, []);
|
|
637
|
+
};
|
|
600
638
|
|
|
601
639
|
/**
|
|
602
640
|
* @description: 返回点位配置
|
|
@@ -605,30 +643,30 @@ const handleOpenCloseConfig = (data: any[], originData: KlineDataType) => {
|
|
|
605
643
|
*/
|
|
606
644
|
export const handlePoint = (markData, originData: KlineDataType) => {
|
|
607
645
|
return markData.reduce((result, next) => {
|
|
608
|
-
const { key, data } = next
|
|
646
|
+
const { key, data } = next;
|
|
609
647
|
// 无数据直接循环下一组数据
|
|
610
|
-
if (data === null || data.length === 0) return result
|
|
648
|
+
if (data === null || data.length === 0) return result;
|
|
611
649
|
// 点位数据转换配置项结构
|
|
612
650
|
const configMap = new Map([
|
|
613
651
|
// 买卖点
|
|
614
652
|
[
|
|
615
|
-
|
|
653
|
+
"sellBuy",
|
|
616
654
|
() => {
|
|
617
|
-
return handleSellBuyConfig(data, originData)
|
|
655
|
+
return handleSellBuyConfig(data, originData);
|
|
618
656
|
},
|
|
619
657
|
],
|
|
620
658
|
// 开平点
|
|
621
659
|
[
|
|
622
|
-
|
|
660
|
+
"openClose",
|
|
623
661
|
() => {
|
|
624
|
-
return handleOpenCloseConfig(data, originData)
|
|
662
|
+
return handleOpenCloseConfig(data, originData);
|
|
625
663
|
},
|
|
626
664
|
],
|
|
627
665
|
// 信号点
|
|
628
|
-
[
|
|
629
|
-
])
|
|
630
|
-
const callBack = configMap.get(key)
|
|
631
|
-
if (callBack instanceof Function) result.push(...callBack())
|
|
632
|
-
return result
|
|
633
|
-
}, [])
|
|
634
|
-
}
|
|
666
|
+
["signal", () => {}],
|
|
667
|
+
]);
|
|
668
|
+
const callBack = configMap.get(key);
|
|
669
|
+
if (callBack instanceof Function) result.push(...callBack());
|
|
670
|
+
return result;
|
|
671
|
+
}, []);
|
|
672
|
+
};
|