st-comp 0.0.45 → 0.0.47
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 +25409 -27447
- package/lib/bundle.umd.cjs +61 -65
- package/lib/style.css +1 -1
- package/package.json +3 -3
- package/packages/KlineNew/components/KlineSlide/index.vue +19 -43
- package/packages/KlineNew/components/KlineSub/index.vue +143 -154
- package/packages/KlineNew/components/{MainTips → KlineTips}/index.vue +9 -9
- package/packages/KlineNew/components/KlineUtils/index.vue +304 -0
- package/packages/KlineNew/index.ts +8 -2
- package/src/pages/KlineNew/components/KlineAction/components/ContextMenu/index.vue +91 -0
- package/src/pages/KlineNew/components/KlineAction/components/YearChart/index.vue +532 -0
- package/src/pages/KlineNew/components/KlineAction/images/pen.png +0 -0
- package/src/pages/KlineNew/components/KlineAction/index.vue +716 -0
- package/src/pages/KlineNew/components/KlineAction/mockApi/index.js +13 -0
- package/src/pages/KlineNew/components/KlineAction/utils.js +571 -0
- package/src/pages/KlineNew/components/KlineBasic/index.vue +336 -0
- package/src/pages/KlineNew/components/KlineBasic/utils.js +33 -0
- package/src/pages/KlineNew/components/KlineSlide/index.vue +446 -0
- package/src/pages/KlineNew/components/KlineSlide/utils.js +78 -0
- package/src/pages/KlineNew/index.vue +60 -32
- package/vitePlugins/createExportFile.ts +2 -1
- package/packages/KlineNew/index.vue +0 -363
- package/packages/KlineNew/klineConfig.ts +0 -44
- package/packages/KlineNew/option.ts +0 -111
- package/packages/KlineNew/utils.ts +0 -156
- package/vite.config.ts +0 -61
|
@@ -1,363 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div
|
|
3
|
-
class="kline"
|
|
4
|
-
@mousemove="isSelect = true"
|
|
5
|
-
@mouseout="isSelect = false"
|
|
6
|
-
>
|
|
7
|
-
<div class="kline-mainTips">
|
|
8
|
-
<MainTips :drawData="drawData" :activeIndex="activeIndex"/>
|
|
9
|
-
</div>
|
|
10
|
-
<div class="kline-mainChart" ref="mainChartRef"></div>
|
|
11
|
-
<div class="kline-sub">
|
|
12
|
-
<KlineSub ref="klineSubRef" v-model="subIndicator" :drawData="drawData" :activeIndex="activeIndex" :subIndicatorList="subIndicatorList" />
|
|
13
|
-
</div>
|
|
14
|
-
<KlineSlide ref="slideChartRef" :data="slideData" @change="slideChange" />
|
|
15
|
-
</div>
|
|
16
|
-
</template>
|
|
17
|
-
|
|
18
|
-
<script setup lang="ts">
|
|
19
|
-
import { ref, onMounted, onUnmounted, watch, computed } from "vue"
|
|
20
|
-
import * as echarts from 'echarts'
|
|
21
|
-
import type { EChartsType } from 'echarts'
|
|
22
|
-
import { getMainOption } from './option.js'
|
|
23
|
-
import { getKlineDataApi, formatData, initTalib } from './utils.js'
|
|
24
|
-
import dayjs from "dayjs"
|
|
25
|
-
import MainTips from "./components/MainTips/index.vue"
|
|
26
|
-
import klineConfig from './klineConfig.js'
|
|
27
|
-
import KlineSlide from "./components/KlineSlide/index.vue"
|
|
28
|
-
import KlineSub from "./components/KlineSub/index.vue"
|
|
29
|
-
|
|
30
|
-
const props = defineProps({
|
|
31
|
-
code: { type: String, required: true }, // 品种代码
|
|
32
|
-
freqId: { type: String, required: true }, // 周期
|
|
33
|
-
freqDict: { type: Object, required: true }, // 周期字典
|
|
34
|
-
mainIndicator: { type: String, required: true }, // 主图指标
|
|
35
|
-
mainIndicatorList: { type: Array, required: true }, // 主图指标列表
|
|
36
|
-
subIndicatorList: { type: Array, required: true }, // 副图指标列表
|
|
37
|
-
config: { type: Object, default: () => ({}) }, // 配置
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
const defaultconfig = {
|
|
41
|
-
defaultShowDays: 50, // 默认展示天数,会根据不同周期进行赋值
|
|
42
|
-
preLoadDays: 50, // 预加载天数,会分局不同周期进行赋值
|
|
43
|
-
maxShowDays: 500, // 最大展示天数,会分局不同周期进行赋值
|
|
44
|
-
defaultShowYears: 10, // 默认展示多少年数据
|
|
45
|
-
preLoadCount: 800, // 预加载数据条数(用于计算指标线)
|
|
46
|
-
loadCheckCount: 500, // 加载数据检查条数
|
|
47
|
-
loadAddCount: 2000, // 加载数据条数
|
|
48
|
-
}
|
|
49
|
-
let mainChart: EChartsType
|
|
50
|
-
let mainDataZoomTimer: any = null // 主图数据缩放定时器
|
|
51
|
-
let isLoadHistory: boolean = false // 是否正在加载历史数据
|
|
52
|
-
let isloadAllHistory: boolean = false // 是否加载完全部历史数据
|
|
53
|
-
let isLoadNew: boolean = false // 是否正在加载新数据
|
|
54
|
-
let isloadAllNew: boolean = false // 是否加载完全部新数据
|
|
55
|
-
let resizeRo: any // dom元素监听事件
|
|
56
|
-
let highlightTimer: any = null // 高亮处理事件的定时器
|
|
57
|
-
|
|
58
|
-
const mainChartRef = ref<HTMLElement>() // 主图
|
|
59
|
-
const klineSubRef = ref<HTMLElement>() // 副图
|
|
60
|
-
const slideChartRef = ref<HTMLElement>() // 拖动轴
|
|
61
|
-
const isSelect = ref(false) // 是否选中,选中可通过键盘按键操作
|
|
62
|
-
const drawData = ref({
|
|
63
|
-
originData: [], // 原数据
|
|
64
|
-
xAxisData: [], // 时间数据
|
|
65
|
-
candlestickData: [], // k线数据
|
|
66
|
-
mainIndicatorData: [], // 主图指标线数据
|
|
67
|
-
subIndicatorData: [], // 副图数据
|
|
68
|
-
length: 0, // 数据长度
|
|
69
|
-
startTime: '', // 开始时间
|
|
70
|
-
endTime: '', // 结束时间
|
|
71
|
-
}) // 绘图数据
|
|
72
|
-
const slideData = ref([])
|
|
73
|
-
const activeIndex = ref(0) // 显示的index
|
|
74
|
-
const subIndicator = ref('VOL') // 副图指标
|
|
75
|
-
|
|
76
|
-
const config = computed(() => {
|
|
77
|
-
const freqName = props.freqDict.find((item: any) => item.value === props.freqId).label
|
|
78
|
-
return {
|
|
79
|
-
...defaultconfig,
|
|
80
|
-
...klineConfig.freqConfig[freqName],
|
|
81
|
-
...props.config,
|
|
82
|
-
}
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
watch(
|
|
86
|
-
() => [props.code, props.freqId, props.mainIndicator, subIndicator],
|
|
87
|
-
() => {
|
|
88
|
-
slideChartRef.value?.reset()
|
|
89
|
-
},
|
|
90
|
-
{ deep: true }
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
onMounted(async () => {
|
|
94
|
-
// 初始化指标计算方法
|
|
95
|
-
await initTalib()
|
|
96
|
-
mainChart = echarts.init(mainChartRef.value)
|
|
97
|
-
klineSubRef.value.connect(mainChart)
|
|
98
|
-
addEventListener()
|
|
99
|
-
initChart()
|
|
100
|
-
// 绑定resize事件
|
|
101
|
-
let isFirst: boolean | null = true
|
|
102
|
-
resizeRo = new ResizeObserver(() => {
|
|
103
|
-
if (isFirst) {
|
|
104
|
-
isFirst = null
|
|
105
|
-
return
|
|
106
|
-
}
|
|
107
|
-
mainChart.resize()
|
|
108
|
-
})
|
|
109
|
-
resizeRo.observe(mainChartRef.value)
|
|
110
|
-
window.addEventListener('keydown', keyDownEvent)
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
onUnmounted(() => {
|
|
114
|
-
window.removeEventListener('keydown', keyDownEvent)
|
|
115
|
-
mainChart.dispose()
|
|
116
|
-
resizeRo.disconnect()
|
|
117
|
-
resizeRo = null
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
// 项目初始化
|
|
121
|
-
const initChart = async () => {
|
|
122
|
-
// 配置初始化
|
|
123
|
-
isLoadHistory = false
|
|
124
|
-
isloadAllHistory = false
|
|
125
|
-
isLoadNew = false
|
|
126
|
-
isloadAllNew = false
|
|
127
|
-
const { defaultShowYears } = config.value
|
|
128
|
-
// 请求滚动条数据
|
|
129
|
-
await getKlineData({
|
|
130
|
-
queryType: '0',
|
|
131
|
-
startTime: `${dayjs().subtract(defaultShowYears, 'year').format("YYYY-MM-DD")} 00:00:00`,
|
|
132
|
-
endTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
|
|
133
|
-
cycle: '6',
|
|
134
|
-
})
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// 绑定事件
|
|
138
|
-
const addEventListener = () => {
|
|
139
|
-
mainChart.on('datazoom', (params: any) => {
|
|
140
|
-
clearTimeout(mainDataZoomTimer)
|
|
141
|
-
mainDataZoomTimer = setTimeout(() => {
|
|
142
|
-
const { loadCheckCount, loadAddCount, preLoadCount } = config.value
|
|
143
|
-
let startIndex = 0
|
|
144
|
-
let endIndex = 0
|
|
145
|
-
if (params.batch) {
|
|
146
|
-
const { start, end } = params.batch[0]
|
|
147
|
-
startIndex = Math.floor(start * drawData.value.length / 100)
|
|
148
|
-
endIndex = end === 100 ? drawData.value.length - 1 : Math.floor(end * drawData.value.length / 100)
|
|
149
|
-
} else {
|
|
150
|
-
startIndex = params.startValue
|
|
151
|
-
endIndex = params.endValue
|
|
152
|
-
}
|
|
153
|
-
// 加载数据
|
|
154
|
-
if (startIndex < loadCheckCount && isLoadHistory === false && isloadAllHistory === false) {
|
|
155
|
-
// 左侧数据小于1000条,加载左侧数据
|
|
156
|
-
isLoadHistory = true
|
|
157
|
-
getMoreData({
|
|
158
|
-
queryType: '1',
|
|
159
|
-
endTime: drawData.value.startTime,
|
|
160
|
-
cycle: props.freqId,
|
|
161
|
-
limit: loadAddCount + preLoadCount,
|
|
162
|
-
})
|
|
163
|
-
}
|
|
164
|
-
if (endIndex > drawData.value.length - loadCheckCount && isLoadNew === false && isloadAllNew === false) {
|
|
165
|
-
// 右侧数据小于1000条,加载右侧数据
|
|
166
|
-
isLoadNew = true
|
|
167
|
-
getMoreData({
|
|
168
|
-
queryType: '2',
|
|
169
|
-
startTime: drawData.value.endTime,
|
|
170
|
-
cycle: props.freqId,
|
|
171
|
-
limit: loadAddCount,
|
|
172
|
-
preLimit: preLoadCount, // 向前多查询数量
|
|
173
|
-
})
|
|
174
|
-
}
|
|
175
|
-
// 重置滚动条
|
|
176
|
-
const { startValue, endValue } = (mainChart.getOption().dataZoom as any[])[0]
|
|
177
|
-
const klineDataTime = (mainChart.getOption().xAxis as any)[0].data
|
|
178
|
-
const startTime = (klineDataTime[startValue] as string).split(' ')[0]
|
|
179
|
-
const endTime = (klineDataTime[endValue] as string).split(' ')[0]
|
|
180
|
-
slideChartRef.value.resetSlide(startTime, endTime)
|
|
181
|
-
clearTimeout(mainDataZoomTimer)
|
|
182
|
-
}, 100)
|
|
183
|
-
})
|
|
184
|
-
// 高亮事件
|
|
185
|
-
mainChart.on('highlight', (data: any) => {
|
|
186
|
-
let index = data.dataIndex || -1
|
|
187
|
-
if (data.batch ) {
|
|
188
|
-
index = typeof data?.batch[0]?.dataIndex === 'number' ? data?.batch[0]?.dataIndex : -1
|
|
189
|
-
}
|
|
190
|
-
clearTimeout(highlightTimer)
|
|
191
|
-
highlightTimer = setTimeout(() => {
|
|
192
|
-
activeIndex.value = index
|
|
193
|
-
clearTimeout(highlightTimer)
|
|
194
|
-
}, 20)
|
|
195
|
-
})
|
|
196
|
-
// 移出图表事件
|
|
197
|
-
mainChart.on('globalout', () => {
|
|
198
|
-
const index = mainChart.getOption().dataZoom[0].endValue
|
|
199
|
-
activeIndex.value = index
|
|
200
|
-
})
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// 键盘事件
|
|
204
|
-
const keyDownEvent = e => {
|
|
205
|
-
// 只有选中或者按ctrl才激活按键
|
|
206
|
-
if (!(e.ctrlKey || isSelect.value)) return
|
|
207
|
-
const option = mainChart.getOption()
|
|
208
|
-
let { startValue, endValue } = (option.dataZoom as any)[0]
|
|
209
|
-
if (e.code === 'ArrowLeft') {
|
|
210
|
-
// 左按键
|
|
211
|
-
if (startValue === 0) {
|
|
212
|
-
return
|
|
213
|
-
}
|
|
214
|
-
startValue = startValue - 1
|
|
215
|
-
endValue = endValue - 1
|
|
216
|
-
mainChart.dispatchAction({
|
|
217
|
-
type: 'highlight',
|
|
218
|
-
dataIndex: endValue,
|
|
219
|
-
})
|
|
220
|
-
} else if (e.code === 'ArrowRight') {
|
|
221
|
-
// 右按键
|
|
222
|
-
if (endValue === (option.xAxis as any)[0].data.length - 1) {
|
|
223
|
-
return
|
|
224
|
-
}
|
|
225
|
-
startValue = startValue + 1
|
|
226
|
-
endValue = endValue + 1
|
|
227
|
-
mainChart.dispatchAction({
|
|
228
|
-
type: 'highlight',
|
|
229
|
-
dataIndex: endValue,
|
|
230
|
-
})
|
|
231
|
-
} else if (e.code === 'ArrowUp') {
|
|
232
|
-
// 上按键-放大 最少保持5条数据
|
|
233
|
-
if(endValue - startValue < 5) {
|
|
234
|
-
return
|
|
235
|
-
}
|
|
236
|
-
const diff = Math.floor((endValue - startValue) / 2) + 1
|
|
237
|
-
startValue = startValue + diff
|
|
238
|
-
if (endValue - startValue < 5) {
|
|
239
|
-
startValue = endValue - 4
|
|
240
|
-
}
|
|
241
|
-
} else if (e.code === 'ArrowDown') {
|
|
242
|
-
// 下按键-缩小
|
|
243
|
-
const diff = Math.min(500, (endValue - startValue))
|
|
244
|
-
startValue = startValue - diff - 1
|
|
245
|
-
}
|
|
246
|
-
mainChart.dispatchAction({
|
|
247
|
-
type: 'dataZoom',
|
|
248
|
-
startValue,
|
|
249
|
-
endValue
|
|
250
|
-
})
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
// 拖动轴发生变化
|
|
254
|
-
const slideChange = async({ startTime, showStartTime, endTime, showEndTime }) => {
|
|
255
|
-
const { preLoadCount } = config.value
|
|
256
|
-
await getKlineData({
|
|
257
|
-
queryType: '0',
|
|
258
|
-
startTime,
|
|
259
|
-
endTime,
|
|
260
|
-
preLimit: preLoadCount, // 向前多查询数量
|
|
261
|
-
cycle: props.freqId,
|
|
262
|
-
})
|
|
263
|
-
draw('main', { showStartTime, showEndTime })
|
|
264
|
-
draw('sub', { showStartTime, showEndTime })
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
// 获取更多数据
|
|
268
|
-
const getMoreData = async(params: any) => {
|
|
269
|
-
const { preLoadCount } = config.value
|
|
270
|
-
const res = await getKlineData(params)
|
|
271
|
-
const { startValue, endValue } = (mainChart.getOption().dataZoom as any[])[0]
|
|
272
|
-
const klineDataTime = (mainChart.getOption().xAxis as any)[0].data
|
|
273
|
-
const showStartTime = klineDataTime[startValue]
|
|
274
|
-
const showEndTime = klineDataTime[endValue]
|
|
275
|
-
if (params.queryType === '1') {
|
|
276
|
-
// 加载历史数据
|
|
277
|
-
if (new Date(slideData.value[0][0]) > new Date(res[0][0])) {
|
|
278
|
-
// 表示历史数据已加载完
|
|
279
|
-
isloadAllHistory = true
|
|
280
|
-
}
|
|
281
|
-
isLoadHistory = false
|
|
282
|
-
} else {
|
|
283
|
-
// 加载新数据
|
|
284
|
-
if (res.length < 1 + preLoadCount) {
|
|
285
|
-
// 表示已经加载完全部新数据
|
|
286
|
-
isloadAllNew = true
|
|
287
|
-
isLoadNew = false
|
|
288
|
-
return
|
|
289
|
-
}
|
|
290
|
-
isLoadNew = false
|
|
291
|
-
}
|
|
292
|
-
draw('main', { showStartTime, showEndTime })
|
|
293
|
-
draw('sub', { showStartTime, showEndTime })
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
// 获取k线数据
|
|
297
|
-
const getKlineData = async(params: any) => {
|
|
298
|
-
const apiParams = {
|
|
299
|
-
contractType: 0, // 合约类型 0-主连 1-加权
|
|
300
|
-
variety: props.code, // 品种
|
|
301
|
-
right: 1, // 0-不复权 1-前复权 2-后复权
|
|
302
|
-
...params,
|
|
303
|
-
}
|
|
304
|
-
const res = await getKlineDataApi(apiParams)
|
|
305
|
-
if (slideData.value.length === 0) {
|
|
306
|
-
slideData.value = res.map(i => [i[0], i[4]])
|
|
307
|
-
return res
|
|
308
|
-
}
|
|
309
|
-
drawData.value = formatData({
|
|
310
|
-
originDrawData: drawData.value,
|
|
311
|
-
addData: res,
|
|
312
|
-
params: apiParams,
|
|
313
|
-
mainIndicator: props.mainIndicator,
|
|
314
|
-
mainIndicatorList: props.mainIndicatorList,
|
|
315
|
-
subIndicator: subIndicator.value,
|
|
316
|
-
subIndicatorList: props.subIndicatorList,
|
|
317
|
-
config: config.value,
|
|
318
|
-
slideData: slideData.value,
|
|
319
|
-
})
|
|
320
|
-
return res
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
// 绘制函数
|
|
324
|
-
const draw = (type: string, params: any = {}) => {
|
|
325
|
-
const { showStartTime, showEndTime } = params
|
|
326
|
-
const { maxShowDays } = config.value
|
|
327
|
-
const { subIndicatorList } = props
|
|
328
|
-
const callBackMap = new Map([
|
|
329
|
-
[ "main", () => {
|
|
330
|
-
mainChart.setOption(getMainOption({ showStartTime, showEndTime, drawData: drawData.value, maxShowDays }), true)
|
|
331
|
-
}],
|
|
332
|
-
[ "sub", () => {
|
|
333
|
-
klineSubRef.value.draw({ showStartTime, showEndTime, drawData: drawData.value , subIndicator: subIndicator.value, subIndicatorList, maxShowDays })
|
|
334
|
-
}],
|
|
335
|
-
]);
|
|
336
|
-
const callBack = callBackMap.get(type);
|
|
337
|
-
if (callBack instanceof Function) {
|
|
338
|
-
callBack();
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
</script>
|
|
342
|
-
|
|
343
|
-
<style lang="scss" scoped>
|
|
344
|
-
.kline {
|
|
345
|
-
width: 100%;
|
|
346
|
-
height: 100%;
|
|
347
|
-
background: #000;
|
|
348
|
-
&-mainTips {
|
|
349
|
-
height: 26px;
|
|
350
|
-
}
|
|
351
|
-
&-mainChart {
|
|
352
|
-
width: 100%;
|
|
353
|
-
height: calc(65% - 26px);
|
|
354
|
-
}
|
|
355
|
-
&-subTips {
|
|
356
|
-
height: 16px;
|
|
357
|
-
}
|
|
358
|
-
&-sub {
|
|
359
|
-
width: 100%;
|
|
360
|
-
height: calc(35% - 50px - 16px);
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
</style>
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
export default {
|
|
2
|
-
freqConfig: {
|
|
3
|
-
'1m': {
|
|
4
|
-
defaultShowDays: 2, // 默认展示天数
|
|
5
|
-
preLoadDays: 4, // 预加载天数
|
|
6
|
-
maxShowDays: 20, // 最大展示天数
|
|
7
|
-
},
|
|
8
|
-
'5m': {
|
|
9
|
-
defaultShowDays: 4, // 默认展示天数
|
|
10
|
-
preLoadDays: 10, // 预加载天数
|
|
11
|
-
maxShowDays: 20, // 最大展示天数
|
|
12
|
-
},
|
|
13
|
-
'15m': {
|
|
14
|
-
defaultShowDays: 12, // 默认展示天数
|
|
15
|
-
preLoadDays: 24, // 预加载天数
|
|
16
|
-
maxShowDays: 50, // 最大展示天数
|
|
17
|
-
},
|
|
18
|
-
'30m': {
|
|
19
|
-
defaultShowDays: 25, // 默认展示天数
|
|
20
|
-
preLoadDays: 50, // 预加载天数
|
|
21
|
-
maxShowDays: 100, // 最大展示天数
|
|
22
|
-
},
|
|
23
|
-
'60m': {
|
|
24
|
-
defaultShowDays: 50, // 默认展示天数
|
|
25
|
-
preLoadDays: 100, // 预加载天数
|
|
26
|
-
maxShowDays: 200, // 最大展示天数
|
|
27
|
-
},
|
|
28
|
-
'1d': {
|
|
29
|
-
defaultShowDays: 200, // 默认展示天数
|
|
30
|
-
preLoadDays: 400, // 预加载天数
|
|
31
|
-
maxShowDays: 800, // 最大展示天数
|
|
32
|
-
},
|
|
33
|
-
'1w': {
|
|
34
|
-
defaultShowDays: 1000, // 默认展示天数
|
|
35
|
-
preLoadDays: 2000, // 预加载天数
|
|
36
|
-
maxShowDays: 4000, // 最大展示天数
|
|
37
|
-
},
|
|
38
|
-
'1mon': {
|
|
39
|
-
defaultShowDays: 4000, // 默认展示天数
|
|
40
|
-
preLoadDays: 8000, // 预加载天数
|
|
41
|
-
maxShowDays: 16000, // 最大展示天数
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import { stMath } from 'st-func'
|
|
2
|
-
const { round } = stMath
|
|
3
|
-
|
|
4
|
-
// 获取主图配置
|
|
5
|
-
export const getMainOption = (config: any) => {
|
|
6
|
-
const { showStartTime, showEndTime, drawData, maxShowDays } = config
|
|
7
|
-
const { xAxisData, candlestickData } = drawData
|
|
8
|
-
let startValue = -1
|
|
9
|
-
let endValue = -1
|
|
10
|
-
let dayPerTime: any = {}
|
|
11
|
-
xAxisData.forEach((time: any, index: number) => {
|
|
12
|
-
dayPerTime[time.split(' ')[0]] = dayPerTime[time.split(' ')[0]] || 0
|
|
13
|
-
dayPerTime[time.split(' ')[0]] += 1
|
|
14
|
-
if (new Date(time) >= new Date(showStartTime) && startValue === -1) {
|
|
15
|
-
startValue = index
|
|
16
|
-
}
|
|
17
|
-
if (new Date(time) <= new Date(showEndTime)) {
|
|
18
|
-
endValue = index
|
|
19
|
-
}
|
|
20
|
-
})
|
|
21
|
-
const maxShowCount = Math.max(...Object.values(dayPerTime)) * maxShowDays
|
|
22
|
-
const indicatorSeries = drawData.mainIndicatorData.map((item: any) => {
|
|
23
|
-
return {
|
|
24
|
-
name: item.key,
|
|
25
|
-
type: 'line',
|
|
26
|
-
silent: true,
|
|
27
|
-
symbol: 'none',
|
|
28
|
-
data: item.data,
|
|
29
|
-
lineStyle: {
|
|
30
|
-
width: item.width || 1,
|
|
31
|
-
},
|
|
32
|
-
itemStyle: {
|
|
33
|
-
color: item.color,
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
})
|
|
37
|
-
return {
|
|
38
|
-
animation: false,
|
|
39
|
-
grid: {
|
|
40
|
-
left: '60px',
|
|
41
|
-
top: '20px',
|
|
42
|
-
right: '20px',
|
|
43
|
-
bottom: '6px',
|
|
44
|
-
},
|
|
45
|
-
dataZoom: [
|
|
46
|
-
{
|
|
47
|
-
type: 'inside',
|
|
48
|
-
startValue,
|
|
49
|
-
endValue,
|
|
50
|
-
maxValueSpan: maxShowCount,
|
|
51
|
-
}
|
|
52
|
-
],
|
|
53
|
-
tooltip: {
|
|
54
|
-
trigger: 'axis',
|
|
55
|
-
appendToBody: true,
|
|
56
|
-
confine: true,
|
|
57
|
-
axisPointer: {
|
|
58
|
-
type: 'cross',
|
|
59
|
-
label: {
|
|
60
|
-
rich: {},
|
|
61
|
-
formatter: data => {
|
|
62
|
-
const { axisDimension, value } = data
|
|
63
|
-
if(axisDimension === 'x') {
|
|
64
|
-
return ''
|
|
65
|
-
} else {
|
|
66
|
-
return String(round(value))
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
|
-
formatter: () => '',
|
|
72
|
-
},
|
|
73
|
-
xAxis: {
|
|
74
|
-
show: false,
|
|
75
|
-
type: 'category',
|
|
76
|
-
data: xAxisData,
|
|
77
|
-
splitLine: {
|
|
78
|
-
show: false,
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
yAxis: {
|
|
82
|
-
type: 'value',
|
|
83
|
-
axisLine: {
|
|
84
|
-
show: true,
|
|
85
|
-
},
|
|
86
|
-
splitLine: {
|
|
87
|
-
show: true,
|
|
88
|
-
lineStyle: {
|
|
89
|
-
type: "dotted",
|
|
90
|
-
color: "#333",
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
|
-
min: (value: any) => round(value.min),
|
|
94
|
-
max: (value: any) => round(value.max),
|
|
95
|
-
},
|
|
96
|
-
series: [
|
|
97
|
-
{
|
|
98
|
-
type: 'candlestick',
|
|
99
|
-
data: candlestickData,
|
|
100
|
-
itemStyle: {
|
|
101
|
-
color: "transparent",
|
|
102
|
-
color0: "#00FFFF",
|
|
103
|
-
borderColor: "#FF0000",
|
|
104
|
-
borderColor0: "#00FFFF",
|
|
105
|
-
borderWidth: 1,
|
|
106
|
-
},
|
|
107
|
-
},
|
|
108
|
-
...indicatorSeries,
|
|
109
|
-
]
|
|
110
|
-
}
|
|
111
|
-
}
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
import axios from 'axios'
|
|
2
|
-
import * as talib from 'talib.js'
|
|
3
|
-
|
|
4
|
-
// ---------------------------------- 公共方法 ----------------------------------
|
|
5
|
-
// 导出数据长度处理
|
|
6
|
-
const sliceData = (data: any[], length: number) => {
|
|
7
|
-
return data.length > length ? data.slice(data.length - length) : data
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
// ---------------------------------- 工具方法 ----------------------------------
|
|
12
|
-
// 注册计算指标线方法
|
|
13
|
-
let isInit = false // 是否初始化
|
|
14
|
-
let loading = true // 初始化loading
|
|
15
|
-
let requestPromise: any[] = [] // 用于存储loading中的计算请求
|
|
16
|
-
export const initTalib = async () => {
|
|
17
|
-
if (!isInit) {
|
|
18
|
-
// 未初始化
|
|
19
|
-
isInit = true
|
|
20
|
-
await talib.init('./talib.wasm')
|
|
21
|
-
loading = false
|
|
22
|
-
requestPromise.forEach(resolve => {
|
|
23
|
-
resolve()
|
|
24
|
-
})
|
|
25
|
-
} else if(loading) {
|
|
26
|
-
// 正在初始化
|
|
27
|
-
return new Promise((resolve) => {
|
|
28
|
-
requestPromise.push(resolve)
|
|
29
|
-
})
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// 默认获取k线参数
|
|
34
|
-
export const getKlineDataApi = async(params: any) => {
|
|
35
|
-
const res = await axios({
|
|
36
|
-
method: 'post',
|
|
37
|
-
headers: {
|
|
38
|
-
token: '041fd377d5d5efc7e08e2ed5b61b0c8d',
|
|
39
|
-
},
|
|
40
|
-
url: 'http://invest.hzyotoy.com/common/qt/getSingleCycleSingleVariety',
|
|
41
|
-
data: params,
|
|
42
|
-
})
|
|
43
|
-
return res.data.body
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// 初始化数据
|
|
47
|
-
export const formatData = (formatDataParams: any) => {
|
|
48
|
-
const { originDrawData, addData, params, mainIndicator, mainIndicatorList, subIndicator, subIndicatorList, config, slideData } = formatDataParams
|
|
49
|
-
let drawData: any = {}
|
|
50
|
-
const { startTime, endTime, queryType } = params
|
|
51
|
-
const { loadAddCount, preLoadCount } = config
|
|
52
|
-
|
|
53
|
-
const time: any[] = [] // 新增数据全部时间数据,用于计算指标线
|
|
54
|
-
const open: any[] = [] // 新增数据全部开盘价,用于指标线计算
|
|
55
|
-
const close: any[] = [] // 新增数据全部收盘价,用于指标线计算
|
|
56
|
-
const high: any[] = [] // 新增数据全部最高价,用于指标线计算
|
|
57
|
-
const low: any[] = [] // 新增数据全部最低价,用于指标线计算
|
|
58
|
-
let xAxisData: any[] = [] // 用于绘图的x轴时间数据
|
|
59
|
-
let candlestickData: any[] = [] // 用于绘图的k线图数据
|
|
60
|
-
|
|
61
|
-
const originData = addData.filter((item: any, index: number) => {
|
|
62
|
-
// 赋值
|
|
63
|
-
time.push(item[0])
|
|
64
|
-
open.push(item[1])
|
|
65
|
-
close.push(item[4])
|
|
66
|
-
high.push(item[2])
|
|
67
|
-
low.push(item[3])
|
|
68
|
-
xAxisData.push(item[0])
|
|
69
|
-
candlestickData.push([ item[1], item[4], item[3], item[2], index === 0 ? 0 : addData[index - 1][4] ])
|
|
70
|
-
// 取范围中的数据
|
|
71
|
-
if (queryType === '0') {
|
|
72
|
-
return new Date(startTime) <= new Date(item[0]) && new Date(item[0]) <= new Date(endTime)
|
|
73
|
-
} else if (queryType === '1') {
|
|
74
|
-
return index >= addData.length - loadAddCount && new Date(slideData[0][0]) <= new Date(item[0]) && new Date(item[0]) <= new Date(slideData[slideData.length - 1][0])
|
|
75
|
-
} else if (queryType === '2') {
|
|
76
|
-
return index >= preLoadCount && new Date(slideData[0][0]) <= new Date(item[0]) && new Date(item[0]) <= new Date(slideData[slideData.length - 1][0])
|
|
77
|
-
}
|
|
78
|
-
return false
|
|
79
|
-
})
|
|
80
|
-
xAxisData = sliceData(xAxisData, originData.length)
|
|
81
|
-
candlestickData = sliceData(candlestickData, originData.length)
|
|
82
|
-
// 指标线相关计算
|
|
83
|
-
const indicatorFormatData = { time, open, close, high, low, originData: addData }
|
|
84
|
-
const mainIndicatorConfig = mainIndicatorList.find((item: any) => item.value === mainIndicator).config
|
|
85
|
-
const mainIndicatorData = mainIndicatorConfig.map((item: any) => ({
|
|
86
|
-
...item,
|
|
87
|
-
data: sliceData(item.calculationFn ? item.calculationFn(talib, indicatorFormatData, []) : [], xAxisData.length),
|
|
88
|
-
}))
|
|
89
|
-
const subIndicatorConfig = subIndicatorList.find((item: any) => item.value === subIndicator).config
|
|
90
|
-
const subIndicatorData = subIndicatorConfig.reduce((res: any[], item: any) => {
|
|
91
|
-
if (item.source === 'calculation') {
|
|
92
|
-
return [
|
|
93
|
-
...res,
|
|
94
|
-
{
|
|
95
|
-
...item,
|
|
96
|
-
data: sliceData(item.calculationFn ? item.calculationFn(talib, indicatorFormatData) : [], xAxisData.length)
|
|
97
|
-
}
|
|
98
|
-
]
|
|
99
|
-
}
|
|
100
|
-
return res
|
|
101
|
-
}, [])
|
|
102
|
-
// 根据不同情况处理数据
|
|
103
|
-
if (queryType === '0') {
|
|
104
|
-
// 重新搜索
|
|
105
|
-
drawData = {
|
|
106
|
-
originData, // 原数据
|
|
107
|
-
xAxisData, // 时间数据
|
|
108
|
-
candlestickData, // k线数据
|
|
109
|
-
mainIndicatorData, // 主图指标线数据
|
|
110
|
-
subIndicatorData, // 副图数据
|
|
111
|
-
}
|
|
112
|
-
} else if (queryType === '1') {
|
|
113
|
-
// 加载历史数据
|
|
114
|
-
drawData = {
|
|
115
|
-
originData: [...originData, ...originDrawData.originData.slice(1)], // 原数据
|
|
116
|
-
xAxisData: [...xAxisData, ...originDrawData.xAxisData.slice(1)], // 时间数据
|
|
117
|
-
candlestickData: [...candlestickData, ...originDrawData.candlestickData.slice(1)], // k线数据
|
|
118
|
-
mainIndicatorData: originDrawData.mainIndicatorData.map((item: any, index: number) => {
|
|
119
|
-
return {
|
|
120
|
-
...item,
|
|
121
|
-
data: [...mainIndicatorData[index].data, ...item.data.slice(1)],
|
|
122
|
-
}
|
|
123
|
-
}), // 主图指标线数据
|
|
124
|
-
subIndicatorData: originDrawData.subIndicatorData.map((item: any, index: number) => {
|
|
125
|
-
return {
|
|
126
|
-
...item,
|
|
127
|
-
data: [...subIndicatorData[index].data, ...item.data.slice(1)],
|
|
128
|
-
}
|
|
129
|
-
}), // 副图数据
|
|
130
|
-
}
|
|
131
|
-
} else if (queryType === '2') {
|
|
132
|
-
// 加载新数据
|
|
133
|
-
drawData = {
|
|
134
|
-
originData: [...originDrawData.originData, ...originData.slice(1)], // 原数据
|
|
135
|
-
xAxisData: [...originDrawData.xAxisData, ...xAxisData.slice(1)], // 时间数据
|
|
136
|
-
candlestickData: [...originDrawData.candlestickData, ...candlestickData.slice(1)], // k线数据
|
|
137
|
-
mainIndicatorData: originDrawData.mainIndicatorData.map((item: any, index: number) => {
|
|
138
|
-
return {
|
|
139
|
-
...item,
|
|
140
|
-
data: [...item.data, ...mainIndicatorData[index].data.slice(1)],
|
|
141
|
-
}
|
|
142
|
-
}), // 主图指标线数据
|
|
143
|
-
subIndicatorData: originDrawData.subIndicatorData.map((item: any, index: number) => {
|
|
144
|
-
return {
|
|
145
|
-
...item,
|
|
146
|
-
data: [...item.data, ...subIndicatorData[index].data.slice(1)],
|
|
147
|
-
}
|
|
148
|
-
}), // 副图数据
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
// 添加一些字段,用于方便使用
|
|
152
|
-
drawData.length = drawData.xAxisData.length
|
|
153
|
-
drawData.startTime = drawData.xAxisData[0]
|
|
154
|
-
drawData.endTime = drawData.xAxisData[drawData.length - 1]
|
|
155
|
-
return drawData
|
|
156
|
-
}
|