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
|
@@ -0,0 +1,663 @@
|
|
|
1
|
+
<!-- 单品种单周期K线组件-Demo -->
|
|
2
|
+
<script setup lang="ts">
|
|
3
|
+
import { RefreshRight } from '@element-plus/icons-vue'
|
|
4
|
+
import { ref, onMounted, onUnmounted, computed, watch } from 'vue'
|
|
5
|
+
import dayjs from 'dayjs'
|
|
6
|
+
import isSameOrAfter from 'dayjs/plugin/isSameOrAfter'
|
|
7
|
+
import { ElMessage } from 'element-plus'
|
|
8
|
+
import 'element-plus/dist/index.css'
|
|
9
|
+
import { formatValue } from '../../../../packages/Kline/utils'
|
|
10
|
+
import { getSingleCycleSingleVariety, getDict, getIndicatorConfig } from '../api.ts'
|
|
11
|
+
|
|
12
|
+
dayjs.extend(isSameOrAfter)
|
|
13
|
+
|
|
14
|
+
const props = defineProps({
|
|
15
|
+
deBugValue: {
|
|
16
|
+
type: Number,
|
|
17
|
+
},
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
const loading = ref(true)
|
|
21
|
+
const netWorkErrorMsg = ref('')
|
|
22
|
+
|
|
23
|
+
// 筛选条件相关参数
|
|
24
|
+
const cycle = ref<any>('2')
|
|
25
|
+
const cycleName = computed(() => {
|
|
26
|
+
if (cycleOptions.value.length > 0) {
|
|
27
|
+
return cycleOptions.value.find((item: any) => item.value === cycle.value).label
|
|
28
|
+
}
|
|
29
|
+
return null
|
|
30
|
+
})
|
|
31
|
+
const cycleOptions = ref<any>([]) // 周期下拉框数据
|
|
32
|
+
|
|
33
|
+
const indicator = computed(() => {
|
|
34
|
+
if (indicatorOptions.value.length > 0) {
|
|
35
|
+
return indicatorOptions.value.find((item: any) => item.value === indicatorName.value).info
|
|
36
|
+
}
|
|
37
|
+
return null
|
|
38
|
+
})
|
|
39
|
+
const indicatorName = ref<any>('DKX_EMA')
|
|
40
|
+
const indicatorOptions = ref<any>([])
|
|
41
|
+
|
|
42
|
+
const sellBuyType = ref(1)
|
|
43
|
+
const sellBuyTypeName = computed(() => {
|
|
44
|
+
if (sellBuyTypeOptions.value.length > 0) {
|
|
45
|
+
return sellBuyTypeOptions.value.find((item: any) => item.value === sellBuyType.value).label
|
|
46
|
+
}
|
|
47
|
+
return null
|
|
48
|
+
})
|
|
49
|
+
const sellBuyTypeOptions = ref<any>([
|
|
50
|
+
{ label: '开平', value: 1 },
|
|
51
|
+
{ label: '买卖', value: 2 },
|
|
52
|
+
])
|
|
53
|
+
|
|
54
|
+
// 接口原生-点位数据
|
|
55
|
+
const originPointData = ref<any>([])
|
|
56
|
+
|
|
57
|
+
// K线组件入参
|
|
58
|
+
const klineData = ref<any>([])
|
|
59
|
+
const markData = ref<any>([])
|
|
60
|
+
const lineData = ref<any>([])
|
|
61
|
+
const brushRange = ref<any>(['2024-01-04 10:10:00', '2024-01-04 21:40:00'])
|
|
62
|
+
const defaultMenuData = ref([
|
|
63
|
+
{
|
|
64
|
+
label: '画线预警',
|
|
65
|
+
callBack: (echartsInstance: any, cursorPenVisible: any) => createWarning(echartsInstance, cursorPenVisible),
|
|
66
|
+
},
|
|
67
|
+
])
|
|
68
|
+
const config = ref({
|
|
69
|
+
totalBarCount: 1900,
|
|
70
|
+
preBarCount: 100,
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
onMounted(() => {
|
|
74
|
+
console.log('---------单品种单周期组件: onMounted挂载成功---------')
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
// 初始化
|
|
78
|
+
const componentInit = async () => {
|
|
79
|
+
try {
|
|
80
|
+
loading.value = true
|
|
81
|
+
await getIndicatorOptions()
|
|
82
|
+
await getDictCycle()
|
|
83
|
+
await getKlineData()
|
|
84
|
+
await getKlinePointData()
|
|
85
|
+
loading.value = false
|
|
86
|
+
await getKlineExtendData()
|
|
87
|
+
} catch (error) {
|
|
88
|
+
console.log(error)
|
|
89
|
+
} finally {
|
|
90
|
+
loading.value = false
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* @description: 获取通用字典[周期]
|
|
96
|
+
*/
|
|
97
|
+
const getDictCycle = async () => {
|
|
98
|
+
const params = {
|
|
99
|
+
dictIds: [1002],
|
|
100
|
+
}
|
|
101
|
+
const res = await getDict(params)
|
|
102
|
+
cycleOptions.value = res.data[1002].map((item: any) => {
|
|
103
|
+
return {
|
|
104
|
+
label: item.dictName,
|
|
105
|
+
value: item.dictCode,
|
|
106
|
+
data: item,
|
|
107
|
+
}
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* @description: 获取指标配置表
|
|
112
|
+
*/
|
|
113
|
+
const getIndicatorOptions = async () => {
|
|
114
|
+
const res = await getIndicatorConfig()
|
|
115
|
+
indicatorOptions.value = Object.keys(res.data).reduce((result:any,key:any)=>{
|
|
116
|
+
if(res.data[key].WINDOW === '#0'){
|
|
117
|
+
result.push({
|
|
118
|
+
value: key,
|
|
119
|
+
label: key,
|
|
120
|
+
info: res.data[key]
|
|
121
|
+
})
|
|
122
|
+
}
|
|
123
|
+
return result
|
|
124
|
+
},[])
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* @description: 获取K线数据
|
|
128
|
+
*/
|
|
129
|
+
const getKlineData = async () => {
|
|
130
|
+
const params = {
|
|
131
|
+
right: 1, // 复权方式
|
|
132
|
+
variety: 'au8888', // 品种
|
|
133
|
+
cycle: cycle.value, // 周期
|
|
134
|
+
endTime: '2024-01-04 23:59:59', // 结束时间
|
|
135
|
+
limit: config.value.totalBarCount + config.value.preBarCount, // 总条数
|
|
136
|
+
queryType: 1, // 0-按时间,1-按结束时间,2-按开始时间
|
|
137
|
+
}
|
|
138
|
+
const res = await getSingleCycleSingleVariety(params)
|
|
139
|
+
klineData.value = res.data.body
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* @description: 获取点位数据
|
|
143
|
+
* @todo: 1.获取点位接口数据 2.格式化处理[数据合并,匹配K线时间轴] 建议分开,此处demo所以简写
|
|
144
|
+
*/
|
|
145
|
+
const getKlinePointData = async () => {
|
|
146
|
+
const resultApi = [
|
|
147
|
+
{
|
|
148
|
+
key: 'sellBuy',
|
|
149
|
+
data: [
|
|
150
|
+
{
|
|
151
|
+
tradeAction: '开', // 交易动作
|
|
152
|
+
direction: '多', // 交易方向
|
|
153
|
+
tradeType: '开多', // 交易类型
|
|
154
|
+
amount: 2, // 手数
|
|
155
|
+
part: 2, // 份数
|
|
156
|
+
time: '2024-01-04 22:30:00', // 交易时间
|
|
157
|
+
tooltip: '<div>买卖点1</div>',
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
tradeAction: '平', // 交易动作
|
|
161
|
+
direction: '空', // 交易方向
|
|
162
|
+
tradeType: '平空', // 交易类型
|
|
163
|
+
amount: 2, // 手数
|
|
164
|
+
part: 2, // 份数
|
|
165
|
+
time: '2024-01-04 22:40:00', // 交易时间
|
|
166
|
+
tooltip: '<div>买卖点2</div>',
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
tradeAction: '开', // 交易动作
|
|
170
|
+
direction: '空', // 交易方向
|
|
171
|
+
tradeType: '开空', // 交易类型
|
|
172
|
+
amount: 2, // 手数
|
|
173
|
+
part: 2, // 份数
|
|
174
|
+
time: '2024-01-04 23:50:00', // 交易时间
|
|
175
|
+
tooltip: '<div>买卖点3</div>',
|
|
176
|
+
},
|
|
177
|
+
],
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
key: 'openClose',
|
|
181
|
+
data: [
|
|
182
|
+
{
|
|
183
|
+
tradeAction: '开', // 交易动作
|
|
184
|
+
direction: '多', // 交易方向
|
|
185
|
+
tradeType: '开多', // 交易类型
|
|
186
|
+
amount: 2, // 手数
|
|
187
|
+
part: 2, // 份数
|
|
188
|
+
time: '2024-01-04 22:30:00', // 交易时间
|
|
189
|
+
tooltip: '<div>开平点1</div>',
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
tradeAction: '平', // 交易动作
|
|
193
|
+
direction: '空', // 交易方向
|
|
194
|
+
tradeType: '平空', // 交易类型
|
|
195
|
+
amount: 2, // 手数
|
|
196
|
+
part: 2, // 份数
|
|
197
|
+
time: '2024-01-04 22:40:00', // 交易时间
|
|
198
|
+
tooltip: '<div>开平点2</div>',
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
tradeAction: '开', // 交易动作
|
|
202
|
+
direction: '空', // 交易方向
|
|
203
|
+
tradeType: '开空', // 交易类型
|
|
204
|
+
amount: 2, // 手数
|
|
205
|
+
part: 2, // 份数
|
|
206
|
+
time: '2024-01-04 23:50:00', // 交易时间
|
|
207
|
+
tooltip: '<div>买卖点3</div>',
|
|
208
|
+
},
|
|
209
|
+
],
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
key: 'signal',
|
|
213
|
+
data: [],
|
|
214
|
+
},
|
|
215
|
+
]
|
|
216
|
+
// 进行时间轴匹配
|
|
217
|
+
const klineTimeAry = klineData.value.map((item: any) => item[0])
|
|
218
|
+
originPointData.value = resultApi.reduce((result: any, next) => {
|
|
219
|
+
const { data } = next
|
|
220
|
+
result.push({
|
|
221
|
+
key: next.key,
|
|
222
|
+
data: data.map((item: any) => {
|
|
223
|
+
const time = klineTimeAry.find((klineTime: string) => dayjs(klineTime).isSameOrAfter(item.time))
|
|
224
|
+
return {
|
|
225
|
+
...item,
|
|
226
|
+
time,
|
|
227
|
+
}
|
|
228
|
+
}),
|
|
229
|
+
})
|
|
230
|
+
return result
|
|
231
|
+
}, [])
|
|
232
|
+
// 判断展示开平/买卖
|
|
233
|
+
sellBuyTypeChange()
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* @description: 获取K线额外画线数据
|
|
237
|
+
*/
|
|
238
|
+
const getKlineExtendData = async () => {
|
|
239
|
+
lineData.value = [
|
|
240
|
+
{
|
|
241
|
+
key: 'warning',
|
|
242
|
+
data: [
|
|
243
|
+
{
|
|
244
|
+
value: 479,
|
|
245
|
+
text: 479,
|
|
246
|
+
// 自定义信息
|
|
247
|
+
info: {},
|
|
248
|
+
// 自定义配置
|
|
249
|
+
config: {
|
|
250
|
+
draggable: true,
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
],
|
|
254
|
+
ondragstart: (params: any, info: any) => {
|
|
255
|
+
console.log('拖拽开始', params, info)
|
|
256
|
+
},
|
|
257
|
+
ondragend: (params: any, info: any, yAxisValue: number) => {
|
|
258
|
+
console.log('拖拽结束', params, info, yAxisValue)
|
|
259
|
+
ElMessage.success('预警线修改更新成功!')
|
|
260
|
+
},
|
|
261
|
+
oncontextmenu: (params: any, info: any, menuData: any) => {
|
|
262
|
+
console.log('右击了', params, info)
|
|
263
|
+
menuData.value = [
|
|
264
|
+
{
|
|
265
|
+
label: '删除画线',
|
|
266
|
+
callBack: () => ElMessage.success('预警线删除成功!'),
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
label: '修改画线',
|
|
270
|
+
callBack: () => ElMessage.success('预警线修改成功!'),
|
|
271
|
+
},
|
|
272
|
+
]
|
|
273
|
+
},
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
key: 'position',
|
|
277
|
+
data: [
|
|
278
|
+
{
|
|
279
|
+
value: 480,
|
|
280
|
+
text: '持仓:192.14万(1份) 数量:4手 方向:多 浮动盈亏:-1280.00',
|
|
281
|
+
// 自定义信息
|
|
282
|
+
info: {},
|
|
283
|
+
// 自定义配置
|
|
284
|
+
config: {},
|
|
285
|
+
},
|
|
286
|
+
],
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
key: 'condition',
|
|
290
|
+
data: [
|
|
291
|
+
{
|
|
292
|
+
value: 482,
|
|
293
|
+
text: '[多损][多盈] 开多↓2269 1份(22手)',
|
|
294
|
+
profitValue: 483,
|
|
295
|
+
profitText: '上破484',
|
|
296
|
+
lossValue: 481,
|
|
297
|
+
lossText: '下破482',
|
|
298
|
+
// 自定义信息
|
|
299
|
+
info: {},
|
|
300
|
+
// 自定义配置
|
|
301
|
+
config: {},
|
|
302
|
+
},
|
|
303
|
+
],
|
|
304
|
+
},
|
|
305
|
+
]
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* @description: 周期切换
|
|
310
|
+
*/
|
|
311
|
+
const cycleChange = async () => {
|
|
312
|
+
try {
|
|
313
|
+
loading.value = true
|
|
314
|
+
await getKlineData()
|
|
315
|
+
await getKlinePointData()
|
|
316
|
+
loading.value = false
|
|
317
|
+
} catch (error) {
|
|
318
|
+
console.log(error)
|
|
319
|
+
} finally {
|
|
320
|
+
loading.value = false
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* @description: 买卖点,开平点切换
|
|
326
|
+
*/
|
|
327
|
+
const sellBuyTypeChange = () => {
|
|
328
|
+
if (sellBuyType.value === 1) {
|
|
329
|
+
markData.value = originPointData.value.filter((item: any) => {
|
|
330
|
+
return item.key !== 'sellBuy'
|
|
331
|
+
})
|
|
332
|
+
} else {
|
|
333
|
+
markData.value = originPointData.value.filter((item: any) => {
|
|
334
|
+
return item.key !== 'openClose'
|
|
335
|
+
})
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// 画线预警
|
|
340
|
+
const createWarning = (echartsInstance: any, cursorPenVisible: any) => {
|
|
341
|
+
// 1.打开画笔模式,并修改指示器样式[画预览线]
|
|
342
|
+
cursorPenVisible.value = true
|
|
343
|
+
const echartsOptions = echartsInstance.getOption()
|
|
344
|
+
const oldTooltip = (echartsOptions.tooltip as Array<any>)[0]
|
|
345
|
+
echartsInstance.setOption({
|
|
346
|
+
...echartsOptions,
|
|
347
|
+
// 指示器样式
|
|
348
|
+
tooltip: {
|
|
349
|
+
...oldTooltip,
|
|
350
|
+
// 坐标轴指示器
|
|
351
|
+
axisPointer: {
|
|
352
|
+
// 保留原有部分配置
|
|
353
|
+
...oldTooltip.axisPointer,
|
|
354
|
+
// X轴指示线的宽度
|
|
355
|
+
lineStyle: {
|
|
356
|
+
width: 0,
|
|
357
|
+
},
|
|
358
|
+
// Y轴指示线的宽度
|
|
359
|
+
crossStyle: {
|
|
360
|
+
width: 2,
|
|
361
|
+
},
|
|
362
|
+
// 文本标签
|
|
363
|
+
label: {
|
|
364
|
+
// 保留原有部分配置
|
|
365
|
+
...oldTooltip.axisPointer.label,
|
|
366
|
+
// 颜色改为透明
|
|
367
|
+
backgroundColor: 'transparent',
|
|
368
|
+
// 仅显示Y轴值
|
|
369
|
+
formatter: (data: any) => {
|
|
370
|
+
const { axisDimension, value } = data
|
|
371
|
+
if (axisDimension === 'y') {
|
|
372
|
+
return String(formatValue(value))
|
|
373
|
+
}
|
|
374
|
+
return ''
|
|
375
|
+
},
|
|
376
|
+
},
|
|
377
|
+
},
|
|
378
|
+
},
|
|
379
|
+
})
|
|
380
|
+
// 2.获取当前列数据并发送请求至后端记录
|
|
381
|
+
const handleClick = (el: any) => {
|
|
382
|
+
// 关闭画笔模式,并移除echarts点击事件
|
|
383
|
+
cursorPenVisible.value = false
|
|
384
|
+
echartsInstance.getZr().off('mousedown', handleClick)
|
|
385
|
+
const yAxisValue = echartsInstance.convertFromPixel({ yAxisIndex: 0 }, el.offsetY)
|
|
386
|
+
const newWarnPrice = Math.round(yAxisValue * 1000) / 1000
|
|
387
|
+
// 3.恢复指示器样式
|
|
388
|
+
echartsInstance.setOption({
|
|
389
|
+
...echartsOptions,
|
|
390
|
+
// 指示器样式
|
|
391
|
+
tooltip: {
|
|
392
|
+
...oldTooltip,
|
|
393
|
+
axisPointer: {
|
|
394
|
+
...oldTooltip.axisPointer,
|
|
395
|
+
lineStyle: {
|
|
396
|
+
width: 1,
|
|
397
|
+
},
|
|
398
|
+
crossStyle: {
|
|
399
|
+
width: 1,
|
|
400
|
+
},
|
|
401
|
+
label: {
|
|
402
|
+
...oldTooltip.axisPointer.label,
|
|
403
|
+
backgroundColor: null,
|
|
404
|
+
},
|
|
405
|
+
},
|
|
406
|
+
},
|
|
407
|
+
})
|
|
408
|
+
// 4.发送保存预警线请求
|
|
409
|
+
lineData.value[0].data.push({
|
|
410
|
+
value: newWarnPrice,
|
|
411
|
+
text: newWarnPrice,
|
|
412
|
+
// 自定义信息
|
|
413
|
+
info: {},
|
|
414
|
+
// 自定义配置
|
|
415
|
+
config: {
|
|
416
|
+
draggable: true,
|
|
417
|
+
},
|
|
418
|
+
})
|
|
419
|
+
console.log(lineData.value[0].data)
|
|
420
|
+
ElMessage.success('画线预警成功!')
|
|
421
|
+
}
|
|
422
|
+
// 绑定echarts点击事件
|
|
423
|
+
echartsInstance.getZr().on('mousedown', handleClick)
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
watch(
|
|
427
|
+
() => props.deBugValue,
|
|
428
|
+
(newValue: any) => {
|
|
429
|
+
if (newValue === 1) {
|
|
430
|
+
// 正常模式
|
|
431
|
+
netWorkErrorMsg.value = ''
|
|
432
|
+
componentInit()
|
|
433
|
+
} else if (newValue === 2) {
|
|
434
|
+
// 网络故障
|
|
435
|
+
loading.value = true
|
|
436
|
+
setTimeout(() => {
|
|
437
|
+
netWorkErrorMsg.value = '网络加载失败,请刷新重试'
|
|
438
|
+
loading.value = false
|
|
439
|
+
}, 1000)
|
|
440
|
+
} else if (newValue === 3) {
|
|
441
|
+
// 空数据
|
|
442
|
+
netWorkErrorMsg.value = ''
|
|
443
|
+
loading.value = true
|
|
444
|
+
setTimeout(() => {
|
|
445
|
+
klineData.value = []
|
|
446
|
+
loading.value = false
|
|
447
|
+
}, 1000)
|
|
448
|
+
}
|
|
449
|
+
},
|
|
450
|
+
{
|
|
451
|
+
immediate: true,
|
|
452
|
+
}
|
|
453
|
+
)
|
|
454
|
+
|
|
455
|
+
onUnmounted(() => {
|
|
456
|
+
console.log('---------单品种单周期组件: onUnmounted卸载成功---------')
|
|
457
|
+
})
|
|
458
|
+
|
|
459
|
+
// 刷新按钮
|
|
460
|
+
const reFresh = () => {
|
|
461
|
+
netWorkErrorMsg.value = ''
|
|
462
|
+
componentInit()
|
|
463
|
+
}
|
|
464
|
+
</script>
|
|
465
|
+
|
|
466
|
+
<template>
|
|
467
|
+
<div id="single-cycle-single-variety">
|
|
468
|
+
<div
|
|
469
|
+
class="st-Kline"
|
|
470
|
+
v-loading="loading"
|
|
471
|
+
element-loading-text="正在加载数据中,请稍等..."
|
|
472
|
+
>
|
|
473
|
+
<!-- 功能区 -->
|
|
474
|
+
<div class="kline-header">
|
|
475
|
+
<!-- 品种名称 -->
|
|
476
|
+
<div class="kline-header-item">黄金 au8888</div>
|
|
477
|
+
<!-- 周期展示 + 选择 -->
|
|
478
|
+
<div class="kline-header-item cycleSelect">
|
|
479
|
+
<span>{{ cycleName }}</span>
|
|
480
|
+
<el-select
|
|
481
|
+
v-model="cycle"
|
|
482
|
+
popper-class="element-dark"
|
|
483
|
+
@change="cycleChange"
|
|
484
|
+
>
|
|
485
|
+
<el-option
|
|
486
|
+
v-for="(item, index) in cycleOptions"
|
|
487
|
+
:key="index"
|
|
488
|
+
:label="item.label"
|
|
489
|
+
:value="item.value"
|
|
490
|
+
/>
|
|
491
|
+
</el-select>
|
|
492
|
+
</div>
|
|
493
|
+
<!-- 指标展示 + 选择 -->
|
|
494
|
+
<div class="kline-header-item cycleSelect">
|
|
495
|
+
<span>{{ indicatorName }}</span>
|
|
496
|
+
<el-select
|
|
497
|
+
v-model="indicatorName"
|
|
498
|
+
popper-class="element-dark"
|
|
499
|
+
>
|
|
500
|
+
<el-option
|
|
501
|
+
v-for="(item, index) in indicatorOptions"
|
|
502
|
+
:key="index"
|
|
503
|
+
:label="item.label"
|
|
504
|
+
:value="item.value"
|
|
505
|
+
/>
|
|
506
|
+
</el-select>
|
|
507
|
+
</div>
|
|
508
|
+
<!-- 开平/买卖展示 + 选择 -->
|
|
509
|
+
<div class="kline-header-item sellBuySelect">
|
|
510
|
+
<span>{{ sellBuyTypeName }}</span>
|
|
511
|
+
<el-select
|
|
512
|
+
v-model="sellBuyType"
|
|
513
|
+
popper-class="element-dark"
|
|
514
|
+
@change="sellBuyTypeChange"
|
|
515
|
+
>
|
|
516
|
+
<el-option
|
|
517
|
+
v-for="(item, index) in sellBuyTypeOptions"
|
|
518
|
+
:key="index"
|
|
519
|
+
:label="item.label"
|
|
520
|
+
:value="item.value"
|
|
521
|
+
/>
|
|
522
|
+
</el-select>
|
|
523
|
+
</div>
|
|
524
|
+
</div>
|
|
525
|
+
<!-- K线本体 -->
|
|
526
|
+
<st-kline
|
|
527
|
+
v-if="!loading && klineData.length && !netWorkErrorMsg"
|
|
528
|
+
class="kline"
|
|
529
|
+
:indicator="indicator"
|
|
530
|
+
:klineData="klineData"
|
|
531
|
+
:markData="markData"
|
|
532
|
+
:lineData="lineData"
|
|
533
|
+
:brushRange="brushRange"
|
|
534
|
+
:defaultMenuData="defaultMenuData"
|
|
535
|
+
:config="config"
|
|
536
|
+
/>
|
|
537
|
+
<!-- 网络请求错误时 -->
|
|
538
|
+
<div
|
|
539
|
+
v-if="netWorkErrorMsg"
|
|
540
|
+
class="netWorkError"
|
|
541
|
+
>
|
|
542
|
+
<span>{{ netWorkErrorMsg }}</span>
|
|
543
|
+
<el-button
|
|
544
|
+
@click="reFresh"
|
|
545
|
+
:icon="RefreshRight"
|
|
546
|
+
>刷新</el-button
|
|
547
|
+
>
|
|
548
|
+
</div>
|
|
549
|
+
<!-- 空数据时 -->
|
|
550
|
+
<div
|
|
551
|
+
class="empty"
|
|
552
|
+
v-else-if="!loading && klineData.length === 0"
|
|
553
|
+
>
|
|
554
|
+
<el-empty description="暂无数据" />
|
|
555
|
+
</div>
|
|
556
|
+
</div>
|
|
557
|
+
</div>
|
|
558
|
+
</template>
|
|
559
|
+
|
|
560
|
+
<style lang="scss" scoped>
|
|
561
|
+
#single-cycle-single-variety {
|
|
562
|
+
margin: auto;
|
|
563
|
+
width: 100%;
|
|
564
|
+
height: 100%;
|
|
565
|
+
.st-Kline {
|
|
566
|
+
height: 100%;
|
|
567
|
+
display: flex;
|
|
568
|
+
flex-direction: column;
|
|
569
|
+
border-radius: 2px;
|
|
570
|
+
box-sizing: border-box;
|
|
571
|
+
background-color: black;
|
|
572
|
+
color-scheme: dark;
|
|
573
|
+
--el-mask-color: rgba(0, 0, 0, 0.8);
|
|
574
|
+
.kline-header {
|
|
575
|
+
display: flex;
|
|
576
|
+
align-items: center;
|
|
577
|
+
color: white;
|
|
578
|
+
border-bottom: 1px solid rgb(153, 153, 153);
|
|
579
|
+
.kline-header-item {
|
|
580
|
+
display: flex;
|
|
581
|
+
align-items: center;
|
|
582
|
+
border-right: 1px solid rgb(153, 153, 153);
|
|
583
|
+
padding: 6px;
|
|
584
|
+
box-sizing: border-box;
|
|
585
|
+
}
|
|
586
|
+
// 功能区: 周期
|
|
587
|
+
.cycleSelect {
|
|
588
|
+
:deep(.el-select) {
|
|
589
|
+
margin-left: 6px;
|
|
590
|
+
width: 16px;
|
|
591
|
+
.el-input__wrapper {
|
|
592
|
+
height: 16px;
|
|
593
|
+
padding: 0;
|
|
594
|
+
border-radius: 50%;
|
|
595
|
+
background-color: #ccc;
|
|
596
|
+
}
|
|
597
|
+
.el-input__inner {
|
|
598
|
+
width: 0;
|
|
599
|
+
}
|
|
600
|
+
.el-select__icon {
|
|
601
|
+
color: black;
|
|
602
|
+
width: 16px;
|
|
603
|
+
height: 16px;
|
|
604
|
+
margin-left: 0;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
// 功能区: 开平/买卖
|
|
609
|
+
.sellBuySelect {
|
|
610
|
+
:deep(.el-select) {
|
|
611
|
+
margin-left: 6px;
|
|
612
|
+
width: 16px;
|
|
613
|
+
.el-input__wrapper {
|
|
614
|
+
height: 16px;
|
|
615
|
+
padding: 0;
|
|
616
|
+
border-radius: 50%;
|
|
617
|
+
background-color: #ccc;
|
|
618
|
+
}
|
|
619
|
+
.el-input__inner {
|
|
620
|
+
width: 0;
|
|
621
|
+
}
|
|
622
|
+
.el-select__icon {
|
|
623
|
+
color: black;
|
|
624
|
+
width: 16px;
|
|
625
|
+
height: 16px;
|
|
626
|
+
margin-left: 0;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
.kline {
|
|
632
|
+
flex: 1;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
.netWorkError {
|
|
636
|
+
color: white;
|
|
637
|
+
font-weight: 600;
|
|
638
|
+
display: flex;
|
|
639
|
+
flex-direction: column;
|
|
640
|
+
align-items: center;
|
|
641
|
+
justify-content: center;
|
|
642
|
+
width: 100%;
|
|
643
|
+
height: 100%;
|
|
644
|
+
font-size: 24px;
|
|
645
|
+
.el-button {
|
|
646
|
+
margin-top: 10px;
|
|
647
|
+
background-color: rgb(0, 0, 0);
|
|
648
|
+
color: white;
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
.empty {
|
|
652
|
+
color: white;
|
|
653
|
+
font-weight: 600;
|
|
654
|
+
display: flex;
|
|
655
|
+
flex-direction: column;
|
|
656
|
+
align-items: center;
|
|
657
|
+
justify-content: center;
|
|
658
|
+
width: 100%;
|
|
659
|
+
height: 100%;
|
|
660
|
+
font-size: 24px;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
</style>
|