st-comp 0.0.13 → 0.0.16
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/auto-imports.d.ts +1 -1
- package/components.d.ts +2 -1
- package/lib/bundle.js +10145 -9151
- package/lib/bundle.umd.cjs +10 -12
- package/lib/style.css +1 -1
- package/lib/talib.wasm +0 -0
- package/package.json +4 -1
- package/packages/Kline/components/Contextmenu/index.vue +110 -0
- package/packages/Kline/components/Tips/index.vue +18 -86
- package/packages/Kline/formatKlineData.ts +67 -40
- package/packages/Kline/images/buy.svg +1 -0
- package/packages/Kline/images/pen.png +0 -0
- package/packages/Kline/images/sell.svg +1 -0
- package/packages/Kline/images/t.svg +1 -0
- package/packages/Kline/index.vue +439 -119
- package/packages/Kline/option.ts +316 -0
- package/packages/Kline/type.d.ts +192 -24
- package/packages/Kline/utils.ts +576 -171
- package/packages/Table/components/Button/index.vue +7 -0
- package/packages/Table/index.vue +37 -24
- package/packages/index.ts +0 -2
- package/public/talib.wasm +0 -0
- package/src/pages/ChartLayout/index.vue +22 -22
- package/src/pages/Kline/api.ts +57 -0
- package/src/pages/Kline/components/MultiCycleSingleVariety.vue +728 -0
- package/src/pages/Kline/components/SingleCycleSingleVariety.vue +663 -0
- package/src/pages/Kline/index.vue +85 -16
- package/src/router/routes.ts +0 -5
- package/src/style.css +75 -0
- package/vite.config.ts +37 -27
- package/vitePlugins/testRelese.ts +67 -0
- package/packages/Echarts/index.ts +0 -8
- package/packages/Echarts/index.vue +0 -113
- package/packages/Kline/kline_theme_dark.json +0 -30
- package/packages/Kline/kline_theme_light.json +0 -30
- package/src/components/Echarts/index.vue +0 -31
- package/src/pages/Echarts/index.vue +0 -12
package/packages/Kline/utils.ts
CHANGED
|
@@ -1,54 +1,23 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
1
|
+
import type { EChartsType, ElementEvent } from 'echarts'
|
|
2
|
+
import type {
|
|
3
|
+
KlineDataType,
|
|
4
|
+
WarningConfigType,
|
|
5
|
+
PositionConfigType,
|
|
6
|
+
ConditionConfigType,
|
|
7
|
+
GraphicEvent,
|
|
8
|
+
} from './type.d.ts'
|
|
4
9
|
|
|
5
|
-
|
|
6
|
-
* @description: 获取K线数据
|
|
7
|
-
* @param {string} code 品种代码
|
|
8
|
-
* @param {number} bar_count 请求数据条数
|
|
9
|
-
* @param {string} tradeDate 交易日期
|
|
10
|
-
* @param {string} frequency 周期
|
|
11
|
-
* @return {*}
|
|
12
|
-
*/
|
|
13
|
-
export const getKline = async (
|
|
14
|
-
code: string,
|
|
15
|
-
bar_count: number,
|
|
16
|
-
tradeDate: string,
|
|
17
|
-
frequency: string
|
|
18
|
-
) => {
|
|
19
|
-
let dt: null | string = dayjs(tradeDate).format('YYYY-MM-DD HH:mm:ss')
|
|
20
|
-
return axios(
|
|
21
|
-
`http://116.62.161.92:8005/history_kline?code=${code}&bar_count=${bar_count}&dt=${dt}&frequency=${frequency}`
|
|
22
|
-
)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* @description: 获取指标线下拉列表类型数据以及相关样式配置
|
|
27
|
-
* @return {*}
|
|
28
|
-
*/
|
|
29
|
-
export const getIndicatorConfigList = () => {
|
|
30
|
-
return axios('http://116.62.161.92:8005/get_indicator')
|
|
31
|
-
}
|
|
10
|
+
// ------------------普通工具函数---------------------
|
|
32
11
|
|
|
33
12
|
/**
|
|
34
|
-
* @description:
|
|
35
|
-
* @param {
|
|
36
|
-
* @param {
|
|
37
|
-
* @param {string} end_date 结束日期
|
|
38
|
-
* @param {string} frequency 周期
|
|
39
|
-
* @param {string} indicator 指标类型
|
|
40
|
-
* @return {*}
|
|
13
|
+
* @description: console方法封装
|
|
14
|
+
* @param {String} message 消息文本
|
|
15
|
+
* @param {Object} option 配置选项
|
|
41
16
|
*/
|
|
42
|
-
export const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
frequency: string,
|
|
47
|
-
indicator: string
|
|
48
|
-
) => {
|
|
49
|
-
return axios(
|
|
50
|
-
`http://116.62.161.92:8005/realtime_indicator?code=${code}&start_date=${start_date}&end_date=${end_date}&indicator=${indicator}&frequency=${frequency}`
|
|
51
|
-
)
|
|
17
|
+
export const printConsole = (message: string, option?: { type?: string; color?: string }) => {
|
|
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}`)
|
|
52
21
|
}
|
|
53
22
|
|
|
54
23
|
/**
|
|
@@ -77,153 +46,589 @@ export const formatPrice = (value: number) => {
|
|
|
77
46
|
}
|
|
78
47
|
}
|
|
79
48
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// 处理指标线数据
|
|
103
|
-
const indicatorInfo = indicatorConfigList[indicator]
|
|
104
|
-
const lineSeries = indicatorData
|
|
105
|
-
? Object.keys(indicatorData[0])
|
|
106
|
-
.filter(i => i !== 'datetime')
|
|
107
|
-
.map((key: string) => {
|
|
108
|
-
let color = 'rgba(238, 238, 238, 0.5)'
|
|
109
|
-
if (indicatorInfo && indicatorInfo[key]) {
|
|
110
|
-
color = `#${indicatorInfo[key].split('#')[1]}`
|
|
111
|
-
}
|
|
112
|
-
return {
|
|
113
|
-
name: key,
|
|
114
|
-
type: 'line',
|
|
115
|
-
symbol: 'none',
|
|
116
|
-
data: indicatorData.map(i => i[key]),
|
|
117
|
-
lineStyle: {
|
|
118
|
-
width: 1,
|
|
119
|
-
},
|
|
120
|
-
itemStyle: {
|
|
121
|
-
color,
|
|
122
|
-
},
|
|
123
|
-
}
|
|
124
|
-
})
|
|
125
|
-
: []
|
|
49
|
+
// -----------------额外画线工具函数-------------------
|
|
50
|
+
interface InfoType {
|
|
51
|
+
info: any
|
|
52
|
+
config: WarningConfigType | PositionConfigType | ConditionConfigType
|
|
53
|
+
event: GraphicEvent
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// 单条线的配置-预警线
|
|
57
|
+
interface warningParamsType {
|
|
58
|
+
y: number
|
|
59
|
+
text: string
|
|
60
|
+
info: InfoType
|
|
61
|
+
gridLeft: number
|
|
62
|
+
gridRight: number
|
|
63
|
+
echartsWidth: number
|
|
64
|
+
echartsInstance: EChartsType
|
|
65
|
+
}
|
|
66
|
+
export const getWarningItem = (params: warningParamsType) => {
|
|
67
|
+
// 1.解构入参
|
|
68
|
+
const { y, text, info, gridLeft, gridRight, echartsWidth, echartsInstance } = params
|
|
69
|
+
const { config, event } = info
|
|
126
70
|
|
|
71
|
+
let dragStart = 0 // 拖拽开始坐标
|
|
72
|
+
|
|
73
|
+
// -----------------------------------return-------------------------------------------
|
|
127
74
|
return {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
75
|
+
type: 'group',
|
|
76
|
+
draggable: config.draggable ? 'vertical' : false,
|
|
77
|
+
children: [
|
|
78
|
+
{
|
|
79
|
+
type: 'line',
|
|
80
|
+
info,
|
|
81
|
+
shape: {
|
|
82
|
+
x1: gridLeft,
|
|
83
|
+
y1: y,
|
|
84
|
+
x2: echartsWidth - gridRight,
|
|
85
|
+
y2: y,
|
|
86
|
+
},
|
|
87
|
+
style: {
|
|
88
|
+
stroke: config.lineColor,
|
|
89
|
+
lineWidth: 1,
|
|
90
|
+
lineDash: [8, 4],
|
|
91
|
+
},
|
|
92
|
+
z: 10,
|
|
132
93
|
},
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
} else {
|
|
151
|
-
return String(formatValue(value))
|
|
152
|
-
}
|
|
94
|
+
{
|
|
95
|
+
type: 'group',
|
|
96
|
+
x: echartsWidth,
|
|
97
|
+
y: y - 5,
|
|
98
|
+
children: [
|
|
99
|
+
{
|
|
100
|
+
type: 'text',
|
|
101
|
+
left: -1 * gridRight,
|
|
102
|
+
info,
|
|
103
|
+
style: {
|
|
104
|
+
fill: config.textColor,
|
|
105
|
+
text,
|
|
106
|
+
stroke: '#000',
|
|
107
|
+
lineWidth: 1,
|
|
108
|
+
opacity: 1,
|
|
109
|
+
},
|
|
110
|
+
z: 10,
|
|
153
111
|
},
|
|
154
|
-
|
|
112
|
+
],
|
|
155
113
|
},
|
|
114
|
+
],
|
|
115
|
+
// 事件:鼠标滑入
|
|
116
|
+
onmouseover: (params: ElementEvent) => {
|
|
117
|
+
if (event.onmouseover instanceof Function) {
|
|
118
|
+
event.onmouseover(params, info)
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
// 事件:鼠标滑出
|
|
122
|
+
onmouseout: (params: ElementEvent) => {
|
|
123
|
+
if (event.onmouseout instanceof Function) {
|
|
124
|
+
event.onmouseout(params, info)
|
|
125
|
+
}
|
|
156
126
|
},
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
127
|
+
// 事件:开始拖拽
|
|
128
|
+
ondragstart: (params: ElementEvent) => {
|
|
129
|
+
if (event.ondragstart instanceof Function && config.draggable) {
|
|
130
|
+
dragStart = params.offsetY // 记录拖拽开始坐标
|
|
131
|
+
event.ondragstart(params, info)
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
// 事件:结束拖拽
|
|
135
|
+
ondragend: (params: ElementEvent) => {
|
|
136
|
+
if (event.ondragend instanceof Function && config.draggable) {
|
|
137
|
+
const dragEnd = params.offsetY // 记录结束拖拽坐标
|
|
138
|
+
const dragInterval = dragEnd - dragStart // 拖拽偏移量
|
|
139
|
+
if (dragInterval === 0) {
|
|
140
|
+
return
|
|
141
|
+
}
|
|
142
|
+
const yAxisValue = echartsInstance.convertFromPixel({ yAxisIndex: 0 }, y + dragInterval)
|
|
143
|
+
event.ondragend(params, info, yAxisValue)
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// 单条线的配置-持仓线
|
|
150
|
+
interface positionParamsType {
|
|
151
|
+
y: number
|
|
152
|
+
text: string
|
|
153
|
+
info: InfoType
|
|
154
|
+
gridLeft: number
|
|
155
|
+
gridRight: number
|
|
156
|
+
echartsWidth: number
|
|
157
|
+
echartsInstance: EChartsType
|
|
158
|
+
}
|
|
159
|
+
export const getPositionItem = (params: positionParamsType) => {
|
|
160
|
+
// 1.解构入参
|
|
161
|
+
const { y, text, info, gridLeft, gridRight, echartsWidth, echartsInstance } = params
|
|
162
|
+
const { config, event } = info
|
|
163
|
+
|
|
164
|
+
let dragStart = 0 // 拖拽开始坐标
|
|
165
|
+
|
|
166
|
+
// --------------------默认鼠标滑入/滑出展示事件: 展示持仓线文本--------------------------
|
|
167
|
+
const defaultOnMouseOver = (params: ElementEvent) => {
|
|
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
|
+
}
|
|
174
|
+
// 处理持仓线鼠标滑入时展示
|
|
175
|
+
groupItem.children()[1].children()[0].animate('style', false).when(200, { opacity: 1 }).start()
|
|
176
|
+
}
|
|
177
|
+
const defaultOnMouseOut = (params: ElementEvent) => {
|
|
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
|
+
}
|
|
184
|
+
// 处理持仓线鼠标滑出时展示
|
|
185
|
+
groupItem.children()[1].children()[0].animate('style', false).when(200, { opacity: 0 }).start()
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// -----------------------------------return-------------------------------------------
|
|
189
|
+
return {
|
|
190
|
+
type: 'group',
|
|
191
|
+
draggable: config.draggable ? 'vertical' : false, // 是否支持拖拽
|
|
192
|
+
children: [
|
|
193
|
+
{
|
|
194
|
+
type: 'line',
|
|
195
|
+
info,
|
|
196
|
+
shape: {
|
|
197
|
+
x1: gridLeft,
|
|
198
|
+
y1: y,
|
|
199
|
+
x2: echartsWidth - gridRight,
|
|
200
|
+
y2: y,
|
|
163
201
|
},
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
lineStyle: {
|
|
168
|
-
type: 'dotted',
|
|
202
|
+
style: {
|
|
203
|
+
stroke: config.lineColor,
|
|
204
|
+
lineWidth: 1,
|
|
169
205
|
},
|
|
206
|
+
z: 10,
|
|
170
207
|
},
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
208
|
+
{
|
|
209
|
+
type: 'group',
|
|
210
|
+
x: echartsWidth / 2,
|
|
211
|
+
y: y - 5,
|
|
212
|
+
children: [
|
|
213
|
+
{
|
|
214
|
+
type: 'text',
|
|
215
|
+
left: 'center',
|
|
216
|
+
info,
|
|
217
|
+
style: {
|
|
218
|
+
fill: config.textColor,
|
|
219
|
+
text,
|
|
220
|
+
stroke: '#000',
|
|
221
|
+
lineWidth: 1,
|
|
222
|
+
opacity: 0, //隐藏文本
|
|
223
|
+
},
|
|
224
|
+
z: 10,
|
|
225
|
+
},
|
|
226
|
+
],
|
|
174
227
|
},
|
|
228
|
+
],
|
|
229
|
+
// 事件:鼠标滑入
|
|
230
|
+
onmouseover: (params: ElementEvent) => {
|
|
231
|
+
if (event.onmouseover instanceof Function) {
|
|
232
|
+
event.onmouseover(params, info)
|
|
233
|
+
} else {
|
|
234
|
+
defaultOnMouseOver(params)
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
// 事件:鼠标滑出
|
|
238
|
+
onmouseout: (params: ElementEvent) => {
|
|
239
|
+
if (event.onmouseout instanceof Function) {
|
|
240
|
+
event.onmouseout(params, info)
|
|
241
|
+
} else {
|
|
242
|
+
defaultOnMouseOut(params)
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
// 事件:开始拖拽
|
|
246
|
+
ondragstart: (params: ElementEvent) => {
|
|
247
|
+
if (event.ondragstart instanceof Function && config.draggable) {
|
|
248
|
+
dragStart = params.offsetY // 记录拖拽开始坐标
|
|
249
|
+
event.ondragstart(params, info)
|
|
250
|
+
}
|
|
175
251
|
},
|
|
176
|
-
|
|
252
|
+
// 事件:结束拖拽
|
|
253
|
+
ondragend: (params: ElementEvent) => {
|
|
254
|
+
if (event.ondragend instanceof Function && config.draggable) {
|
|
255
|
+
const dragEnd = params.offsetY // 记录结束拖拽坐标
|
|
256
|
+
const dragInterval = dragEnd - dragStart // 拖拽偏移量
|
|
257
|
+
if (dragInterval === 0) {
|
|
258
|
+
return
|
|
259
|
+
}
|
|
260
|
+
const yAxisValue = echartsInstance.convertFromPixel({ yAxisIndex: 0 }, y + dragInterval)
|
|
261
|
+
event.ondragend(params, info, yAxisValue)
|
|
262
|
+
}
|
|
263
|
+
},
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// 单条线的配置-条件单
|
|
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
|
|
280
|
+
}
|
|
281
|
+
export const getConditionItem = (params: conditionParamsType) => {
|
|
282
|
+
// 1.解构入参
|
|
283
|
+
const { y, text, profitY, profitText, lossY, lossText, info, gridLeft, gridRight, echartsWidth, echartsInstance } =
|
|
284
|
+
params
|
|
285
|
+
const { config, event } = info
|
|
286
|
+
|
|
287
|
+
let dragStart = 0 // 拖拽开始坐标
|
|
288
|
+
|
|
289
|
+
// --------------------默认鼠标滑入/滑出展示事件: alt展示盈亏线---------------------------
|
|
290
|
+
// 键盘按下事件函数
|
|
291
|
+
let handleKeyDown: any = null
|
|
292
|
+
// 键盘弹起函数
|
|
293
|
+
let handleKeyUp: any = null
|
|
294
|
+
// [展示/隐藏]盈亏线
|
|
295
|
+
const handleProfitLossShow = (groupItem: any, show: boolean) => {
|
|
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
|
+
// 默认的鼠标滑入事件
|
|
302
|
+
const defaultOnMouseOver = (params: ElementEvent) => {
|
|
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
|
+
}
|
|
309
|
+
// 处理持仓线鼠标滑入+按下alt时展示
|
|
310
|
+
handleKeyDown = e => {
|
|
311
|
+
e.preventDefault()
|
|
312
|
+
if (e.code === 'AltLeft' || e.code === 'AltRight') {
|
|
313
|
+
handleProfitLossShow(groupItem, true)
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
handleKeyUp = e => {
|
|
317
|
+
if (e.code === 'AltLeft' || e.code === 'AltRight') {
|
|
318
|
+
handleProfitLossShow(groupItem, false)
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
window.addEventListener('keydown', handleKeyDown)
|
|
322
|
+
window.addEventListener('keyup', handleKeyUp)
|
|
323
|
+
}
|
|
324
|
+
// 默认的鼠标滑出事件
|
|
325
|
+
const defaultOnMouseOut = (params: ElementEvent) => {
|
|
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
|
+
}
|
|
332
|
+
// 处理持仓线鼠标滑出时展示
|
|
333
|
+
handleProfitLossShow(groupItem, false)
|
|
334
|
+
window.removeEventListener('keydown', handleKeyDown)
|
|
335
|
+
window.removeEventListener('keyup', handleKeyUp)
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// -----------------------------------return-------------------------------------------
|
|
339
|
+
return {
|
|
340
|
+
type: 'group',
|
|
341
|
+
draggable: config.draggable ? 'vertical' : false, // 是否支持拖拽
|
|
342
|
+
children: [
|
|
343
|
+
// 条件单-主线
|
|
177
344
|
{
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
345
|
+
type: 'line',
|
|
346
|
+
info,
|
|
347
|
+
shape: {
|
|
348
|
+
x1: gridLeft,
|
|
349
|
+
y1: y,
|
|
350
|
+
x2: echartsWidth - gridRight,
|
|
351
|
+
y2: y,
|
|
352
|
+
},
|
|
353
|
+
style: {
|
|
354
|
+
stroke: config.lineColor,
|
|
355
|
+
lineWidth: 1,
|
|
185
356
|
},
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
357
|
+
z: 10,
|
|
358
|
+
},
|
|
359
|
+
// 条件单-文本内容
|
|
360
|
+
{
|
|
361
|
+
type: 'group',
|
|
362
|
+
x: echartsWidth / 2,
|
|
363
|
+
y: y - 5,
|
|
364
|
+
children: [
|
|
365
|
+
{
|
|
366
|
+
type: 'text',
|
|
367
|
+
left: 'center',
|
|
368
|
+
info,
|
|
369
|
+
style: {
|
|
370
|
+
fill: config.textColor, // 填充色
|
|
371
|
+
text: text,
|
|
372
|
+
stroke: '#000', // 线条颜色
|
|
373
|
+
lineWidth: 1,
|
|
374
|
+
opacity: 1, //直接展示文本
|
|
375
|
+
},
|
|
376
|
+
z: 10,
|
|
190
377
|
},
|
|
378
|
+
],
|
|
379
|
+
},
|
|
380
|
+
// 条件单-止盈线
|
|
381
|
+
{
|
|
382
|
+
type: 'line',
|
|
383
|
+
info,
|
|
384
|
+
shape: {
|
|
385
|
+
x1: gridLeft,
|
|
386
|
+
y1: profitY,
|
|
387
|
+
x2: echartsWidth - gridRight,
|
|
388
|
+
y2: profitY,
|
|
191
389
|
},
|
|
192
|
-
|
|
193
|
-
|
|
390
|
+
style: {
|
|
391
|
+
stroke: (config as ConditionConfigType).profitLineColor,
|
|
392
|
+
lineWidth: 1,
|
|
393
|
+
lineDash: [8, 4],
|
|
394
|
+
opacity: 0,
|
|
194
395
|
},
|
|
396
|
+
z: 10,
|
|
195
397
|
},
|
|
196
|
-
|
|
197
|
-
dataZoom: [
|
|
398
|
+
// 条件单-止盈线文本内容
|
|
198
399
|
{
|
|
199
|
-
type: '
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
400
|
+
type: 'group',
|
|
401
|
+
x: echartsWidth / 2,
|
|
402
|
+
y: profitY - 5,
|
|
403
|
+
children: [
|
|
404
|
+
{
|
|
405
|
+
type: 'text',
|
|
406
|
+
left: 'center',
|
|
407
|
+
info,
|
|
408
|
+
style: {
|
|
409
|
+
fill: (config as ConditionConfigType).profitTextColor,
|
|
410
|
+
text: profitText,
|
|
411
|
+
stroke: '#000',
|
|
412
|
+
lineWidth: 1,
|
|
413
|
+
opacity: 0,
|
|
414
|
+
},
|
|
415
|
+
z: 10,
|
|
416
|
+
},
|
|
417
|
+
],
|
|
203
418
|
},
|
|
204
|
-
|
|
205
|
-
series: [
|
|
419
|
+
// 条件单-止损线
|
|
206
420
|
{
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
421
|
+
type: 'line',
|
|
422
|
+
info,
|
|
423
|
+
shape: {
|
|
424
|
+
x1: gridLeft,
|
|
425
|
+
y1: lossY,
|
|
426
|
+
x2: echartsWidth - gridRight,
|
|
427
|
+
y2: lossY,
|
|
428
|
+
},
|
|
429
|
+
style: {
|
|
430
|
+
stroke: (config as ConditionConfigType).lossLineColor,
|
|
431
|
+
lineWidth: 1,
|
|
432
|
+
lineDash: [8, 4],
|
|
433
|
+
opacity: 0,
|
|
434
|
+
},
|
|
435
|
+
z: 10,
|
|
436
|
+
},
|
|
437
|
+
// 条件单-止损线文本内容
|
|
438
|
+
{
|
|
439
|
+
type: 'group',
|
|
440
|
+
x: echartsWidth / 2,
|
|
441
|
+
y: lossY - 5,
|
|
442
|
+
children: [
|
|
443
|
+
{
|
|
444
|
+
type: 'text',
|
|
445
|
+
left: 'center',
|
|
446
|
+
info,
|
|
447
|
+
style: {
|
|
448
|
+
fill: (config as ConditionConfigType).lossTextColor,
|
|
449
|
+
text: lossText,
|
|
450
|
+
stroke: '#000',
|
|
451
|
+
lineWidth: 1,
|
|
452
|
+
opacity: 0,
|
|
453
|
+
},
|
|
454
|
+
z: 10,
|
|
455
|
+
},
|
|
456
|
+
],
|
|
210
457
|
},
|
|
211
|
-
...lineSeries,
|
|
212
458
|
],
|
|
213
|
-
|
|
214
|
-
|
|
459
|
+
// 事件:鼠标滑入
|
|
460
|
+
onmouseover: (params: ElementEvent) => {
|
|
461
|
+
if (event.onmouseover instanceof Function) {
|
|
462
|
+
event.onmouseover(params, info)
|
|
463
|
+
} else {
|
|
464
|
+
defaultOnMouseOver(params)
|
|
465
|
+
}
|
|
215
466
|
},
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
467
|
+
// 事件:鼠标滑出
|
|
468
|
+
onmouseout: (params: ElementEvent) => {
|
|
469
|
+
if (event.onmouseout instanceof Function) {
|
|
470
|
+
event.onmouseout(params, info)
|
|
471
|
+
} else {
|
|
472
|
+
defaultOnMouseOut(params)
|
|
473
|
+
}
|
|
474
|
+
},
|
|
475
|
+
// 事件:开始拖拽
|
|
476
|
+
ondragstart: (params: ElementEvent) => {
|
|
477
|
+
if (event.ondragstart instanceof Function && config.draggable) {
|
|
478
|
+
dragStart = params.offsetY // 记录拖拽开始坐标
|
|
479
|
+
event.ondragstart(params, info)
|
|
480
|
+
}
|
|
227
481
|
},
|
|
482
|
+
// 事件:结束拖拽
|
|
483
|
+
ondragend: (params: ElementEvent) => {
|
|
484
|
+
if (event.ondragend instanceof Function && config.draggable) {
|
|
485
|
+
const dragEnd = params.offsetY // 记录结束拖拽坐标
|
|
486
|
+
const dragInterval = dragEnd - dragStart // 拖拽偏移量
|
|
487
|
+
if (dragInterval === 0) {
|
|
488
|
+
return
|
|
489
|
+
}
|
|
490
|
+
const yAxisValue = echartsInstance.convertFromPixel({ yAxisIndex: 0 }, y + dragInterval)
|
|
491
|
+
event.ondragend(params, info, yAxisValue)
|
|
492
|
+
}
|
|
493
|
+
},
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// -----------------点位处理工具函数--------------------
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* @description: 返回交易类型
|
|
501
|
+
* @param {Object} data 单个点位数据
|
|
502
|
+
* @param {String} type 买卖点[sellbuy], 开平点[openClose]
|
|
503
|
+
* @returns {String} tradeType
|
|
504
|
+
*/
|
|
505
|
+
const handleTradeType = (
|
|
506
|
+
data: {
|
|
507
|
+
direction?: string
|
|
508
|
+
tradeAction?: string
|
|
509
|
+
tradeType?: string
|
|
510
|
+
},
|
|
511
|
+
type: string
|
|
512
|
+
) => {
|
|
513
|
+
const { direction = '', tradeAction = '', tradeType = '' } = data
|
|
514
|
+
if (type === 'sellBuy') {
|
|
515
|
+
const key = tradeType ?? direction + tradeAction
|
|
516
|
+
const keyMap = new Map([
|
|
517
|
+
['开多', '买'],
|
|
518
|
+
['平多', '卖'],
|
|
519
|
+
['开空', '卖'],
|
|
520
|
+
['平空', '买'],
|
|
521
|
+
])
|
|
522
|
+
return keyMap.get(key)
|
|
523
|
+
} else if (type === 'openClose') {
|
|
524
|
+
return tradeType ?? direction + tradeAction
|
|
228
525
|
}
|
|
229
526
|
}
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* @description: 返回买卖点配置
|
|
530
|
+
* @todo: 均标注在K线最上方
|
|
531
|
+
*/
|
|
532
|
+
const handleSellBuyConfig = (data: any[], originData: KlineDataType) => {
|
|
533
|
+
return data.reduce((result, next) => {
|
|
534
|
+
// 1.获取交易类型
|
|
535
|
+
const tradeType = handleTradeType(next, 'sellBuy')
|
|
536
|
+
/**
|
|
537
|
+
* 2.获取标注图标
|
|
538
|
+
* 因为传入参数数据时,已经对数据进行了合并处理,不会出现例如: 两个平空数据于一条K线上,这种情况,所以
|
|
539
|
+
* 简单判断该条K线上是否有多个数据即可判断出是否是买卖同时存在,如果同时存在图标变成T
|
|
540
|
+
*/
|
|
541
|
+
let symbol = 'image://' + new URL(`./images/${tradeType === '买' ? 'buy' : 'sell'}.svg`, import.meta.url).href
|
|
542
|
+
if (data.filter((item: any) => item.time === next.time).length > 1) {
|
|
543
|
+
symbol = 'image://' + new URL('./images/t.svg', import.meta.url).href
|
|
544
|
+
}
|
|
545
|
+
// 3.获取对应Y轴值
|
|
546
|
+
const originDataItem = originData.find((item: any) => item[0] === next.time) ?? []
|
|
547
|
+
const yAxisValue = originDataItem[2]
|
|
548
|
+
result.push({
|
|
549
|
+
symbol, // 图标
|
|
550
|
+
symbolSize: 25, // 图标大小
|
|
551
|
+
animation: false, // 是否展示动画
|
|
552
|
+
coord: [next.time + '', yAxisValue], // X轴[时间],Y轴[最高价]
|
|
553
|
+
symbolRotate: 0, // 旋转角度
|
|
554
|
+
symbolOffset: [0, '-7'], // 偏移距离
|
|
555
|
+
})
|
|
556
|
+
return result
|
|
557
|
+
}, [])
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* @description: 返回开平点配置
|
|
562
|
+
* @todo: 开标注在K线最上方,平标注在K线最下方
|
|
563
|
+
*/
|
|
564
|
+
const handleOpenCloseConfig = (data: any[], originData: KlineDataType) => {
|
|
565
|
+
return data.reduce((result, next, index) => {
|
|
566
|
+
// 1.获取交易类型
|
|
567
|
+
const tradeType = handleTradeType(next, 'openClose')
|
|
568
|
+
// 2.确定位置
|
|
569
|
+
const position = tradeType === '开多' || tradeType === '开空' ? 'top' : 'bottom'
|
|
570
|
+
// 3.获取对应Y轴值
|
|
571
|
+
const originDataItem = originData.find((item: any) => item[0] === next.time) ?? []
|
|
572
|
+
const yAxisValue = position === 'top' ? originDataItem[2] : originDataItem[3]
|
|
573
|
+
// 4.计算偏移量,避免点位重叠
|
|
574
|
+
let offset = 7
|
|
575
|
+
offset +=
|
|
576
|
+
data.slice(0, index).filter((item: any) => {
|
|
577
|
+
const itemTradeType = handleTradeType(item, 'openClose')
|
|
578
|
+
const itemPosition = itemTradeType === '开多' || itemTradeType === '开空' ? 'top' : 'bottom'
|
|
579
|
+
return itemPosition === position && item.time === next.time
|
|
580
|
+
}).length * 7
|
|
581
|
+
result.push({
|
|
582
|
+
symbol: 'triangle', // 图标
|
|
583
|
+
symbolSize: [10, 12], // 图标大小
|
|
584
|
+
animation: false, // 是否展示动画
|
|
585
|
+
coord: [next.time + '', yAxisValue], // X轴[时间],Y轴[最高价||最低价]
|
|
586
|
+
symbolRotate: position === 'top' ? 180 : 0, //标注旋转角度
|
|
587
|
+
symbolOffset: [0, `${position === 'top' ? offset * -1 : offset}`], //标注偏移距离
|
|
588
|
+
itemStyle: { color: position === 'top' ? '#FF0000' : '#389e0d' }, // 图标颜色
|
|
589
|
+
// 文本
|
|
590
|
+
label: {
|
|
591
|
+
show: true, // 是否展示
|
|
592
|
+
position,
|
|
593
|
+
color: '#fff',
|
|
594
|
+
formatter: `${tradeType} ${position === 'top' ? '+' : '-'} ${next.amount}手 (${next.part}份)`,
|
|
595
|
+
},
|
|
596
|
+
})
|
|
597
|
+
return result
|
|
598
|
+
}, [])
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
/**
|
|
602
|
+
* @description: 返回点位配置
|
|
603
|
+
* @param {Array} markData 点位数据
|
|
604
|
+
* @param {Array} originData K线源数据
|
|
605
|
+
*/
|
|
606
|
+
export const handlePoint = (markData, originData: KlineDataType) => {
|
|
607
|
+
return markData.reduce((result, next) => {
|
|
608
|
+
const { key, data } = next
|
|
609
|
+
// 无数据直接循环下一组数据
|
|
610
|
+
if (data === null || data.length === 0) return result
|
|
611
|
+
// 点位数据转换配置项结构
|
|
612
|
+
const configMap = new Map([
|
|
613
|
+
// 买卖点
|
|
614
|
+
[
|
|
615
|
+
'sellBuy',
|
|
616
|
+
() => {
|
|
617
|
+
return handleSellBuyConfig(data, originData)
|
|
618
|
+
},
|
|
619
|
+
],
|
|
620
|
+
// 开平点
|
|
621
|
+
[
|
|
622
|
+
'openClose',
|
|
623
|
+
() => {
|
|
624
|
+
return handleOpenCloseConfig(data, originData)
|
|
625
|
+
},
|
|
626
|
+
],
|
|
627
|
+
// 信号点
|
|
628
|
+
['signal', () => {}],
|
|
629
|
+
])
|
|
630
|
+
const callBack = configMap.get(key)
|
|
631
|
+
if (callBack instanceof Function) result.push(...callBack())
|
|
632
|
+
return result
|
|
633
|
+
}, [])
|
|
634
|
+
}
|