You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1152 lines
31 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div>
<div class="bg">
<div class="title">正道能源监控系统</div>
<div class="time">{{ clockText }}</div>
<div class="subTitle" style="top: 13.5%;left: 6%;">设备总览</div>
<div class="subTitle" style="top: 42.3%;left: 6%">本月{{ currentTypeMeta.rankName }}排行</div>
<div class="subTitle" style="top: 71.2%;left: 6%">本月{{ currentTypeMeta.rankName }}分项统计</div>
<div class="subTitle" style="top: 71.2%;left: 30.5%">能耗统计</div>
<div class="subTitle" style="top: 71.2%;left: 78%">实时预警</div>
<div class="subTitle" style="top: 13.5%;left: 78%">近7天能耗统计</div>
<div class="select">
<div class="selectItem" style="left: 57%" :class="{'active': selectData === 'day'}"
@click="selectChange('day')">
</div>
<div class="selectItem" style="left: calc(57% + 4vw)" :class="{'active': selectData === 'month'}"
@click="selectChange('month')">
</div>
<!-- <div class="selectItem" style="left: calc(57% + 8vw)" :class="{'active': selectData === '3'}"-->
<!-- @click="selectChange('3')">-->
<!-- 本季度-->
<!-- </div>-->
<div class="selectItem" style="left: calc(57% + 8vw)" :class="{'active': selectData === 'year'}"
@click="selectChange('year')">
</div>
</div>
<div class="typeSelect">
<div class="selectItem" style="width:2.4vw;left: calc(57%)" :class="{'active': typeData === '4'}"
@click="typeChange('4')">
</div>
<div class="selectItem" style="width:2.4vw;left: calc(57% + 2.4vw)" :class="{'active': typeData === '3'}"
@click="typeChange('3')">
</div>
<div class="selectItem" style="width:3.8vw;left: calc(57% + 4.8vw)" :class="{'active': typeData === '5'}"
@click="typeChange('5')">
</div>
<div class="selectItem" style="width:3vw;left: calc(57% + 8.6vw)" :class="{'active': typeData === '6'}"
@click="typeChange('6')">
</div>
<div class="selectItem" style="width:3vw;left: calc(57% + 11.6vw)" :class="{'active': typeData === '2'}"
@click="typeChange('2')">
</div>
</div>
<div class="sbzl">
<div class="num" style="top: 22%;left: 7%;">{{ deviceOverviewData.deviceSum }}</div>
<div class="num" style="top: 22%;left: 14.3%">{{ deviceOverviewData.waterSum }}</div>
<div class="num" style="top: 22%;left: 21.7%">{{ deviceOverviewData.dnbSum }}</div>
<div class="num" style="top: 31%;left: 7%">{{ deviceOverviewData.airSum }}</div>
<div class="num" style="top: 31%;left: 14.3%">{{ deviceOverviewData.steamSum }}</div>
<div class="num" style="top: 31%;left: 21.7%">{{ deviceOverviewData.nitrogenSum }}</div>
<div class="text" style="top: 22.2%;left: 7%">网关总数</div>
<div class="text" style="top: 22.2%;left: 14.3%">水表总数</div>
<div class="text" style="top: 22.2%;left: 21.7%">电表总数</div>
<div class="text" style="top: 31.2%;left: 7%">压缩空气表总数</div>
<div class="text" style="top: 31.2%;left: 14.3%">蒸汽表总数</div>
<div class="text" style="top: 31.2%;left: 21.7%">氮气表总数</div>
</div>
<div class="zxnr">
<div class="text" style="top: 18.5%;left: 45%;">用电量(kwh)</div>
<div class="text" style="top: 18.5%;left: 57%;">用水量()</div>
<div class="text" style="top: 30%;left: 38.5%;">用压缩空气量()</div>
<div class="text" style="top: 31.5%;left: 51.5%;">用蒸汽量()</div>
<div class="text" style="top: 30%;left: 65%;">用氮气量()</div>
<div class="num" style="top: 20.3%;left: 45%">{{ fiveConsumptionStatisticsData.dnbSum }}</div>
<div class="num" style="top: 20.3%;left: 57%;">{{ fiveConsumptionStatisticsData.waterSum }}</div>
<div class="num" style="top: 31.8%;left: 38.5%">{{ fiveConsumptionStatisticsData.airSum }}</div>
<div class="num" style="top: 33.3%;left: 51.5%">{{ fiveConsumptionStatisticsData.steamSum }}</div>
<div class="num" style="top: 31.8%;left: 65%">{{ fiveConsumptionStatisticsData.nitrogenSum }}</div>
<div class="qs" style="top: 23.3%;left: 45%">
<span>{{
fiveConsumptionStatisticsData.dnbRate > 0 ? '上升' : '下降'
}}{{ Math.abs(fiveConsumptionStatisticsData.dnbRate) }}%</span>
<div :class="fiveConsumptionStatisticsData.dnbRate > 0 ? 'img':'img1'"></div>
</div>
<div class="qs" style="top: 23.3%;left: 57%;">
<span>{{
fiveConsumptionStatisticsData.waterRate > 0 ? '上升' : '下降'
}}{{ Math.abs(fiveConsumptionStatisticsData.waterRate) }}%</span>
<div :class="fiveConsumptionStatisticsData.waterRate > 0 ? 'img':'img1'"></div>
</div>
<div class="qs" style="top: 34.8%;left: 38.5%">
<span>{{
fiveConsumptionStatisticsData.airRate > 0 ? '上升' : '下降'
}}{{ Math.abs(fiveConsumptionStatisticsData.airRate) }}%</span>
<div :class="fiveConsumptionStatisticsData.airRate > 0 ? 'img':'img1'"></div>
</div>
<div class="qs" style="top: 36.3%;left: 51.5%">
<span>{{
fiveConsumptionStatisticsData.steamRate > 0 ? '上升' : '下降'
}}{{ Math.abs(fiveConsumptionStatisticsData.steamRate) }}%</span>
<div :class="fiveConsumptionStatisticsData.steamRate > 0 ? 'img':'img1'"></div>
</div>
<div class="qs" style="top: 34.8%;left: 65%">
<span>{{
fiveConsumptionStatisticsData.nitrogenRate > 0 ? '上升' : '下降'
}}{{ Math.abs(fiveConsumptionStatisticsData.nitrogenRate) }}%</span>
<div :class="fiveConsumptionStatisticsData.nitrogenRate > 0 ? 'img':'img1'"></div>
</div>
</div>
<div class="table1">
<div class="h1" style="line-height: 1vw">
<div class="scrollTable" :style="getTableCellStyle(true)">
设备名称
</div>
<div
class="scrollTable"
v-for="column in currentTypeMeta.columns"
:key="column.key"
:style="getTableCellStyle(true)"
>
{{ column.label }}
</div>
</div>
<vue-seamless-scroll
:class-option="{...chart1TableOption,limitMoveNum:6}"
:data="table1Data"
:key="scrollKey1"
class="case-item"
style="height: calc(100% - 1vw);overflow: hidden;"
>
<div
v-for="(item, index) in table1Data"
:key="index"
>
<div class="T1">
<div class="scrollTable" :style="getTableCellStyle()">
{{ item.monitorName || '' }}
</div>
<div
class="scrollTable"
v-for="column in currentTypeMeta.columns"
:key="column.key"
:style="getTableCellStyle()"
>
{{ item[column.key] || 0 }}
</div>
</div>
</div>
</vue-seamless-scroll>
</div>
<div class="table2">
<div class="h2">
<div class="scrollTable" style="font-weight: bold;width: calc(33% - 60px);">
区域
</div>
<div class="scrollTable" style="font-weight: bold;width: calc(66% - 120px);">
设备
</div>
<div class="scrollTable" style="font-weight: bold;width: calc(180px);">
报警时间
</div>
</div>
<vue-seamless-scroll
:class-option="{...chart1TableOption,limitMoveNum:6}"
:data="realTimeAlarmData"
:key="scrollKey2"
class="case-item"
style="height: 84%;overflow: hidden;"
>
<div
v-for="(item, index) in realTimeAlarmData"
:key="index"
>
<div class="T2">
<div class="scrollTable" style="width: calc(33% - 60px);font-size: 0.7vw">
{{ item.deviceName }}
</div>
<div class="scrollTable" style="width: calc(66% - 120px);font-size: 0.7vw">
<span style="color:red">{{ item.monitorName }}</span>:{{ item.alarmData }}
</div>
<div class="scrollTable" style="width: 180px; font-size: 0.7vw">
{{ item.collectTime }}
</div>
</div>
</div>
</vue-seamless-scroll>
</div>
<Chart class="jfpgtjBar" ref="jfpgtjBar"></Chart>
<Chart class="nhtjBar" ref="nhtjBar"></Chart>
<Chart class="jfpgtjPie" ref="jfpgtjPie"></Chart>
<Chart class="ydfxtjPie" ref="ydfxtjPie"></Chart>
<div class="jfpgtjInfo">
<div style="width: 100%"></div>
<div class="jfpgtjInfoItem" v-for="(i,k) in peaksValleysConsumptionData">
<div class="market" :style="`background-color:${colors[k]}`"></div>
<div class="text">
{{ i[0] }}
</div>
<div class="num">
<span class="numValue" :style="`color:${colors[k]}`">
{{ i[2] }}
</span>%
</div>
</div>
<div style="width: 100%"></div>
</div>
<div class="ydph">
<template v-for="(i,k) in topRankingData">
<div class="icon" :class="`icon${k+1}`">
<div class="img"></div>
</div>
<div class="ph" :class="`ph${k+1}`">
<div class="text">{{ i.workUnitName }}</div>
<div class="num">
<span style="color: #25B89A">{{ i.expend }}</span>
<span>{{ currentTypeMeta.unit }}</span>
</div>
<div class="schedule">
<div class="schedule1" :style="`width:${Math.min(100,i.expend)}%`"></div>
</div>
</div>
</template>
</div>
</div>
</div>
</template>
<script>
import vueSeamlessScroll from "vue-seamless-scroll";
import Chart from "@/components/Charts/Chart.vue";
import * as echarts from 'echarts'
import {
deviceOverview, energyConsumptionStatistics,
fiveConsumptionStatistics,
monthConsumptionRanking,
peaksValleysConsumption, realTimeAlarm,
realTimeDataByEnergy
} from "@/api/board";
export default {
name: 'Board',
components: {
vueSeamlessScroll,
Chart
},
computed: {
topRankingData() {
return this.rankingData.slice(0, 5)
},
currentTypeMeta() {
const map = {
'2': {
rankName: '用电',
unit: 'kWh',
columns: [
{ key: 'iA', label: '电流' },
{ key: 'vA', label: '电压' },
{ key: 'zxyg', label: '正向有功' }
]
},
'3': {
rankName: '用水',
unit: 'm³',
columns: [
{ key: 'fluxFlow', label: '瞬时流量' },
{ key: 'waterFlow', label: '累计流量' }
]
},
'4': {
rankName: '用蒸汽',
unit: 't',
columns: [
{ key: 'fluxFlow', label: '瞬时流量' },
{ key: 'steamFlow', label: '累计流量' }
]
},
'5': {
rankName: '用压缩空气',
unit: 'm³',
columns: [
{ key: 'fluxFlow', label: '瞬时流量' },
{ key: 'steamFlow', label: '累计流量' }
]
},
'6': {
rankName: '用氮气',
unit: 'm³',
columns: [
{ key: 'fluxFlow', label: '瞬时流量' },
{ key: 'steamFlow', label: '累计流量' }
]
}
}
return map[this.typeData] || map['4']
}
},
data() {
return {
selectData: 'day',
typeData: "4",
colors: ['#30A0FB', '#00FF89', '#F9E435', '#FB5C2D', '#73c0de'],
chart1TableOption: {
step: 0.5, // 数值越大速度滚动越快
limitMoveNum: 3, // 开始无缝滚动的数据量 this.dataList.length
hoverStop: true, // 是否开启鼠标悬停stop
direction: 1, // 0向下 1向上 2向左 3向右
openWatch: true, // 开启数据实时监控刷新dom
singleHeight: 0, // 单步运动停止的高度(默认值0是无缝不停止的滚动) direction => 0/1
singleWidth: 0, // 单步运动停止的宽度(默认值0是无缝不停止的滚动) direction => 2/3
waitTime: 0,
},
table1Data: [],
scrollKey1: '',
scrollKey2: '',
clockText: '',
timer: null,
dataTimer: null,
deviceOverviewData: {},
rankingData: [],
statisticsData: [],
peaksValleysConsumptionData: [],
fiveConsumptionStatisticsData: {},
realTimeAlarmData: []
}
},
async mounted() {
this.tickClock()
this.timer = setInterval(this.tickClock, 1000)
this.getData()
this.dataTimer = setInterval(this.getData, 10 * 60 * 1000)
},
beforeDestroy() {
if (this.timer) clearInterval(this.timer)
if (this.dataTimer) clearInterval(this.dataTimer)
},
methods: {
tickClock() {
const d = new Date()
const pad = n => (n < 10 ? '0' + n : '' + n)
this.clockText = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`
},
getTableCellStyle(isHeader = false) {
const width = `calc(100% / ${this.currentTypeMeta.columns.length + 1})`
return {
width,
...(isHeader ? { lineHeight: '1vw', fontWeight: 'bold' } : {})
}
},
getData() {
deviceOverview().then(res => {
this.deviceOverviewData = res.data
})
monthConsumptionRanking({monitorType: this.typeData}).then(res => {
this.rankingData = res.data.ranking
this.statisticsData = res.data.statistics
this.$refs.ydfxtjPie.setData({
graphic: [
{
type: 'text',
left: 'center',
top: 'center',
style: {
text: '能耗\n占比',
textAlign: 'center',
fill: '#4FB8FF', // 数字颜色
fontSize: 20,
fontWeight: 'bold',
lineHeight: 30
}
}
],
series: [
{
type: 'pie',
radius: ['55%', '70%'],
tooltip: {
show: false
},
label: {
formatter: params => {
return `${params.name}\n${params.value}`
},
color: '#fff'
},
labelLine: {
length: 10,
length2: 10,
},
data: res.data.statistics.map((e, k) => {
return {
value: e.expend,
name: e.workUnitName,
itemStyle: {
color: this.colors[k] + '99',
shadowColor: this.colors[k] + 'cc',
shadowBlur: 20,
shadowOffsetX: 0,
shadowOffsetY: 0
}
}
})
},
]
})
})
peaksValleysConsumption({ monitorType: this.typeData }).then(async res => {
let oriData = (res.data?.reportList || []).reduce((acc, item) => {
if (!acc[item.unitName]) {
acc[item.unitName] = 0;
}
acc[item.unitName] += Number(item.expend || 0);
return acc;
}, {})
let all = Object.values(oriData).reduce((acc, item) => {
return Number(acc) + Number(item)
}, 0)
let chartData = Object.keys(oriData).map((e) => {
const percentage = all === 0 ? 0 : (oriData[e] / all * 100)
return [e, oriData[e], percentage.toFixed(2)]
})
this.peaksValleysConsumptionData = chartData
let seriesData = []
chartData.forEach(e => {
seriesData.push({
value: all / 100 / chartData.length, name: '',
label: {
show: false
},
tooltip: {
show: false
},
itemStyle: {
color: '#0000'
}
})
seriesData.push({
value: e[1], name: e[0], percentage: e[2]
})
})
this.$refs.jfpgtjPie.setData({
tooltip: {
trigger: 'item',
formatter: (params) => {
return `${params.marker}${params.name}${params.data.percentage}%`
}
},
graphic: [
{
type: 'text',
left: 'center',
top: 'center',
style: {
text: `{num|${Number(all).toFixed(2)}}\n{unit|${this.currentTypeMeta.unit}}`,
textAlign: 'center',
rich: {
num: {
fill: '#4FB8FF', // 数字颜色
fontSize: 20,
fontWeight: 'bold',
lineHeight: 30
},
unit: {
fill: '#4FB8FF', // 字母颜色
fontSize: 16,
fontWeight: 'bold'
}
},
}
}
],
series: [
{
name: 'pie1',
type: 'pie',
radius: ['62%', '70%'],
label: {
show: false
},
labelLine: {
show: false
},
tooltip: {
show: false
},
data: seriesData
},
{
name: 'pie2',
type: 'pie',
radius: ['45%', '62%'],
itemStyle: {
opacity: 0.6,
},
label: {
show: false
},
labelLine: {
show: false
},
data: seriesData
}
]
})
await this.$nextTick()
const chart = this.$refs.jfpgtjPie.getChart()
chart.on('mouseover', (params) => {
if (params.seriesType === 'pie') {
const other = params.seriesName === 'pie1' ? 'pie2' : 'pie1'
chart.dispatchAction({
type: 'highlight',
seriesName: other,
name: params.name
})
}
})
chart.on('mouseout', (params) => {
if (params.seriesType === 'pie') {
const other = params.seriesName === 'pie1' ? 'pie2' : 'pie1'
chart.dispatchAction({
type: 'downplay',
seriesName: other,
name: params.name
})
}
})
function groupByDate(data) {
const result = {};
const types = new Set();
data.forEach(item => {
if (!result[item.date]) {
result[item.date] = {date: item.date, data: {}};
}
result[item.date].data[item.unitName] = Number(item.expend || 0);
types.add(item.unitName);
});
return {
grouped: Object.values(result),
types: Array.from(types),
typeCount: types.size
};
}
let barData = groupByDate(res.data?.reportList)?.grouped
let types = groupByDate(res.data?.reportList)?.types
this.$refs.jfpgtjBar.setData({
tooltip: {
trigger: 'axis',
axisPointer: {type: 'shadow'}
},
legend: {
show: false
},
grid: {
left: '5%',
right: '5%',
bottom: '5%',
top: '10%',
containLabel: true
},
yAxis: {
type: 'value',
name: `单位(${this.currentTypeMeta.unit})`,
max: function (value) {
return parseFloat((value.max * 1.2).toFixed(1));
},
nameTextStyle: {color: '#ccc'},
axisLabel: {color: '#ccc'},
axisLine: {
show: true
},
splitLine: {
show: true,
lineStyle: {
color: 'rgba(255, 255,255, 0.3)',
type: 'dashed'
}
}
},
xAxis: {
type: 'category',
data: barData.map(e => e.date),
axisLabel: {color: '#ccc'},
splitLine: {
show: true,
lineStyle: {
color: 'rgba(255, 255,255, 0.3)',
type: 'dashed'
}
}
},
series: types.map((e, k) => {
return {
name: e,
type: 'bar',
stack: 'total',
label: {
show: false,
position: 'top',
color: '#fff',
fontSize: 10
},
barWidth: '50%',
barMaxWidth: '60px',
barMinWidth: '30px',
data: barData.map(v => {
return v.data[e] || 0
}),
itemStyle: {color: this.colors[k]}
}
})
})
})
fiveConsumptionStatistics().then(res => {
this.fiveConsumptionStatisticsData = res.data
})
energyConsumptionStatistics({monitorType: this.typeData, dateType: this.selectData}).then(res => {
this.$refs.nhtjBar.setData({
tooltip: {
trigger: 'axis',
axisPointer: {type: 'shadow'}
},
legend: {
show: false
},
grid: {
left: '5%',
right: '5%',
bottom: '0',
top: '35',
containLabel: true
},
yAxis: {
type: 'value',
name: `单位(${this.currentTypeMeta.unit})`,
max: function (value) {
return value.max * 1.2;
},
nameTextStyle: {color: '#ccc'},
axisLabel: {color: '#ccc'},
axisLine: {
show: true
},
splitLine: {
show: true,
lineStyle: {
color: 'rgba(255, 255,255, 0.3)',
type: 'dashed'
}
}
},
xAxis: {
type: 'category',
data: res.data.reportList.map(v => v.date),
axisLabel: {color: '#ccc'},
splitLine: {
show: true,
lineStyle: {
color: 'rgba(255, 255,255, 0.3)',
type: 'dashed'
}
}
},
series: [
{
name: '能耗',
type: 'bar',
label: {
show: false,
},
barWidth: '30px',
data: res.data.reportList.map(v => v.expend),
itemStyle: {
color: new echarts.graphic.LinearGradient(
0, 0, 0, 1, // 从顶部到底部
[
{offset: 0, color: '#1FA7F4'}, // 顶部颜色
{offset: 1, color: '#3351B4'} // 底部颜色
]
)
}
},
{
tooltip: {
show: false
},
type: 'line',
label: {
show: false,
},
barWidth: '30px',
data: res.data.reportList.map(v => v.expend),
itemStyle: {color: '#fff'},
areaStyle: {
color: new echarts.graphic.LinearGradient(
0, 0, 0, 1, // x0,y0 → x1,y1 (垂直渐变)
[
{offset: 0, color: 'rgba(255,255,255,0.53)'}, // #fff8
{offset: 1, color: 'rgba(255,255,255,0)'} // #fff0
]
)
}
},
]
})
})
realTimeAlarm().then(res => {
this.realTimeAlarmData = JSON.parse(JSON.stringify(res.data.alarmDataList))
this.scrollKey2 = new Date().getTime()
})
realTimeDataByEnergy({
monitorType: this.typeData,
isAmmeter: '1'
}).then(res => {
this.table1Data = res.data
this.scrollKey1 = new Date().getTime()
})
},
selectChange(data) {
this.selectData = data
this.getData()
},
typeChange(data) {
this.typeData = data
this.getData()
}
}
}
</script>
<style scoped lang="less">
.scrollTable {
color: rgb(185, 186, 192);
margin: auto 0px;
padding: 4px 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text-align: center;
display: inline-block;
width: 25%;
}
.table1 {
position: absolute;
top: 44%;
left: 28%;
width: 44%;
height: 21%;
overflow: hidden;
}
.h1 {
background-size: 100% 100%;
background-repeat: no-repeat;
background-image: url('~@/assets/board/T1bg.png')
}
.T1 {
background-size: 100% 100%;
background-repeat: no-repeat;
background-image: url('~@/assets/board/h1bg.png');
margin-top: 2px;
}
.table2 {
position: absolute;
top: 74%;
left: 75%;
width: 22%;
height: 21%;
overflow: hidden;
}
.h2 {
background-size: 100% 100%;
background-repeat: no-repeat;
background-image: url('~@/assets/board/T1-1bg.png')
}
.T2 {
background-size: 100% 100%;
background-repeat: no-repeat;
background-image: url('~@/assets/board/h1-1bg.png');
margin-top: 2px;
}
.bg {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
background-repeat: no-repeat;
background-size: 100% 100%;
background-image: url('~@/assets/board/bg.jpg');
overflow: hidden;
}
.title {
position: absolute;
top: 2%;
left: 50%;
color: #eee;
font-size: 2vw;
font-weight: 600;
letter-spacing: 0.5vw;
transform: translateX(-50%);
}
.time {
position: absolute;
top: 2.4%;
right: 2%;
font-size: 1vw;
color: #9fc4e8;
}
.subTitle {
position: absolute;
font-size: 1vw;
color: #eee;
font-weight: 600;
transform: translateY(-50%);
}
.sbzl {
.num {
position: absolute;
font-size: 1.2vw;
color: #66D49E;
transform: translateY(-100%);
}
.text {
position: absolute;
font-size: 0.6vw;
color: #fff;
width: 3vw;
text-align: left;
}
}
.zxnr {
.text {
position: absolute;
font-size: 0.6vw;
color: #fff;
text-align: left;
}
.num {
position: absolute;
font-size: 1.2vw;
color: #4EACF3;
font-weight: 600;
letter-spacing: 0.2vw;
}
.qs {
position: absolute;
font-size: 0.6vw;
color: #fff;
text-align: left;
.img {
display: inline-block;
vertical-align: middle;
width: 1vw;
height: 1vw;
background-repeat: no-repeat;
background-size: 100% 100%;
background-image: url('~@/assets/board/.png');
}
.img1 {
display: inline-block;
vertical-align: middle;
width: 1vw;
height: 1vw;
background-repeat: no-repeat;
background-size: 100% 100%;
background-image: url('~@/assets/board/.png');
}
}
}
.jfpgtjBar {
position: absolute;
top: 39%;
left: 75%;
width: 22%;
height: 27%;
}
.nhtjBar {
position: absolute;
top: 74%;
left: 27.5%;
width: 45%;
height: 20.5%;
}
.jfpgtjPie {
position: absolute;
top: 17%;
left: 75%;
width: 12.5%;
height: 20%;
}
.ydfxtjPie {
position: absolute;
top: 74%;
left: 3%;
width: 22%;
height: 20%;
}
.jfpgtjInfo {
position: absolute;
top: 17%;
left: 87.5%;
width: 8.5%;
height: 20%;
color: #fff;
display: flex;
flex-direction: column;
justify-content: space-between;
.jfpgtjInfoItem {
display: flex;
align-items: center;
min-width: 0;
width: 100%;
white-space: nowrap;
}
.market {
flex: 0 0 auto;
width: 0.8vw;
height: 0.8vw;
margin-right: 0.45vw;
background-color: #28A7FC;
border-radius: 50%;
}
.text {
flex: 1;
min-width: 0;
font-size: 0.8vw;
overflow: hidden;
text-overflow: ellipsis;
text-align: left;
}
.num {
flex: 0 0 2.9vw;
font-size: 0.8vw;
text-align: right;
white-space: nowrap;
}
.numValue {
font-weight: bold;
font-size: 0.85vw;
}
}
.icon {
position: absolute;
width: 2vw;
height: 2vw;
background-color: #fff1;
.img {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 60%;
height: 60%;
background-repeat: no-repeat;
background-size: 100% 100%;
}
}
.icon1 {
top: 46%;
left: 4%;
.img {
background-image: url('~@/assets/board/jz1.png');
}
}
.icon2 {
top: 50%;
left: 4%;
.img {
background-image: url('~@/assets/board/jz2.png');
}
}
.icon3 {
top: 54%;
left: 4%;
.img {
background-image: url('~@/assets/board/jz3.png');
}
}
.icon4 {
top: 58%;
left: 4%;
.img {
background-image: url('~@/assets/board/jz4.png');
}
}
.icon5 {
top: 62%;
left: 4%;
.img {
background-image: url('~@/assets/board/jz5.png');
}
}
.ph {
position: absolute;
width: 19vw;
height: 2vw;
background: linear-gradient(to right, rgba(255, 255, 255, 0.067), rgba(255, 255, 255, 0));
.text {
position: absolute;
font-size: 0.8vw;
color: #fff;
top: 70%;
transform: translateY(-100%);
left: 1vw;
}
.num {
position: absolute;
font-size: 0.8vw;
text-align: right;
color: #fff;
top: 70%;
transform: translateY(-100%);
right: 1vw;
}
.schedule {
position: absolute;
top: 80%;
left: 1vw;
width: calc(100% - 2vw);
height: 3px;
background-color: #fff2;
.schedule1 {
position: absolute;
top: 0;
left: 0;
height: 100%;
background: linear-gradient(to right, #249CE3, #2FE1E0);
}
}
}
.ph1 {
top: 46%;
left: 6.5%;
}
.ph2 {
top: 50%;
left: 6.5%;
}
.ph3 {
top: 54%;
left: 6.5%;
}
.ph4 {
top: 58%;
left: 6.5%;
}
.ph5 {
top: 62%;
left: 6.5%;
}
.select {
.selectItem {
position: absolute;
font-size: 0.7vw;
color: #fff9;
top: 11%;
width: 3.7vw;
height: 1.58vw;
line-height: 1.58vw;
text-align: center;
cursor: pointer;
background-repeat: no-repeat;
background-size: 100% 100%;
background-image: url("~@/assets/board/.png");
&.active {
color: #fff;
background-image: url("~@/assets/board/.png");
}
}
}
.typeSelect {
.selectItem {
position: absolute;
font-size: 0.7vw;
color: #fff9;
top: 69.5%;
height: 2.1vw;
line-height: 2.1vw;
text-align: center;
cursor: pointer;
background-color: #0000;
&.active {
background-color: #0F2E51;
color: #4096D7;
border-bottom: 2px solid #4096D7;
}
}
}
</style>