:bgColor="isLeave != 1 ? Color(0,tooltipData[3]) : Color(0,symbol.pc)" :navTransparentFixedBackgrpundColor="isLeave != 1 ? Color(0,tooltipData[3]) : Color(0,symbol.pc)" transparentFixedFontColor="#fff" :fontColor="'#fff'" :navFontColor="'#fff'" :pageParams="2" class="hq-nav" v-if="navIndex == 0">
:style="{backgroundColor: isLeave != 1 ? Color(0,tooltipData[3]) : Color(0,symbol.pc)}" v-if="navIndex == 0"> {{ isLeave != 1 ? tooltipData[1] == null || tooltipData[1] == '' || tooltipData[1] == '0.00' ? '--' : toDecimal(tooltipData[1],getTickDecLen(symbol), true) : (symbol.cp == null || symbol.cp == '' || symbol.cp == '0.00' ? '--' : toDecimal(symbol.cp,getTickDecLen(symbol), true)) }}
v-if="isLeave != 1">{{ tooltipData[3] > 0 ? "+" : ""}}{{tooltipData[3] == null || tooltipData[3] == '' ? '--' : toDecimal(tooltipData[3],2, true)}}
v-else>{{ symbol.pc > 0 ? "+" : ""}}{{symbol.pc == null || symbol.pc == '' ? '--' : toDecimal(symbol.pc,2, true)}}
今开
{{toDecimal(symbol.op,digit, true)}}
现量
{{formatNumUnit(symbol.cq, 1)}}
总额
{{formatNumUnit(symbol.tm, 1)}}
换手
净值
{{symbol.nav==null?'--':formatNumUnit(symbol.nav, 3)}}
总额
{{formatNumUnit(symbol.tm, 1)}}
涨家
{{toDecimal(symbol.un,0)}}
总值
{{symbol.tmv==null?'--':formatNumUnit(symbol.tmv, 1)}}
最高
{{toDecimal(symbol.hp,digit, true)}}
总手
总手
溢价
{{toDecimal(symbol.pre,3)}}
外盘
{{symbol.bv==null?'--':formatNumUnit(parseInt(symbol.bv), 1)}}
跌家
{{toDecimal(symbol.dn,0)}}
流值
{{symbol.cmv==null?'--':formatNumUnit(symbol.cmv,1)}}
最低
{{toDecimal(symbol.lp,digit, true)}}
均价
{{toDecimal(symbol.ap,digit, true)}}
委比
{{symbol.or == null ? '--':toDecimal(symbol.or * 100, 2, true)+'%'}}
溢价率
内盘
{{symbol.sv==null?'--':formatNumUnit(parseInt(symbol.sv), 1)}}
平家
{{toDecimal(symbol.fn,0)}}
市盈率
:haswd="haswd" :preclose="symbol.pp" :curIndex="curIndex" :isLeave="isLeave" @getTooltipData="getTooltipData" /> import common from "@/common/index"; import chartMin from './components/chartMin.vue'; import { allSelfSecurity, addSelfSecurity, deleteSelfSecurity } from "@/api/optional.js"; // 后端接口 import { turnColor, getQueryString } from './u.js'; import { IsEndMatch, getMatchAndExercise } from "@/api/practice.js"; // 后端接口 import { signalrsOn, signalrInvoke } from '@/util/signalR.js'; // 行情订阅与取消订阅接口 import { trigger } from '@/util/callback'; export default { components: { chartMin }, data() { return { bgColor: '#57B967', curIndex: 0, shortname: '', code: '', maket: '', securityType: '', plateId: '', selectId: '', navList: [{ label: '分时' }, { label: '日K' }, { label: '周K' }, { label: '月K' }, ], navType: [ 'L1MinQuotation', 'DayKlineQuotation', 'WeekKlineQuotation', 'MonthKlineQuotation' ], navIndex: 0, mlist: {}, mdata: {}, removeDuplication: {}, symbol: { cp: null, cg: null, cr: null, op: null, hp: null, lp: null, tr: '', tq: null, tm: null, or: null, tm: null, cmv: null, pe1: null, pp: null, // 昨收 pre: null, // 溢价 prer: null, // 溢价率 nav: null, // 净值 cq: null, //现量 bv: null, //外盘 sv: null, //内盘 tr: null, // 换手 or: null, // 委比 pc: null, // 涨跌 utc: '', // 时间 }, tq: 0, op: 0, haswd: true, // 是否显示五档行情 sbData: [], selectList: [], sbList: [], partType: '', // 成分股类型 loadingShow: false, // 阻止频繁链接断开socket lockTime: null, isIos: sessionStorage.getItem('isIOS'), preNavIndex: 0, // 日K切换上一个记录,用于取消订阅 tradingTimeList: [], // 买卖时间数组 scrollTopPage: 0, tooltipData: [], // 分时图数据 isLeave: 1, // 分时图是否离开点击(1:是 0:否) isKLineLeave: 1, // K线图是否离开点击(1:是 0:否) topNum: 590, tradePageTypeData:true,//正常股票显示,该大赛包含港股通,显示 } }, // 实时获取滚动条的位置 onPageScroll(res) { this.scrollTopPage = res.scrollTop }, onReachBottom() { if(this.securityType == 'S0101') { this.$refs.sharesInfo.loadFund() } }, methods: { // 小数位数 getTickDecLen(item) { return common.getTickDecLen(this.securityType, item.mk); }, // 获取分时图涨跌,涨跌幅,时间,现价数据 getTooltipData(value) { this.tooltipData = value this.isLeave = value[4] }, // 行情订阅 SubscribeOn() { signalrsOn('SubscribeReturn', (item) => { if (item.quotationtype) { if (item.quotationtype === 'L1MinQuotation' && item.tranparam == 10) { if (this.securityType == 'S0104') { setTimeout(() => { this.initMdata(item.data) }, 200) } else { this.initMdata(item.data) } this.isLeave = 1 this.symbol.cp = item.data[item.data.length - 1].cp // 现价 this.symbol.pc = item.data[item.data.length - 1].pc // 涨跌 this.symbol.cr = item.data[item.data.length - 1].cr // 涨跌幅 this.symbol.utc = this.formatDate(new Date(item.data[item.data.length - 1].utc), 'hh:mm') // 时间 trigger('TickQuotationInfoList', this.mdata) } else if (item.quotationtype === 'TickQuotationInfo' && this.maket != 'PIDX') { if (`${this.code}.${this.maket}` != `${item.data.sm}.${item.data.mk}`) { return; } this.symbol.cp = item.data.cp this.symbol.cg = item.data.cg this.symbol.cr = item.data.cr this.symbol.op = item.data.op this.symbol.hp = item.data.hp this.symbol.lp = item.data.lp this.symbol.tr = item.data.tr this.symbol.tq = item.data.tq this.symbol.or = item.data.or this.symbol.tm = item.data.tm this.symbol.cmv = item.data.cmv this.symbol.pe1 = item.data.pe1 this.symbol.pp = item.data.pp this.symbol.sid = item.data.sid this.symbol.sm = item.data.sm this.symbol.mk = item.data.mk this.symbol.sn = item.data.sn this.symbol.tmv = item.data.tmv this.symbol.pre = item.data.pre this.symbol.prer = item.data.prer this.symbol.nav = this.toDecimal(item.data.nav, 3) this.symbol.cq = item.data.cq this.symbol.bv = item.data.bv this.symbol.sv = item.data.sv this.symbol.ap = item.data.ap // 均价 trigger('getPp', this.symbol.pp) } else if (item.quotationtype === 'FiveGearQuoteInfo') { if (item.data.buylevels && item.data.buylevels.length > 0) { item.data.buylevels.forEach(r => { r.volume = Math.round(r.volume) r.price = this.toDecimal(Number(r.price), this.digit) }) } if (item.data.selllevels && item.data.selllevels.length > 0) { item.data.selllevels.forEach(r => { r.volume = Math.round(r.volume) r.price = this.toDecimal(Number(r.price), this.digit) }) } trigger('FiveGearQuoteInfo', item) } else if (item && item.quotationtype == 'TickQuotationcs') { let res = item if (res && res.data) { let { data } = res.data this.sbData[this.tranparam] = [] if (data && data.length && data.length <= 10) { data.forEach((item) => { item.selectId = "" let index = this.sbData[this.tranparam].findIndex((sb) => { return sb.sid == item.sid }) if (index > -1) { if (JSON.stringify(i) != JSON.stringify(this.sbData[this .tranparam][index])) { this.$set(this.sbData[this.tranparam], index, i); } } else { this.sbData[this.tranparam].push(item) } }) let list = this.sbData[this.tranparam] if (this.selectList.length) { for (let i = 0; i < list.length; i++) { let id = list[i].sm + "." + list[i].mk; list[i].selectId = ""; for (let j = 0; j < this.selectList.length; j++) { let code = this.selectList[j].commodityCode + "." + this .selectList[j].market; if (code == id) { list[i].selectId = this.selectList[j].id || ''; break; } } } } this.sbList = list if (this.sbList.length) { let [{ tid }] = this.sbList this.partType = tid } } } } else if (item.quotationtype === 'PlateIndexQuotationInfo' && this.maket == 'PIDX') { if (`${this.code}.${this.maket}` != `${item.data.sm}.${item.data.mk}`) { return; } this.symbol = item.data this.symbol.cp = item.data.lp this.symbol.cg = item.data.c this.symbol.cr = item.data.cr this.symbol.op = item.data.op this.symbol.hp = item.data.hp this.symbol.lp = item.data.lowprice this.symbol.tr = item.data.tr this.symbol.tq = item.data.tv this.symbol.or = item.data.or this.symbol.tm = item.data.ta this.symbol.cmv = item.data.cmv this.symbol.pe1 = item.data.pe1 this.symbol.pp = item.data.pp this.symbol.sid = item.data.sid this.symbol.sm = item.data.sm this.symbol.mk = item.data.mk this.symbol.sn = item.data.sn this.symbol.tmv = item.data.tmv this.symbol.pre = item.data.pre this.symbol.prer = item.data.prer this.symbol.nav = this.toDecimal(item.data.nav, 3) this.symbol.cq = item.data.cq this.symbol.bv = item.data.bv this.symbol.sv = item.data.sv trigger('getPp', this.symbol.pp) } } }) }, unSubscribe() { signalrInvoke('Quotation2', 'UnSubscribe', { QuotationType: 'FiveGearQuoteInfo' }) signalrInvoke('Quotation', 'UnSubscribe', { QuotationType: 'TickQuotationInfo' }) for (var i in this.navType) { signalrInvoke('Quotation', 'UnSubscribe', { QuotationType: this.navType[i] }) } // 指数的 成分股列表订阅 let urls = getQueryString(window.location.href); if (urls.securityType == 'S0104') { signalrInvoke('Quotation', 'UnSubscribe', { QuotationType: 'TickQuotationcs', }) signalrInvoke('Quotation', 'UnSubscribe', { QuotationType: 'PlateIndexQuotationInfo' }) } this.mlist = {} this.mdata = {} this.tq = 0 }, unSubscribe1(index) { this.tq = 0 if (this.securityType != 'S0104') { setTimeout(() => { signalrInvoke('Quotation', 'UnSubscribe', { QuotationType: this.navType[this.preNavIndex] }) this.preNavIndex = index }, 50) } else { signalrInvoke('Quotation', 'UnSubscribe', { QuotationType: this.navType[this.preNavIndex] }) this.preNavIndex = index } }, Color(str1, str2) { return turnColor(str1, str2) }, // 验证是否能进行买卖 checkAbled() { // 日内转大赛非选证券 let matchInfo = sessionStorage.getItem("raceInfo") || {}; let matchUseCodesList = matchInfo.matchUseCodes || []; let codes = matchUseCodesList.map(item => { return item.securityID }) if (matchInfo.matchType == 4 && !codes.includes(this.code)) { uni.showToast({ title: `非当前日内回转赛指定证券!`, icon: "none", }) return false } else { return true } }, // 未选中大赛默认选取练习场 setPracticeInfo(res) { let practiceInfo = res.data[0] const { matchID, msTraderID, traderID } = practiceInfo // 1 练习场 sessionStorage.setItem("raceId", matchID); sessionStorage.setItem("userId", msTraderID); sessionStorage.setItem("mnTraderId", traderID); sessionStorage.setItem("raceInfo", practiceInfo); }, // 判断大赛是否结束 async checkIsEndMatch() { let raceInfo = sessionStorage.getItem("raceInfo") || {}; if (Object.keys(raceInfo).length == 0) { let pres = await getMatchAndExercise(); this.setPracticeInfo(pres) } else { // 组合不做大赛结束判断 if (raceInfo.endTime) { const params = { matchId: raceInfo.matchID || 1, }; // 大赛结束 let res = await IsEndMatch(params) if (res.isOK) { if (res.data && res.data.isStaticEnd) { let pres = await getMatchAndExercise(); this.setPracticeInfo(pres) } } } } }, async hqBuy() { if (!this.checkAbled()) return // 获取当前大赛状态,判断 let searchArr = sessionStorage.getItem('searchArr'); let stObj = searchArr.find(i => { return i.a == this.symbol.sm }) || {} let securityType = stObj.e let info = { securityID: this.symbol.sm, symbol: this.symbol.sm, securityType: securityType, market: this.symbol.mk, shortName: this.symbol.sn } if(this.maket=='HKEX'){//港股通过无快捷买卖弹框,直接跳转下单页面 this.$store.commit("setTradePageType","HKT") //general正常大赛操作,HKT是港股通操作 uni.redirectTo({ url: '/pages/mnsc/buyHKT?info=' + JSON.stringify(info) + '&isNaverEndMatch=1' }); return } }, async hqSale() { if (!this.checkAbled()) return // 获取当前大赛状态,判断 let searchArr = sessionStorage.getItem('searchArr'); let stObj = searchArr.find(i => { return i.a == this.symbol.sm }) || {} let securityType = stObj.e let info = { securityID: this.symbol.sm, symbol: this.symbol.sm, securityType: securityType, market: this.symbol.mk, shortName: this.symbol.sn } if(this.maket=='HKEX'){//港股通过无快捷买卖弹框,直接跳转下单页面 this.$store.commit("setTradePageType","HKT") //general正常大赛操作,HKT是港股通操作 uni.redirectTo({ url: '/pages/mnsc/saleHKT?info=' + JSON.stringify(info) + '&isNaverEndMatch=1' }); return } }, // 初始化分时图数据 initMdata(data) { // 筛选无效数据不做绘图 data = data.filter(item => { return !!item.cp }) if (data && data.length > 0) { data.forEach(item => { const temp = { utc: this.formatDate(new Date(item.utc), 'HHmm'), cp: this.toDecimal(item.cp, this.digit), // 收价 avg: this.toDecimal(item.avg, this.digit), // 均价 tv: this.toDecimal(item.tv, 0), // 总量 ta: item.ta || '--', // 总额 cr: this.toDecimal(this.numMul(item.cr, 100), 3), // 涨幅 pp: this.toDecimal(item.pp, this.digit), utc1: this.formatDate(new Date(item.utc), 'HH:mm'), utc2: item.utc, pc: this.toDecimal(item.pc, this.digit), // 涨跌 } this.$set(this.mlist, this.formatDate(new Date(item.utc), 'HHmm'), temp) }) } let lstData = [] for (const i in this.mlist) { try { let listItem = [ this.mlist[i].utc, this.toDecimal(+this.mlist[i].cp, this.digit), this.toDecimal(+this.mlist[i].avg, this.digit), this.mlist[i].tv, this.mlist[i].ta, this.mlist[i].cr, this.toDecimal(+this.mlist[i].pp, this.digit), this.mlist[i].utc1, this.mlist[i].utc2, this.mlist[i].pc, ] lstData.push(listItem) } catch (e) { console.log(e) } } lstData.sort((a, b) => a[0] - b[0]) this.mdata = { data: lstData, yestclose: this.mlist[0] && this.mlist[0].pp ? this.mlist[0].pp : this.toDecimal(this.symbol.pp, this.digit) } }, compareNum(a, b) { if (a >= b) { return true } else { return false } }, combomList(arr1, arr2) { arr2.forEach((item1, j) => { let flag = arr1.findIndex(r => r[0] === item1[0]) if (flag < 0) { this.$set(arr1, arr1.length, item1) } else { this.$set(arr1, flag, item1) } }) return arr1 }, // xx率乘100 toRatio(num) { if (num == null) { return 0.00 } return this.toDecimal(this.numMul(num, 100)) }, /** * 精确乘 * @param arg1 * @param arg2 * @returns {number} */ numMul(arg1, arg2) { var r1 = arg1 + ""; var r2 = arg2 + ""; var r3 = 0; var r4 = 0; try { r3 = r1.split(".")[1].length; } catch (err) { r3 = 0; } try { r4 = r2.split(".")[1].length; } catch (err) { r4 = 0; } return ( (Number(r1.replace(".", "")) * Number(r2.replace(".", ""))) / Math.pow(10, r4 + r3) ); }, // 格式化日期 formatDate(date, format) { var v = ""; if (typeof date === "string" || typeof date !== "object") { return; } var year = date.getFullYear(); var month = date.getMonth() + 1; var day = date.getDate(); var hour = date.getHours(); var minute = date.getMinutes(); var second = date.getSeconds(); var weekDay = date.getDay(); var ms = date.getMilliseconds(); var weekDayString = ""; if (weekDay === 1) { weekDayString = "星期一"; } else if (weekDay === 2) { weekDayString = "星期二"; } else if (weekDay === 3) { weekDayString = "星期三"; } else if (weekDay === 4) { weekDayString = "星期四"; } else if (weekDay === 5) { weekDayString = "星期五"; } else if (weekDay === 6) { weekDayString = "星期六"; } else if (weekDay === 0) { weekDayString = "星期日"; } v = format; // Year v = v.replace(/yyyy/g, year); v = v.replace(/YYYY/g, year); v = v.replace(/yy/g, (year + "").substring(2, 4)); v = v.replace(/YY/g, (year + "").substring(2, 4)); // Month var monthStr = "0" + month; v = v.replace(/MM/g, monthStr.substring(monthStr.length - 2)); // Day var dayStr = "0" + day; v = v.replace(/dd/g, dayStr.substring(dayStr.length - 2)); // hour var hourStr = "0" + hour; v = v.replace(/HH/g, hourStr.substring(hourStr.length - 2)); v = v.replace(/hh/g, hourStr.substring(hourStr.length - 2)); // minute var minuteStr = "0" + minute; v = v.replace(/mm/g, minuteStr.substring(minuteStr.length - 2)); // Millisecond v = v.replace(/sss/g, ms); v = v.replace(/SSS/g, ms); // second var secondStr = "0" + second; v = v.replace(/ss/g, secondStr.substring(secondStr.length - 2)); v = v.replace(/SS/g, secondStr.substring(secondStr.length - 2)); // weekDay v = v.replace(/E/g, weekDayString); return v; }, async allSelfSecurity() { let res = await allSelfSecurity(); if (res.isOK) { if (res.data && res.data.length) { this.selectList = res.data; let result = res.data.filter((dd) => `${dd.commodityCode}.${dd.market}` == `${this.code}.${this.maket}`) if (result && result.length) { this.selectId = result[0]['id'] || '' } else { this.selectId = "" } } else { this.selectId = "" } } }, // 添加自选代码 async addSelfData() { let res = await addSelfSecurity({ market: this.maket, securityType: this.securityType, shortName: this.shortname, plateID: this.plateId, commodityCode: this.code }) if (res.isOK) { this.selectId = res.data || '' uni.showToast({ title: `添加成功`, icon: "none", }) allSelfSecurity() } else { uni.showToast({ title: res.msg, icon: "none", }) } }, // 删除自选代码 async deleteSelfData() { let res = await deleteSelfSecurity({ id: this.selectId, }); if (res.isOK) { this.selectId = "" uni.showToast({ title: `删除成功`, icon: "none", }); this.allSelfSecurity() } else { uni.showToast({ title: `删除失败`, icon: "none", }); } }, // 指数成分股列表加入自选 setSbList(index, val) { this.$set(this.sbList[index], "selectId", val) this.allSelfSecurity() }, //去除自选 deleteSelect(index) { this.$set(this.sbList[index], "selectId", '') this.allSelfSecurity() } }, computed: { title() { return this.shortname + '(' + this.code + ')' }, digit() { //判断是不是深圳债券 if (Number(this.curIndex) == 6 || (+this.curIndex) < 3 || Number(this.curIndex) == 5) { return 2 } else { return 3 } }, divol() { if (this.curIndex == 4 && this.maket == 'SZSE') { return 10 } else { return 1 } }, }, onLoad(options) { uni.showLoading({ title: '加载中', mask: true }); // 接收买卖时间点 if (options.tradingTimeList) { this.tradingTimeList = JSON.parse(options.tradingTimeList) } this.shortname = options.shortname this.code = options.code this.maket = options.maket this.plateId = options.plateId // ['沪深A股', '科创板', '创业板', '基金', '债券', '北交所', '指数'] this.curIndex = options.curIndex // 从股、债、基、指模块进入详情 this.securityType = options.securityType // 进入详情呈现的类型股、债、基、指 this.selectId = options.selectId || '' this.haswd = !(options.curIndex == 6) // 指数板块没五档行情 // BK开头的衍生指数,展示分时; if (this.code.indexOf('BK') > -1) { this.navList = [{ label: '分时' }] } let timeout = +options.fromQuery ? 20 : (this.securityType == 'S0104' ? 20 : 0) setTimeout(() => { // 五档行情 signalrInvoke('Quotation2', 'Subscribe', { QuotationType: 'FiveGearQuoteInfo', SearchParamData: { Symbols: `${this.code}.${this.maket}` } }) // 股债基指头部信息 signalrInvoke('Quotation', 'Subscribe', { QuotationType: 'TickQuotationInfo', SearchParamData: { Symbols: `${this.code}.${this.maket}` } }) // 日周月K数 signalrInvoke('Quotation', 'Subscribe', { QuotationType: this.navType[0], SearchParamData: [{ Symbol: `${this.code}.${this.maket}` }], Limit: 1000, tranparam: 10 }) // 指数的 成分股列表订阅 let urls = getQueryString(window.location.href); if (urls.securityType == 'S0104') { // 指数地域板块 signalrInvoke('Quotation', 'Subscribe', { QuotationType: 'PlateIndexQuotationInfo', SearchParamData: { Symbols: `${this.code}.${this.maket}` } }) // 指数成分股 signalrInvoke('Quotation', 'Subscribe', { QuotationType: "TickQuotationcs", SearchParamData: { PageIndex: 1, PageSize: 10, OrderBy: 'cr', // 根据所选的排序字段 Sortord: 1, PlateId: this.plateId, IndustryId: null, SecurityId: 0, }, tranparam: 0 }) } }, timeout) this.SubscribeOn() this.allSelfSecurity() }, onHide() { this.unSubscribe() // 取消订阅 }, onShow() { // 回显时候刷新自选 this.SubscribeOn() this.allSelfSecurity() // 五档行情 setTimeout(() => { signalrInvoke('Quotation2', 'Subscribe', { QuotationType: 'FiveGearQuoteInfo', SearchParamData: { Symbols: `${this.code}.${this.maket}` } }) // 股债基指头部信息 signalrInvoke('Quotation', 'Subscribe', { QuotationType: 'TickQuotationInfo', SearchParamData: { Symbols: `${this.code}.${this.maket}` } }) // 指数的 成分股列表订阅 let urls = getQueryString(window.location.href); if (urls.securityType == 'S0104') { // 指数地域板块 signalrInvoke('Quotation', 'Subscribe', { QuotationType: 'PlateIndexQuotationInfo', SearchParamData: { Symbols: `${this.code}.${this.maket}` } }) // 指数成分股 signalrInvoke('Quotation', 'Subscribe', { QuotationType: "TickQuotationcs", SearchParamData: { PageIndex: 1, PageSize: 10, OrderBy: 'cr', // 根据所选的排序字段 Sortord: 1, PlateId: this.plateId, IndustryId: null, SecurityId: 0, }, tranparam: 0 }) } }, 50) setTimeout(() => { uni.hideLoading(); }, 1000) if(this.maket=='HKEX'){//默认的练习场没有港股通 this.tradePageTypeData = false } let matchInfo = sessionStorage.getItem("raceInfo") || {}; if(matchInfo&&matchInfo.hasOwnProperty("tradePageType")){ this.tradePageTypeData = matchInfo.tradePageType//当前大赛是否有港股通 } } } @import '@/static/css/mixin.scss'; @import '@/static/css/hq.scss'; page { background-color: #f4f5f6; .hq-detail-wrapper { .foot-wrapper { height: auto; background-color: #F9F9FA; border-top: 1px solid #EDEDED; .xflex-j-a { justify-content: space-around } .add { font-weight: 500; font-size: 24rpx; padding: 24rpx 0; .iconfont { font-size: 30rpx; } .text-but { color: #333333; font-weight: 400; font-family: Microsoft YaHei; } .text-but2 { color: #E93A40; font-weight: 400; font-family: Microsoft YaHei; } } } .search_icon { margin-right: 14rpx; padding-bottom: 5rpx; } .ai { flex: 1; font-weight: 500; font-size: 24rpx; margin: 24rpx 0; .iconfont { font-size: 30rpx; } .text-but { color: #333333; font-weight: 400; font-family: Microsoft YaHei; } } .ai-border-left { border-left: 1px solid #EDEDED; } .item-label { white-space: nowrap; } } .xflex { // position: sticky; top: 0; } .mask { position: fixed; z-index: 9999999999; top: 0; left: 50%; transform: translateX(-50%); bottom: 0; height: 100vh; width: 100vw; display: flex; flex-direction: column; justify-content: center; align-items: center; flex-wrap: wrap; } .mask.mask-show { background: rgba(255, 255, 255, 0.8); } .title { color: #666; font-size: 28rpx; margin-top: 20rpx; } .scroll-top { width: 82rpx; height: 82rpx; border-radius: 50%; opacity: 1; transition: opacity .5s; -webkit-transition: opacity .5s; bottom: 60rpx; } .show-img { opacity: 0; } } var bgColor = "#ffffff"; //背景 var upColor = "#E93A40"; //涨颜色 var downColor = "#57B967"; //跌颜色 import hq from './wdhq.vue'; import * as echarts from '@/common/echarts/echarts.min.js' import { fetchEmptyQuoteList } from "@/api/hq.js" // 后端接口 import { on } from '../../../util/callback'; /** * 计算价格涨跌幅百分比 * @param {Object} price 现价 * @param {Object} yclose 昨收价 */ function ratioCalculate(price, yclose) { return ((price - yclose) / yclose * 100).toFixed(2); } import dateFormat from '@/utils/dateFormat' export default { components: { hq }, props: ['mdata', 'code', 'shortname', 'maket', 'curIndex', 'haswd', 'isLeave'], data() { return { preclose: 0, mdata1: [], leftMax: 0, leftMin: 0, rightMax: 0, rightMin: 0, mChart: null, timeArr: [], // 根据品种取横轴坐标 isLeave1: this.isLeave } }, computed: { digit() { // && this.maket == 'SZSE' let isSZSE = this.curIndex == 4 if (Number(this.curIndex) == 3 || isSZSE) { return 3 } else { return 2 } }, divol() { if (this.curIndex != 4) { return 100 } else if (this.curIndex == 4 && this.maket == 'SZSE') { return 10 } else { return 1 } } }, watch: { mdata: { handler: function(newVal, oldVal) { if (newVal) { this.mdata1 = JSON.parse(JSON.stringify(newVal)) this.drawLine() } }, deep: true } }, methods: { /** * 15:20 时:分 格式时间增加num分钟 * @param {Object} time 起始时间 * @param {Object} num */ addTimeStr(time, num) { var hour = time.split(':')[0]; var mins = Number(time.split(':')[1]); var mins_un = parseInt((mins + num) / 60); var hour_un = parseInt((Number(hour) + mins_un) / 24); if (mins_un > 0) { if (hour_un > 0) { var tmpVal = ((Number(hour) + mins_un) % 24) + ""; hour = tmpVal.length > 1 ? tmpVal : '0' + tmpVal; //判断是否是一位 } else { var tmpVal = Number(hour) + mins_un + ""; hour = tmpVal.length > 1 ? tmpVal : '0' + tmpVal; } var tmpMinsVal = ((mins + num) % 60) + ""; mins = tmpMinsVal.length > 1 ? tmpMinsVal : 0 + tmpMinsVal; //分钟数为 取余60的数 } else { var tmpMinsVal = mins + num + ""; mins = tmpMinsVal.length > 1 ? tmpMinsVal : '0' + tmpMinsVal; //不大于整除60 } return hour + ":" + mins; }, //获取增加指定分钟数的 数组 如 09:30增加2分钟 结果为 ['09:31','09:32'] getNextTime(startTime, endTIme, offset, resultArr) { var result = this.addTimeStr(startTime, offset); resultArr.push(result); if (result == endTIme) { return resultArr; } else { return this.getNextTime(result, endTIme, offset, resultArr); } }, /** * 不同类型的股票的交易时间会不同 * @param {Object} type hs=沪深 us=美股 hk=港股 */ time_arr(type, time) { return this.timeArr }, // 重组分时数据 get_m_data(m_data, type) { var priceArr = new Array(); var avgPrice = new Array(); var vol = new Array(); var pcArr = new Array() var times = new Array(); var changeRatio = new Array() if (m_data.data && m_data.data.length > 0) { m_data.data.forEach((v) => { priceArr.push(Number(v[1])); avgPrice.push(Number(v[2])); vol.push(Number(v[3])); changeRatio.push(Number(v[5])) pcArr.push(Number(v[9])) if(v[7] != '00:00') { times.push(v[7]) } }) } var _time = this.time_arr(type, m_data.data[m_data.data.length - 1][8]); for (var t in _time) { if (!times.includes(_time[t])) { times.push(_time[t]) } } let obj = { priceArr: priceArr, avgPrice: avgPrice, vol: vol, times: times, pcArr: pcArr, changeRatio: changeRatio, yestclose: Number(m_data.yestclose) } this.getMaxMin(obj) return obj }, getMaxMin(obj) { var avgMax; var avgMin; var priceMax; var priceMin = 0; avgMax = this.getMax(obj.avgPrice); avgMin = this.getMin(obj.avgPrice); priceMax = this.getMax(obj.priceArr); priceMin = this.getMin(obj.priceArr); const middleLineVal = obj.yestclose; if ((middleLineVal - priceMax) * -1 > (middleLineVal - priceMin)) { priceMin = (middleLineVal - ((middleLineVal - priceMax) * -1)); } else { priceMax = (middleLineVal + (middleLineVal - priceMin)); } this.leftMax = avgMax > priceMax ? avgMax:priceMax this.leftMin = avgMin > priceMin ? priceMin : avgMin this.leftInterval = (this.leftMax - this.leftMin) / 2 this.rightMax = this.getMax(obj.changeRatio) this.rightMin = this.getMin(obj.changeRatio) const middleLineVal1 = 0; const max1 = this.rightMax - middleLineVal1 const min1 = middleLineVal1 - this.rightMin const absMax1 = Math.max(Math.abs(max1), Math.abs(min1)); if (absMax1 == 0) { this.rightMax = middleLineVal1 * 1.05 this.rightMin = middleLineVal1 * 0.95 } else { this.rightMax = middleLineVal1 + absMax1 this.rightMin = middleLineVal1 - absMax1 } this.rightInterval = Number( this.toDecimal( (this.rightMax - this.rightMin) / 2, 3, true ) ); }, getMax(arr) { const maxList = arr.filter((item) => item !== "-" && item != 0); let Max = 0; if (maxList.length > 0) { const max0 = maxList[0]; Max = max0; maxList.forEach((item) => { if (Number(item) > Number(Max)) { Max = Number(item); } }); } return Number(Max); }, getMin(arr) { const minList = arr.filter((item) => item !== "-" && item != 0); let Min = 0; if (minList.length > 0) { const min0 = minList[0]; Min = min0; minList.forEach((item) => { if (Number(item) < Number(Min)) { Min = Number(item); } }); } return Number(Min); }, initData() { this.mdata1 = JSON.parse(JSON.stringify(this.mdata)) }, async getTimeArr() { let res = await fetchEmptyQuoteList({symbol: this.code, exchangeCode: this.maket}) let timeArr = res.data.map(item => { return dateFormat(new Date(item), "hh:mm") }) || [] return timeArr }, /** * 生成分时option * @param {Object} m_data 分时数据 * @param {Object} type 股票类型 us-美股 hs-沪深 hk-港股 */ initMOption(m_data, type) { var m_datas = this.get_m_data(m_data, type); var _this = this; return { tooltip: { //弹框指示器 position: [5, '10%'], hideDelay: 10000, formatter: function(params, ticket, callback) { var i = params[0].dataIndex; var cpriceColor; var avgPriceColor; var radioColor; if (params[0].seriesType !== "line" || params[0].axisDim == "y") { return "" } // 现价 if (m_datas.priceArr[i] > m_data.yestclose) { cpriceColor = 'style="color:#ff4242"'; } else if(m_datas.priceArr[i] == m_data.yestclose) { cpriceColor = 'style="color:#fff"'; } else { cpriceColor = 'style="color:#26bf66"'; } // 均价 if (m_datas.avgPrice[i] > m_data.yestclose) { avgPriceColor = 'style="color:#ff4242"'; } else if(m_datas.avgPrice[i] == m_data.yestclose) { avgPriceColor = 'style="color:#fff"'; } else { avgPriceColor = 'style="color:#26bf66"'; } // 涨幅 if (m_datas.changeRatio[i] > 0) { radioColor = 'style="color:#ff4242"'; } else if(m_datas.changeRatio[i] == 0) { radioColor = 'style="color:#fff"'; } else { radioColor = 'style="color:#26bf66"'; } var html = ' ' _this.toDecimal(m_datas.priceArr[i], _this.digit) + ' html += ' html += ' html += ' '' _this.isLeave1 = 0 _this.$emit('getTooltipData', [params[0].axisValue, _this.toDecimal(m_datas.priceArr[i], _this.digit), m_datas.changeRatio[i], m_datas.pcArr[i], _this.isLeave1]) return html; } }, color: ['#2f569e', '#F39142'], legend: { //图例控件,点击图例控制哪些系列不显示 icon: 'rect', type: 'scroll', itemWidth: 14, itemHeight: 2, left: 0, top: '-1%', data: ['现价', '均价', '现手'], textStyle: { fontSize: 12, color: '#999999' } }, axisPointer: { show: true, link: { xAxisIndex: [0, 2] } }, grid: [{ id: 'gd1', left: '4%', right: '4%', height: '62.5%', //主K线的高度, top: '7%' }, { id: 'gd2', left: '4%', right: '4%', height: '62.5%', //主K线的高度, top: '7%' }, { id: 'gd3', left: '4%', right: '4%', top: '75%', height: '19%' //交易量图的高度 } ], xAxis: [ //==== x轴 { //主图 gridIndex: 0, data: m_datas.times, show: false, splitLine: { show: false, }, axisLine: { lineStyle: { color: 'red', width: 1, //这里是为了突出显示加上的 } }, axisPointer: { label: { show: false } } }, { show: false, gridIndex: 1, data: m_datas.times, splitLine: { show: false, }, axisTick: { show: false }, axisPointer: { label: { show: false } } }, { //交易量图 // splitNumber: 2, type: 'category', gridIndex: 2, data: m_datas.times, axisLabel: { //label文字设置 color: '#9b9da9', fontSize: 8, interval: 59, textAlign: 'center' } } ], yAxis: [ //y轴 { gridIndex: 0, scale: true, splitNumber: 3, axisLabel: { //label文字设置 inside: true, //label文字朝内对齐 // fontWeight:'bold', fontSize: 10, color: function(val) { if (val == m_data.yestclose) { return '#aaa' } return val > m_data.yestclose ? upColor : downColor; }, formatter: function(val) { return _this.toDecimal(val, _this.digit) } }, z: 4, splitLine: { //分割线设置 show: false, lineStyle: { color: '#181a23' // #E5E5E5 } }, axisLine: { lineStyle: { color: 'transparent', width: 0, //这里是为了突出显示加上的 } }, axisPointer: { show: true, label: { show: false } }, min: _this.leftMin, max: _this.leftMax, interval: _this.leftInterval, }, { scale: true, gridIndex: 1, splitNumber: 3, position: 'right', z: 4, axisLabel: { //label文字设置 interval: true, color: function(val) { if (val == 0) { return '#aaa' } return val > 0 ? upColor : downColor; }, inside: true, //label文字朝内对齐 fontSize: 10, formatter: function(val) { return _this.toDecimal(val, 2, true) + '%' }, }, splitLine: { //分割线设置 show: false, lineStyle: { color: '#181a23' } }, axisPointer: { show: true, label: { show: false } }, axisLine: { lineStyle: { color: 'transparent', width: 0, //这里是为了突出显示加上的 } }, min: _this.rightMin, max: _this.rightMax, interval: _this.rightInterval }, { //交易图 gridIndex: 2, z: 4, splitNumber: 3, axisLine: { onZero: false }, axisTick: { show: false }, splitLine: { show: false }, axisLabel: { //label文字设置 color: '#c7c7c7', inside: true, //label文字朝内对齐 fontSize: 8, formatter: function(value) { return _this.formatNumUnit(value); }, }, } ], dataZoom: [ ], animation:false,//禁止动画效果 backgroundColor: bgColor, blendMode: 'source-over', series: [{ name: '现价', type: 'line', data: m_datas.priceArr, smooth: true, symbol: "none", //中时有小圆点 lineStyle: { normal: { opacity: 0.8, color: '#2f569e', width: 1 } }, areaStyle: { normal: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: 'rgba(246, 246, 255, 1)' }, { offset: 0.8, color: 'rgba(246, 246, 255, 0.5)' }], false), shadowColor: 'rgba(0, 0, 0, 0.1)', shadowBlur: 10 } }, markLine: { silent: true, symbol: ["none", "none"], label: { normal: { show: false, color: '#fff' } }, lineStyle: { color: "#2f569e", opacity: 0.5, type: "dot", }, data: [{ name: "Y 轴值为 yAxis 的水平线", yAxis: _this.toDecimal(m_datas.yestclose, _this.digit), }, ], }, }, { name: '均价', type: 'line', data: m_datas.avgPrice, smooth: true, symbol: "none", lineStyle: { //标线的样式 normal: { opacity: 0.8, color: '#F39142', width: 1 } } }, { type: 'line', data: m_datas.priceArr, smooth: true, symbol: "none", gridIndex: 1, xAxisIndex: 1, yAxisIndex: 1, lineStyle: { //标线的样式 normal: { width: 0 } } }, { name: '现手', type: 'bar', gridIndex: 2, xAxisIndex: 2, yAxisIndex: 2, data: m_datas.vol, barWidth: '60%', itemStyle: { normal: { color: function(params) { let colorList = '' if (params.dataIndex == 0) { if (m_datas.priceArr[0] >= m_datas.yestclose) { colorList = upColor } else { colorList = downColor } } else { if (m_datas.priceArr[params.dataIndex] >= m_datas.priceArr[params.dataIndex - 1]) { colorList = upColor; } else { colorList = downColor; } } return colorList }, } } } ] }; }, aboutMaxAbs(arr,closeVal,digit) { let absArr = [] arr.forEach(el => { absArr.push(Math.abs(el - closeVal)) }) let max = Math.max(...absArr) let maxVal = max + closeVal; let minVal = closeVal -max; return [maxVal.toFixed(digit),minVal.toFixed(digit)]; }, drawLine() { if (this.mChart != null && this.mChart != "" && this.mChart != undefined) { this.mChart.dispose(); } let chartDom = document.getElementById('m-line') if (chartDom) { this.mChart = echarts.init(chartDom); let options = {} if (this.mdata1.data && this.mdata1.data.length > 0) { options = this.initMOption(this.mdata1, 'hs') } if (this.mChart) { this.mChart.setOption(options); } } } }, async created() { on('getPp', (r) => { this.preclose = r }) this.timeArr = await this.getTimeArr() this.initData() }, mounted() { this.leftMax = 0; this.leftMin = 0; setTimeout(() => { this.drawLine() }, 1000) }, beforeDestroy() { let chartDom = document.getElementById('m-line') if (this.mChart != null && this.mChart != "" && this.mChart != undefined) { this.mChart.dispose(); } } } .xflex { -webkit-display: flex; -khtml-display: flex; -moz-display: flex; -ms-display: flex; display: flex; } .xflex-1 { -webkit-flex: 1; -khtml-flex: 1; -moz-flex: 1; -ms-flex: 1; flex: 1; } .border1 { border: 1px solid red; } .xflex-a-c { -webkit-align-items: center; -khtml-align-items: center; -moz-align-items: center; -ms-align-items: center; align-items: center; } .xflex-j-s { -webkit-justify-content: space-between; -khtml-justify-content: space-between; -moz-justify-content: space-between; -ms-justify-content: space-between; justify-content: space-between; } .xflex-j-c { -webkit-justify-content: center; -khtml-justify-content: center; -moz-justify-content: center; -ms-justify-content: center; justify-content: center; } .xflex-col { -webkit-flex-direction: column; -khtml-flex-direction: column; -moz-flex-direction: column; -ms-flex-direction: column; flex-direction: column; } .t-a-c { text-align: center; } .color-up { color: #CC0000; } .color-down { color: #20B120; } .min-wrapper { height: 100%; .hq-wrapper { width: 250rpx; } .chart-min { margin-top: 12rpx; .m-line { // border: 1px solid blue; height: 100%; width: 100%; } } } var bgColor = "#ffffff"; //背景 var upColor = "#E93A40"; //涨颜色 var downColor = "#57B967"; //跌颜色 import hq from './wdhq.vue'; import * as echarts from '@/common/echarts/echarts.min.js' import { fetchEmptyQuoteList } from "@/api/hq.js" // 后端接口 import { on } from '../../../util/callback'; /** * 计算价格涨跌幅百分比 * @param {Object} price 现价 * @param {Object} yclose 昨收价 */ function ratioCalculate(price, yclose) { return ((price - yclose) / yclose * 100).toFixed(2); } import dateFormat from '@/utils/dateFormat' export default { components: { hq }, props: ['mdata', 'code', 'shortname', 'maket', 'curIndex', 'haswd', 'isLeave'], data() { return { preclose: 0, mdata1: [], leftMax: 0, leftMin: 0, rightMax: 0, rightMin: 0, mChart: null, timeArr: [], // 根据品种取横轴坐标 isLeave1: this.isLeave } }, computed: { digit() { // && this.maket == 'SZSE' let isSZSE = this.curIndex == 4 if (Number(this.curIndex) == 3 || isSZSE) { return 3 } else { return 2 } }, divol() { if (this.curIndex != 4) { return 100 } else if (this.curIndex == 4 && this.maket == 'SZSE') { return 10 } else { return 1 } } }, watch: { mdata: { handler: function(newVal, oldVal) { if (newVal) { this.mdata1 = JSON.parse(JSON.stringify(newVal)) this.drawLine() } }, deep: true } }, methods: { /** * 15:20 时:分 格式时间增加num分钟 * @param {Object} time 起始时间 * @param {Object} num */ addTimeStr(time, num) { var hour = time.split(':')[0]; var mins = Number(time.split(':')[1]); var mins_un = parseInt((mins + num) / 60); var hour_un = parseInt((Number(hour) + mins_un) / 24); if (mins_un > 0) { if (hour_un > 0) { var tmpVal = ((Number(hour) + mins_un) % 24) + ""; hour = tmpVal.length > 1 ? tmpVal : '0' + tmpVal; //判断是否是一位 } else { var tmpVal = Number(hour) + mins_un + ""; hour = tmpVal.length > 1 ? tmpVal : '0' + tmpVal; } var tmpMinsVal = ((mins + num) % 60) + ""; mins = tmpMinsVal.length > 1 ? tmpMinsVal : 0 + tmpMinsVal; //分钟数为 取余60的数 } else { var tmpMinsVal = mins + num + ""; mins = tmpMinsVal.length > 1 ? tmpMinsVal : '0' + tmpMinsVal; //不大于整除60 } return hour + ":" + mins; }, //获取增加指定分钟数的 数组 如 09:30增加2分钟 结果为 ['09:31','09:32'] getNextTime(startTime, endTIme, offset, resultArr) { var result = this.addTimeStr(startTime, offset); resultArr.push(result); if (result == endTIme) { return resultArr; } else { return this.getNextTime(result, endTIme, offset, resultArr); } }, /** * 不同类型的股票的交易时间会不同 * @param {Object} type hs=沪深 us=美股 hk=港股 */ time_arr(type, time) { return this.timeArr }, // 重组分时数据 get_m_data(m_data, type) { var priceArr = new Array(); var avgPrice = new Array(); var vol = new Array(); var pcArr = new Array() var times = new Array(); var changeRatio = new Array() if (m_data.data && m_data.data.length > 0) { m_data.data.forEach((v) => { priceArr.push(Number(v[1])); avgPrice.push(Number(v[2])); vol.push(Number(v[3])); changeRatio.push(Number(v[5])) pcArr.push(Number(v[9])) if(v[7] != '00:00') { times.push(v[7]) } }) } var _time = this.time_arr(type, m_data.data[m_data.data.length - 1][8]); for (var t in _time) { if (!times.includes(_time[t])) { times.push(_time[t]) } } let obj = { priceArr: priceArr, avgPrice: avgPrice, vol: vol, times: times, pcArr: pcArr, changeRatio: changeRatio, yestclose: Number(m_data.yestclose) } this.getMaxMin(obj) return obj }, getMaxMin(obj) { var avgMax; var avgMin; var priceMax; var priceMin = 0; avgMax = this.getMax(obj.avgPrice); avgMin = this.getMin(obj.avgPrice); priceMax = this.getMax(obj.priceArr); priceMin = this.getMin(obj.priceArr); const middleLineVal = obj.yestclose; if ((middleLineVal - priceMax) * -1 > (middleLineVal - priceMin)) { priceMin = (middleLineVal - ((middleLineVal - priceMax) * -1)); } else { priceMax = (middleLineVal + (middleLineVal - priceMin)); } this.leftMax = avgMax > priceMax ? avgMax:priceMax this.leftMin = avgMin > priceMin ? priceMin : avgMin this.leftInterval = (this.leftMax - this.leftMin) / 2 this.rightMax = this.getMax(obj.changeRatio) this.rightMin = this.getMin(obj.changeRatio) const middleLineVal1 = 0; const max1 = this.rightMax - middleLineVal1 const min1 = middleLineVal1 - this.rightMin const absMax1 = Math.max(Math.abs(max1), Math.abs(min1)); if (absMax1 == 0) { this.rightMax = middleLineVal1 * 1.05 this.rightMin = middleLineVal1 * 0.95 } else { this.rightMax = middleLineVal1 + absMax1 this.rightMin = middleLineVal1 - absMax1 } this.rightInterval = Number( this.toDecimal( (this.rightMax - this.rightMin) / 2, 3, true ) ); }, getMax(arr) { const maxList = arr.filter((item) => item !== "-" && item != 0); let Max = 0; if (maxList.length > 0) { const max0 = maxList[0]; Max = max0; maxList.forEach((item) => { if (Number(item) > Number(Max)) { Max = Number(item); } }); } return Number(Max); }, getMin(arr) { const minList = arr.filter((item) => item !== "-" && item != 0); let Min = 0; if (minList.length > 0) { const min0 = minList[0]; Min = min0; minList.forEach((item) => { if (Number(item) < Number(Min)) { Min = Number(item); } }); } return Number(Min); }, initData() { this.mdata1 = JSON.parse(JSON.stringify(this.mdata)) }, async getTimeArr() { let res = await fetchEmptyQuoteList({symbol: this.code, exchangeCode: this.maket}) let timeArr = res.data.map(item => { return dateFormat(new Date(item), "hh:mm") }) || [] return timeArr }, /** * 生成分时option * @param {Object} m_data 分时数据 * @param {Object} type 股票类型 us-美股 hs-沪深 hk-港股 */ initMOption(m_data, type) { var m_datas = this.get_m_data(m_data, type); var _this = this; return { tooltip: { //弹框指示器 position: [5, '10%'], hideDelay: 10000, formatter: function(params, ticket, callback) { var i = params[0].dataIndex; var cpriceColor; var avgPriceColor; var radioColor; if (params[0].seriesType !== "line" || params[0].axisDim == "y") { return "" } // 现价 if (m_datas.priceArr[i] > m_data.yestclose) { cpriceColor = 'style="color:#ff4242"'; } else if(m_datas.priceArr[i] == m_data.yestclose) { cpriceColor = 'style="color:#fff"'; } else { cpriceColor = 'style="color:#26bf66"'; } // 均价 if (m_datas.avgPrice[i] > m_data.yestclose) { avgPriceColor = 'style="color:#ff4242"'; } else if(m_datas.avgPrice[i] == m_data.yestclose) { avgPriceColor = 'style="color:#fff"'; } else { avgPriceColor = 'style="color:#26bf66"'; } // 涨幅 if (m_datas.changeRatio[i] > 0) { radioColor = 'style="color:#ff4242"'; } else if(m_datas.changeRatio[i] == 0) { radioColor = 'style="color:#fff"'; } else { radioColor = 'style="color:#26bf66"'; } var html = ' ' _this.toDecimal(m_datas.priceArr[i], _this.digit) + ' html += ' html += ' html += ' '' _this.isLeave1 = 0 _this.$emit('getTooltipData', [params[0].axisValue, _this.toDecimal(m_datas.priceArr[i], _this.digit), m_datas.changeRatio[i], m_datas.pcArr[i], _this.isLeave1]) return html; } }, color: ['#2f569e', '#F39142'], legend: { //图例控件,点击图例控制哪些系列不显示 icon: 'rect', type: 'scroll', itemWidth: 14, itemHeight: 2, left: 0, top: '-1%', data: ['现价', '均价', '现手'], textStyle: { fontSize: 12, color: '#999999' } }, axisPointer: { show: true, link: { xAxisIndex: [0, 2] } }, grid: [{ id: 'gd1', left: '4%', right: '4%', height: '62.5%', //主K线的高度, top: '7%' }, { id: 'gd2', left: '4%', right: '4%', height: '62.5%', //主K线的高度, top: '7%' }, { id: 'gd3', left: '4%', right: '4%', top: '75%', height: '19%' //交易量图的高度 } ], xAxis: [ //==== x轴 { //主图 gridIndex: 0, data: m_datas.times, show: false, splitLine: { show: false, }, axisLine: { lineStyle: { color: 'red', width: 1, //这里是为了突出显示加上的 } }, axisPointer: { label: { show: false } } }, { show: false, gridIndex: 1, data: m_datas.times, splitLine: { show: false, }, axisTick: { show: false }, axisPointer: { label: { show: false } } }, { //交易量图 // splitNumber: 2, type: 'category', gridIndex: 2, data: m_datas.times, axisLabel: { //label文字设置 color: '#9b9da9', fontSize: 8, interval: 59, textAlign: 'center' } } ], yAxis: [ //y轴 { gridIndex: 0, scale: true, splitNumber: 3, axisLabel: { //label文字设置 inside: true, //label文字朝内对齐 // fontWeight:'bold', fontSize: 10, color: function(val) { if (val == m_data.yestclose) { return '#aaa' } return val > m_data.yestclose ? upColor : downColor; }, formatter: function(val) { return _this.toDecimal(val, _this.digit) } }, z: 4, splitLine: { //分割线设置 show: false, lineStyle: { color: '#181a23' // #E5E5E5 } }, axisLine: { lineStyle: { color: 'transparent', width: 0, //这里是为了突出显示加上的 } }, axisPointer: { show: true, label: { show: false } }, min: _this.leftMin, max: _this.leftMax, interval: _this.leftInterval, }, { scale: true, gridIndex: 1, splitNumber: 3, position: 'right', z: 4, axisLabel: { //label文字设置 interval: true, color: function(val) { if (val == 0) { return '#aaa' } return val > 0 ? upColor : downColor; }, inside: true, //label文字朝内对齐 fontSize: 10, formatter: function(val) { return _this.toDecimal(val, 2, true) + '%' }, }, splitLine: { //分割线设置 show: false, lineStyle: { color: '#181a23' } }, axisPointer: { show: true, label: { show: false } }, axisLine: { lineStyle: { color: 'transparent', width: 0, //这里是为了突出显示加上的 } }, min: _this.rightMin, max: _this.rightMax, interval: _this.rightInterval }, { //交易图 gridIndex: 2, z: 4, splitNumber: 3, axisLine: { onZero: false }, axisTick: { show: false }, splitLine: { show: false }, axisLabel: { //label文字设置 color: '#c7c7c7', inside: true, //label文字朝内对齐 fontSize: 8, formatter: function(value) { return _this.formatNumUnit(value); }, }, } ], dataZoom: [ ], animation:false,//禁止动画效果 backgroundColor: bgColor, blendMode: 'source-over', series: [{ name: '现价', type: 'line', data: m_datas.priceArr, smooth: true, symbol: "none", //中时有小圆点 lineStyle: { normal: { opacity: 0.8, color: '#2f569e', width: 1 } }, areaStyle: { normal: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: 'rgba(246, 246, 255, 1)' }, { offset: 0.8, color: 'rgba(246, 246, 255, 0.5)' }], false), shadowColor: 'rgba(0, 0, 0, 0.1)', shadowBlur: 10 } }, markLine: { silent: true, symbol: ["none", "none"], label: { normal: { show: false, color: '#fff' } }, lineStyle: { color: "#2f569e", opacity: 0.5, type: "dot", }, data: [{ name: "Y 轴值为 yAxis 的水平线", yAxis: _this.toDecimal(m_datas.yestclose, _this.digit), }, ], }, }, { name: '均价', type: 'line', data: m_datas.avgPrice, smooth: true, symbol: "none", lineStyle: { //标线的样式 normal: { opacity: 0.8, color: '#F39142', width: 1 } } }, { type: 'line', data: m_datas.priceArr, smooth: true, symbol: "none", gridIndex: 1, xAxisIndex: 1, yAxisIndex: 1, lineStyle: { //标线的样式 normal: { width: 0 } } }, { name: '现手', type: 'bar', gridIndex: 2, xAxisIndex: 2, yAxisIndex: 2, data: m_datas.vol, barWidth: '60%', itemStyle: { normal: { color: function(params) { let colorList = '' if (params.dataIndex == 0) { if (m_datas.priceArr[0] >= m_datas.yestclose) { colorList = upColor } else { colorList = downColor } } else { if (m_datas.priceArr[params.dataIndex] >= m_datas.priceArr[params.dataIndex - 1]) { colorList = upColor; } else { colorList = downColor; } } return colorList }, } } } ] }; }, aboutMaxAbs(arr,closeVal,digit) { let absArr = [] arr.forEach(el => { absArr.push(Math.abs(el - closeVal)) }) let max = Math.max(...absArr) let maxVal = max + closeVal; let minVal = closeVal -max; return [maxVal.toFixed(digit),minVal.toFixed(digit)]; }, drawLine() { if (this.mChart != null && this.mChart != "" && this.mChart != undefined) { this.mChart.dispose(); } let chartDom = document.getElementById('m-line') if (chartDom) { this.mChart = echarts.init(chartDom); let options = {} if (this.mdata1.data && this.mdata1.data.length > 0) { options = this.initMOption(this.mdata1, 'hs') } if (this.mChart) { this.mChart.setOption(options); } } } }, async created() { on('getPp', (r) => { this.preclose = r }) this.timeArr = await this.getTimeArr() this.initData() }, mounted() { this.leftMax = 0; this.leftMin = 0; setTimeout(() => { this.drawLine() }, 1000) }, beforeDestroy() { let chartDom = document.getElementById('m-line') if (this.mChart != null && this.mChart != "" && this.mChart != undefined) { this.mChart.dispose(); } } } .xflex { -webkit-display: flex; -khtml-display: flex; -moz-display: flex; -ms-display: flex; display: flex; } .xflex-1 { -webkit-flex: 1; -khtml-flex: 1; -moz-flex: 1; -ms-flex: 1; flex: 1; } .border1 { border: 1px solid red; } .xflex-a-c { -webkit-align-items: center; -khtml-align-items: center; -moz-align-items: center; -ms-align-items: center; align-items: center; } .xflex-j-s { -webkit-justify-content: space-between; -khtml-justify-content: space-between; -moz-justify-content: space-between; -ms-justify-content: space-between; justify-content: space-between; } .xflex-j-c { -webkit-justify-content: center; -khtml-justify-content: center; -moz-justify-content: center; -ms-justify-content: center; justify-content: center; } .xflex-col { -webkit-flex-direction: column; -khtml-flex-direction: column; -moz-flex-direction: column; -ms-flex-direction: column; flex-direction: column; } .t-a-c { text-align: center; } .color-up { color: #CC0000; } .color-down { color: #20B120; } .min-wrapper { height: 100%; .hq-wrapper { width: 250rpx; } .chart-min { margin-top: 12rpx; .m-line { // border: 1px solid blue; height: 100%; width: 100%; } } } // 链接参数获取 export function getQueryString(url="") { let ItemArr = []; let ItemObj = {}; url .substring(url.lastIndexOf("?") + 1, url.length) .split("&") .map((item) => { ItemArr.push(item.split("=")); }); ItemArr.map((item) => { ItemObj[item[0]] = item[1]; }); return ItemObj; } /** * 设置跌涨颜色 * val1: 对比的值 如:preClosePrice昨收价 * val2: 当前显示的值 * */ export function turnColor(val1, val2) { var num1 = isNaN(Number(val1)) ? 0 : Number(val1) var num2 = isNaN(Number(val2)) ? 0 : Number(val2) // 判断是否是-0 if (num1 == 0 && num2 == 0 && (1 / num2 < 0)) { return '#57B967' } if (num1 == 0 && num2 == 0) { return '#BEC0C7' } if (num1 > num2) { return '#57B967' } else if (num1 < num2) { return '#E93A40' } else { return '#BEC0C7' } } var _callbacks = {} export function on(eventName, callback) { if (!_callbacks[eventName]) { _callbacks[eventName] = [] } _callbacks[eventName].push(callback) } export function off(eventName, callback) { var callbacks = _callbacks[eventName] if (!callbacks) { return } var index = -1 for (var i = 0; i < callbacks.length; i++) { if (callbacks[i] === callback) { index = i break } } if (index < 0) { return } _callbacks[eventName].splice(index, 1) } export function trigger(eventName) { var callbacks = _callbacks[eventName] if (!callbacks || !callbacks.length) { return } var args = Array.prototype.slice.call(arguments, 1) for (var i = 0; i < callbacks.length; i++) { callbacks[i].apply(this, args) } } var duestate = {} export function lock(lockname,func){ if(!duestate[lockname]){ duestate[lockname] = true on("State",()=>{ duestate[lockname] = false }) return func } } /** * [dateFormat 时间格式化] * @param {[Number,String]} [timestamp=Date.now()] [需转化的时间戳或一个能格式化的时间字符串] * @param {[String]} [format='yyyy-M-d'] [需转化的时间格式] * yyyy年,月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q),两个字符表示按2位字符输入 * 举例: * dateFormat(Date.now(), "yyyy-MM-dd hh:mm:ss") ==> 2017-04-25 16:06:06 * dateFormat(Date.now(), "yyyy-M-d h:m:s q") ==> 2017-4-25 16:6:6 2 * @return {[String]} [格式化时间字符串] */ export default function dateFormat(timestamp = Date.now(), format = 'yyyy-M-d') { return getFormatDate(getJsonDate(timestamp), format) } // 生成时间对象 export function getJsonDate(timestamp) { let time = new Date(getCorrectTime(timestamp)) let jsonDate = { y: time.getFullYear(), //年 M: time.getMonth() + 1, //月 d: time.getDate(), //日 h: time.getHours(), //时 m: time.getMinutes(), //分 s: time.getSeconds(), //秒 q: Math.floor((time.getMonth() + 3) / 3) //季度 } return jsonDate } // 生成格式化时间字符串 export function getFormatDate(jsonDate, format) { let dateStr = format.replace(/yyyy/g, jsonDate.y) Object.keys(jsonDate).forEach(e => { // 时间格式化操作 let double = e.repeat(2) let num = jsonDate[e] if (format.includes(double)) { // 如果需要两位的格式化数据,则转换为两位数 dateStr = dateStr.replace(double, getTwoDigit(num)) } else { dateStr = dateStr.replace(e, num) } }) return dateStr } // 数字如果为一位数,前面加0 function getTwoDigit(num) { return Number(num) < 10 ? `0${num}` : num } // 对于传入时间数据的转换 function getCorrectTime(timestamp) { if (isNaN(timestamp)) { // ios日期格式兼容处理 timestamp = timestamp.toString().includes('-') ? (timestamp.replace(/-/g, '/')).slice(0,19) : timestamp } else { timestamp = Number(timestamp) } return timestamp } // 大数字单位处理(num为比较值 小于num数据不进行处理) formatNumUnit(value, fixedLen = 2, num = 10000) { if (value == "--") { return value; } if (value == null) { return '--' } var result = {}; var k = 10000; var sizes = ["", "万", "亿", "万亿"]; var i; if (value < num) { result.value = value; result.unit = ""; } else { i = Math.floor(Math.log(value) / Math.log(k)); result.value = this.round(value / Math.pow(k, i), fixedLen); result.unit = sizes[i]; } return result.value + result.unit; }, /** * 转化数字为几位小数,四舍五入或者截取多于位数 * num [需转化的数字] * @param {Number} [digit=2] [需保留或截取的位数] * @param {Boolean} [isRround=true] [true四舍五入,false截取多于小数] * */ toDecimal(num, n, b) { if (num === null || num === undefined || isNaN(num) || num === '') { return "--"; } else if (num == 0) { return parseFloat(num).toFixed(n); } return toDecimal1(num, n, b); }, /** * [toDecimal 转化数字为几位小数,四舍五入或者截取多于位数] * @param {[Number]} num [需转化的数字] * @param {Number} [digit=2] [需保留或截取的位数] * @param {Boolean} [isRround=true] [true四舍五入,false截取多于小数] * @return {[Number, String]} [转换后的结果] */ toDecimal1(num, digit = 2, isRround = true) { if (num === null || num === undefined) { return '' } // 负数处理四舍五入,先转成正数 let sign = '' if (num < 0) { sign = '-' } num = Math.abs(num).toString() // 出现了科学计数法 if (num.indexOf('e-') != -1) { num = noKeXueJiShuFa(num) } const numArr = num.split('.') if (numArr.length > 1) { // 有小数时的处理 if (numArr[1].length <= digit) { // 小数位数少于需保留位数的时候 return sign + Number(num).toFixed(digit) } else { // 小数位数多于需保留位数的时候 if (isRround) { // 四舍五入处理 num = numArr[1][digit] >= 5 ? parseInt(noKeXueJiShuFa(num * Math.pow(10, digit))) + 1 : parseInt(noKeXueJiShuFa(num * Math.pow(10, digit))) return sign + (num / Math.pow(10, digit)).toFixed(digit) } else { // 去除多于小数 return sign + `${numArr[0]}.${numArr[1].substring(0, digit)}` } } } else { // 无小数时的处理 return sign + Number(num).toFixed(digit) } } noKeXueJiShuFa(num) { if (String(num).indexOf('e-') != -1) { num = '0' + String(Number(num) + 1).substr(1) } return num }chartMin组件代码:
' +
';
';
';
wdhq五档行情组件代码:
' +
';
';
';
u.js文件方法:
callback.js文件方法:
dateFormat文件方法:
页面公共文件方法: