|
|
@@ -1,5 +1,5 @@
|
|
|
<template>
|
|
|
- <div ref="chartRef" style="width:375px;height: 300px;background-color: #fff;"></div>
|
|
|
+ <HQChart :option="chartOption" width="1000px" height="600px" @ready="onReady" />
|
|
|
<ul>
|
|
|
<li @click="changePeriod(4)">1分钟</li>
|
|
|
<li @click="changePeriod(5)">5分钟</li>
|
|
|
@@ -7,13 +7,12 @@
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
-import { shallowRef, onMounted } from 'vue'
|
|
|
-import { Chart } from 'hqchart'
|
|
|
+import { shallowRef, onMounted, onUnmounted } from 'vue'
|
|
|
import { ChartCycleType } from '@/constants/chart'
|
|
|
-import { queryHistoryDatas } from '@/services/api/quote'
|
|
|
import { useFuturesStore } from '@/stores'
|
|
|
-import moment from 'moment'
|
|
|
+import { useKLine, NetworkFilterData, NetworkFilterCallback } from './kline'
|
|
|
import quoteSocket from '@/services/websocket/quote'
|
|
|
+import HQChart from '@/components/base/hqchart/index.vue'
|
|
|
|
|
|
const props = defineProps({
|
|
|
goodsCode: {
|
|
|
@@ -22,189 +21,91 @@ const props = defineProps({
|
|
|
}
|
|
|
})
|
|
|
|
|
|
-const { getGoodsQuote, quoteWatch } = useFuturesStore()
|
|
|
-const quote = getGoodsQuote(props.goodsCode)
|
|
|
-const subscribe = quoteSocket.createSubscribe()
|
|
|
-
|
|
|
-const chartRef = shallowRef()
|
|
|
-const chartCycleType = shallowRef(ChartCycleType.Minutes) // 周期类型
|
|
|
+const { cycleType, networkFilter, updateLastData } = useKLine(props.goodsCode)
|
|
|
+const { quoteWatch } = useFuturesStore()
|
|
|
+const chartSymbol = '600000.sh' // 股票代码(必填)
|
|
|
const chartInstance = shallowRef() // 图表实例
|
|
|
+const subscribe = quoteSocket.createSubscribe()
|
|
|
|
|
|
-subscribe.start(props.goodsCode)
|
|
|
-
|
|
|
-let updateChart: (opt: { symbol: string; data: (string | number)[][]; }) => void = () => ({})
|
|
|
+// https://blog.csdn.net/jones2000/article/details/90272733
|
|
|
+const chartOption = {
|
|
|
+ Symbol: chartSymbol,
|
|
|
+ Type: '历史K线图',
|
|
|
+ IsAutoUpdate: false,
|
|
|
+ IsApiPeriod: true, // 每次切换周期请求接口数据
|
|
|
+ NetworkFilter: (data: NetworkFilterData, callback: NetworkFilterCallback) => networkFilter(data, callback),
|
|
|
+ Windows: [
|
|
|
+ { Index: 'MA', Modify: false, Change: false },
|
|
|
+ { Index: 'VOL', Modify: false, Change: false }
|
|
|
+ ],
|
|
|
+ IsShowCorssCursorInfo: true,
|
|
|
+ Border: {
|
|
|
+ Left: 1,
|
|
|
+ Right: 1, //右边间距
|
|
|
+ Top: 25,
|
|
|
+ Bottom: 25,
|
|
|
+ },
|
|
|
+ KLine: {
|
|
|
+ Right: 1,
|
|
|
+ // [30001-32000) 秒周期
|
|
|
+ // 0=日线 1=周线 2=月线 3=年线 9=季线 [40001-50000) 自定义日线
|
|
|
+ // 4=1分钟 5=5分钟 6=15分钟 7=30分钟 8=60分钟 11=120分钟 12=240分钟 [20001-30000) 自定义分钟
|
|
|
+ Period: 4,
|
|
|
+ PageSize: 50,
|
|
|
+ IsShowTooltip: true,
|
|
|
+ },
|
|
|
+ KLineTitle:
|
|
|
+ {
|
|
|
+ IsShowName: false, // 不显示股票名称
|
|
|
+ IsShowSettingInfo: false // 不显示周期/复权
|
|
|
+ },
|
|
|
+ Frame: [
|
|
|
+ {
|
|
|
+ Custom: [
|
|
|
+ {
|
|
|
+ Type: 0,
|
|
|
+ Position: 'right',
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ IsShowRightText: false // 是否显示Y轴右侧刻度
|
|
|
+ },
|
|
|
+ {
|
|
|
+ IsShowRightText: false // 是否显示Y轴右侧刻度
|
|
|
+ }
|
|
|
+ ]
|
|
|
+}
|
|
|
|
|
|
// 切换周期
|
|
|
const changePeriod = (period: number) => {
|
|
|
switch (period) {
|
|
|
case 1:
|
|
|
- chartCycleType.value = ChartCycleType.Week
|
|
|
+ cycleType.value = ChartCycleType.Week
|
|
|
break
|
|
|
case 4:
|
|
|
- chartCycleType.value = ChartCycleType.Minutes
|
|
|
+ cycleType.value = ChartCycleType.Minutes
|
|
|
break
|
|
|
case 5:
|
|
|
- chartCycleType.value = ChartCycleType.Minutes5
|
|
|
+ cycleType.value = ChartCycleType.Minutes5
|
|
|
break
|
|
|
}
|
|
|
- //chartInstance.value.ChangeSymbol('600000.sh') // 切换股票
|
|
|
+ //chartInstance.value.ChangeSymbol(chartSymbol) // 切换股票
|
|
|
chartInstance.value.ChangePeriod(period) // 切换周期
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-const historyData = shallowRef<Model.HistoryDatasRsp[]>([])
|
|
|
-
|
|
|
-
|
|
|
-const reqeustHistoryData = () => {
|
|
|
- // 获取历史行情
|
|
|
- queryHistoryDatas({
|
|
|
- data: {
|
|
|
- cycleType: chartCycleType.value,
|
|
|
- goodsCode: props.goodsCode,
|
|
|
- count: 1440,
|
|
|
- }
|
|
|
- }).then((res) => {
|
|
|
- const data = res.data.sort((a, b) => moment(a.ts).valueOf() - moment(b.ts).valueOf())
|
|
|
- historyData.value = data
|
|
|
-
|
|
|
- updateChart({
|
|
|
- symbol: '600000.sh', // 股票代码(必填)
|
|
|
- data: data.map((e) => ([
|
|
|
- moment(e.ts).format('YYYYMMDD'),
|
|
|
- quote.value?.preclose ?? 0,
|
|
|
- e.o,
|
|
|
- e.h,
|
|
|
- e.l,
|
|
|
- e.c,
|
|
|
- e.tv,
|
|
|
- e.tt,
|
|
|
- moment(e.ts).format('HHmm'),
|
|
|
- ]))
|
|
|
- })
|
|
|
-
|
|
|
-
|
|
|
- console.log('chartInstance', chartInstance.value)
|
|
|
- })
|
|
|
+const onReady = (chart: unknown) => {
|
|
|
+ chartInstance.value = chart
|
|
|
}
|
|
|
|
|
|
quoteWatch(props.goodsCode, (q) => {
|
|
|
- const { last, lasttime } = q
|
|
|
- if (last && lasttime) {
|
|
|
-
|
|
|
- const lastIndex = historyData.value.length - 1 // 历史数据最后索引位置
|
|
|
-
|
|
|
- const oldTime = lastIndex === -1 ? moment(lasttime) : moment(historyData.value[lastIndex].ts) // 历史行情最后时间
|
|
|
- const diffTime = moment(lasttime).valueOf() - oldTime.valueOf() // 计算时间差
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- // 判断时间差是否大于周期时间
|
|
|
- if (lastIndex === -1 || diffTime > 60 * 1000) {
|
|
|
- historyData.value.push({
|
|
|
- o: last,
|
|
|
- h: last,
|
|
|
- l: last,
|
|
|
- c: last,
|
|
|
- tv: 0,
|
|
|
- tt: 0,
|
|
|
- hv: 0,
|
|
|
- s: 0,
|
|
|
- ts: lasttime,
|
|
|
- f: false
|
|
|
- })
|
|
|
- } else {
|
|
|
- // 更新列表中最后一条记录的数据
|
|
|
- const record = historyData.value[lastIndex]
|
|
|
- if (record.l > last) {
|
|
|
- record.l = last // 更新最低价
|
|
|
- }
|
|
|
- if (record.h < last) {
|
|
|
- record.h = last // 更新最高价
|
|
|
- }
|
|
|
- record.c = last // 更新收盘价
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- // updateChart({
|
|
|
- // symbol: '600000.sh',
|
|
|
- // data: historyData.value.map((e) => ([
|
|
|
- // moment(e.ts).format('YYYYMMDD'),
|
|
|
- // quote.value?.preclose ?? 0,
|
|
|
- // e.o,
|
|
|
- // e.h,
|
|
|
- // e.l,
|
|
|
- // e.c,
|
|
|
- // e.tv,
|
|
|
- // e.tt,
|
|
|
- // moment(e.ts).format('HHmm'),
|
|
|
- // ]))
|
|
|
- // })
|
|
|
+ const data = updateLastData(q)
|
|
|
+ if (chartInstance.value && data.length) {
|
|
|
+ chartInstance.value.JSChartContainer.RecvMinuteRealtimeDataV2({
|
|
|
+ symbol: chartSymbol,
|
|
|
+ data
|
|
|
+ })
|
|
|
}
|
|
|
})
|
|
|
|
|
|
-onMounted(() => {
|
|
|
- // https://blog.csdn.net/jones2000/article/details/90272733
|
|
|
- const option = {
|
|
|
- Symbol: '600000.sh', // 股票代码(必填)
|
|
|
- Type: '历史K线图',
|
|
|
- IsAutoUpdate: false,
|
|
|
- IsApiPeriod: true, // 每次切换周期请求接口数据
|
|
|
- NetworkFilter: (data: { Name: string; Explain: string; PreventDefault: boolean; }, callback: (opt: { symbol: string; data: (string | number)[][]; }) => void) => {
|
|
|
- data.PreventDefault = true
|
|
|
- // https://blog.csdn.net/jones2000/article/details/100557649
|
|
|
- switch (data.Name) {
|
|
|
- case 'KLineChartContainer::ReqeustHistoryMinuteData':
|
|
|
- updateChart = callback
|
|
|
- reqeustHistoryData()
|
|
|
- break
|
|
|
- case 'KLineChartContainer::RequestHistoryData':
|
|
|
- updateChart = callback
|
|
|
- reqeustHistoryData()
|
|
|
- break
|
|
|
- }
|
|
|
- },
|
|
|
- Windows: [
|
|
|
- { Index: 'MA', Modify: false, Change: false },
|
|
|
- { Index: 'VOL', Modify: false, Change: false }
|
|
|
- ],
|
|
|
- IsShowCorssCursorInfo: true,
|
|
|
- Border: {
|
|
|
- Left: 1,
|
|
|
- Right: 1, //右边间距
|
|
|
- Top: 25,
|
|
|
- Bottom: 25,
|
|
|
- },
|
|
|
- KLine: {
|
|
|
- Right: 1,
|
|
|
- // [30001-32000) 秒周期
|
|
|
- // 0=日线 1=周线 2=月线 3=年线 9=季线 [40001-50000) 自定义日线
|
|
|
- // 4=1分钟 5=5分钟 6=15分钟 7=30分钟 8=60分钟 11=120分钟 12=240分钟 [20001-30000) 自定义分钟
|
|
|
- Period: 4,
|
|
|
- PageSize: 50,
|
|
|
- IsShowTooltip: true
|
|
|
- },
|
|
|
- Frame: [
|
|
|
- {
|
|
|
- IsShowRightText: false // 是否显示Y轴右侧刻度
|
|
|
- },
|
|
|
- {
|
|
|
- IsShowRightText: false // 是否显示Y轴右侧刻度
|
|
|
- }
|
|
|
- ]
|
|
|
- }
|
|
|
-
|
|
|
- const resource = Chart.JSChart.GetResource()
|
|
|
- resource.FrameLogo.Text = ''
|
|
|
-
|
|
|
- // https://blog.csdn.net/jones2000/article/details/104122774
|
|
|
- Chart.JSConsole.Chart.Log = () => ({})
|
|
|
- Chart.JSConsole.Complier.Log = () => ({})
|
|
|
-
|
|
|
- chartInstance.value = Chart.JSChart.Init(chartRef.value)
|
|
|
- chartInstance.value.SetOption(option)
|
|
|
-})
|
|
|
+onMounted(() => subscribe.start(props.goodsCode))
|
|
|
+onUnmounted(() => subscribe.stop())
|
|
|
</script>
|