factory_web/src/views/bigScreen/index_enm.vue

1819 lines
49 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.

<template>
<div class="dashboard">
<header>
<div class="title_left"></div>
<h1 class="title">{{ factoryName }}</h1>
<h2 class="title_right">数据更新: {{ updateTime }}</h2>
</header>
<div class="left_main animate__animated animate__zoomIn">
<div class="panel">
<div class="panel_title">本月全厂主要数据</div>
<el-row :gutter="16" style="height: 72px; margin-top: 4px">
<el-col :span="12" class="panel_item">
<div class="panel_label">
<img
src="img/elec.png"
style="height: 24px; vertical-align: middle"
/>动力电消耗
</div>
<div class="pannel_number">
<span class="panel_value">{{
factoryData.elec_consume
}}</span>
<span class="panel_unit">(kW·h)</span>
</div>
</el-col>
<el-col :span="12" class="panel_item">
<div class="panel_label">
<img
src="img/coal.png"
style="height: 24px; vertical-align: bottom"
/>煤粉消耗
</div>
<div class="pannel_number">
<span class="panel_value">{{
factoryData.pcoal_consume
}}</span>
<span class="panel_unit">(t)</span>
</div>
</el-col>
</el-row>
<el-row :gutter="16" style="height: 72px; margin-top: 4px">
<el-col :span="12" class="panel_item">
<div class="panel_label">
<img
src="img/water.png"
style="height: 24px; vertical-align: bottom"
/>工业水消耗
</div>
<div class="pannel_number">
<span class="panel_value">{{
factoryData.water_consume
}}</span>
<span class="panel_unit">(t)</span>
</div>
</el-col>
<el-col :span="12" class="panel_item">
<div class="panel_label">
<img
src="img/cair.png"
style="height: 24px; vertical-align: bottom"
/>压缩空气消耗
</div>
<div class="pannel_number">
<span class="panel_value">{{
factoryData.cair_consume
}}</span>
<span class="panel_unit">(t)</span>
</div>
</el-col>
</el-row>
</div>
</div>
<div class="model">
<div id="loadingScreen">
<el-progress
type="circle"
:percentage="loadedPercent"
:width="220"
status="warning"
>
<template #default="{ percentage }">
<div
style="
font-size: 30px;
color: white;
font-weight: bold;
"
>
{{ percentage }}%
</div>
<div
style="
font-size: 18px;
color: white;
margin-top: 10px;
"
>
工厂模型加载中
</div>
</template>
</el-progress>
<!-- 工厂模型加载中.....{{ loadedPercent }}% -->
</div>
<canvas id="renderCanvas"></canvas>
</div>
<div class="right_main">
<div class="panel">
<div class="panel_title">
今日工段主要数据-{{ activeSectionName }}
</div>
<el-row :gutter="16" style="height: 72px; margin-top: 4px">
<el-col :span="12" class="panel_item">
<div class="panel_label">
<img
src="img/elec.png"
style="height: 24px; vertical-align: middle"
/>单位产品电耗
</div>
<div class="pannel_number">
<span class="panel_value" v-if="sectionData">{{
sectionData.elec_consume_unit
}}</span>
<span class="panel_unit">(kW·h)</span>
</div>
</el-col>
<el-col :span="12" class="panel_item">
<div class="panel_label">
<img
src="img/total_production.png"
style="height: 24px; vertical-align: middle"
/>产品产量
</div>
<div class="pannel_number">
<span class="panel_value" v-if="sectionData">{{
sectionData.total_production
}}</span>
<span class="panel_unit">(t)</span>
</div>
</el-col>
</el-row>
<el-row :gutter="16" style="height: 72px; margin-top: 4px">
<el-col :span="12" class="panel_item">
<div class="panel_label">
<img
src="img/run_rate.png"
style="height: 24px; vertical-align: middle"
/>
运转率
</div>
<div class="pannel_number">
<span class="panel_value" v-if="sectionData">{{
sectionData.run_rate
}}</span>
<span class="panel_unit">(%)</span>
</div>
</el-col>
<el-col :span="12" class="panel_item" v-show="showKgcet">
<div class="panel_label">
<img
src="img/coal.png"
style="height: 24px; vertical-align: bottom"
/>单位产品标煤耗
</div>
<div class="pannel_number">
<span class="panel_value" v-if="sectionData">{{
sectionData.coal_consume_unit
}}</span>
<span class="panel_unit">(kgce/t)</span>
</div>
</el-col>
</el-row>
</div>
</div>
<div class="dropdown">
<div
class="dropdown-item"
v-for="(val, index) in sectionNames"
:key="val"
@click="handleSectionClick(val, index)"
:class="{ active: activeSection === index }"
>
{{ val }}
</div>
</div>
<div class="left_other animate__animated animate__backInLeft">
<div class="panel">
<div class="panel_title">动力电消耗趋势图</div>
<div class="chart" id="chart1"></div>
</div>
<div class="panel">
<div class="panel_title">工业水/原煤消耗趋势图</div>
<div class="chart" id="chart2"></div>
</div>
<div class="panel">
<div class="panel_title">压缩空气消耗趋势图</div>
<div class="chart" id="chart3"></div>
</div>
</div>
<div class="right_other">
<div class="panel">
<div class="panel_title">单位产品电耗趋势图</div>
<div class="chart" id="chart4"></div>
</div>
<div class="panel">
<div class="panel_title">产品产量趋势图</div>
<div class="chart" id="chart5"></div>
</div>
<div class="panel">
<div class="panel_title">运转率趋势图</div>
<div class="chart" id="chart6"></div>
</div>
</div>
</div>
</template>
<script>
import tool from "@/utils/tool";
import config from "@/config";
import * as echarts from "echarts";
import * as BABYLON from "babylonjs";
import * as BABYLON_GUI from "babylonjs-gui";
import * as BABYLON_GRID from "@/utils/gridMaterial";
import * as BABYLON_MATERIAL from "@/utils/babylonMaterial";
import "babylonjs-loaders";
import "animate.css";
export default {
data() {
return {
query: {
year_s: 2023,
month_s: 8,
type: "month_s",
page: 0,
},
factoryData: {},
sectionData: {},
nowDay: 1,
initialAlpha: -Math.PI / 0.89,
initialBeta: Math.PI / 3.3,
initialRadius: 18,
initialTarget: null,
// scene: null,
// myui: null,
// engine: null,
// camera: null,
is_mainviewpoint: false,
resizeTimeout: null,
loadedPercent: 0,
sectionNames: {
干渣库_primitive0: "电石渣",
原料磨及废气处理_primitive0: "原料磨",
: "回转窑",
煤粉制备_primitive1: "煤磨",
水泥磨房_primitive0: "水泥磨",
水泥储存及散装库_primitive2: "水泥包装",
// "停车场": "停车场"
},
factoryName: "",
showKgcet: true,
currentLightMesh: null,
activeSection: 2,
activeSectionName: "回转窑",
updateTime: "",
basicOption: {
color: "rgb(1,235,239)",
backgroundColor: "",
xAxis: {
data: ["一月", "二月", "三月", "四月", "五月", "六月"],
},
yAxis: { type: "value" },
series: [
{
name: "销量",
type: "bar",
barwidth: 10,
label: {
show: true,
position: "top",
},
itemStyle: {
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{ offset: 0, color: "#83bff6" },
{ offset: 0.5, color: "#188df0" },
{ offset: 1, color: "#188df0" },
]
),
},
emphasis: {
itemStyle: {
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{ offset: 0, color: "#2378f7" },
{ offset: 0.7, color: "#2378f7" },
{ offset: 1, color: "#83bff6" },
]
),
},
},
data: [],
},
],
grid: {
// 让图表占满容器
top: "10%",
left: "12%",
right: "0px",
bottom: "15%",
},
},
year_start: 0,
end_time: "",
start_time: "",
xAxisData: [],
arrMonth: [],
chart1Option: {},
chart2Option: {},
chart3Option: {},
chart4Option: {},
chart5Option: {},
chart6Option: {},
seriesData1: [0, 0, 0, 0, 0, 0],
seriesData2: [0, 0, 0, 0, 0, 0],
seriesData2_2: [0, 0, 0, 0, 0, 0],
seriesData3: [0, 0, 0, 0, 0, 0],
seriesData3_2: [0, 0, 0, 0, 0, 0],
seriesData4: [0, 0, 0, 0, 0, 0],
seriesData5: [0, 0, 0, 0, 0, 0],
seriesData6: [0, 0, 0, 0, 0, 0],
path: "ws://49.232.14.174:2226/ws/my/?token=",
ws: null,
mgroupValues: {
电石渣: { total: "0", elec: "0" },
原料磨: { total: "0", elec: "0" },
煤磨: { total: "0", elec: "0" },
回转窑: { total: "0", elec: "0" },
水泥磨: { total: "0", elec: "0" },
水泥包装: { total: "0", elec: "0" },
},
sectionDatas: {
回转窑: {
elec_consume_unit: 29,
total_production: 2541,
coal_consume_unit: 105,
run_rate: 100,
charts_ele: [30, 29, 28, 31, 28, 16],
charts_prod: [2530, 2698, 2600, 2550, 2610, 2000],
charts_rate: [100, 100, 100, 100, 100, 100],
},
电石渣: {
elec_consume_unit: 4,
total_production: 1523,
coal_consume_unit: "",
run_rate: 100,
charts_ele: [3, 6, 4, 7, 5, 3],
charts_prod: [2015, 2698, 2904, 2550, 2610, 1200],
charts_rate: [100, 100, 100, 100, 100, 100],
},
原料磨: {
elec_consume_unit: 15,
total_production: 3230,
coal_consume_unit: "",
run_rate: 100,
charts_ele: [16, 15, 17, 15, 16, 10],
charts_prod: [3204, 3500, 3385, 3461, 3359, 2000],
charts_rate: [100, 100, 100, 100, 100, 100],
},
煤磨: {
elec_consume_unit: 36,
total_production: 420,
coal_consume_unit: "",
run_rate: 100,
charts_ele: [35, 37, 36, 37, 36, 20],
charts_prod: [426, 445, 425, 449, 438, 265],
charts_rate: [100, 100, 100, 100, 100, 100],
},
水泥磨: {
elec_consume_unit: 35,
total_production: 3063,
coal_consume_unit: "",
run_rate: 100,
charts_ele: [35, 37, 36, 37, 36, 20],
charts_prod: [3204, 3500, 3385, 3461, 3359, 2000],
charts_rate: [100, 100, 100, 100, 100, 100],
},
水泥包装: {
elec_consume_unit: 2,
total_production: 1000,
coal_consume_unit: "",
run_rate: 100,
charts_ele: [1, 3, 2, 3, 2, 1],
charts_prod: [1052, 1462, 1268, 1389, 1156, 800],
charts_rate: [100, 100, 100, 100, 100, 100],
},
},
};
},
mounted() {
var that = this;
this.initCharts();
this.addListener();
let myDate = new Date();
let year = myDate.getFullYear();
let month = myDate.getMonth() + 1;
let day = myDate.getDate();
that.nowDay = day;
that.query.year_s = year;
that.query.month_s = month;
that.updateTime =
myDate.getFullYear() +
"-" +
(myDate.getMonth() + 1) +
"-" +
myDate.getDate() +
" " +
myDate.getHours() +
":" +
myDate.getMinutes() +
":" +
myDate.getSeconds();
this.factoryName = that.$TOOL.data.get("BASE_INFO").base.base_name;
this.initDomStyle();
this.$nextTick(() => {
this.$API.enm.enstat
.req({ type: "month_s", month_s: month, year_s: year, page: 0 })
.then((res1) => {
console.log("工段数据:", res1);
// debugger
res1.forEach((item) => {
if (item.mgroup_name == "电石渣") {
that.mgroupValues.电石渣.total =
item.total_production + "";
that.mgroupValues.电石渣.elec =
item.elec_consume_unit + "";
} else if (item.mgroup_name == "原料磨") {
that.mgroupValues.原料磨.total =
item.total_production + "";
that.mgroupValues.原料磨.elec =
item.elec_consume_unit + "";
} else if (item.mgroup_name == "煤磨") {
that.mgroupValues.煤磨.total =
item.total_production + "";
that.mgroupValues.煤磨.elec =
item.elec_consume_unit + "";
} else if (item.mgroup_name == "回转窑") {
that.mgroupValues.回转窑.total =
item.total_production + "";
that.mgroupValues.回转窑.elec =
item.elec_consume_unit + "";
} else if (item.mgroup_name == "水泥磨") {
that.mgroupValues.水泥磨.total =
item.total_production + "";
that.mgroupValues.水泥磨.elec =
item.elec_consume_unit + "";
} else if (item.mgroup_name == "水泥包装") {
that.mgroupValues.水泥包装.total =
item.total_production + "";
that.mgroupValues.水泥包装.elec =
item.elec_consume_unit + "";
}
});
});
setTimeout(function () {
that.initFactory();
}, 1000);
});
let month1 = month > 9 ? month : "0" + month;
let end_time = year + "-" + month1 + "-01 10:00:00";
let year_s = year;
if (month < 6) {
year_s = year - 1;
}
let arr = [],
xAxisData = [];
let monthItem = month;
for (let i = 0; i < 6; i++) {
arr.push(monthItem);
if (monthItem === 1) {
monthItem = 12;
} else {
monthItem--;
}
}
arr.reverse();
for (let i = 0; i < 6; i++) {
let item = arr[i] + "月";
xAxisData.push(item);
}
// 模拟数据
xAxisData = ["1.19", "1.20", "1.21", "1.22", "1.23", "1.24"];
let month0 = arr[0] > 9 ? arr[0] : "0" + arr[0];
let start_time = year_s + "-" + month0 + "-01 10:00:00";
that.arrMonth = arr;
that.year_start = year_s;
that.xAxisData = xAxisData;
that.start_time = start_time;
that.end_time = end_time;
this.getFactoryData();
this.getSectionData();
this.getDayData();
this.init();
setTimeout(() => {
this.getMockData();
}, 1000);
},
beforeUnmount() {
// 性能优化
const canvas = document.getElementById("renderCanvas");
if (canvas) {
canvas.parentNode.removeChild(canvas);
}
},
methods: {
// 动态绑定Class
bindClass(type) {
let classInfo = {
socketDom: true,
redColor: false,
orangeColor: false,
yellowColor: false,
blueColor: true,
};
if (type == "") {
classInfo.redColor = true;
}
return classInfo;
},
init() {
var that = this;
if (typeof WebSocket === "undefined") {
alert("您的浏览器不支持socket");
} else {
this.ws = new WebSocket(this.path + tool.data.get("TOKEN"));
//监听是否连接成功
this.ws.onopen = () => {
// console.log("socket连接成功");
setTimeout(() => {
that.ws.send(JSON.stringify({ type: "event" }));
}, 500);
};
//接听服务器发回的信息并处理展示
this.ws.onmessage = (msg) => {
let data = JSON.parse(msg.data);
console.log(data);
if (data.type == "event") {
that.bindClass();
}
if (data.type == "ticket") {
}
if (data.type == "remaind") {
}
};
// 监听并处理error事件
this.ws.onerror = function (error) {
console.log("ws断开,尝试重连");
// setTimeout(() => {
// this.ws = null;
// this.init()
// }, 5000)
};
}
},
getMessage(msg) {
console.log(msg);
},
close() {
if (this.ws) {
this.ws.close();
this.ws = null;
console.log("socket已经关闭");
}
},
compare(property) {
return function (a, b) {
return a[property] - b[property];
};
},
getMockData() {
let that = this;
this.factoryData = {
elec_consume: 10983267,
pcoal_consume: 9500,
water_consume: 12825,
cair_consume: 676534,
};
this.mgroupValues = {
电石渣: { total: 1523, elec: 4 },
原料磨: { total: 3230, elec: 15 },
煤磨: { total: 420, elec: 36 },
回转窑: { total: 2541, elec: 29 },
水泥磨: { total: 3063, elec: 35 },
水泥包装: { total: 1000, elec: 2 },
};
this.sectionData = this.sectionDatas[this.activeSectionName];
setInterval(() => {
this.factoryData.elec_consume += Math.floor(Math.random() * 10);
this.factoryData.pcoal_consume += Math.floor(
Math.random() * 10
);
this.factoryData.water_consume += Math.floor(
Math.random() * 10
);
this.factoryData.cair_consume += Math.floor(Math.random() * 10);
this.sectionDatas[this.activeSectionName].total_production +=
Math.floor(Math.random() * 10);
this.sectionDatas[this.activeSectionName].elec_consume_unit +=
Math.floor(Math.random() * 1);
this.sectionDatas[this.activeSectionName].charts_ele[5] =
this.sectionDatas[this.activeSectionName].elec_consume_unit;
this.sectionDatas[this.activeSectionName].charts_prod[5] =
this.sectionDatas[this.activeSectionName].total_production;
let data = new Date();
that.updateTime =
data.getFullYear() +
"-" +
(data.getMonth() + 1) +
"-" +
data.getDate() +
" " +
data.getHours() +
":" +
data.getMinutes() +
":" +
data.getSeconds();
}, 10000);
},
getFactoryData() {
var that = this;
that.$API.enm.enstat2.req(that.query).then((res) => {
if (res.length > 0) {
that.factoryData = res[0];
} else {
}
});
//图表数据
let obj = {};
obj.type = "month_s";
obj.start_time = that.start_time;
obj.end_time = that.end_time;
obj.page = 0;
this.$API.enm.enstat2.req(obj).then((res1) => {
let list0 = res1.sort(this.compare("month_s"));
let list = list0.sort(this.compare("year_s"));
let seriesData1 = [0, 0, 0, 0, 0, 0],
seriesData2 = [0, 0, 0, 0, 0, 0],
seriesData3 = [0, 0, 0, 0, 0, 0],
seriesData3_2 = [0, 0, 0, 0, 0, 0];
list.forEach((item) => {
let index = that.arrMonth.indexOf(item.month_s);
seriesData1[index] = Number(item.elec_consume);
seriesData2[index] = Number(item.pcoal_consume);
seriesData3[index] = Number(item.water_consume);
seriesData3_2[index] = Number(item.cair_consume);
});
that.seriesData1 = seriesData1;
that.seriesData2 = seriesData2;
that.seriesData3 = seriesData3;
that.seriesData3_2 = seriesData3_2;
// 模拟数据
that.seriesData1 = [
303468, 303524, 312095, 305684, 307468, 223420,
];
that.chart1Option.yAxis.min = 200000;
that.seriesData2 = [425, 430, 436, 430, 443, 340];
that.seriesData2_2 = [586, 560, 576, 555, 543, 205];
that.chart2Option.yAxis.min = 100;
that.seriesData3 = [20456, 24783, 21430, 22354, 25531, 15687];
// that.seriesData3 = [586, 560, 576, 555, 543, 205]
that.chart3Option.yAxis.min = 15000;
that.initCharts();
});
},
getSectionData() {
var that = this;
let obj = {};
obj.type = "month_s";
obj.start_time = that.start_time;
obj.end_time = that.end_time;
obj.mgroup__name = that.activeSectionName;
obj.page = 0;
this.$API.enm.enstat.req(obj).then((res) => {
let list0 = res.sort(this.compare("month_s"));
let list = list0.sort(this.compare("year_s"));
let seriesData4 = [0, 0, 0, 0, 0, 0],
seriesData5 = [0, 0, 0, 0, 0, 0],
seriesData6 = [0, 0, 0, 0, 0, 0];
list.forEach((item) => {
let index = that.arrMonth.indexOf(item.month_s);
seriesData4[index] = Number(item.elec_consume_unit);
seriesData5[index] = Number(item.total_production);
seriesData6[index] = Number(item.run_rate);
});
that.seriesData4 = seriesData4;
that.seriesData5 = seriesData5;
that.seriesData6 = seriesData6;
// 模拟数据
that.seriesData4 = this.sectionDatas.回转窑.charts_ele;
that.seriesData5 = this.sectionDatas.回转窑.charts_prod;
that.seriesData6 = this.sectionDatas.回转窑.charts_rate;
// that.chart4Option.yAxis.min = 200000;
// that.seriesData5 = [425, 430, 436, 430, 443, 340];
// that.chart5Option.yAxis.min = 300;
// that.seriesData6 = [586, 560, 576, 555, 543, 205]
// that.chart6Option.yAxis.min = 500;
that.initCharts1();
});
},
getDayData() {
var that = this;
let obj = {};
obj.type = "day_s";
obj.year_s = that.query.year_s;
obj.month_s = that.query.month_s;
obj.day_s = that.nowDay;
obj.mgroup__name = that.activeSectionName;
obj.page = 0;
this.$API.enm.enstat.req(obj).then((res) => {
that.sectionData = res[0];
});
},
initCharts() {
let that = this;
function deepCopy(obj) {
return JSON.parse(JSON.stringify(obj));
}
// 初始化所有表格
that.basicOption.xAxis.data = that.xAxisData;
that.chart1Option = deepCopy(that.basicOption);
that.chart1Option.series = [
{
name: "电耗",
type: "bar",
barWidth: 15,
label: {
show: true,
position: "top",
},
emphasis: {
focus: "series",
},
data: that.seriesData1,
},
];
that.setChart("chart1", that.chart1Option);
this.chart2Option = deepCopy(that.basicOption);
this.chart2Option.series[0].type = "line";
(this.chart2Option.series[1] = {
name: "工业水",
type: "line",
barWidth: 15,
label: {
show: true,
position: "top",
},
emphasis: {
focus: "series",
},
data: that.seriesData2_2,
}),
(this.chart2Option.series[0].data = that.seriesData2);
this.setChart("chart2", this.chart2Option);
this.chart3Option = deepCopy(that.basicOption);
this.chart3Option.series = [
{
name: "压缩空气",
type: "bar",
barWidth: 15,
emphasis: {
focus: "series",
},
data: that.seriesData3,
},
];
this.setChart("chart3", this.chart3Option);
},
initCharts1() {
let that = this;
function deepCopy(obj) {
return JSON.parse(JSON.stringify(obj));
}
that.basicOption.xAxis.data = that.xAxisData;
this.chart4Option = deepCopy(that.basicOption);
this.chart4Option.series[0].type = "bar";
this.chart4Option.series[0].barWidth = 20;
this.chart4Option.series[0].data = that.seriesData4;
this.setChart("chart4", this.chart4Option);
this.chart5Option = deepCopy(that.basicOption);
this.chart5Option.series[0].type = "line";
this.chart5Option.series[0].data = that.seriesData5;
this.setChart("chart5", this.chart5Option);
this.chart6Option = deepCopy(that.basicOption);
this.chart6Option.series[0].type = "bar";
this.chart6Option.series[0].barWidth = 20;
this.chart6Option.series[0].data = that.seriesData6;
this.setChart("chart6", this.chart6Option);
},
addListener() {
var that = this;
window.addEventListener("resize", function () {
// 如果已经有 resizeTimeout清除它
if (this.resizeTimeout) {
clearTimeout(this.resizeTimeout);
}
// 设置一个新的 resizeTimeout延迟调整样式
this.resizeTimeout = setTimeout(function () {
that.initDomStyle();
}, 300); // 延迟 300 毫秒,可以根据需要调整
});
},
initDomStyle() {
// 获取窗口的总高度
var windowHeight = window.innerHeight;
var windowWidth = window.innerWidth;
// 获取目标元素
var dashboard = document.getElementsByClassName("dashboard")[0];
var left_main = document.getElementsByClassName("left_main")[0];
var left_other = document.getElementsByClassName("left_other")[0];
var right_main = document.getElementsByClassName("right_main")[0];
var right_other = document.getElementsByClassName("right_other")[0];
var model = document.getElementsByClassName("model")[0];
// var renderCanvas = document.getElementById('renderCanvas');
if (windowWidth > 960) {
dashboard.style.overflow = "hidden";
// 设置目标元素的高度
left_main.style.position = "absolute";
left_main.style.width = "22%";
right_main.style.position = "absolute";
right_main.style.width = "22%";
left_other.style.position = "absolute";
left_other.style.width = "22%";
right_other.style.position = "absolute";
right_other.style.width = "22%";
model.style.position = "absolute";
model.style.height = windowHeight - 3 + "px";
model.style.top = 0;
var chartHeight = (windowHeight - 400) / 3 + "px";
var charts = document.getElementsByClassName("chart");
for (var i = 0; i < charts.length; i++) {
var chart = charts[i];
chart.style.height = chartHeight;
}
} else {
dashboard.style.overflow = "auto";
var chartHeight = windowWidth * 0.6;
left_main.style.position = "static";
left_main.style.width = "100%";
right_main.style.position = "static";
right_main.style.width = "100%";
left_other.style.position = "static";
left_other.style.width = "100%";
right_other.style.position = "static";
right_other.style.width = "100%";
model.style.position = "relative";
model.style.height = chartHeight;
var charts = document.getElementsByClassName("chart");
for (var i = 0; i < charts.length; i++) {
var chart = charts[i];
chart.style.height = chartHeight;
}
}
if (this.engine != null) {
this.engine.resize();
}
this.resizeChart("chart1");
this.resizeChart("chart2");
this.resizeChart("chart3");
this.resizeChart("chart4");
this.resizeChart("chart5");
this.resizeChart("chart6");
},
resizeChart(name) {
// 根据name resize chart
var myChart = echarts.getInstanceByDom(
document.getElementById(name)
);
if (myChart != undefined) {
// console.log(name + ' :resize')
myChart.resize();
}
},
setChart(name, option = null) {
// 根据name 渲染数据, option需填写否则option为模拟数据
var myChart = echarts.getInstanceByDom(
document.getElementById(name)
);
if (myChart == undefined) {
myChart = echarts.init(document.getElementById(name), "dark", {
renderer: "svg",
});
}
if (option == null) {
option = Object.assign({}, this.basicOption);
}
setTimeout(() => {
try {
myChart.setOption(option);
} catch (error) {}
}, 500);
},
handleSectionClick(val, index) {
let that = this;
this.activeSectionName = val;
this.activeSection = index;
if (val == "回转窑") {
this.showKgcet = true;
} else {
this.showKgcet = false;
}
let obj = {};
obj.type = "month_s";
obj.start_time = that.start_time;
obj.end_time = that.end_time;
obj.mgroup__name = val;
obj.page = 0;
this.$API.enm.enstat.req(obj).then((res) => {
let list0 = res.sort(this.compare("month_s"));
let list = list0.sort(this.compare("year_s"));
let seriesData4 = [0, 0, 0, 0, 0, 0],
seriesData5 = [0, 0, 0, 0, 0, 0],
seriesData6 = [0, 0, 0, 0, 0, 0];
list.forEach((item) => {
let index = that.arrMonth.indexOf(item.month_s);
seriesData4[index] = Number(item.elec_consume_unit);
seriesData5[index] = Number(item.total_production);
seriesData6[index] = Number(item.run_rate);
});
that.seriesData4 = seriesData4;
that.seriesData5 = seriesData5;
that.seriesData6 = seriesData6;
//模拟数据
that.seriesData4 =
this.sectionDatas[this.activeSectionName].charts_ele;
that.seriesData5 =
this.sectionDatas[this.activeSectionName].charts_prod;
that.seriesData6 =
this.sectionDatas[this.activeSectionName].charts_rate;
that.initCharts1();
const element_main = document.querySelector(".right_main");
element_main.classList.add(
"animate__animated",
"animate__fadeIn"
);
element_main.addEventListener("animationend", () => {
// 移除属性
element_main.classList.remove("animate__fadeIn");
});
const element = document.querySelector(".right_other");
element.classList.add("animate__animated", "animate__fadeIn");
element.addEventListener("animationend", () => {
// 移除属性
element.classList.remove("animate__fadeIn");
});
const sectionUI = this.myui.getControlByName(val + "_rect");
sectionUI.onPointerDownObservable.notifyObservers();
});
},
getMgroupChartData(name) {
let that = this;
this.sectionData = this.sectionDatas[this.activeSectionName];
//模拟数据
that.seriesData4 =
this.sectionDatas[this.activeSectionName].charts_ele;
that.seriesData5 =
this.sectionDatas[this.activeSectionName].charts_prod;
that.seriesData6 =
this.sectionDatas[this.activeSectionName].charts_rate;
that.initCharts1();
console.log(this.sectionData, this.activeSectionName);
// 模拟数据
// var that = this;
// let obj = {};
// obj.type = 'month_s';
// obj.start_time = that.start_time;
// obj.end_time = that.end_time;
// obj.mgroup__name = name;
// obj.page = 0;
// this.$API.enm.enstat.req(obj).then((res) => {
// let list0 = res.sort(this.compare('month_s'));
// let list = list0.sort(this.compare('year_s'));
// let seriesData4 = [0, 0, 0, 0, 0, 0],
// seriesData5 = [0, 0, 0, 0, 0, 0],
// seriesData6 = [0, 0, 0, 0, 0, 0];
// list.forEach(item => {
// let index = that.arrMonth.indexOf(item.month_s);
// seriesData4[index] = Number(item.elec_consume_unit)
// seriesData5[index] = Number(item.total_production)
// seriesData6[index] = Number(item.run_rate)
// })
// that.seriesData4 = seriesData4;
// that.seriesData5 = seriesData5;
// that.seriesData6 = seriesData6;
// that.initCharts1();
// })
},
initFactory() {
var that = this;
const canvas = document.getElementById("renderCanvas"); // Get the canvas element
const engine = new BABYLON.Engine(canvas, true); // Generate the BABYLON 3D engine
BABYLON.DefaultLoadingScreen.prototype.displayLoadingUI =
function () {};
BABYLON.DefaultLoadingScreen.prototype.hideLoadingUI = function () {
document.getElementById("loadingScreen").style.display = "none";
};
engine.displayLoadingUI();
// Add your code here matching the playground format
const createScene = function () {
const scene = new BABYLON.Scene(engine);
scene.clearColor = BABYLON.Color3.Black(); //BABYLON.Color3(1, 0, 1);
const ground = BABYLON.MeshBuilder.CreateGround("ground", {
width: 100,
height: 100,
});
const groundMaterial = new BABYLON_GRID.GridMaterial(
"groundMaterial",
scene
);
groundMaterial.majorUnitFrequency = 5;
groundMaterial.minorUnitVisibility = 0.5;
groundMaterial.gridRatio = 2;
// groundMaterial.opacity = 0.99;
ground.material = groundMaterial;
ground.position.y = -0.1;
// 加载背景图片
// const backgroundImage = new BABYLON.Layer('', 'img/bj.png', scene, true);
const camera = new BABYLON.ArcRotateCamera(
"camera",
that.initialAlpha,
that.initialBeta,
that.initialRadius,
new BABYLON.Vector3(0, 0, 1.2)
);
that.camera = camera;
that.initialTarget = camera.getTarget();
camera.upperBetaLimit = Math.PI / 2.3; //无法移动到地面以下
camera.attachControl(canvas, true);
camera.maxZ = 1000; // 调整适当的值
// 相机限制
camera.lowerRadiusLimit = 6;
camera.upperRadiusLimit = 18;
// 灯光
const light = new BABYLON.HemisphericLight(
"light",
new BABYLON.Vector3(1, 1, 0)
);
light.intensity = 1.6;
// skybox
const skybox = BABYLON.MeshBuilder.CreateBox(
"skyBox",
{ size: 150 },
scene
);
var skyboxMaterial = new BABYLON_MATERIAL.SkyMaterial(
"skyMaterial",
scene
);
skyboxMaterial.backFaceCulling = false;
skybox.material = skyboxMaterial;
/*
* Keys:
* - 1: Day
* - 2: Evening
* - 3: Increase Luminance
* - 4: Decrease Luminance
* - 5: Increase Turbidity
* - 6: Decrease Turbidity
* - 7: Move horizon to -50
* - 8: Restore horizon to 0
*/
var setSkyConfig = function (property, from, to) {
var keys = [
{ frame: 0, value: from },
{ frame: 100, value: to },
];
var animation = new BABYLON.Animation(
"animation",
property,
100,
BABYLON.Animation.ANIMATIONTYPE_FLOAT,
BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT
);
animation.setKeys(keys);
scene.stopAnimation(skybox);
scene.beginDirectAnimation(
skybox,
[animation],
0,
100,
false,
1
);
};
window.addEventListener("keydown", function (evt) {
switch (evt.keyCode) {
case 49:
setSkyConfig(
"material.inclination",
skyboxMaterial.inclination,
0
);
break; // 1
case 50:
setSkyConfig(
"material.inclination",
skyboxMaterial.inclination,
-0.5
);
break; // 2
case 51:
setSkyConfig(
"material.luminance",
skyboxMaterial.luminance,
0.1
);
break; // 3
case 52:
setSkyConfig(
"material.luminance",
skyboxMaterial.luminance,
1.0
);
break; // 4
case 53:
setSkyConfig(
"material.turbidity",
skyboxMaterial.turbidity,
40
);
break; // 5
case 54:
setSkyConfig(
"material.turbidity",
skyboxMaterial.turbidity,
5
);
break; // 6
case 55:
setSkyConfig(
"material.cameraOffset.y",
skyboxMaterial.cameraOffset.y,
50
);
break; // 7
case 56:
setSkyConfig(
"material.cameraOffset.y",
skyboxMaterial.cameraOffset.y,
0
);
break; // 8
default:
break;
}
});
// Set to Day
setSkyConfig(
"material.inclination",
skyboxMaterial.inclination,
0
);
// 全屏GUI
const advancedTexture =
BABYLON_GUI.AdvancedDynamicTexture.CreateFullscreenUI(
"myUI"
);
that.myui = advancedTexture;
// 创建一个高亮层
const highlightLayer = new BABYLON.HighlightLayer(
"highlightLayer",
scene
);
// 主控制区
var control_main = new BABYLON_GUI.StackPanel();
control_main.isVertical = false;
control_main.top = "-40%";
control_main.left = "-20%";
advancedTexture.addControl(control_main);
var button_main = BABYLON_GUI.Button.CreateSimpleButton(
"button_main",
"主视角"
);
button_main.width = "80px";
button_main.height = "30px";
button_main.color = "white";
button_main.cornerRadius = 20;
button_main.background = "green";
control_main.addControl(button_main);
button_main.onPointerClickObservable.add(() => {
that.flyToMesh();
});
// 高亮显示mesh名
const mesh_rect = new BABYLON_GUI.Rectangle("mesh_rect");
mesh_rect.width = "100px";
mesh_rect.height = "25px";
mesh_rect.background = "orange";
mesh_rect.alpha = 0.6;
mesh_rect.isVisible = false;
advancedTexture.addControl(mesh_rect);
var mesh_name = new BABYLON_GUI.TextBlock("mesh_name");
mesh_name.text = "";
mesh_name.color = "white";
mesh_name.fontSize = "14px";
mesh_rect.addControl(mesh_name);
var remoteGlbUrl = config.HOST_URL + "/media/model/factory.glb";
// var remoteGlbUrl = process.env.VUE_APP_BASEURL + "/media/model/factory.glb";
BABYLON.SceneLoader.Append(
remoteGlbUrl,
"",
scene,
function (scene) {
// debugger;
// console.log(scene)
// console.table(scene.meshes)
// 判断字符串是否包含中文------ /[\u4E00-\u9FA5]+/g.test(str)
for (let key in that.sectionNames) {
const value = that.sectionNames[key];
const mesh = scene.getMeshByName(key);
if (mesh) {
//建筑标签
that.createLabelPanel(value, mesh);
// 创建一个工段数据展示panel
const info = { name: value,
rows:[{label: "产品产量(t)", field: "total_production", value: 100},
{label: "运转率(%)", field: "run_rate", value: 100},
{label: "单位电耗(kwh)", field: "elec_consume_unit", value: 100}
] };
that.createDetailPanel(info, mesh);
}
}
engine.hideLoadingUI();
},
function (evt) {
var loadedPercent = 0;
if (evt.lengthComputable) {
loadedPercent = parseInt(
(evt.loaded * 100) / evt.total
);
} else {
var dlCount = evt.loaded / (1024 * 1024);
loadedPercent = Math.floor(dlCount * 100.0) / 100.0;
}
that.loadedPercent = loadedPercent;
}
);
// 自动旋转checkbox
var checkbox = new BABYLON_GUI.Checkbox();
checkbox.width = "20px";
checkbox.height = "20px";
checkbox.isChecked = false;
checkbox.marginLeft = "16px";
checkbox.color = "green";
checkbox.onIsCheckedChangedObservable.add(function (value) {
if (value) {
camera.useAutoRotationBehavior = true;
} else {
camera.useAutoRotationBehavior = false;
}
});
control_main.addControl(checkbox);
var header = new BABYLON_GUI.TextBlock();
header.text = "自动旋转";
header.width = "80px";
header.textHorizontalAlignment =
BABYLON_GUI.Control.HORIZONTAL_ALIGNMENT_LEFT;
header.color = "white";
control_main.addControl(header);
// 工段数据checkbox
var checkbox1 = new BABYLON_GUI.Checkbox();
checkbox1.width = "20px";
checkbox1.height = "20px";
checkbox1.isChecked = true;
checkbox1.marginLeft = "16px";
checkbox1.color = "green";
checkbox1.onIsCheckedChangedObservable.add(function (value) {
// debugger;
if (value) {
for (let key in that.sectionNames) {
let name = that.sectionNames[key] + "_data_view";
console.log(name);
let dataView =
advancedTexture.getControlByName(name);
dataView.isVisible = true;
}
} else {
for (let key in that.sectionNames) {
let name = that.sectionNames[key] + "_data_view";
console.log(name);
let dataView =
advancedTexture.getControlByName(name);
dataView.isVisible = false;
}
}
});
control_main.addControl(checkbox1);
var header1 = new BABYLON_GUI.TextBlock();
header1.text = "工段数据";
header1.width = "80px";
header1.textHorizontalAlignment =
BABYLON_GUI.Control.HORIZONTAL_ALIGNMENT_LEFT;
header1.color = "white";
control_main.addControl(header1);
// 添加抓取事件
canvas.addEventListener("mousemove", (event) => {
// 使用 scene.pick 检测鼠标拾取
const pickResult = scene.pick(
scene.pointerX,
scene.pointerY
);
if (that.currentLightMesh) {
mesh_rect.isVisible = false;
highlightLayer.removeAllMeshes();
}
if (pickResult.hit) {
const mesh = pickResult.pickedMesh;
highlightLayer.removeAllMeshes();
if (
/.*[\u4e00-\u9fa5]+.*$/.test(mesh.name) &&
mesh.name !== "地面1" &&
mesh.name !== "绿地" &&
mesh.name !== "停车场"
) {
// 在选中的 mesh 上添加高亮效果
highlightLayer.addMesh(
mesh,
new BABYLON.Color3(1, 1, 0.5)
);
that.currentLightMesh = mesh;
mesh_rect.linkWithMesh(mesh);
let name = mesh.name.split("_")[0];
mesh_name.text = name;
mesh_rect.isVisible = true;
}
}
});
// checkbox.isChecked = true; //默认开启自动旋转
return scene;
};
const scene = createScene(); //Call the createScene function
// // scene.debugLayer.show()
// // Register a render loop to repeatedly render the scene
engine.runRenderLoop(function () {
scene.render();
});
this.engine = engine;
this.scene = scene;
// Watch for browser/canvas resize events
window.addEventListener("resize", function () {
engine.resize();
});
},
flyToMesh(mesh = undefined) {
// 不传mesh默认回到初始位置
let that = this;
const camera = that.camera;
if (mesh == undefined) {
if (
camera.alpha != that.initialAlpha ||
camera.beta != that.initialBeta ||
camera.radius != that.initialRadius
) {
let cameraPosition = new BABYLON.Vector3(
0 +
that.initialRadius *
Math.sin(that.initialBeta) *
Math.cos(that.initialAlpha),
0 + that.initialRadius * Math.cos(that.initialBeta),
0 +
that.initialRadius *
Math.sin(that.initialBeta) *
Math.sin(that.initialAlpha)
);
let position = that.initialTarget;
var ease = new BABYLON.CubicEase();
ease.setEasingMode(BABYLON.EasingFunction.EASINGMODE_EASEINOUT);
BABYLON.Animation.CreateAndStartAnimation(
"at5",
camera,
"position",
45,
200,
camera.position,
cameraPosition,
0,
ease
);
BABYLON.Animation.CreateAndStartAnimation(
"at51",
camera,
"target",
45,
200,
camera.target,
position,
0,
ease
);
}
} else if (camera.target != mesh.position) {
console.log('fly to')
// 计算新的相机位置
let position = mesh._parentNode._position;
if (mesh._parentNode.id == "__root__") {
position = mesh.position;
}
let cameraPosition = new BABYLON.Vector3(
mesh.position.x +
9 * Math.sin(camera.beta) * Math.cos(Math.PI),
mesh.position.y + 9 * Math.cos(camera.beta),
mesh.position.z +
9 * Math.sin(camera.beta) * Math.sin(Math.PI)
);
var ease = new BABYLON.CubicEase();
ease.setEasingMode(BABYLON.EasingFunction.EASINGMODE_EASEINOUT);
BABYLON.Animation.CreateAndStartAnimation(
"at5",
camera,
"position",
45,
200,
camera.position,
cameraPosition,
0,
ease
);
BABYLON.Animation.CreateAndStartAnimation(
"at51",
camera,
"target",
45,
200,
camera.target,
position,
0,
ease
);
}
},
createLabelPanel(value, mesh) {
let that = this;
let advancedTexture = that.myui;
const rect1 = new BABYLON_GUI.Rectangle(value + "_rect");
rect1.width = "64px";
rect1.height = "30px";
rect1.cornerRadius = 1;
rect1.thickness = 0;
rect1.background = "rgba(0, 128, 0, 0.8)";
rect1.isPointerBlocker = true; // 防止点击穿透
advancedTexture.addControl(rect1);
var label = new BABYLON_GUI.TextBlock(value + "_label");
label.text = value;
label.color = "white";
label.fontSize = "14px";
rect1.addControl(label);
rect1.linkWithMesh(mesh);
rect1.linkOffsetY = -30;
if (value == "电石渣") {
rect1.linkOffsetY = -200;
var line = new BABYLON_GUI.Line();
line.lineWidth = 4;
line.color = "Orange";
line.y1 = 10;
line.y2 = 15;
line.linkOffsetY = -15;
line.dash = [3, 3];
advancedTexture.addControl(line);
line.linkWithMesh(mesh);
let connectedControl =
advancedTexture.getControlByName("电石渣_rect");
line.connectedControl = connectedControl;
}
rect1.onPointerDownObservable.add(() => {
const mesh = rect1.linkedMesh;
that.flyToMesh(mesh);
// let dataViewName = rect1.name.split('_')[0] + '_data_view';
let dataViewName = rect1.name.split("_")[0];
that.activeSectionName = dataViewName;
that.activeSection = 2;
that.getMgroupChartData(dataViewName);
let dataView = that.myui.getControlByName(
dataViewName + "_data_view"
);
if (dataView) {
// // 在这里进行矩形的操作
dataView.isVisible = true;
}
});
},
// 创建3D数据展示层GUI
createDetailPanel(info, mesh) {
// info格式{"name": "xxx",
//"rows": ["label": "xxx1", "field": "ccc", "value": 123, "type": "primary"]}
let that = this;
const data_view = new BABYLON_GUI.StackPanel(
info.name + "_data_view"
);
data_view.width = "200px"; // StackPanel的宽度
// data_view.height = "140px";
data_view.background = "rgba(0, 34, 51, 0.6)"; //暗色
const mgroup_line = new BABYLON_GUI.Rectangle(info.name + "_line");
mgroup_line.height = "3px";
mgroup_line.width = "200px";
mgroup_line.thickness = 0;
mgroup_line.background = "rgba(44, 237, 255, 0.8)";
data_view.addControl(mgroup_line);
const header = new BABYLON_GUI.StackPanel(info.name + "_header");
header.width = "200px";
header.height = "30px";
// header.background = "rgba(0, 34, 51, 0.6)";
header.isVertical = false;
const mgroupName = new BABYLON_GUI.TextBlock(info.name + "_label");
mgroupName.height = "30px";
mgroupName.width = "175px";
mgroupName.color = "white";
mgroupName.text = info.name;
mgroupName.textHorizontalAlignment = 0;
mgroupName.paddingLeft = "8px";
header.addControl(mgroupName);
const mgroup_close = BABYLON_GUI.Button.CreateSimpleButton(
info.name + "_close",
"X"
);
mgroup_close.width = "25px";
mgroup_close.height = "25px";
mgroup_close.color = "rgb(255,165,0,0.7)";
mgroup_close.cornerRadius = 16;
mgroup_close.fontSize = "12px";
mgroup_close.thickness = 0;
// mgroup_close.background = "white";
mgroup_close.onPointerClickObservable.add(() => {
data_view.isVisible = false;
});
header.addControl(mgroup_close);
data_view.addControl(header);
info.rows.forEach((item, index)=>{
const row = new BABYLON_GUI.StackPanel(info.name + `_${item.field}` + "_row");
row.width = "200px";
row.height = "30px";
row.isVertical = false;
const field = new BABYLON_GUI.TextBlock(info.name + `_${item.field}` + "_label");
field.width = "120px";
field.height = "30px";
field.color = "rgba(255,255,255, 0.7)";
field.fontSize = 14;
field.text = item.label;
field.textHorizontalAlignment = 0;
field.paddingLeft = "8px";
row.addControl(field);
const valx = new BABYLON_GUI.TextBlock(info.name + `_${item.field}` + "_value");
valx.width = "80px";
valx.height = "30px";
valx.color = "white";
valx.fontSize = 14;
valx.text = item.value;
valx.textHorizontalAlignment = BABYLON_GUI.Control.HORIZONTAL_ALIGNMENT_RIGHT;
valx.paddingRight = "8px";
row.addControl(valx);
data_view.addControl(row);
})
// 将StackPanel添加到GUI系统中
that.myui.addControl(data_view);
data_view.linkWithMesh(mesh);
data_view.linkOffsetY = -120;
if (info.name == "电石渣") {
data_view.linkOffsetY = -290;
}
},
},
unmounted() {
this.close();
window.removeEventListener("resize", ()=>{this.engine.resize()});
},
};
</script>
<style scoped>
.dashboard {
background-color: black;
/* background-color: #0b2e4a; */
font-family: Inter, "-apple-system", BlinkMacSystemFont, "PingFang SC",
"Hiragino Sans GB", "noto sans", "Microsoft YaHei", "Helvetica Neue",
Helvetica, Arial, sans-serif;
}
header {
position: relative;
z-index: 10;
height: 50px;
/* 调整头部高度 */
background-image: url("/public/img/header.png");
/* 替换为实际的背景图片路径 */
background-size: cover;
background-position: center;
display: flex;
justify-content: space-between;
align-items: center;
}
.title_left {
flex: 1;
}
.title {
flex: 1;
text-align: center;
color: white;
font-size: 24px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
}
.title_right {
flex: 1;
font-size: 20px;
color: white;
text-align: right;
}
.model {
top: 0;
width: 100%;
background-image: url("/public/img/bj.png");
background-size: cover;
}
#renderCanvas {
width: 100%;
height: 100%;
}
#loadingScreen {
position: absolute;
width: 100%;
top: 260px;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 30px;
}
.left_main,
.right_main {
z-index: 10;
position: absolute;
top: 40px;
width: 20%;
}
.right_main {
right: 0;
}
.left_other,
.right_other {
position: absolute;
top: 240px;
width: 20%;
}
.right_other {
right: 0;
}
.panel {
padding: 4px 8px;
overflow: auto;
background: linear-gradient(#99fffe, #99fffe) left -3px top 0,
linear-gradient(#99fffe, #99fffe) left -3px top -3px,
linear-gradient(#99fffe, #99fffe) right -3px top 0,
linear-gradient(#99fffe, #99fffe) right -3px top -3px,
linear-gradient(#99fffe, #99fffe) left -3px bottom 0,
linear-gradient(#99fffe, #99fffe) left -3px bottom -3px,
linear-gradient(#99fffe, #99fffe) right -3px bottom 0,
linear-gradient(#99fffe, #99fffe) right -3px bottom -3px;
background-color: rgba(0, 34, 51, 0.5);
background-repeat: no-repeat;
background-size: 20px 20px, 20px 20px;
background-size: 3px 16px, 16px 3px;
border: 1px solid transparent;
margin: 6px 6px;
}
.panel_title {
height: 30px;
margin-bottom: 4px;
font-size: 18px;
font-weight: bold;
color: #fff;
}
.panel_item {
color: #fff;
padding: 6px;
background: linear-gradient(
40deg,
rgba(11, 101, 140, 0.451),
rgba(0, 34, 48, 0.335)
);
}
.panel_label {
font-size: 16px;
margin-bottom: 6px;
}
.pannel_number {
position: relative;
}
.panel_value {
padding-left: 1em;
font-size: 20px;
font-weight: bold;
text-align: right;
}
.panel_unit {
right: 5px;
color: #aebfe9;
font-size: 12px;
text-align: right;
position: absolute;
}
.chart {
width: 100%;
height: 220px;
}
.dropdown {
/* top: 20%;
font-size: 18px;
right: 22%;
position: absolute; */
bottom: 3%;
font-size: 18px;
left: 50%;
position: absolute;
transform: translateX(-50%);
}
/* .dropdown-item {
padding: 12px 16px;
text-decoration: none;
display: block;
color: white;
background: linear-gradient(40deg, rgba(11, 101, 140, 0.451), rgba(0, 25, 36, 0.335));
border-radius: 5%;
margin-bottom: 6px;
border: 1px solid #99fffe;
}
*/
.dropdown-item {
text-decoration: none;
display: inline-block;
color: white;
width: 8vw;
height: 3.4vw;
font-size: 1vw;
text-align: center;
background: url(./../../../public/img/menu.png) no-repeat;
background-size: 100%;
line-height: 3.7vw;
margin: 0 0.1vw 0.1vw 0.1vw;
}
.dropdown-item:hover,
.dropdown-item.active {
/* background-color: #ddd; */
width: 8.2vw;
height: 3.5vw;
font-size: 1vw;
line-height: 3.7vw;
margin: 0;
text-decoration: none;
display: inline-block;
color: white;
text-align: center;
background: url(./../../../public/img/menu_active.png) no-repeat;
background-size: 100%;
}
</style>