楼宇能效监测控制系统
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

<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>