long_IslandOcean/src/views/overview/index.vue

792 lines
22 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup>
import calendar from "@/components/calendar/index.vue";
import * as echarts from "echarts";
import { onMounted, ref } from "vue";
import {getPower,getRealtimeLoad,getCarbonEmission,getEnergyCalendar,getMeteorologicalStation,getSystemRanking} from '@/api/overview'
import getPath from "@/utils/getPath.js";
// 实时负荷
const realTimeLoad = ref([
{ pic: getPath.roomnum, name: "配电室数量", value: 8, unit: "个" },
{ pic: getPath.WL, name: "实时负荷", value: 1465.2, unit: "kW" }, //负荷
{ pic: getPath.E, name: "今日电量", value: 146, unit: "kWh" }, //电量
]);
// 气象站
const weatherStation = ref([
{ pic: getPath.rain, name: "雨量", value: 100, unit: "mm" },
{ pic: getPath.rainsnow, name: "雨雪", value: "实际取值", unit: "mm" },
{ pic: getPath.wind, name: "风向", value: "东南风" },
{ pic: getPath.illuminance, name: "光照度", value: 101, unit: "lux" },
{ pic: getPath.windspeed, name: "风速", value: "东南风3级" },
{ pic: getPath.air, name: "空气质量", value: "优" },
]);
// const getImageUrl=(name)=>{
// return `url(${new URL(name, import.meta.url).href})`
// }
// 用电量列表
const powerList = ref([])
onMounted(() => {
// 用电量接口
powerInterface()
// 实时负荷接口
realtimeLoadInterface()
// 气象站接口
stationInterface()
// 系统用电排名接口
systemRankingInterface()
// 碳排放的接口
CarbonEmissionInterface()
//碳排放
// getCarbonEmissionEcahrts();
});
// 用电量时间切换
const powerDate = ref("year");
const togglePower = (event) => {
powerDate.value = event.srcElement.className;
powerInterface()
};
// 碳排放时间切换
const carbonEmissionDate = ref("month");
const toggleCarbonEmission = (event) => {
carbonEmissionDate.value = event.srcElement.className;
// 碳排放接口
CarbonEmissionInterface()
};
const drawPowerEcharts = (item) => {
let myChart = echarts.init(document.getElementById("power"));
const option = {
// backgroundColor: "#05224d",
tooltip: {},
grid: {
top: "18%",
left: "4%",
right: "4%",
bottom: "4%",
containLabel: true,
},
xAxis: [
{
type: "category",
axisLine: {
//坐标轴轴线相关设置。数学上的x轴
show: true,
lineStyle: {
// type:'dashed',
color: "#557775",
// color: "#233e64",
},
},
axisLabel: {
//坐标轴刻度标签的相关设置
textStyle: {
color: "#DDFFFD",
margin: 40,
},
},
axisTick: { show: false },
boundaryGap: true,
// data: ["1月", "2月", "3月", "4月", "5月", "6月", "7月"],
data:item.map(el=>{
return el.time
})
},
],
yAxis: [
{
type: "value",
name: "单位:kWh",
nameTextStyle: {
color: "#DDFFFD",
},
min: 0,
max: 500,
splitNumber: 5,
splitLine: {
show: true,
lineStyle: {
type: "dashed",
color: "rgba(1, 39, 37, 0.30)",
},
},
axisLine: { show: false },
axisLabel: {
textStyle: {
color: "#DDFFFD",
},
},
axisTick: { show: false },
},
],
series: [
{
name: "异常流量",
type: "line",
smooth: true, //是否平滑曲线显示
// symbol:'circle', // 默认是空心圆(中间是白色的),改成实心圆
symbolSize: 0,
lineStyle: {
normal: {
color: "#5BFAF1", // 线条颜色
},
},
areaStyle: {
//区域填充样式
normal: {
//线性渐变前4个参数分别是x0,y0,x2,y2(范围0~1);相当于图形包围盒中的百分比。如果最后一个参数是true则该四个值是绝对像素位置。
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{ offset: 0, color: "rgba(91, 250, 241, 0.40)" },
{ offset: 1, color: "rgba(91, 250, 241, 0)" },
],
false
),
shadowColor: "rgba(53,142,215, 0.9)", //阴影颜色
shadowBlur: 20, //shadowBlur设图形阴影的模糊大小。配合shadowColor,shadowOffsetX/Y, 设置图形的阴影效果。
},
},
// data: [110, 200, 300, 325, 400, 322, 250],
data:item.map(el=>{
return el.EH
})
},
],
};
myChart.setOption(option);
// 添加 resize 事件处理程序
window.addEventListener("resize", function () {
myChart.resize(); // 调用 resize 函数进行自适应大小调整
});
};
const drawRankEcharts = (data) => {
let myChart = echarts.init(document.getElementById("rank"));
let option = {
grid: {
left: "5%",
right: "5%",
bottom: "-10%",
top: "8%",
containLabel: true,
},
tooltip: {
trigger: "axis",
axisPointer: {
type: "none",
},
formatter: function (params) {
return (
params[0].name +
"<br/>" +
"<span style='display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color:rgba(36,207,233,0.9)'></span>" +
params[0].seriesName +
" : " +
Number(
(params[0].value.toFixed(4) / 10000).toFixed(2)
).toLocaleString() +
" 万元<br/>"
);
},
},
xAxis: {
show: false,
type: "value",
},
yAxis: [
{
type: "category",
inverse: true,
axisLabel: {
padding: [0, 0, 10, -10],
verticalAlign: "bottom",
inside: true,
show: true,
textStyle: {
color: "#fff",
fontSize: "14",
},
},
splitLine: {
show: false,
},
axisTick: {
show: false,
},
axisLine: {
show: false,
},
// data: ["空调系统", "照明系统", "消防系统", "电梯系统", "展陈系统"],
data:data.map(el=>{
return el.name
})
},
{
type: "category",
inverse: true,
axisTick: "none",
axisLine: "none",
show: true,
axisLabel: {
padding: [0, 0, 10, -10],
verticalAlign: "bottom",
inside: true,
textStyle: {},
formatter: function (value) {
return "{a|" + (value / 10000).toLocaleString() + "}" + "{b|kWh}";
},
rich: {
a: {
fontSize: "16",
color: "rgba(0, 255, 240, 1)",
padding: [0, 6, 0, 0],
},
b: {
color: "#fff",
fontSize: "12",
},
},
},
// data: [50000000, 22000000, 10000000, 5000000, 1],
data:data.map(el=>{
return el.EH
})
},
],
series: [
{
name: "金额",
type: "bar",
zlevel: 1,
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{
offset: 0,
color: "rgba(29, 169, 153, 1)",
},
{
offset: 1,
color: "rgba(223, 243, 240, 1)",
},
]),
},
barWidth: 8,
// data: [50000000, 22000000, 10000000, 5000000, 200],
data:data.map(el=>{
return el.EH
})
},
{
name: "背景",
type: "bar",
barWidth: 10,
barGap: "-115%",
data: [50000000, 50000000, 50000000, 50000000, 50000000],
itemStyle: {
color: "rgba(5, 33, 31, 0.32)",
},
},
],
};
myChart.setOption(option);
// 添加 resize 事件处理程序
window.addEventListener("resize", function () {
myChart.resize(); // 调用 resize 函数进行自适应大小调整
});
};
//碳排放
function getCarbonEmissionEcahrts(data) {
const offsetX = 10; //bar宽
const offsetY = 5; //倾斜角度
// 绘制左侧面
const CubeLeft = echarts.graphic.extendShape({
shape: {
x: 0,
y: 0,
},
buildPath: function (ctx, shape) {
const xAxisPoint = shape.xAxisPoint;
const c0 = [shape.x - 7, shape.y];
const c1 = [shape.x + 7, shape.y];
const c2 = [xAxisPoint[0] + 7, xAxisPoint[1]];
const c3 = [xAxisPoint[0] - 7, xAxisPoint[1]];
ctx
.moveTo(c0[0], c0[1])
.lineTo(c1[0], c1[1])
.lineTo(c2[0], c2[1])
.lineTo(c3[0], c3[1])
.closePath();
ctx.stroke();
},
});
// 绘制右侧面
const CubeRight = echarts.graphic.extendShape({
shape: {
x: 0,
y: 0,
},
buildPath: function (ctx, shape) {
const xAxisPoint = shape.xAxisPoint;
const c1 = [shape.x + 7, shape.y];
const c2 = [xAxisPoint[0] + 7, xAxisPoint[1]];
const c3 = [xAxisPoint[0] + 7 + 7, xAxisPoint[1] - 10];
const c4 = [shape.x + 7 + 7, shape.y - 5];
ctx
.moveTo(c1[0], c1[1])
.lineTo(c2[0], c2[1])
.lineTo(c3[0], c3[1])
.lineTo(c4[0], c4[1])
.closePath();
ctx.stroke();
},
});
// 绘制顶面
const CubeTop = echarts.graphic.extendShape({
shape: {
x: 0,
y: 0,
},
buildPath: function (ctx, shape) {
const c1 = [shape.x - 7, shape.y];
const c2 = [shape.x + 8, shape.y];
const c3 = [shape.x + 15, shape.y - 5];
const c4 = [shape.x - 2, shape.y - 5];
ctx
.moveTo(c1[0], c1[1])
.lineTo(c2[0], c2[1])
.lineTo(c3[0], c3[1])
.lineTo(c4[0], c4[1])
.closePath();
ctx.stroke();
},
});
// 注册三个面图形
echarts.graphic.registerShape("CubeLeft", CubeLeft);
echarts.graphic.registerShape("CubeRight", CubeRight);
echarts.graphic.registerShape("CubeTop", CubeTop);
// let xAxisData = ["1月", "2月", "3月", "4月", "5月", "6月", "7月"];
let xAxisData = data.map(el=>{return el.time})
// let seriesData = [100, 200, 300, 400, 200, 250];
let seriesData = data.map(el=>{return el.CarbonEmission})
// 绿色渐变
// let colorArr = [["#12D5AF"], ["#0BC19D", "rgba(13,8,16,0)"], ["#68EFD4", "rgba(14,185,151,0)"]]
// 蓝色渐变
let colorArr = [
["rgba(0, 193, 113, 1)"],
["rgba(0, 255, 140, 1)", "rgba(0, 255, 140,0)"],
["rgba(0, 255, 140, 1)", "rgba(0, 255, 140,0)"],
];
let myChart = echarts.init(document.getElementById("carbonEmission"));
const option = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow",
},
formatter: function (params, ticket, callback) {
const item = params[1];
return item.name + " : " + item.value;
},
},
grid: {
left: "4%",
right: "5%",
top: "18%",
bottom: "5%",
containLabel: true,
},
xAxis: {
type: "category",
data: xAxisData,
axisLine: {
show: true,
lineStyle: {
width: 1,
type: "solid",
color: "rgba(255, 255, 255, 0.20)",
},
},
axisTick: {
show: false,
},
axisLabel: {
color: "rgba(221, 255, 253, 1)",
fontSize: 12,
interval: 0,
// 使用函数模板,函数参数分别为刻度数值(类目),刻度的索引
// formatter: function (value) {
// const length = value.length;
// if (length > 3) {
// const start = Math.floor(length / 2);
// const str =
// value.slice(0, start) + "\n" + value.slice(start, length);
// return str;
// }
// return value;
// },
},
},
yAxis: {
type: "value",
name: "单位:kWh",
nameTextStyle: {
color: "#DDFFFD",
padding: [0, 5, 0, 0],
},
// minInterval: 1,
// y轴竖直线
axisLine: {
show: false,
},
// y轴横向 标线
splitLine: {
show: true,
lineStyle: {
type: "dashed",
color: "rgba(1, 39, 37, 0.30)",
},
},
// y轴刻度线
axisTick: {
show: false,
},
// y轴文字
axisLabel: {
fontSize: 12,
color: "#DDFFFD",
},
},
series: [
{
type: "custom",
renderItem: (params, api) => {
const location = api.coord([api.value(0), api.value(1)]);
return {
type: "group",
children: [
// 左侧面
{
type: "CubeLeft",
shape: {
api,
xValue: api.value(0),
yValue: api.value(1),
x: location[0],
y: location[1],
xAxisPoint: api.coord([api.value(0), 0]),
},
style: {
fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: colorArr[1][0],
},
{
offset: 1,
color: colorArr[1][1],
},
]),
},
},
// 右侧面
{
type: "CubeRight",
shape: {
api,
xValue: api.value(0),
yValue: api.value(1),
x: location[0],
y: location[1],
xAxisPoint: api.coord([api.value(0), 0]),
},
style: {
fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: colorArr[2][0],
},
{
offset: 1,
color: colorArr[2][1],
},
]),
},
},
// 顶部
{
type: "CubeTop",
shape: {
api,
xValue: api.value(0),
yValue: api.value(1),
x: location[0],
y: location[1],
xAxisPoint: api.coord([api.value(0), 0]),
},
style: {
fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: colorArr[0][0],
},
{
offset: 1,
color: colorArr[0][0],
},
]),
},
},
],
};
},
data: seriesData,
},
{
type: "bar",
label: {
normal: {
show: false,
position: "top",
formatter: (e) => {
return e.value;
},
fontSize: 16,
color: "#43C4F1",
offset: [0, -5],
},
},
itemStyle: {
color: "transparent",
},
tooltip: {},
data: seriesData,
},
],
};
myChart.setOption(option);
// 添加 resize 事件处理程序
window.addEventListener("resize", function () {
myChart.resize(); // 调用 resize 函数进行自适应大小调整
});
}
// 获取用电量
const powerInterface=()=>{
let params = {
date:powerDate.value==='year'?'年':'月'
}
getPower(params).then(res=>{
// 渲染用电量图表
drawPowerEcharts(res.data);
})
}
// 获取实时负荷
const realtimeLoadInterface = () =>{
getRealtimeLoad().then(res=>{
realTimeLoad.value.forEach(item=>{
if(item.name==='配电室数量'){
item.value = res.data[0].Amount
}else if(item.name==='实时负荷'){
item.value = res.data[0].P
}else if(item.name==='今日电量'){
item.value = res.data[0].EH
}
})
})
}
// 获取气象站数据
const stationInterface = () =>{
getMeteorologicalStation().then(res=>{
weatherStation.value.forEach(item=>{
res.data.forEach(el=>{
if(el.name.indexOf(item.name)!==-1){
item.value = el.value
}
})
})
})
}
// 系统用电量排名
const systemRankingInterface = () =>{
getSystemRanking().then(res=>{
// 系统用电排名chart图
drawRankEcharts(res.data)
})
}
const CarbonEmissionInterface = () =>{
let params = {
date:carbonEmissionDate.value === 'month'?'月':'年'
}
getCarbonEmission(params).then(res=>{
getCarbonEmissionEcahrts(res.data)
})
}
</script>
<template>
<div class="page m100">
<div class="page-left-box">
<!-- 用电量-->
<div class="title">
<span>用电量</span>
<p>
<span
class="year"
:class="powerDate === 'year' ? 'selectYear' : ''"
@click="togglePower"
></span
>
<span
class="month"
:class="powerDate === 'month' ? 'selectMonth' : ''"
@click="togglePower"
></span
>
</p>
</div>
<div class="margin10 box-bg" id="power"></div>
<!-- 日历-->
<div class="title margin10">
<span>能耗日历</span>
<p>
<span>单位kgce</span>
</p>
</div>
<div class="margin10 box-bg">
<calendar />
</div>
<!-- 碳排放-->
<div class="title margin10">
<span>碳排放</span>
<p>
<span
class="year"
:class="carbonEmissionDate === 'year' ? 'selectYear' : ''"
@click="toggleCarbonEmission"
></span
>
<span
class="month"
:class="carbonEmissionDate === 'month' ? 'selectMonth' : ''"
@click="toggleCarbonEmission"
></span
>
</p>
</div>
<div class="margin10 box-bg" id="carbonEmission"></div>
</div>
<div class="page-right-box">
<!-- 实时负荷 -->
<div class="title">
<span>实时负荷</span>
</div>
<div class="margin10 box-bg">
<ul class="real-time-load">
<li
v-for="(item, index) in realTimeLoad"
:style="'background-image:url(' + item.pic + ')'"
>
<span class="unit">{{ item.name }}</span>
<p>
<span class="value">{{ item.value }}</span>
<span class="unit">{{ item.unit }}</span>
</p>
</li>
</ul>
</div>
<!-- 气象站-->
<div class="title margin10">
<span>气象站</span>
</div>
<div class="margin10 box-bg">
<ul class="weather-station">
<li v-for="(item, index) in weatherStation">
<p class="img" :style="'background-image:url(' + item.pic + ')'">
<span>{{ item.name }}</span>
</p>
<p>
<span class="wea-value">{{ item.value }}</span
><span class="unit" v-if="item.unit">{{ item.unit }}</span>
</p>
</li>
</ul>
</div>
<!-- 系统用电排名-->
<div class="title margin10">
<span>系统用电排名</span>
</div>
<div class="margin10 box-bg" id="rank"></div>
</div>
</div>
</template>
<style lang="scss" scoped>
.real-time-load {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
flex-wrap: wrap;
align-content: space-evenly;
li {
width: 24.125rem;
height: 28%;
display: flex;
align-items: center;
justify-content: space-between;
padding-left: 4.75rem;
padding-right: 1.3rem;
box-sizing: border-box;
.value {
margin-right: 0.7rem;
font-size: 1.5rem;
font-weight: 700;
color: rgba(91, 250, 241, 1);
}
.unit {
font-size: 0.8rem;
color: rgba(221, 255, 253, 1);
}
}
}
.weather-station {
width: 100%;
height: 100%;
padding: 0.8rem;
box-sizing: border-box;
display: flex;
flex-wrap: wrap;
align-content: space-evenly;
justify-content: space-between;
li {
height: 30%;
.wea-value {
font-weight: 600;
color: rgba(91, 250, 241, 1);
margin: 0 0.4rem 0 1rem;
}
.unit {
font-size: 0.8rem;
color: rgba(221, 255, 253, 1);
}
}
.img {
margin-bottom: 0.3rem;
width: 11.125rem;
display: flex;
align-items: center;
padding-left: 2.6rem;
box-sizing: border-box;
font-size: 0.9rem;
font-style: italic;
height: 50%;
color: rgba(221, 255, 253, 1);
}
}
</style>