|
|
@@ -0,0 +1,1527 @@
|
|
|
+<template>
|
|
|
+ <vue-fullscreen
|
|
|
+ class="box-container"
|
|
|
+ v-model="isFullscreen"
|
|
|
+ fullscreenClass="box-container"
|
|
|
+ :exit-on-click-wrapper="false"
|
|
|
+ v-cloak
|
|
|
+ >
|
|
|
+ <div class="box-container">
|
|
|
+ <div class="box-header">
|
|
|
+ <div class="logo">
|
|
|
+ <!-- <img src="../../../assets/logo_1.png" alt="" />
|
|
|
+ <span>株硬集团型材分公司</span> -->
|
|
|
+ </div>
|
|
|
+ <div class="title"> 型材设备信息看板 </div>
|
|
|
+ <div class="time">
|
|
|
+ <span
|
|
|
+ style="color: #7fa7ce; margin: 5px 10px 15px 0; cursor: pointer"
|
|
|
+ @click.passive="onFullscreen"
|
|
|
+ >
|
|
|
+ <i
|
|
|
+ v-if="isFullscreen"
|
|
|
+ title="取消全屏"
|
|
|
+ class="el-icon-_screen-restore"
|
|
|
+ ></i>
|
|
|
+ <i v-else title="全屏" class="el-icon-_screen-full"></i>
|
|
|
+ </span>
|
|
|
+ <div style="margin-right: 10px">
|
|
|
+ <span style="color: #7fa7ce">{{ date }}</span>
|
|
|
+ <span style="color: rgb(210 215 221); padding: 0 5px">{{
|
|
|
+ time
|
|
|
+ }}</span>
|
|
|
+ <span style="color: #7fa7ce">{{ week }} </span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="top_bar">
|
|
|
+ <div class="runDeviceInfo">
|
|
|
+ <div
|
|
|
+ >运行设备<span style="">{{ totalData.total }}</span
|
|
|
+ >台</div
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ <div class="faultDeviceInfo">
|
|
|
+ <div
|
|
|
+ >故障维修设备<span>{{ totalData.repairNum }}</span
|
|
|
+ >台</div
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="echarts_bar">
|
|
|
+ <div class="title">
|
|
|
+ <div>
|
|
|
+ <span>设备使用情况</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="echartsList">
|
|
|
+ <div>
|
|
|
+ <div class="echarts_title"
|
|
|
+ >混合料设备总台数<span> {{ totalData.mixedDeviceNum }} </span
|
|
|
+ >台</div
|
|
|
+ >
|
|
|
+ <div class="echarts_box" ref="pie3d_3"></div>
|
|
|
+ <div class="space"></div>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <div class="space"></div>
|
|
|
+ <div class="echarts_title"
|
|
|
+ >成型设备总台数<span> {{ totalData.moldingDeviceNum }} </span
|
|
|
+ >台</div
|
|
|
+ >
|
|
|
+ <div class="echarts_box" ref="pie3d_4"></div>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <div class="echarts_title"
|
|
|
+ >烧结设备总台数<span> {{ totalData.sinteringDeviceNum }} </span
|
|
|
+ >台</div
|
|
|
+ >
|
|
|
+ <div class="echarts_box" ref="pie3d_5"></div>
|
|
|
+ <div class="space"></div>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <div class="echarts_title"
|
|
|
+ >深加设备总台数<span> {{ totalData.deepAddingDeviceNum }} </span
|
|
|
+ >台</div
|
|
|
+ >
|
|
|
+ <div class="echarts_box" ref="pie3d_1"></div>
|
|
|
+ <div class="space"></div>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <div class="space"></div>
|
|
|
+ <div class="echarts_title"
|
|
|
+ >质检设备总台数<span> {{ totalData.inspectionDeviceNum }} </span
|
|
|
+ >台</div
|
|
|
+ >
|
|
|
+ <div class="echarts_box" ref="pie3d_2"></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="table_bar">
|
|
|
+ <div class="title">
|
|
|
+ <div>
|
|
|
+ <span>设备故障维修列表</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="table"> </div>
|
|
|
+ <dv-scroll-board
|
|
|
+ v-if="isFlag"
|
|
|
+ :config="config"
|
|
|
+ style="width: 90%; height: 87%; transform: translate(5%, 1%)"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- <button type="button" @click="toggle">{{ fullscreen?"退出":"进入" }}全屏</button>-->
|
|
|
+ </vue-fullscreen>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+ import dvBorderContent from './dv-border-content.vue';
|
|
|
+ import * as echarts from 'echarts';
|
|
|
+ import 'echarts-gl';
|
|
|
+ import { component } from 'vue-fullscreen';
|
|
|
+ import { getRepairWorkList, statisticsDeviceStatus } from '@/api/equipment';
|
|
|
+ export default {
|
|
|
+ name: 'index',
|
|
|
+ components: {
|
|
|
+ dvBorderContent,
|
|
|
+ VueFullscreen: component
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ contentWidth() {
|
|
|
+ return this.$store.state.theme.contentWidth;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ isFullscreen: {
|
|
|
+ handler() {
|
|
|
+ this.isFlag = false;
|
|
|
+ this.$nextTick(() => {
|
|
|
+ let { clientWidth: deviceWidth, clientHeight: deviceHeight } =
|
|
|
+ document.documentElement;
|
|
|
+ let eleAdminHeaderHeight =
|
|
|
+ (!this.isFullscreen &&
|
|
|
+ document.getElementsByClassName('ele-admin-header')[0]
|
|
|
+ ?.offsetHeight) ||
|
|
|
+ 0;
|
|
|
+ let eleAdminSidebarWidth =
|
|
|
+ (!this.isFullscreen &&
|
|
|
+ document.getElementsByClassName('ele-admin-sidebar')[0]
|
|
|
+ ?.offsetWidth) ||
|
|
|
+ 0;
|
|
|
+ let eleAdminTabsWidth =
|
|
|
+ (!this.isFullscreen &&
|
|
|
+ document.getElementsByClassName('ele-admin-tabs')[0]
|
|
|
+ ?.offsetHeight) ||
|
|
|
+ 0;
|
|
|
+
|
|
|
+ const setContainerSize = (item) => {
|
|
|
+ item.style.height =
|
|
|
+ deviceHeight - eleAdminHeaderHeight - eleAdminTabsWidth + 'px';
|
|
|
+ item.style.width = deviceWidth - eleAdminSidebarWidth + 'px';
|
|
|
+ };
|
|
|
+ let boxContainer = [
|
|
|
+ ...document.getElementsByClassName('box-container')
|
|
|
+ ];
|
|
|
+ boxContainer.forEach(setContainerSize);
|
|
|
+
|
|
|
+ document.documentElement.style.fontSize = this.isFullscreen
|
|
|
+ ? '18px'
|
|
|
+ : '16px';
|
|
|
+ this.isFlag = true;
|
|
|
+
|
|
|
+ this.$nextTick(() => {
|
|
|
+ statisticsDeviceStatus().then((data) => {
|
|
|
+ console.log(data);
|
|
|
+ this.totalData = data;
|
|
|
+ this.initCircle(
|
|
|
+ this.$refs.pie3d_1,
|
|
|
+ data.deepAddingDeviceNum,
|
|
|
+ data.deepAddingDeviceNum1
|
|
|
+ );
|
|
|
+ this.initCircle(
|
|
|
+ this.$refs.pie3d_2,
|
|
|
+ data.inspectionDeviceNum,
|
|
|
+ data.inspectionDeviceNum1
|
|
|
+ );
|
|
|
+ this.initCircle(
|
|
|
+ this.$refs.pie3d_3,
|
|
|
+ data.mixedDeviceNum,
|
|
|
+ data.mixedDeviceNum1
|
|
|
+ );
|
|
|
+ this.initCircle(
|
|
|
+ this.$refs.pie3d_4,
|
|
|
+ data.moldingDeviceNum,
|
|
|
+ data.moldingDeviceNum1
|
|
|
+ );
|
|
|
+ this.initCircle(
|
|
|
+ this.$refs.pie3d_5,
|
|
|
+ data.sinteringDeviceNum,
|
|
|
+ data.sinteringDeviceNum1
|
|
|
+ );
|
|
|
+ });
|
|
|
+ // this.initChartR2();
|
|
|
+ // let chartDom = this.$refs.monthly_sales_volume;
|
|
|
+ // this.salesChart = echarts.init(chartDom);
|
|
|
+ // let chartDom2 = this.$refs.monthly_output;
|
|
|
+ // this.outputChart = echarts.init(chartDom2);
|
|
|
+ // this.getMonthlySalesStatistic();
|
|
|
+ // this.getMonthlyProduceStatistic();
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ immediate: true
|
|
|
+ },
|
|
|
+ contentWidth: {
|
|
|
+ handler() {
|
|
|
+ this.isFlag = false;
|
|
|
+ this.$nextTick(() => {
|
|
|
+ let { clientWidth: deviceWidth, clientHeight: deviceHeight } =
|
|
|
+ document.documentElement;
|
|
|
+ let eleAdminHeaderHeight =
|
|
|
+ (!this.isFullscreen &&
|
|
|
+ document.getElementsByClassName('ele-admin-header')[0]
|
|
|
+ ?.offsetHeight) ||
|
|
|
+ 0;
|
|
|
+ let eleAdminSidebarWidth =
|
|
|
+ (!this.isFullscreen &&
|
|
|
+ document.getElementsByClassName('ele-admin-sidebar')[0]
|
|
|
+ ?.offsetWidth) ||
|
|
|
+ 0;
|
|
|
+ let eleAdminTabsWidth =
|
|
|
+ (!this.isFullscreen &&
|
|
|
+ document.getElementsByClassName('ele-admin-tabs')[0]
|
|
|
+ ?.offsetHeight) ||
|
|
|
+ 0;
|
|
|
+ const setContainerSize = (item) => {
|
|
|
+ item.style.height =
|
|
|
+ deviceHeight - eleAdminHeaderHeight - eleAdminTabsWidth + 'px';
|
|
|
+ item.style.width = deviceWidth - eleAdminSidebarWidth + 'px';
|
|
|
+ };
|
|
|
+ let boxContainer = [
|
|
|
+ ...document.getElementsByClassName('box-container')
|
|
|
+ ];
|
|
|
+ boxContainer.forEach(setContainerSize);
|
|
|
+ document.documentElement.style.fontSize = this.isFullscreen
|
|
|
+ ? '18px'
|
|
|
+ : '16px';
|
|
|
+ this.isFlag = true;
|
|
|
+ this.$nextTick(() => {
|
|
|
+ statisticsDeviceStatus().then((data) => {
|
|
|
+ console.log(data);
|
|
|
+ this.totalData = data;
|
|
|
+ this.initCircle(
|
|
|
+ this.$refs.pie3d_1,
|
|
|
+ data.deepAddingDeviceNum,
|
|
|
+ data.deepAddingDeviceNum1
|
|
|
+ );
|
|
|
+ this.initCircle(
|
|
|
+ this.$refs.pie3d_2,
|
|
|
+ data.inspectionDeviceNum,
|
|
|
+ data.inspectionDeviceNum1
|
|
|
+ );
|
|
|
+ this.initCircle(
|
|
|
+ this.$refs.pie3d_3,
|
|
|
+ data.mixedDeviceNum,
|
|
|
+ data.mixedDeviceNum1
|
|
|
+ );
|
|
|
+ this.initCircle(
|
|
|
+ this.$refs.pie3d_4,
|
|
|
+ data.moldingDeviceNum,
|
|
|
+ data.moldingDeviceNum1
|
|
|
+ );
|
|
|
+ this.initCircle(
|
|
|
+ this.$refs.pie3d_5,
|
|
|
+ data.sinteringDeviceNum,
|
|
|
+ data.sinteringDeviceNum1
|
|
|
+ );
|
|
|
+ });
|
|
|
+ // this.initChartR2();
|
|
|
+ // let chartDom = this.$refs.monthly_sales_volume;
|
|
|
+ // this.salesChart = echarts.init(chartDom);
|
|
|
+ // let chartDom2 = this.$refs.monthly_output;
|
|
|
+ // this.outputChart = echarts.init(chartDom2);
|
|
|
+ // this.getMonthlySalesStatistic();
|
|
|
+ // this.getMonthlyProduceStatistic();
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ immediate: true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ deactivated() {
|
|
|
+ clearInterval(this.updateTimer);
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ totalData: {},
|
|
|
+ isFullscreen: false, // 是否是全屏
|
|
|
+ isFlag: false, // 是否展示图表
|
|
|
+ date: '',
|
|
|
+ time: '',
|
|
|
+ week: '',
|
|
|
+ signedTotal: 0,
|
|
|
+ deliveryTotal: 0,
|
|
|
+ salesTotal: 0,
|
|
|
+ WeightGainTotal: 0,
|
|
|
+ WeightStorageTotal: 0,
|
|
|
+ salesChart: null,
|
|
|
+ outputChart: null,
|
|
|
+ orderStatusOptions: {
|
|
|
+ 0: '待接收',
|
|
|
+ 1: '已接收',
|
|
|
+ 2: '执行中',
|
|
|
+ 3: '待验收',
|
|
|
+ 4: '已完成'
|
|
|
+ },
|
|
|
+ tableHeader: ['岗位', '设备名称', '执行人', '状态', '故障描述'],
|
|
|
+ config: {
|
|
|
+ header: [],
|
|
|
+ data: [],
|
|
|
+ align: ['center', 'center', 'center', 'center', 'center', 'center'],
|
|
|
+ headerBGC: '#031d42',
|
|
|
+ columnWidth: [110, 120],
|
|
|
+ headerHeight: 20,
|
|
|
+ oddRowBGC: '#031d42',
|
|
|
+ evenRowBGC: '#031d42',
|
|
|
+ waitTime: 5000,
|
|
|
+ rowNum: 12
|
|
|
+ },
|
|
|
+ optionData: [
|
|
|
+ {
|
|
|
+ code: '3',
|
|
|
+ name: '运行数量',
|
|
|
+ cws: 80,
|
|
|
+ zcs: 20,
|
|
|
+ zcl: '25%',
|
|
|
+ value: 80,
|
|
|
+ startRatio: 0,
|
|
|
+ endRatio: 0.34782608695652173,
|
|
|
+ itemStyle: {
|
|
|
+ color: '#5089F2',
|
|
|
+ opacity: 1
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ code: '1',
|
|
|
+ name: '故障检修数量',
|
|
|
+ cws: 40,
|
|
|
+ zcs: 30,
|
|
|
+ zcl: '75%',
|
|
|
+ value: 40,
|
|
|
+ startRatio: 0.8260869565217391,
|
|
|
+ endRatio: 1,
|
|
|
+ itemStyle: {
|
|
|
+ color: '#FF736A',
|
|
|
+ opacity: 1
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ };
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ // window.isFullscreen = false
|
|
|
+ this.updateTimer = setInterval(this.updateTime, 1000);
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.getSalesFinishList();
|
|
|
+ setInterval(() => {
|
|
|
+ this.getSalesFinishList();
|
|
|
+ }, 3600000);
|
|
|
+
|
|
|
+ // this.init(this.$refs.pie3d_1);
|
|
|
+ // this.init(this.$refs.pie3d_2);
|
|
|
+ // this.init(this.$refs.pie3d_3);
|
|
|
+ // this.init(this.$refs.pie3d_4);
|
|
|
+ // this.init(this.$refs.pie3d_5);
|
|
|
+ statisticsDeviceStatus().then((data) => {
|
|
|
+ console.log(data);
|
|
|
+ this.totalData = data;
|
|
|
+ this.initCircle(
|
|
|
+ this.$refs.pie3d_1,
|
|
|
+ data.deepAddingDeviceNum,
|
|
|
+ data.deepAddingDeviceNum1
|
|
|
+ );
|
|
|
+ this.initCircle(
|
|
|
+ this.$refs.pie3d_2,
|
|
|
+ data.inspectionDeviceNum,
|
|
|
+ data.inspectionDeviceNum1
|
|
|
+ );
|
|
|
+ this.initCircle(
|
|
|
+ this.$refs.pie3d_3,
|
|
|
+ data.mixedDeviceNum,
|
|
|
+ data.mixedDeviceNum1
|
|
|
+ );
|
|
|
+ this.initCircle(
|
|
|
+ this.$refs.pie3d_4,
|
|
|
+ data.moldingDeviceNum,
|
|
|
+ data.moldingDeviceNum1
|
|
|
+ );
|
|
|
+ this.initCircle(
|
|
|
+ this.$refs.pie3d_5,
|
|
|
+ data.sinteringDeviceNum,
|
|
|
+ data.sinteringDeviceNum1
|
|
|
+ );
|
|
|
+ });
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ initCircle(ref, total, repairNum) {
|
|
|
+ let rightChart2 = echarts.init(ref);
|
|
|
+ let option = {
|
|
|
+ legend: {
|
|
|
+ left: 'center',
|
|
|
+ top: 'bottom',
|
|
|
+ data: ['运行数量', '维修数量'],
|
|
|
+ textStyle: {
|
|
|
+ color: '#fff'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: 'Radius Mode',
|
|
|
+ type: 'pie',
|
|
|
+ radius: ['20%', '40%'],
|
|
|
+ center: ['50%', '50%'],
|
|
|
+ // roseType: 'radius',
|
|
|
+ // itemStyle: {
|
|
|
+ // borderRadius: 0
|
|
|
+ // },
|
|
|
+ label: {
|
|
|
+ formatter: '{per|{d}%}\n{hr|}\n {c|{c}} ',
|
|
|
+ backgroundColor: 'transparent',
|
|
|
+ borderWidth: 0,
|
|
|
+ rich: {
|
|
|
+ a: {
|
|
|
+ color: '#fff',
|
|
|
+ lineHeight: 22,
|
|
|
+ align: 'center'
|
|
|
+ },
|
|
|
+ hr: {
|
|
|
+ borderColor: '#fff',
|
|
|
+ width: '100%',
|
|
|
+ borderWidth: 1,
|
|
|
+ height: 0
|
|
|
+ },
|
|
|
+ b: {
|
|
|
+ color: '#fff',
|
|
|
+ fontSize: 12,
|
|
|
+ fontWeight: 'bold',
|
|
|
+ lineHeight: 33
|
|
|
+ },
|
|
|
+ c: {
|
|
|
+ color: '#fff',
|
|
|
+ fontSize: 12,
|
|
|
+ fontWeight: 'bold',
|
|
|
+ lineHeight: 33
|
|
|
+ },
|
|
|
+ per: {
|
|
|
+ color: '#fff',
|
|
|
+ padding: [3, 4],
|
|
|
+ borderRadius: 4
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ emphasis: {
|
|
|
+ label: {
|
|
|
+ show: true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data: [
|
|
|
+ {
|
|
|
+ value: total - repairNum,
|
|
|
+ name: '运行数量'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: repairNum,
|
|
|
+ name: '维修数量'
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ color: ['#4681F4', '#EDB2C7']
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ };
|
|
|
+ rightChart2.setOption(option);
|
|
|
+ },
|
|
|
+ initChartR2(ref) {
|
|
|
+ let rightChart2 = echarts.init(ref);
|
|
|
+ function getParametricEquation(
|
|
|
+ startRatio,
|
|
|
+ endRatio,
|
|
|
+ isSelected,
|
|
|
+ isHovered,
|
|
|
+ k,
|
|
|
+ height
|
|
|
+ ) {
|
|
|
+ // 计算
|
|
|
+ const midRatio = (startRatio + endRatio) / 2;
|
|
|
+
|
|
|
+ const startRadian = startRatio * Math.PI * 2;
|
|
|
+ const endRadian = endRatio * Math.PI * 2;
|
|
|
+ const midRadian = midRatio * Math.PI * 2;
|
|
|
+
|
|
|
+ // 如果只有一个扇形,则不实现选中效果。
|
|
|
+ if (startRatio === 0 && endRatio === 1) {
|
|
|
+ isSelected = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 通过扇形内径/外径的值,换算出辅助参数 k(默认值 1/3)
|
|
|
+ k = typeof k !== 'undefined' ? k : 1 / 3;
|
|
|
+
|
|
|
+ // 计算选中效果分别在 x 轴、y 轴方向上的位移(未选中,则位移均为 0)
|
|
|
+ const offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;
|
|
|
+ const offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0;
|
|
|
+
|
|
|
+ // 计算高亮效果的放大比例(未高亮,则比例为 1)
|
|
|
+ const hoverRate = isHovered ? 1.05 : 1;
|
|
|
+
|
|
|
+ // 返回曲面参数方程
|
|
|
+ return {
|
|
|
+ u: {
|
|
|
+ min: -Math.PI,
|
|
|
+ max: Math.PI * 3,
|
|
|
+ step: Math.PI / 32
|
|
|
+ },
|
|
|
+
|
|
|
+ v: {
|
|
|
+ min: 0,
|
|
|
+ max: Math.PI * 2,
|
|
|
+ step: Math.PI / 20
|
|
|
+ },
|
|
|
+
|
|
|
+ x: function (u, v) {
|
|
|
+ if (u < startRadian) {
|
|
|
+ return (
|
|
|
+ offsetX +
|
|
|
+ Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate
|
|
|
+ );
|
|
|
+ }
|
|
|
+ if (u > endRadian) {
|
|
|
+ return (
|
|
|
+ offsetX +
|
|
|
+ Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate
|
|
|
+ );
|
|
|
+ }
|
|
|
+ return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate;
|
|
|
+ },
|
|
|
+
|
|
|
+ y: function (u, v) {
|
|
|
+ if (u < startRadian) {
|
|
|
+ return (
|
|
|
+ offsetY +
|
|
|
+ Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate
|
|
|
+ );
|
|
|
+ }
|
|
|
+ if (u > endRadian) {
|
|
|
+ return (
|
|
|
+ offsetY +
|
|
|
+ Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate
|
|
|
+ );
|
|
|
+ }
|
|
|
+ return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate;
|
|
|
+ },
|
|
|
+
|
|
|
+ z: function (u, v) {
|
|
|
+ if (u < -Math.PI * 0.5) {
|
|
|
+ return Math.sin(u);
|
|
|
+ }
|
|
|
+ if (u > Math.PI * 2.5) {
|
|
|
+ return Math.sin(u);
|
|
|
+ }
|
|
|
+ return Math.sin(v) > 0 ? 1 * height : -1;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ }
|
|
|
+ // 生成模拟 3D 饼图的配置项
|
|
|
+ function getPie3D(pieData, internalDiameterRatio) {
|
|
|
+ const series = [];
|
|
|
+ let sumValue = 0;
|
|
|
+ let startValue = 0;
|
|
|
+ let endValue = 0;
|
|
|
+ const legendData = [];
|
|
|
+ const k =
|
|
|
+ typeof internalDiameterRatio !== 'undefined'
|
|
|
+ ? (1 - internalDiameterRatio) / (1 + internalDiameterRatio)
|
|
|
+ : 1 / 3;
|
|
|
+
|
|
|
+ // 为每一个饼图数据,生成一个 series-surface 配置
|
|
|
+ for (let i = 0; i < pieData.length; i++) {
|
|
|
+ sumValue += pieData[i].value;
|
|
|
+
|
|
|
+ const seriesItem = {
|
|
|
+ name:
|
|
|
+ typeof pieData[i].name === 'undefined'
|
|
|
+ ? `series${i}`
|
|
|
+ : pieData[i].name,
|
|
|
+ type: 'surface',
|
|
|
+ parametric: true,
|
|
|
+ wireframe: {
|
|
|
+ show: false
|
|
|
+ },
|
|
|
+ pieData: pieData[i],
|
|
|
+ pieStatus: {
|
|
|
+ selected: false,
|
|
|
+ hovered: false,
|
|
|
+ k: k
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ if (typeof pieData[i].itemStyle !== 'undefined') {
|
|
|
+ const itemStyle = {};
|
|
|
+
|
|
|
+ typeof pieData[i].itemStyle.color !== 'undefined'
|
|
|
+ ? (itemStyle.color = pieData[i].itemStyle.color)
|
|
|
+ : null;
|
|
|
+ typeof pieData[i].itemStyle.opacity !== 'undefined'
|
|
|
+ ? (itemStyle.opacity = pieData[i].itemStyle.opacity)
|
|
|
+ : null;
|
|
|
+
|
|
|
+ seriesItem.itemStyle = itemStyle;
|
|
|
+ }
|
|
|
+ series.push(seriesItem);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 使用上一次遍历时,计算出的数据和 sumValue,调用 getParametricEquation 函数,
|
|
|
+ // 向每个 series-surface 传入不同的参数方程 series-surface.parametricEquation,也就是实现每一个扇形。
|
|
|
+ for (let i = 0; i < series.length; i++) {
|
|
|
+ endValue = startValue + series[i].pieData.value;
|
|
|
+ series[i].pieData.startRatio = startValue / sumValue;
|
|
|
+ series[i].pieData.endRatio = endValue / sumValue;
|
|
|
+ series[i].parametricEquation = getParametricEquation(
|
|
|
+ series[i].pieData.startRatio,
|
|
|
+ series[i].pieData.endRatio,
|
|
|
+ false,
|
|
|
+ false,
|
|
|
+ k,
|
|
|
+ 2000
|
|
|
+ );
|
|
|
+
|
|
|
+ startValue = endValue;
|
|
|
+
|
|
|
+ legendData.push(series[i].name);
|
|
|
+ }
|
|
|
+ return series;
|
|
|
+ }
|
|
|
+ // 传入数据生成 option
|
|
|
+ const optionsData = [
|
|
|
+ {
|
|
|
+ name: '运行数量',
|
|
|
+ value: 0.6,
|
|
|
+ itemStyle: {
|
|
|
+ opacity: 0.5,
|
|
|
+ color: '#2f97df'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '故障检修数量',
|
|
|
+ value: 72.17,
|
|
|
+ itemStyle: {
|
|
|
+ opacity: 0.5,
|
|
|
+ color: '#d35e5f'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ];
|
|
|
+ const series = getPie3D(
|
|
|
+ optionsData.map((item) => {
|
|
|
+ if (item.value < 5) {
|
|
|
+ item.value = 5;
|
|
|
+ }
|
|
|
+ return item;
|
|
|
+ }),
|
|
|
+ 0,
|
|
|
+ 240,
|
|
|
+ 28,
|
|
|
+ 26,
|
|
|
+ 0.5
|
|
|
+ );
|
|
|
+ series.push({
|
|
|
+ name: 'pie2d',
|
|
|
+ type: 'pie',
|
|
|
+ label: {
|
|
|
+ opacity: 1,
|
|
|
+ position: 'outside',
|
|
|
+ fontSize: 12,
|
|
|
+ lineHeight: 20,
|
|
|
+ textStyle: {
|
|
|
+ fontSize: 12,
|
|
|
+ color: '#fff'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ labelLine: {
|
|
|
+ length: 30,
|
|
|
+ length2: 30
|
|
|
+ },
|
|
|
+ minAngle: 10,
|
|
|
+ startAngle: -50, // 起始角度,支持范围[0, 360]。
|
|
|
+ clockwise: false, // 饼图的扇区是否是顺时针排布。上述这两项配置主要是为了对齐3d的样式
|
|
|
+ radius: ['0', '25%'],
|
|
|
+ center: ['50%', '50%'],
|
|
|
+ data: optionsData.map((item) => {
|
|
|
+ item.itemStyle.opacity = 0;
|
|
|
+ return item;
|
|
|
+ })
|
|
|
+ });
|
|
|
+ // 准备待返回的配置项,把准备好的 legendData、series 传入。
|
|
|
+ const option = {
|
|
|
+ legend: {
|
|
|
+ show: false
|
|
|
+ },
|
|
|
+ animation: true,
|
|
|
+ tooltip: {
|
|
|
+ formatter: (params) => {
|
|
|
+ if (
|
|
|
+ params.seriesName !== 'mouseoutSeries' &&
|
|
|
+ params.seriesName !== 'pie2d'
|
|
|
+ ) {
|
|
|
+ return `${
|
|
|
+ params.seriesName
|
|
|
+ }<br/><span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${
|
|
|
+ params.color
|
|
|
+ };"></span>${
|
|
|
+ option.series[params.seriesIndex].pieData.value + '%'
|
|
|
+ }`;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ textStyle: {
|
|
|
+ fontSize: 14
|
|
|
+ }
|
|
|
+ },
|
|
|
+ title: {
|
|
|
+ x: 'center',
|
|
|
+ top: '20',
|
|
|
+ textStyle: {
|
|
|
+ color: '#fff',
|
|
|
+ fontSize: 22
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // backgroundColor: '#0E3567',
|
|
|
+ labelLine: {
|
|
|
+ show: true,
|
|
|
+ lineStyle: {
|
|
|
+ color: '#7BC0CB'
|
|
|
+ },
|
|
|
+ normal: {
|
|
|
+ show: true,
|
|
|
+ length: 10,
|
|
|
+ length2: 10
|
|
|
+ }
|
|
|
+ },
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ position: 'outside',
|
|
|
+ formatter: '{b} \n{d}%',
|
|
|
+ textStyle: {
|
|
|
+ color: '#fff',
|
|
|
+ fontSize: '12px'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ xAxis3D: {
|
|
|
+ min: -1,
|
|
|
+ max: 1
|
|
|
+ },
|
|
|
+ yAxis3D: {
|
|
|
+ min: -1,
|
|
|
+ max: 1
|
|
|
+ },
|
|
|
+ zAxis3D: {
|
|
|
+ min: -1,
|
|
|
+ max: 1
|
|
|
+ },
|
|
|
+ grid3D: {
|
|
|
+ show: false,
|
|
|
+ boxHeight: 0.01,
|
|
|
+ // top: '30%',
|
|
|
+ bottom: '50%',
|
|
|
+ // environment: "rgba(255,255,255,0)",
|
|
|
+ viewControl: {
|
|
|
+ distance: 300,
|
|
|
+ alpha: 35,
|
|
|
+ beta: 60,
|
|
|
+ autoRotate: false // 自动旋转
|
|
|
+ }
|
|
|
+ },
|
|
|
+ series: series
|
|
|
+ };
|
|
|
+ rightChart2.setOption(option);
|
|
|
+ },
|
|
|
+ //初始化构建
|
|
|
+ init(refs) {
|
|
|
+ let myChart = echarts.init(refs);
|
|
|
+ // 传入数据生成 option ; getPie3D(数据,透明的空心占比(调节中间空心范围的0就是普通饼1就很镂空))
|
|
|
+ this.option = this.getPie3D(this.optionData, 0.85);
|
|
|
+ //将配置项设置进去
|
|
|
+ myChart.setOption(this.option);
|
|
|
+ //鼠标移动上去特效效果
|
|
|
+ this.bindListen(myChart);
|
|
|
+ },
|
|
|
+ // 监听鼠标事件,实现饼图选中效果(单选),近似实现高亮(放大)效果。
|
|
|
+ bindListen(myChart) {
|
|
|
+ let that = this;
|
|
|
+ let selectedIndex = '';
|
|
|
+ let hoveredIndex = '';
|
|
|
+ // 监听点击事件,实现选中效果(单选)
|
|
|
+ myChart.on('click', function (params) {
|
|
|
+ // 从 option.series 中读取重新渲染扇形所需的参数,将是否选中取反。
|
|
|
+ let isSelected =
|
|
|
+ !that.option.series[params.seriesIndex].pieStatus.selected;
|
|
|
+ let isHovered =
|
|
|
+ that.option.series[params.seriesIndex].pieStatus.hovered;
|
|
|
+ let k = that.option.series[params.seriesIndex].pieStatus.k;
|
|
|
+ let startRatio =
|
|
|
+ that.option.series[params.seriesIndex].pieData.startRatio;
|
|
|
+ let endRatio =
|
|
|
+ that.option.series[params.seriesIndex].pieData.endRatio;
|
|
|
+ // 如果之前选中过其他扇形,将其取消选中(对 option 更新)
|
|
|
+ if (selectedIndex !== '' && selectedIndex !== params.seriesIndex) {
|
|
|
+ that.option.series[selectedIndex].parametricEquation =
|
|
|
+ that.getParametricEquation(
|
|
|
+ that.option.series[selectedIndex].pieData.startRatio,
|
|
|
+ that.option.series[selectedIndex].pieData.endRatio,
|
|
|
+ false,
|
|
|
+ false,
|
|
|
+ k,
|
|
|
+ that.option.series[selectedIndex].pieData.value
|
|
|
+ );
|
|
|
+ that.option.series[selectedIndex].pieStatus.selected = false;
|
|
|
+ }
|
|
|
+ // 对当前点击的扇形,执行选中/取消选中操作(对 option 更新)
|
|
|
+ that.option.series[params.seriesIndex].parametricEquation =
|
|
|
+ that.getParametricEquation(
|
|
|
+ startRatio,
|
|
|
+ endRatio,
|
|
|
+ isSelected,
|
|
|
+ isHovered,
|
|
|
+ k,
|
|
|
+ that.option.series[params.seriesIndex].pieData.value
|
|
|
+ );
|
|
|
+ that.option.series[params.seriesIndex].pieStatus.selected =
|
|
|
+ isSelected;
|
|
|
+ // 如果本次是选中操作,记录上次选中的扇形对应的系列号 seriesIndex
|
|
|
+ isSelected ? (selectedIndex = params.seriesIndex) : null;
|
|
|
+ // 使用更新后的 option,渲染图表
|
|
|
+ myChart.setOption(that.option);
|
|
|
+ });
|
|
|
+ // 监听 mouseover,近似实现高亮(放大)效果
|
|
|
+ myChart.on('mouseover', function (params) {
|
|
|
+ // 准备重新渲染扇形所需的参数
|
|
|
+ let isSelected;
|
|
|
+ let isHovered;
|
|
|
+ let startRatio;
|
|
|
+ let endRatio;
|
|
|
+ let k;
|
|
|
+ // 如果触发 mouseover 的扇形当前已高亮,则不做操作
|
|
|
+ if (hoveredIndex === params.seriesIndex) {
|
|
|
+ return;
|
|
|
+ // 否则进行高亮及必要的取消高亮操作
|
|
|
+ } else {
|
|
|
+ // 如果当前有高亮的扇形,取消其高亮状态(对 option 更新)
|
|
|
+ if (hoveredIndex !== '') {
|
|
|
+ // 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 false。
|
|
|
+ isSelected = that.option.series[hoveredIndex].pieStatus.selected;
|
|
|
+ isHovered = false;
|
|
|
+ startRatio = that.option.series[hoveredIndex].pieData.startRatio;
|
|
|
+ endRatio = that.option.series[hoveredIndex].pieData.endRatio;
|
|
|
+ k = that.option.series[hoveredIndex].pieStatus.k;
|
|
|
+ // 对当前点击的扇形,执行取消高亮操作(对 option 更新)
|
|
|
+ that.option.series[hoveredIndex].parametricEquation =
|
|
|
+ that.getParametricEquation(
|
|
|
+ startRatio,
|
|
|
+ endRatio,
|
|
|
+ isSelected,
|
|
|
+ isHovered,
|
|
|
+ k,
|
|
|
+ that.option.series[hoveredIndex].pieData.value
|
|
|
+ );
|
|
|
+ that.option.series[hoveredIndex].pieStatus.hovered = isHovered;
|
|
|
+ // 将此前记录的上次选中的扇形对应的系列号 seriesIndex 清空
|
|
|
+ hoveredIndex = '';
|
|
|
+ }
|
|
|
+ // 如果触发 mouseover 的扇形不是透明圆环,将其高亮(对 option 更新)
|
|
|
+ if (
|
|
|
+ params.seriesName !== 'mouseoutSeries' &&
|
|
|
+ params.seriesName !== 'pie2d'
|
|
|
+ ) {
|
|
|
+ // 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 true。
|
|
|
+ isSelected =
|
|
|
+ that.option.series[params.seriesIndex].pieStatus.selected;
|
|
|
+ isHovered = true;
|
|
|
+ startRatio =
|
|
|
+ that.option.series[params.seriesIndex].pieData.startRatio;
|
|
|
+ endRatio =
|
|
|
+ that.option.series[params.seriesIndex].pieData.endRatio;
|
|
|
+ k = that.option.series[params.seriesIndex].pieStatus.k;
|
|
|
+ // 对当前点击的扇形,执行高亮操作(对 option 更新)
|
|
|
+ that.option.series[params.seriesIndex].parametricEquation =
|
|
|
+ that.getParametricEquation(
|
|
|
+ startRatio,
|
|
|
+ endRatio,
|
|
|
+ isSelected,
|
|
|
+ isHovered,
|
|
|
+ k,
|
|
|
+ that.option.series[params.seriesIndex].pieData.value + 5
|
|
|
+ );
|
|
|
+ that.option.series[params.seriesIndex].pieStatus.hovered =
|
|
|
+ isHovered;
|
|
|
+ // 记录上次高亮的扇形对应的系列号 seriesIndex
|
|
|
+ hoveredIndex = params.seriesIndex;
|
|
|
+ }
|
|
|
+ // 使用更新后的 option,渲染图表
|
|
|
+ myChart.setOption(that.option);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ // 修正取消高亮失败的 bug
|
|
|
+ myChart.on('globalout', function () {
|
|
|
+ // 准备重新渲染扇形所需的参数
|
|
|
+ let isSelected;
|
|
|
+ let isHovered;
|
|
|
+ let startRatio;
|
|
|
+ let endRatio;
|
|
|
+ let k;
|
|
|
+ if (hoveredIndex !== '') {
|
|
|
+ // 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 true。
|
|
|
+ isSelected = that.option.series[hoveredIndex].pieStatus.selected;
|
|
|
+ isHovered = false;
|
|
|
+ k = that.option.series[hoveredIndex].pieStatus.k;
|
|
|
+ startRatio = that.option.series[hoveredIndex].pieData.startRatio;
|
|
|
+ endRatio = that.option.series[hoveredIndex].pieData.endRatio;
|
|
|
+ // 对当前点击的扇形,执行取消高亮操作(对 option 更新)
|
|
|
+ that.option.series[hoveredIndex].parametricEquation =
|
|
|
+ that.getParametricEquation(
|
|
|
+ startRatio,
|
|
|
+ endRatio,
|
|
|
+ isSelected,
|
|
|
+ isHovered,
|
|
|
+ k,
|
|
|
+ that.option.series[hoveredIndex].pieData.value
|
|
|
+ );
|
|
|
+ that.option.series[hoveredIndex].pieStatus.hovered = isHovered;
|
|
|
+ // 将此前记录的上次选中的扇形对应的系列号 seriesIndex 清空
|
|
|
+ hoveredIndex = '';
|
|
|
+ }
|
|
|
+ // 使用更新后的 option,渲染图表
|
|
|
+ myChart.setOption(that.option);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ getPie3D(pieData, internalDiameterRatio) {
|
|
|
+ let that = this;
|
|
|
+ let series = [];
|
|
|
+ let sumValue = 0;
|
|
|
+ let startValue = 0;
|
|
|
+ let endValue = 0;
|
|
|
+ let legendData = [];
|
|
|
+ let legendBfb = [];
|
|
|
+ let k = 1 - internalDiameterRatio;
|
|
|
+ pieData.sort((a, b) => {
|
|
|
+ return b.value - a.value;
|
|
|
+ });
|
|
|
+ // 为每一个饼图数据,生成一个 series-surface(参数曲面) 配置
|
|
|
+ for (let i = 0; i < pieData.length; i++) {
|
|
|
+ sumValue += pieData[i].value;
|
|
|
+ let seriesItem = {
|
|
|
+ //系统名称
|
|
|
+ name:
|
|
|
+ typeof pieData[i].name === 'undefined'
|
|
|
+ ? `series${i}`
|
|
|
+ : pieData[i].name,
|
|
|
+ type: 'surface',
|
|
|
+ //是否为参数曲面(是)
|
|
|
+ parametric: true,
|
|
|
+ //曲面图网格线(否)上面一根一根的
|
|
|
+ wireframe: {
|
|
|
+ show: false
|
|
|
+ },
|
|
|
+ pieData: pieData[i],
|
|
|
+ pieStatus: {
|
|
|
+ selected: false,
|
|
|
+ hovered: false,
|
|
|
+ k: k
|
|
|
+ }
|
|
|
+ };
|
|
|
+ //曲面的颜色、不透明度等样式。
|
|
|
+ if (typeof pieData[i].itemStyle != 'undefined') {
|
|
|
+ let itemStyle = {};
|
|
|
+ typeof pieData[i].itemStyle.color != 'undefined'
|
|
|
+ ? (itemStyle.color = pieData[i].itemStyle.color)
|
|
|
+ : null;
|
|
|
+ typeof pieData[i].itemStyle.opacity != 'undefined'
|
|
|
+ ? (itemStyle.opacity = pieData[i].itemStyle.opacity)
|
|
|
+ : null;
|
|
|
+ seriesItem.itemStyle = itemStyle;
|
|
|
+ }
|
|
|
+ series.push(seriesItem);
|
|
|
+ console.log('seriesItem----------', seriesItem);
|
|
|
+ }
|
|
|
+ // 使用上一次遍历时,计算出的数据和 sumValue,调用 getParametricEquation 函数,
|
|
|
+ // 向每个 series-surface 传入不同的参数方程 series-surface.parametricEquation,也就是实现每一个扇形。
|
|
|
+ legendData = [];
|
|
|
+ legendBfb = [];
|
|
|
+ for (let i = 0; i < series.length; i++) {
|
|
|
+ endValue = startValue + series[i].pieData.value;
|
|
|
+ series[i].pieData.startRatio = startValue / sumValue;
|
|
|
+ series[i].pieData.endRatio = endValue / sumValue;
|
|
|
+ series[i].parametricEquation = this.getParametricEquation(
|
|
|
+ series[i].pieData.startRatio,
|
|
|
+ series[i].pieData.endRatio,
|
|
|
+ false,
|
|
|
+ false,
|
|
|
+ k,
|
|
|
+ series[i].pieData.value
|
|
|
+ );
|
|
|
+ startValue = endValue;
|
|
|
+ let bfb = that.fomatFloat(series[i].pieData.value / sumValue, 4);
|
|
|
+ legendData.push({
|
|
|
+ name: series[i].name,
|
|
|
+ value: bfb
|
|
|
+ });
|
|
|
+ legendBfb.push({
|
|
|
+ name: series[i].name,
|
|
|
+ value: bfb
|
|
|
+ });
|
|
|
+ }
|
|
|
+ //(第二个参数可以设置你这个环形的高低程度)
|
|
|
+ let boxHeight = this.getHeight3D(series, 15); //通过传参设定3d饼/环的高度
|
|
|
+ // 准备待返回的配置项,把准备好的 legendData、series 传入。
|
|
|
+ let option = {
|
|
|
+ //图例组件
|
|
|
+ legend: {
|
|
|
+ data: legendData,
|
|
|
+ //图例列表的布局朝向。
|
|
|
+ orient: 'vertical',
|
|
|
+ right: '0%',
|
|
|
+ x: 'right',
|
|
|
+ y: 'bottom',
|
|
|
+
|
|
|
+ //图例文字每项之间的间隔
|
|
|
+ itemGap: 10,
|
|
|
+ textStyle: {
|
|
|
+ color: '#A1E2FF',
|
|
|
+ fontSize: '0.8rem'
|
|
|
+ },
|
|
|
+ show: true,
|
|
|
+ icon: 'circle',
|
|
|
+ //格式化图例文本(我是数值什么显示什么)
|
|
|
+ formatter: function (name) {
|
|
|
+ var target;
|
|
|
+ for (var i = 0, l = pieData.length; i < l; i++) {
|
|
|
+ if (pieData[i].name == name) {
|
|
|
+ target = pieData[i].value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return `${name}: ${target}`;
|
|
|
+ }
|
|
|
+ // 这个可以显示百分比那种(可以根据你想要的来配置)
|
|
|
+ // formatter: function(param) {
|
|
|
+ // let item = legendBfb.filter(item => item.name == param)[0];
|
|
|
+ // let bfs = that.fomatFloat(item.value * 100, 2) + "%";
|
|
|
+ // console.log(item.name)
|
|
|
+ // return `${item.name} :${bfs}`;
|
|
|
+ // }
|
|
|
+ },
|
|
|
+ //移动上去提示的文本内容
|
|
|
+ tooltip: {
|
|
|
+ formatter: function (params) {
|
|
|
+ console.log('name', name);
|
|
|
+ var target;
|
|
|
+ for (var i = 0, l = pieData.length; i < l; i++) {
|
|
|
+ if (pieData[i].name == params.seriesName) {
|
|
|
+ target = pieData[i].value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return `${params.seriesName}: ${target}`;
|
|
|
+ }
|
|
|
+ // formatter: (params) => {
|
|
|
+ // if (
|
|
|
+ // params.seriesName !== 'mouseoutSeries' &&
|
|
|
+ // params.seriesName !== 'pie2d'
|
|
|
+ // ) {
|
|
|
+ // let bfb = (
|
|
|
+ // (option.series[params.seriesIndex].pieData.endRatio -
|
|
|
+ // option.series[params.seriesIndex].pieData.startRatio) *
|
|
|
+ // 100
|
|
|
+ // ).toFixed(2);
|
|
|
+ // return (
|
|
|
+ // `${params.seriesName}<br/>` +
|
|
|
+ // `<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${params.color};"></span>` +
|
|
|
+ // `${bfb}`
|
|
|
+ // );
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ },
|
|
|
+ //这个可以变形
|
|
|
+ xAxis3D: {
|
|
|
+ min: -1,
|
|
|
+ max: 1
|
|
|
+ },
|
|
|
+ yAxis3D: {
|
|
|
+ min: -1,
|
|
|
+ max: 1
|
|
|
+ },
|
|
|
+ zAxis3D: {
|
|
|
+ min: -1,
|
|
|
+ max: 1
|
|
|
+ },
|
|
|
+ //此处是修改样式的重点
|
|
|
+ grid3D: {
|
|
|
+ show: false,
|
|
|
+ boxHeight: boxHeight, //圆环的高度
|
|
|
+ //这是饼图的位置
|
|
|
+ top: '0%',
|
|
|
+ viewControl: {
|
|
|
+ //3d效果可以放大、旋转等,请自己去查看官方配置
|
|
|
+ alpha: 35, //角度(这个很重要 调节角度的)
|
|
|
+ distance: 165, //调整视角到主体的距离,类似调整zoom(这是整体大小)
|
|
|
+ rotateSensitivity: 1, //设置为0无法旋转
|
|
|
+ zoomSensitivity: 0, //设置为0无法缩放
|
|
|
+ panSensitivity: 0, //设置为0无法平移
|
|
|
+ autoRotate: true //自动旋转
|
|
|
+ }
|
|
|
+ },
|
|
|
+ series: series
|
|
|
+ };
|
|
|
+ return option;
|
|
|
+ },
|
|
|
+ getHeight3D(series, height) {
|
|
|
+ series.sort((a, b) => {
|
|
|
+ return b.pieData.value - a.pieData.value;
|
|
|
+ });
|
|
|
+ return (height * 25) / series[0].pieData.value;
|
|
|
+ },
|
|
|
+ getParametricEquation(startRatio, endRatio, isSelected, isHovered, k, h) {
|
|
|
+ // 计算
|
|
|
+ let midRatio = (startRatio + endRatio) / 2;
|
|
|
+ let startRadian = startRatio * Math.PI * 2;
|
|
|
+ let endRadian = endRatio * Math.PI * 2;
|
|
|
+ let midRadian = midRatio * Math.PI * 2;
|
|
|
+ // 如果只有一个扇形,则不实现选中效果。
|
|
|
+ if (startRatio === 0 && endRatio === 1) {
|
|
|
+ isSelected = false;
|
|
|
+ }
|
|
|
+ // 通过扇形内径/外径的值,换算出辅助参数 k(默认值 1/3)
|
|
|
+ k = typeof k !== 'undefined' ? k : 1 / 3;
|
|
|
+ // 计算选中效果分别在 x 轴、y 轴方向上的位移(未选中,则位移均为 0)
|
|
|
+ let offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;
|
|
|
+ let offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0;
|
|
|
+ // 计算高亮效果的放大比例(未高亮,则比例为 1)
|
|
|
+ let hoverRate = isHovered ? 1.05 : 1;
|
|
|
+ // 返回曲面参数方程
|
|
|
+ return {
|
|
|
+ u: {
|
|
|
+ min: -Math.PI,
|
|
|
+ max: Math.PI * 3,
|
|
|
+ step: Math.PI / 32
|
|
|
+ },
|
|
|
+ v: {
|
|
|
+ min: 0,
|
|
|
+ max: Math.PI * 2,
|
|
|
+ step: Math.PI / 20
|
|
|
+ },
|
|
|
+ x: function (u, v) {
|
|
|
+ if (u < startRadian) {
|
|
|
+ return (
|
|
|
+ offsetX +
|
|
|
+ Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate
|
|
|
+ );
|
|
|
+ }
|
|
|
+ if (u > endRadian) {
|
|
|
+ return (
|
|
|
+ offsetX +
|
|
|
+ Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate
|
|
|
+ );
|
|
|
+ }
|
|
|
+ return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate;
|
|
|
+ },
|
|
|
+ y: function (u, v) {
|
|
|
+ if (u < startRadian) {
|
|
|
+ return (
|
|
|
+ offsetY +
|
|
|
+ Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate
|
|
|
+ );
|
|
|
+ }
|
|
|
+ if (u > endRadian) {
|
|
|
+ return (
|
|
|
+ offsetY +
|
|
|
+ Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate
|
|
|
+ );
|
|
|
+ }
|
|
|
+ return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate;
|
|
|
+ },
|
|
|
+ z: function (u, v) {
|
|
|
+ if (u < -Math.PI * 0.5) {
|
|
|
+ return Math.sin(u);
|
|
|
+ }
|
|
|
+ if (u > Math.PI * 2.5) {
|
|
|
+ return Math.sin(u) * h * 0.1;
|
|
|
+ }
|
|
|
+ return Math.sin(v) > 0 ? 1 * h * 0.1 : -1;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ },
|
|
|
+ fomatFloat(num, n) {
|
|
|
+ var f = parseFloat(num);
|
|
|
+ if (isNaN(f)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ f = Math.round(num * Math.pow(10, n)) / Math.pow(10, n); // n 幂
|
|
|
+ var s = f.toString();
|
|
|
+ var rs = s.indexOf('.');
|
|
|
+ //判定如果是整数,增加小数点再补0
|
|
|
+ if (rs < 0) {
|
|
|
+ rs = s.length;
|
|
|
+ s += '.';
|
|
|
+ }
|
|
|
+ while (s.length <= rs + n) {
|
|
|
+ s += '0';
|
|
|
+ }
|
|
|
+ return s;
|
|
|
+ },
|
|
|
+ /* 全屏切换 */
|
|
|
+ onFullscreen() {
|
|
|
+ this.isFullscreen = !this.isFullscreen;
|
|
|
+ },
|
|
|
+ //
|
|
|
+ async getSalesFinishList() {
|
|
|
+ /*customerMark 客户代号 string
|
|
|
+deliveryStatus 交付状态 1未交付2提前3按时4延期 integer(int32)
|
|
|
+produceStatus 生产状态 1未生产2已生产3已完成 integer(int32)
|
|
|
+purchaseStatus 采购状态 1未采购2已采购3已入库 integer(int32)
|
|
|
+saleOrderCode 销售订单号 string
|
|
|
+scheduleStatus 排产状态 1待排产2已排产 integer(int32)*/
|
|
|
+ let HeaderFiled = [
|
|
|
+ 'customerMark',
|
|
|
+ 'saleOrderCode',
|
|
|
+ 'purchaseStatus',
|
|
|
+ 'scheduleStatus',
|
|
|
+ 'produceStatus',
|
|
|
+ 'deliveryStatus'
|
|
|
+ ];
|
|
|
+ let data = await getRepairWorkList();
|
|
|
+ console.log(data);
|
|
|
+ this.config = {
|
|
|
+ header: this.tableHeader.map(
|
|
|
+ (item) =>
|
|
|
+ `<div style="color: #0577FF;font-size: 1.3rem;font-weight: bold">${item}</div>`
|
|
|
+ ),
|
|
|
+ data:
|
|
|
+ data.map((item) => {
|
|
|
+ let list = [];
|
|
|
+ for (let i in item) {
|
|
|
+ let div = '';
|
|
|
+ if (i === 'executeGroupName') {
|
|
|
+ div = `<div class="white" style="font-size: 1.3rem;">${item[i]}</div>`;
|
|
|
+ list[0] = div;
|
|
|
+ }
|
|
|
+ if (i === 'deviceName') {
|
|
|
+ div = `<div class="white" style="font-size: 1.3rem;">${item[i]}</div>`;
|
|
|
+ list[1] = div;
|
|
|
+ }
|
|
|
+ if (i === 'executeUserName') {
|
|
|
+ div = `<div class="white" style="font-size: 1.3rem;">${item[i]}</div>`;
|
|
|
+ list[2] = div;
|
|
|
+ }
|
|
|
+ if (i === 'orderStatus') {
|
|
|
+ if (item[i] > -1) {
|
|
|
+ div = `<div class="white" style="font-size: 1.3rem;">${
|
|
|
+ this.orderStatusOptions[item[i]]
|
|
|
+ }</div>`;
|
|
|
+ list[3] = div;
|
|
|
+ } else {
|
|
|
+ div = `<div class="white" style="font-size: 1.3rem;"></div>`;
|
|
|
+ list[3] = div;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (i === 'remark') {
|
|
|
+ div = `<div class="white" style="font-size: 1.3rem;">${item[i]}</div>`;
|
|
|
+ list[4] = div;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+ }) ?? [],
|
|
|
+ align: ['center', 'center', 'center', 'center', 'center', 'center'],
|
|
|
+ headerBGC: '#031d42',
|
|
|
+ columnWidth: [140, 250, 170, 150],
|
|
|
+ headerHeight: 30,
|
|
|
+ oddRowBGC: '#031d42',
|
|
|
+ evenRowBGC: '#031d42',
|
|
|
+ waitTime: 5000,
|
|
|
+ rowNum: 8
|
|
|
+ };
|
|
|
+ },
|
|
|
+ //实时更新日期
|
|
|
+ updateTime() {
|
|
|
+ let now = new Date();
|
|
|
+ let hours = now.getHours();
|
|
|
+ let minutes = now.getMinutes();
|
|
|
+ let seconds = now.getSeconds();
|
|
|
+ this.time =
|
|
|
+ hours.toString().padStart(2, '0') +
|
|
|
+ ':' +
|
|
|
+ minutes.toString().padStart(2, '0') +
|
|
|
+ ':' +
|
|
|
+ seconds.toString().padStart(2, '0');
|
|
|
+
|
|
|
+ let year = now.getFullYear();
|
|
|
+ let month = now.getMonth() + 1;
|
|
|
+ let day = now.getDate();
|
|
|
+ this.date = year + '年' + month + '月' + day + '日';
|
|
|
+
|
|
|
+ let weekInfo = {
|
|
|
+ 1: '一',
|
|
|
+ 2: '二',
|
|
|
+ 3: '三',
|
|
|
+ 4: '四',
|
|
|
+ 5: '五',
|
|
|
+ 6: '六',
|
|
|
+ 0: '日'
|
|
|
+ };
|
|
|
+ this.week = '星期' + weekInfo[now.getDay()];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+</script>
|
|
|
+<style lang="scss" scoped>
|
|
|
+ .box-container {
|
|
|
+ font-size: 16px;
|
|
|
+ font-family: 'AlibabaPuHuiTi';
|
|
|
+
|
|
|
+ background: #031d42;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+
|
|
|
+ .box-header {
|
|
|
+ background-image: url('@/assets/border2.png');
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-size: 100% 100%;
|
|
|
+ display: flex;
|
|
|
+ width: 100% !important;
|
|
|
+ height: 10%;
|
|
|
+ justify-content: space-between;
|
|
|
+
|
|
|
+ .title {
|
|
|
+ font-family: '优设标题黑';
|
|
|
+ font-size: 2.75rem;
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ color: #fff;
|
|
|
+ transform: translateY(-10%);
|
|
|
+ letter-spacing: 0.4rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .logo {
|
|
|
+ display: inline-block;
|
|
|
+ width: 20%;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ > img {
|
|
|
+ width: 6.48rem;
|
|
|
+ height: 3rem;
|
|
|
+ }
|
|
|
+ > span {
|
|
|
+ color: #fff;
|
|
|
+ font-size: 1rem;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .time {
|
|
|
+ width: 20%;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-around;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: flex-end;
|
|
|
+ justify-content: flex-start;
|
|
|
+ font-size: 0.8rem;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .top_bar {
|
|
|
+ height: 8.625rem;
|
|
|
+ width: 100%;
|
|
|
+ position: relative;
|
|
|
+ > div {
|
|
|
+ width: 25.77rem;
|
|
|
+ height: 6.27rem;
|
|
|
+ background-size: 100% 100%;
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ line-height: 6.27rem;
|
|
|
+ }
|
|
|
+ .runDeviceInfo {
|
|
|
+ position: absolute;
|
|
|
+ top: 1.177rem;
|
|
|
+ left: 14.625rem;
|
|
|
+ background-image: url('@/assets/runDevice.png');
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ > div {
|
|
|
+ font-family: '优设标题黑';
|
|
|
+ font-size: 2.3rem;
|
|
|
+ color: #fff;
|
|
|
+ > span {
|
|
|
+ color: #00c1fd;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .faultDeviceInfo {
|
|
|
+ position: absolute;
|
|
|
+ top: 1.177rem;
|
|
|
+ right: 14.625rem;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ background-image: url('@/assets/faultDevice.png');
|
|
|
+ > div {
|
|
|
+ font-family: '优设标题黑';
|
|
|
+ font-size: 2.3rem;
|
|
|
+ color: #fff;
|
|
|
+ > span {
|
|
|
+ color: #f26e6c;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .echarts_bar {
|
|
|
+ height: 23.3125rem;
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ .title {
|
|
|
+ height: 2.2rem;
|
|
|
+ background: linear-gradient(90deg, #1f385e 0%, #021f4b 55%);
|
|
|
+ > div {
|
|
|
+ height: 2.2rem;
|
|
|
+ line-height: 2.2rem;
|
|
|
+ width: 17.3125rem;
|
|
|
+ padding-left: 2.8rem;
|
|
|
+ background-image: url('@/assets/title_bg.png');
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-size: 100% 100%;
|
|
|
+ > span {
|
|
|
+ font-size: 1.3rem;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .echartsList {
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ overflow: hidden;
|
|
|
+ > div {
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ .echarts_title {
|
|
|
+ font-size: 1.3rem;
|
|
|
+ margin: 1rem;
|
|
|
+ color: #fff;
|
|
|
+ > span {
|
|
|
+ font-size: 2rem;
|
|
|
+ font-family: '优设标题黑';
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .echarts_box {
|
|
|
+ flex: 3;
|
|
|
+ }
|
|
|
+ .space {
|
|
|
+ flex: 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .table_bar {
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ overflow: hidden;
|
|
|
+ .title {
|
|
|
+ background: linear-gradient(90deg, #1f385e 0%, #021f4b 55%);
|
|
|
+ height: 2.2rem;
|
|
|
+ > div {
|
|
|
+ height: 2.2rem;
|
|
|
+ line-height: 2.2rem;
|
|
|
+ width: 17.3125rem;
|
|
|
+ padding-left: 2.8rem;
|
|
|
+ background-image: url('@/assets/title_bg.png');
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-size: 100% 100%;
|
|
|
+ > span {
|
|
|
+ font-size: 1.3rem;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .table {
|
|
|
+ flex: 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ [v-cloak] {
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+</style>
|
|
|
+<style>
|
|
|
+ .white {
|
|
|
+ color: #ffffff;
|
|
|
+ }
|
|
|
+
|
|
|
+ .yellow {
|
|
|
+ color: #ffd16c;
|
|
|
+ }
|
|
|
+
|
|
|
+ .green {
|
|
|
+ color: green;
|
|
|
+ }
|
|
|
+
|
|
|
+ .red {
|
|
|
+ color: red;
|
|
|
+ }
|
|
|
+ .row-item {
|
|
|
+ margin-bottom: 0.4rem;
|
|
|
+ }
|
|
|
+</style>
|