You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
735 lines
23 KiB
735 lines
23 KiB
<template> |
|
<div class="app-container" v-loading="loading"> |
|
<div class="overview-top"> |
|
<div class="overview-top-left"> |
|
<div class="special-div"> |
|
<div class="special-top"> |
|
<div class="special-title">项目概况</div> |
|
</div> |
|
<div class="overview-data"> |
|
<div class="overview-data-li"> |
|
<img |
|
class="overview-img" |
|
src="../../../assets/images/overview1.png" |
|
alt="" |
|
/> |
|
<div class="overview-num">640.4</div> |
|
<div class="overview-title">昨日用水量(吨)</div> |
|
</div> |
|
<div class="overview-data-li"> |
|
<img |
|
class="overview-img" |
|
src="../../../assets/images/overview2.png" |
|
alt="" |
|
/> |
|
<div class="overview-num">2428.88</div> |
|
<div class="overview-title">昨日用电量(度)</div> |
|
</div> |
|
<div class="overview-data-li"> |
|
<img |
|
class="overview-img" |
|
src="../../../assets/images/overview3.png" |
|
alt="" |
|
/> |
|
<div class="overview-num">3.79</div> |
|
<div class="overview-title">昨日单耗(度/吨)</div> |
|
</div> |
|
<div class="overview-data-li"> |
|
<img |
|
class="overview-img" |
|
src="../../../assets/images/overview4.png" |
|
alt="" |
|
/> |
|
<div class="overview-num">186</div> |
|
<div class="overview-title">通讯设备设备总数(台)</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
<div class="overview-top-right"> |
|
<div class="special-div"> |
|
<div class="special-top"> |
|
<div class="special-title">热泵运行状态</div> |
|
</div> |
|
<div class="pump-charts" ref="pumpChart_ref"></div> |
|
</div> |
|
</div> |
|
</div> |
|
<div class="overview-bottom"> |
|
<div class="overview-top-left"> |
|
<div class="special-div"> |
|
<div class="special-top"> |
|
<div class="special-title">当月数据统计</div> |
|
</div> |
|
<div class="choice"> |
|
<div |
|
class="mr20" |
|
v-for="(item, index) in timeData2" |
|
:key="index" |
|
@click="handleEnter(index, $event)" |
|
:class="{ timeStyle: currentIndex == index }" |
|
> |
|
{{ item.title }} |
|
</div> |
|
</div> |
|
<div class="brokenEcharts" ref="analyse_ref"></div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</template> |
|
<script> |
|
import * as echarts from "echarts"; |
|
export default { |
|
data() { |
|
return { |
|
loading: false, |
|
chartInstance: null, |
|
option: {}, |
|
chartData1: "", |
|
chartData2: "", |
|
allData: "", |
|
|
|
timeData2: [{ title: "用水量" }, { title: "用电量" }, { title: "单耗" }], |
|
currentIndex: 0, |
|
brokenOption: "", |
|
brokenInstanc: null, |
|
brokenData1: [], |
|
brokenData2: [], |
|
brokenData3: [], |
|
brokenTime: [], |
|
}; |
|
}, |
|
mounted() { |
|
this.initChart(); |
|
this.initChart2(); |
|
this.getTableData(); |
|
window.addEventListener("resize", this.screenAdapter); |
|
window.addEventListener("resize", this.screenAdapter2); |
|
this.screenAdapter(); |
|
// this.screenAdapter2(); |
|
this.pumpEchartsData(); |
|
}, |
|
destroyed() { |
|
//取消监听器 |
|
window.removeEventListener("resize", this.screenAdapter); |
|
window.removeEventListener("resize", this.screenAdapter2); |
|
}, |
|
methods: { |
|
// 饼图自适应 |
|
screenAdapter() { |
|
//自己定义的比较合适的适配大小,2.6 mes_ref是图表盒子 |
|
const titleFontSize = this.$refs.pumpChart_ref.offsetWidth / 30; |
|
//因为option可以多次配置的,所以这里的option只需要写 需要配置大小的相关数据 |
|
const adapterOption = { |
|
title: { |
|
subtextStyle: { |
|
fontSize: titleFontSize, |
|
}, |
|
}, |
|
}; |
|
//记得重新给配置项给实例对象。只要实例对象.chartInstance不变,option就可以多次配置不同的条件。也可以配置一个dataoption只写需要从后台请求的数据相关 |
|
this.chartInstance.setOption(adapterOption); |
|
//手动的调用图标对象的resize才能产生效果 |
|
this.chartInstance.resize(); |
|
}, |
|
// 获取热泵运行状态 |
|
pumpEchartsData() { |
|
let data = true; |
|
this.chartData1 = 10; |
|
this.chartData2 = 3; |
|
this.allData = 13; |
|
if (data) { |
|
const titleFontSize = (this.$refs.pumpChart_ref.offsetWidth / 100) * 2; |
|
const colorList = ["#ffe21e", "#08c8ff"]; // 提取颜色列表 |
|
const adapterOption = { |
|
tooltip: { |
|
trigger: "item", |
|
formatter: "{a} <br/>{b} : {c} ({d}%)", |
|
}, |
|
//环形图中间文字 |
|
title: { |
|
subtext: this.allData, |
|
}, |
|
legend: { |
|
itemWidth: titleFontSize, |
|
itemHeight: titleFontSize, |
|
itemGap: titleFontSize * 2, |
|
formatter: function (name) { |
|
var arr = []; |
|
let data = adapterOption.series[0].data; |
|
var index = 0; |
|
var total = 0; |
|
for (var i = 0; i < data.length; i++) { |
|
total += data[i].value; |
|
if (data[i].name == name) { |
|
index = i; |
|
} |
|
} |
|
arr.push( |
|
"{name|" + name + "}", |
|
"{text|" + " " + ":" + " " + "}", |
|
"{value|" + data[index].value + "}", |
|
"{text|" + " " + "台" + "}" |
|
); |
|
return arr.join(""); |
|
}, |
|
textStyle: { |
|
color: function (name) { |
|
const dataSeries = adapterOption.series[1].data; // 数据圆的data |
|
const index = dataSeries.findIndex( |
|
(item) => item.name === name |
|
); |
|
const colorList = ["#2df499", "#08c8ff"]; // 数据圆的颜色列表 |
|
return colorList[index]; |
|
}, |
|
rich: { |
|
name: { |
|
align: "left", |
|
fontSize: titleFontSize * 1.6, |
|
}, |
|
text: { |
|
align: "left", |
|
fontSize: titleFontSize * 1.6, |
|
}, |
|
value: { |
|
align: "left", |
|
fontSize: titleFontSize * 1.6, |
|
// color: function (params) { |
|
// let data = adapterOption.series[1].data; |
|
// return data.itemStyle.color({ dataIndex: params.dataIndex }); |
|
// }, |
|
}, |
|
percentage: { |
|
align: "left", |
|
fontSize: titleFontSize * 2, |
|
// color: function (params) { |
|
// let data = adapterOption.series[1].data; |
|
// return data.itemStyle.color({ dataIndex: params.dataIndex }); |
|
// }, |
|
}, |
|
}, |
|
}, |
|
}, |
|
series: [ |
|
{ |
|
name: "温度监测:", |
|
data: [ |
|
{ value: this.chartData1, name: "运行" }, |
|
{ value: this.chartData2, name: "不运行" }, |
|
], |
|
itemStyle: { |
|
color: function (params) { |
|
var colorList = ["#2df499", "#08c8ff"]; |
|
return colorList[params.dataIndex]; |
|
}, |
|
// borderWidth: 5, |
|
borderColor: "#002a56", |
|
}, |
|
}, |
|
{ |
|
data: [ |
|
{ value: this.chartData1, name: "运行" }, |
|
{ value: this.chartData2, name: "不运行" }, |
|
], |
|
}, |
|
], |
|
}; |
|
this.chartInstance.setOption(adapterOption); |
|
this.chartInstance.resize(); |
|
} else { |
|
const titleFontSize = (this.$refs.pumpChart_ref.offsetWidth / 100) * 2; |
|
const adapterOption = { |
|
tooltip: { |
|
trigger: "item", |
|
formatter: "{a} <br/>{b} : {c} ({d}%)", |
|
}, |
|
//环形图中间文字 |
|
title: { |
|
subtext: 0, |
|
}, |
|
legend: { |
|
itemWidth: titleFontSize, |
|
itemHeight: titleFontSize, |
|
itemGap: titleFontSize * 2, |
|
formatter: function (name) { |
|
var arr = []; |
|
let data = adapterOption.series[0].data; |
|
var index = 0; |
|
var total = 0; |
|
for (var i = 0; i < data.length; i++) { |
|
total += data[i].value; |
|
if (data[i].name == name) { |
|
index = i; |
|
} |
|
} |
|
arr.push( |
|
"{name|" + name + "}", |
|
"{text|" + " " + ":" + " " + "}", |
|
"{value|" + data[index].value + "}", |
|
"{text|" + " " + "台" + "}" |
|
); |
|
return arr.join(""); |
|
}, |
|
textStyle: { |
|
color: function (name) { |
|
const dataSeries = adapterOption.series[1].data; // 数据圆的data |
|
const index = dataSeries.findIndex( |
|
(item) => item.name === name |
|
); |
|
const colorList = ["#2df499", "#08c8ff"]; // 数据圆的颜色列表 |
|
return colorList[index]; |
|
}, |
|
rich: { |
|
name: { |
|
align: "left", |
|
fontSize: titleFontSize * 1.6, |
|
}, |
|
text: { |
|
align: "left", |
|
fontSize: titleFontSize * 1.6, |
|
}, |
|
value: { |
|
align: "left", |
|
fontSize: titleFontSize * 1.6, |
|
// color: function (params) { |
|
// let data = adapterOption.series[1].data; |
|
// return data.itemStyle.color({ dataIndex: params.dataIndex }); |
|
// }, |
|
}, |
|
percentage: { |
|
align: "left", |
|
fontSize: titleFontSize * 1.6, |
|
// color: function (params) { |
|
// let data = adapterOption.series[1].data; |
|
// return data.itemStyle.color({ dataIndex: params.dataIndex }); |
|
// }, |
|
}, |
|
}, |
|
}, |
|
}, |
|
series: [ |
|
{ |
|
name: "温度监测:", |
|
data: [ |
|
{ value: 0, name: "运行" }, |
|
{ value: 0, name: "不运行" }, |
|
], |
|
itemStyle: { |
|
color: function (params) { |
|
var colorList = ["#2df499", "#08c8ff"]; |
|
return colorList[params.dataIndex]; |
|
}, |
|
// borderWidth: 5, |
|
borderColor: "#002a56", |
|
}, |
|
}, |
|
{ |
|
data: [ |
|
{ value: 0, name: "运行" }, |
|
{ value: 0, name: "不运行" }, |
|
], |
|
}, |
|
], |
|
}; |
|
this.chartInstance.setOption(adapterOption); |
|
this.chartInstance.resize(); |
|
} |
|
}, |
|
//初始化chartInstance对象-饼图 |
|
initChart() { |
|
this.chartInstance = echarts.init(this.$refs.pumpChart_ref); |
|
this.option = { |
|
//环形图中间文字 |
|
title: { |
|
subtext: this.allData, |
|
textStyle: { |
|
color: "#ffffff", |
|
fontSize: 20, |
|
}, |
|
subtextStyle: { |
|
color: "#ffffff", |
|
}, |
|
textAlign: "center", |
|
x: "28.5%", |
|
y: "35%", //距离上边的距离 |
|
}, |
|
tooltip: { |
|
trigger: "item", |
|
formatter: "{a} <br/>{b} : {c} ({d}%)", |
|
}, |
|
//图例 |
|
legend: { |
|
orient: "vertical", // 垂直分布 |
|
right: "10%", // 位于最右边 |
|
top: "center", // 垂直居中 |
|
//图例文字颜色 |
|
textStyle: { |
|
color: "#ffffff", |
|
// fontSize: 18, |
|
}, |
|
}, |
|
series: [ |
|
// 数据圆 |
|
{ |
|
name: "温度监测:", |
|
type: "pie", |
|
radius: ["50%", "62%"], |
|
center: ["30%", "44%"], |
|
avoidLabelOverlap: false, |
|
label: { |
|
show: false, |
|
position: "center", |
|
}, |
|
labelLine: { |
|
show: false, |
|
}, |
|
itemStyle: { |
|
color: function (params) { |
|
var colorList = ["#2df499", "#08c8ff"]; |
|
return colorList[params.dataIndex]; |
|
}, |
|
borderWidth: 5, |
|
borderColor: "#002a56", |
|
}, |
|
z: 10, //设置层级更高,否则会被阴影圆遮住 |
|
}, |
|
// 阴影圆 |
|
{ |
|
type: "pie", |
|
radius: ["40%", "52%"], |
|
center: ["30%", "44%"], |
|
avoidLabelOverlap: false, |
|
label: { |
|
show: false, |
|
position: "center", |
|
}, |
|
silent: true, |
|
labelLine: { |
|
show: false, |
|
}, |
|
//颜色 |
|
itemStyle: { |
|
color: function (colors) { |
|
var colorList = ["#09596b", "#024e7d"]; |
|
return colorList[colors.dataIndex]; |
|
}, |
|
}, |
|
z: 15, |
|
}, |
|
// 内圈边框 |
|
{ |
|
// 颜色 |
|
color: ["#305376"], |
|
type: "pie", |
|
silent: true, //鼠标移入不显示内容,不触发鼠标事件 |
|
// hoverAnimation: false, //鼠标移入不放大,此属性已被废弃 |
|
// 使用emphasis.scale 是否开启高亮后扇区的放大效果,默认true |
|
// 这里开启silent: true, 就达到效果了 |
|
// center与非内圈一致 |
|
radius: ["28%", "29%"], |
|
center: ["30%", "44%"], |
|
label: { |
|
show: false, |
|
}, |
|
data: [ |
|
{ |
|
value: 0, |
|
name: "", |
|
itemStyle: {}, |
|
}, |
|
], |
|
}, |
|
// 最里面渐变小圆 |
|
{ |
|
// 颜色 |
|
type: "pie", |
|
silent: true, //鼠标移入不显示内容,不触发鼠标事件 |
|
// hoverAnimation: false, //鼠标移入不放大,此属性已被废弃 |
|
// 使用emphasis.scale 是否开启高亮后扇区的放大效果,默认true |
|
// 这里开启silent: true, 就达到效果了 |
|
// center与非内圈一致 |
|
radius: ["0%", "29%"], |
|
center: ["30%", "44%"], |
|
label: { |
|
show: false, |
|
}, |
|
data: [ |
|
{ |
|
value: 0, |
|
name: "", |
|
itemStyle: {}, |
|
}, |
|
], |
|
itemStyle: { |
|
color: { |
|
type: "linear", |
|
x: 0, |
|
y: 0, |
|
x2: 1, |
|
y2: 1, |
|
colorStops: [ |
|
{ offset: 0, color: "#002a55" }, // 0% 处的颜色 |
|
{ offset: 1, color: "#0a457a" }, // 100% 处的颜色 |
|
], |
|
global: false, // 缺省为 false |
|
}, |
|
}, |
|
}, |
|
], |
|
}; |
|
//把配置项给实例对象 |
|
this.chartInstance.setOption(this.option, true); |
|
}, |
|
handleEnter(index) { |
|
this.currentIndex = index; |
|
this.renderingBroken(); |
|
}, |
|
//初始化chartInstance2对象 折线图 |
|
initChart2() { |
|
this.brokenInstanc = echarts.init(this.$refs.analyse_ref); |
|
this.brokenOption = { |
|
tooltip: { |
|
trigger: "axis", |
|
}, |
|
legend: { |
|
show: false, |
|
selectedMode: false, // 是否允许图例进行点击 |
|
icon: "cricle", //图例样式,可以自行查看样式选择 |
|
//图例文字颜色 |
|
textStyle: { |
|
color: "#ffff", |
|
fontSize: 16, //这里改字体大小 |
|
}, |
|
// left: "73%", |
|
left: "66%", |
|
top: "0", |
|
//图例距离饼图的距离 |
|
itemGap: 5, |
|
itemWidth: 10, |
|
itemHeight: 5, |
|
}, |
|
|
|
grid: { |
|
top: "4%", |
|
left: "3%", |
|
right: "4%", |
|
bottom: "5%", |
|
containLabel: true, |
|
}, |
|
xAxis: { |
|
type: "category", |
|
//设置为true代表离零刻度间隔一段距离 |
|
boundaryGap: true, |
|
// 修饰刻度标签的颜色即x坐标数据 |
|
axisLabel: { |
|
// interval: 0, //强制显示所有x轴数据 |
|
// rotate: 30, //x轴坐标字体倾斜30度 |
|
color: "rgba(255, 255, 255, 1)", |
|
fontSize: 14, // 设置字体大小,可根据需要调整 |
|
}, |
|
axisTick: { |
|
show: false, // 不显示坐标轴刻度线 |
|
}, |
|
// x坐标轴的颜色 |
|
axisLine: { |
|
show: true, |
|
lineStyle: { |
|
color: "#365576", |
|
}, |
|
}, |
|
splitLine: { |
|
lineStyle: { |
|
color: "#e2e6f0", |
|
}, |
|
}, //x轴分割线 |
|
data: this.brokenTime, |
|
}, |
|
yAxis: { |
|
min: 0, |
|
// max:20, |
|
// // // min:'dataMin', |
|
// // // max:'dataMax', |
|
// name: "kwh", // 第一个 y 轴的单位描述 |
|
// 设置 name 的样式 |
|
nameTextStyle: { |
|
color: "rgba(255, 255, 255, 1)", |
|
fontSize: 12, |
|
}, |
|
miniInterval: 5, |
|
type: "value", |
|
// 修饰刻度标签的颜色即y坐标数据 |
|
axisLabel: { |
|
color: "rgba(255, 255, 255, 1)", |
|
}, |
|
// 显示y坐标轴 |
|
axisLine: { |
|
show: true, |
|
lineStyle: { |
|
color: "#365576", // 设置 y 轴线的颜色 |
|
}, |
|
fontSize: 14, // 设置字体大小,可根据需要调整 |
|
}, |
|
//y轴分割线段数 |
|
// splitNumber: 10, |
|
// 修改y轴分割线的颜色 |
|
splitLine: { |
|
lineStyle: { |
|
color: "#1a3d62", // 设置分割线的颜色 |
|
type: "dashed", // 设置分割线为虚线 |
|
}, |
|
}, |
|
}, |
|
series: [ |
|
{ |
|
type: "line", |
|
// 拐点大小 |
|
symbolSize: 8, |
|
data: this.brokenData1, |
|
//折线颜色 |
|
itemStyle: { |
|
color: "#d48e17", //折线点的颜色 |
|
lineStyle: { |
|
color: "#d48e17", //折线的颜色 |
|
}, |
|
}, |
|
}, |
|
], |
|
}; |
|
//把配置项给实例对象 |
|
this.brokenInstanc.setOption(this.brokenOption, true); |
|
}, |
|
//折线图自适应 |
|
screenAdapter2() { |
|
console.log("没有数据吗", this.brokenData1); |
|
//自己定义的比较合适的适配大小,2.6 mes_ref是图表盒子 |
|
const titleFontSize = this.$refs.analyse_ref.offsetWidth / 130; |
|
const adapterOption = {}; |
|
//记得重新给配置项给实例对象。只要实例对象.chartInstance不变,option就可以多次配置不同的条件。也可以配置一个dataoption只写需要从后台请求的数据相关 |
|
this.brokenInstanc.setOption(adapterOption); |
|
//手动的调用图标对象的resize才能产生效果 |
|
this.brokenInstanc.resize(); |
|
}, |
|
// 获取折线图数据 |
|
getTableData() { |
|
this.brokenData1 = [30, 40, 29]; |
|
this.brokenData2 = [10, 23, 12]; |
|
this.brokenData3 = [3, 4, 2]; |
|
this.brokenTime = ["3月", "4月", "5月"]; |
|
this.renderingBroken(); |
|
}, |
|
renderingBroken() { |
|
if (this.currentIndex === 0) { |
|
this.brokenOption.series[0].data = this.brokenData1; |
|
this.brokenOption.series[0].itemStyle.color = "#d48e17"; |
|
} else if (this.currentIndex === 1) { |
|
this.brokenOption.series[0].data = this.brokenData2; |
|
this.brokenOption.series[0].itemStyle.color = "#1ab395"; |
|
} else if (this.currentIndex === 2) { |
|
this.brokenOption.series[0].data = this.brokenData3; |
|
this.brokenOption.series[0].itemStyle.color = "#1f8dee"; |
|
} |
|
// 保存当前索引用于闭包 |
|
const currentIndex = this.currentIndex; |
|
// 动态设置 tooltip 格式化函数 |
|
this.brokenOption.tooltip = { |
|
trigger: "axis", |
|
formatter: function (params) { |
|
// 获取当前数据点信息 |
|
const data = params[0]; |
|
const month = data.name; |
|
const value = data.value; |
|
|
|
// 根据索引返回不同内容 |
|
if (currentIndex === 0) { |
|
return `${month}<br/>用水量: ${value} 吨`; |
|
} else if (currentIndex === 1) { |
|
return `${month}<br/>用电量: ${value} 度`; |
|
} else if (currentIndex === 2) { |
|
return `${month}<br/>单耗: ${value} 度/吨`; |
|
} |
|
}, |
|
}; |
|
this.brokenOption.xAxis.data = this.brokenTime; |
|
this.brokenInstanc.setOption(this.brokenOption); |
|
}, |
|
}, |
|
}; |
|
</script> |
|
<style lang="scss" scoped> |
|
.overview-top { |
|
width: 100%; |
|
display: flex; |
|
flex-direction: row; |
|
align-items: stretch; |
|
justify-content: space-between; |
|
margin-bottom: 0.2rem; |
|
.overview-top-left { |
|
width: 65%; |
|
.overview-data { |
|
width: 100%; |
|
padding: 0.5rem; |
|
display: flex; |
|
flex-direction: row; |
|
align-items: center; |
|
justify-content: space-between; |
|
.overview-data-li { |
|
width: 1.8rem; |
|
height: 1.65rem; |
|
position: relative; |
|
.overview-img { |
|
width: 1.8rem; |
|
height: 1.65rem; |
|
position: absolute; |
|
top: 0; |
|
} |
|
.overview-num { |
|
font-family: DIN-Bold; |
|
font-size: 0.3rem; |
|
font-weight: bold; |
|
font-stretch: normal; |
|
line-height: 0.5rem; |
|
letter-spacing: 0px; |
|
color: #ffffff; |
|
position: absolute; |
|
top: 0.28rem; |
|
right: 0; |
|
} |
|
.overview-title { |
|
font-family: SourceHanSansCN-Regular; |
|
font-size: 0.18rem; |
|
font-weight: normal; |
|
font-stretch: normal; |
|
line-height: 0.22rem; |
|
letter-spacing: 0px; |
|
color: #ffffff; |
|
position: absolute; |
|
top: 0.77rem; |
|
right: 0; |
|
} |
|
} |
|
} |
|
} |
|
.overview-top-right { |
|
width: 33%; |
|
.pump-charts { |
|
width: 100%; |
|
height: 2.65rem; |
|
} |
|
} |
|
} |
|
.overview-bottom { |
|
.choice { |
|
margin: 20px; |
|
.mr20 { |
|
padding: 0.05rem 0.2rem; |
|
white-space: nowrap; |
|
width: auto; |
|
} |
|
} |
|
.brokenEcharts { |
|
width: 100%; |
|
height: 4rem; |
|
} |
|
} |
|
</style>
|
|
|