Procházet zdrojové kódy

Merge branch 'master' of http://47.101.159.18:3000/Muchinfo/MTP2.0_WEB

huangbin před 4 roky
rodič
revize
c45c29e4cc

+ 6 - 9
src/common/components/echart/echart-kline/index.vue

@@ -35,18 +35,15 @@ export default defineComponent({
 
         // 处理图表数据
         const handleData = (rawData: QueryHistoryDatasRsp[]): void => {
-            const datas: number[][] = [];
-            const times: string[] = [];
             historyIndexs.length = 0; // 清空数据
+            const datas: number[][] = [],
+                times: string[] = [];
 
             rawData.forEach((item, index) => {
                 const { o, c, h, l, ts } = item;
                 datas.push([o, c, h, l]);
-                times.push(moment(ts).format('YYYY-MM-DD HH:mm:ss'));
-                // 排除补充数据
-                if (!item.f) {
-                    historyIndexs.push(index);
-                }
+                times.push(moment(ts).format('MM-DD HH:mm'));
+                if (!item.f) historyIndexs.push(index); // 排除补充数据
             });
 
             chartData.datas = datas;
@@ -179,7 +176,7 @@ export default defineComponent({
             // 判断时间差是否大于周期时间
             if (diffTime > cycleMilliseconds) {
                 lastTime.add(cycleMilliseconds, 'ms');
-                times.push(lastTime.format('YYYY-MM-DD HH:mm:ss')); // 添加历史行情时间
+                times.push(lastTime.format('MM-DD HH:mm')); // 添加历史行情时间
                 datas.push([newPrice, newPrice, newPrice, newPrice]); // 添加历史行情数据
                 historyIndexs.push(lastIndex + 1); // 添加历史行情索引
             } else {
@@ -224,7 +221,7 @@ export default defineComponent({
             const params: QueryHistoryDatas = {
                 cycleType: props.cycleType,
                 goodsCode: props.quoteData.goodscode,
-                count: 2000,
+                count: 1440,
             };
             // 查询K线数据
             queryHistoryDatas(params).then((res) => {

+ 1 - 1
src/common/components/echart/echart-kline/setup.ts

@@ -100,7 +100,7 @@ export function handleEchart() {
                     let result = '';
                     params.forEach((item: any) => {
                         if (item.seriesType === 'candlestick') {
-                            result += '<div class="tooltip-title">' + moment(item.name).format('YYYY/MM/DD') + '</div>';
+                            result += '<div class="tooltip-title">' + item.name + '</div>';
                             item.value.forEach((data: number[], i: number) => {
                                 if (i > 0) {
                                     result += '<div class="tooltip-item"><span><i style="background-color:' + item.color + ';"></i>';

+ 77 - 47
src/common/components/echart/echart-timeline/index.vue

@@ -6,11 +6,11 @@
 import { defineComponent, ref, watch, PropType } from 'vue';
 import { QueryTSDataRsp, QueryQuoteDayRsp } from '@/services/go/quote/interface';
 import { QueryTSData } from '@/services/go/quote';
-import { getGoodsByCode } from '@/services/bus/goods';
-import { handleEchart, ChartData } from './setup';
-import EchartBase from '../echart-base/index.vue';
-import { getRangeTime } from '@/utils/time';
+import { debounce, getRangeTime } from '@/utils/time';
 import { toDecimalFull } from '@/utils/number';
+import EchartBase from '../echart-base/index.vue';
+import { handleEchart } from './setup';
+import moment from 'moment';
 
 export default defineComponent({
     name: 'EchartTime',
@@ -26,39 +26,50 @@ export default defineComponent({
     },
     setup(props) {
         const loading = ref(true);
+        const historyIndexs: number[] = []; // 行情历史数据中所有非补充数据的索引位置(用于计算均线)
         const { chartData, options, updateOptions, initOptions } = handleEchart();
 
         // 处理图表数据
-        const handleData = (rawData: QueryTSDataRsp): ChartData => {
-            const datas = rawData.historyDatas!.map((item) => item.c),
-                startTime = rawData.startTime!,
-                endTime = rawData.endTime!,
-                times = getRangeTime(startTime, endTime, 'HH:mm', 'm'),
-                yestclose = rawData.preSettle!,
-                decimal = rawData.decimalPlace!;
+        const handleData = (rawData: QueryTSDataRsp): void => {
+            historyIndexs.length = 0; // 清空数据
+            const datas: number[] = [],
+                times: string[] = [],
+                xAxisTimes: string[] = [],
+                yestclose = rawData.preSettle,
+                decimal = rawData.decimalPlace;
 
-            const { last, lasttime: lastTime } = props.quoteData;
-            const { min, max } = calcDataLine(datas, yestclose, last);
+            rawData.historyDatas.forEach((item, index) => {
+                const { c, ts } = item;
+                datas.push(c);
+                times.push(moment(ts).format('MM-DD HH:mm'));
+                if (!item.f) historyIndexs.push(index);
+            });
 
-            return {
+            rawData.runSteps.forEach((item) => {
+                const { start, end } = item;
+                const rangeTime = getRangeTime(start, end, 'HH:mm', 'm');
+                xAxisTimes.push(...rangeTime);
+            });
+
+            chartData.value = {
                 datas,
                 times,
+                xAxisTimes,
                 yestclose,
-                last,
-                lastTime,
                 decimal,
-                min,
-                max,
-                ma5: calcMA(rawData, 5),
+                ma5: calcMA(datas, 5, decimal),
+                ...calcDataLine(datas, yestclose),
             };
         };
 
         // 计算图表最高低指标线
-        const calcDataLine = (datas: number[], yestclose: number, last: number) => {
-            let max = Math.max(...datas, last); // 取历历史数据最高价
-            let min = Math.min(...datas, last); // 取历史数据最低价
-            const a = yestclose - min; // 计算收盘价和最低价的差值
-            const b = max - yestclose; // 计算收盘价和最高价的差值
+        const calcDataLine = (datas: number[], yestclose: number) => {
+            let max = Math.max(...datas); // 取历史行情最高价
+            let min = Math.min(...datas); // 取历史行情最低价
+
+            const last = datas[datas.length - 1], // 历史行情最后收盘价
+                a = yestclose - min, // 计算收盘价和最低价的差值
+                b = max - yestclose; // 计算收盘价和最高价的差值
 
             // 比较差值大小
             if (a > b) {
@@ -84,37 +95,28 @@ export default defineComponent({
         };
 
         // 计算平均线
-        const calcMA = (rawData: QueryTSDataRsp, count: number) => {
-            const datas = rawData.historyDatas!,
-                decimal = rawData.decimalPlace!;
-
+        const calcMA = (datas: number[], count: number, decimal: number) => {
             const result: string[] = [];
             if (datas.length >= count) {
-                // 所有非补充数据的索引id
-                const dataIndexs = datas.reduce((prev: number[], cur, index) => {
-                    if (!cur.f) prev.push(index);
-                    return prev;
-                }, []);
                 // 均线起始位置
-                const startIndex = dataIndexs[count - 1];
-
+                const startIndex = historyIndexs[count - 1];
                 datas.forEach((item, index) => {
                     if (index < startIndex) {
                         result.push('-');
                     } else {
-                        const j = dataIndexs.findIndex((val) => val === index);
+                        const j = historyIndexs.findIndex((val) => val === index);
                         // 判断是否补充数据
                         if (j === -1) {
                             // 取上个平均值
                             result.push(result[result.length - 1]);
                         } else {
                             // 向后取MA数
-                            const splitIndexs = dataIndexs.slice(j - (count - 1), j + 1);
+                            const maIndexs = historyIndexs.slice(j - (count - 1), j + 1);
                             // 计算总价
-                            const total = splitIndexs.reduce((sum, val) => sum + datas[val].c, 0);
+                            const total = maIndexs.reduce((sum, val) => sum + datas[val], 0);
                             // 计算均线
-                            const average = toDecimalFull(total / count, decimal);
-                            result.push(average);
+                            const ma = toDecimalFull(total / count, decimal);
+                            result.push(ma);
                         }
                     }
                 });
@@ -122,21 +124,49 @@ export default defineComponent({
             return result;
         };
 
+        // 更新图表K线数据
+        const updateChartData = () => {
+            const { datas, times } = chartData.value,
+                lastIndex = datas.length - 1, // 历史行情最后索引位置
+                lastTime = moment(times[times.length - 1]), // 历史行情最后时间
+                newTime = moment(props.quoteData.lasttime), // 实时行情最新时间
+                newPrice = props.quoteData.last; // 实时行情最新价
+
+            const cycleMilliseconds = 60 * 1000; // 周期毫秒数
+
+            const diffTime = newTime.valueOf() - lastTime.valueOf(); // 计算时间差
+            // 判断时间差是否大于周期时间
+            if (diffTime > cycleMilliseconds) {
+                lastTime.add(cycleMilliseconds, 'ms');
+                times.push(lastTime.format('MM-DD HH:mm')); // 添加历史行情时间
+                datas.push(newPrice); // 添加历史行情数据
+                historyIndexs.push(lastIndex + 1); // 添加历史行情索引
+            } else {
+                datas[lastIndex] = newPrice; // 更新历史行情数据
+            }
+
+            // 延迟图表更新,减少卡顿
+            debounce(() => {
+                const { min, max } = calcDataLine(datas, chartData.value.yestclose);
+                chartData.value.ma5 = calcMA(datas, 5, chartData.value.decimal);
+                chartData.value.min = min;
+                chartData.value.max = max;
+
+                updateOptions();
+            }, 1000);
+        };
+
         // 查询分时数据
         QueryTSData(props.quoteData.goodscode).then((res) => {
-            chartData.value = handleData(res);
+            handleData(res);
             initOptions();
         });
 
         watch(
             () => props.quoteData.last,
-            (val) => {
+            () => {
                 if (!loading.value) {
-                    const { min, max } = calcDataLine(chartData.value.datas, chartData.value.yestclose, val);
-                    chartData.value.last = val;
-                    chartData.value.min = min;
-                    chartData.value.max = max;
-                    updateOptions();
+                    updateChartData();
                 }
             }
         );

+ 25 - 17
src/common/components/echart/echart-timeline/setup.ts

@@ -23,10 +23,9 @@ type Colors = {
 // 图表数据
 export type ChartData = {
     datas: number[], // 历史数据
-    times: string[], // 历史日期
+    times: string[], // 历史时间
+    xAxisTimes: string[], // X轴时间数据
     yestclose: number, // 昨日收盘价
-    last: number, // 最新行情价
-    lastTime: string, // 最新行情时间
     decimal: number, // 保留小数位
     min: number, // Y轴最低指标线
     max: number, // Y轴最高指标线
@@ -41,9 +40,8 @@ export function handleEchart() {
     const chartData = ref<ChartData>({
         datas: [],
         times: [],
+        xAxisTimes: [],
         yestclose: 0,
-        last: 0,
-        lastTime: '',
         decimal: 0,
         min: 0,
         max: 0,
@@ -58,7 +56,7 @@ export function handleEchart() {
 
     // 初始化图表配置
     const initOptions = () => {
-        const { datas, times, yestclose, last, min, max, ma5, decimal } = chartData.value;
+        const { datas, times, yestclose, min, max, ma5, decimal, xAxisTimes } = chartData.value;
         const option: EChartsOption = {
             animation: false,
             legend: {
@@ -84,13 +82,12 @@ export function handleEchart() {
                 textStyle: {
                     color: '#4d535c',
                 },
-                // eslint-disable-next-line
                 formatter: (params: any) => {
                     const i = params[0].dataIndex;
-                    const result = `
-    <div><span style="display: inline-block; width: 40px">当前价:</span><span style="display: inline-block; width: 100px; text-align: right">${datas[i]}</span></div>
-    <div><span style="display: inline-block; width: 40px">均价:</span><span style="display: inline-block; width: 100px; text-align: right">${ma5[i]}</span></div>
-    <div><span style="display: inline-block; width: 40px">涨幅:</span><span style="display: inline-block; width: 100px; text-align: right">${calcRatio(datas[i])}</span></div>`;
+                    let result = '<div class="tooltip-title">' + times[i] + '</div>';
+                    result += '<div class="tooltip-item"><span><i style="background-color:' + params[0].color + ';"></i>收盘</span><span>' + datas[i] + '</span></div>';
+                    result += '<div class="tooltip-item"><span><i style="background-color:' + params[2].color + ';"></i>均价</span><span>' + ma5[i] + '</span></div>';
+                    result += '<div class="tooltip-item"><span><i></i>涨幅</span><span>' + calcRatio(datas[i]) + '</span></div>';
                     return result;
                 },
             },
@@ -103,11 +100,16 @@ export function handleEchart() {
             xAxis: {
                 type: 'category',
                 // X轴时间线
-                data: times,
+                data: xAxisTimes,
                 splitLine: {
                     // 坐标分隔线
                     show: true,
                 },
+                axisLabel: {
+                    showMinLabel: true,
+                    showMaxLabel: true,
+                    interval: 50,
+                }
             },
             yAxis: [
                 // Y轴左侧标签
@@ -137,12 +139,12 @@ export function handleEchart() {
             // series 中不指定 yAxisId 或 yAxisIndex 默认关联 yAxis 第一个配置,xAxis 配置同理
             series: [
                 {
-                    name: '当前价',
+                    name: '分时',
                     type: 'line',
                     yAxisId: 'leftPrice',
                     data: chartData.value.datas,
                     smooth: true,
-                    symbol: 'circle', //中时有小圆点
+                    symbol: 'none', //中时有小圆点
                     lineStyle: {
                         opacity: 0.8,
                         width: 1,
@@ -154,7 +156,7 @@ export function handleEchart() {
                         data: [
                             {
                                 // 最新价
-                                yAxis: last,
+                                yAxis: datas[datas.length - 1],
                             },
                             {
                                 // 昨结价
@@ -197,7 +199,7 @@ export function handleEchart() {
 
     // 动态更新数据
     const updateOptions = () => {
-        const { datas, last, yestclose, min, max } = chartData.value;
+        const { datas, yestclose, ma5, min, max } = chartData.value;
         if (datas.length) {
             options.value = {
                 yAxis: [
@@ -216,11 +218,13 @@ export function handleEchart() {
                 ],
                 series: [
                     {
+                        name: '分时',
+                        data: datas,
                         markLine: {
                             data: [
                                 {
                                     // 最新价
-                                    yAxis: last,
+                                    yAxis: datas[datas.length - 1],
                                 },
                                 {
                                     // 昨结价
@@ -235,6 +239,10 @@ export function handleEchart() {
                             ],
                         },
                     },
+                    {
+                        name: '均价',
+                        data: ma5,
+                    },
                 ],
             };
         }

+ 10 - 10
src/services/go/quote/interface.ts

@@ -67,16 +67,16 @@ export interface historyDatas {
     tv: number;
 }
 export interface QueryTSDataRsp {
-    Count?: number;
-    decimalPlace?: number;
-    endTime?: string;
-    goodsCode?: string;
-    outGoodsCode?: string;
-    preSettle?: number;
-    startTime?: string;
-    tradeDate?: string;
-    historyDatas?: historyDatas[];
-    RunSteps?: RunSteps[];
+    Count: number;
+    decimalPlace: number;
+    endTime: string;
+    goodsCode: string;
+    outGoodsCode: string;
+    preSettle: number;
+    startTime: string;
+    tradeDate: string;
+    historyDatas: historyDatas[];
+    runSteps: RunSteps[];
 }
 
 export interface RunSteps {