whyczyk
2021-10-18 edba26ba8377814d94b65b4a1a1fe04f0365afc9
src/components/charts/CustomPie.vue
@@ -1,368 +1,424 @@
<template>
    <div class="echarts-wrapper">
        <div class="echarts-content" ref="chart"></div>
    </div>
   <div class="echarts-wrapper" @dblclick="dblclick">
      <div class="echarts-content" ref="chart"></div>
   </div>
</template>
<script>
    import * as echarts from 'echarts';
    import sigh from './images/sigh.png';
    import {
        chartFontsize
    } from '@/assets/js/chartFontsize';
    import {
        powerAlarmError
    } from '@/assets/js/api'
    export default {
        name: "CustomPie",
        chart: "",
        chartData: {},
        data() {
            return {}
        },
        methods: {
            setOption(opt) {
                this.$options.chart.setOption(opt);
            },
            organizeData(data) {
                let angle = 0;
                let color = "#007CD0";
                let radius = 0.55;
                let lineWidth = 4;
                let width = this.$refs.chart.offsetWidth;
                let height = this.$refs.chart.offsetHeight;
                let realWidth = width > height ? height : width;
                let option = {
                    legend: [{
                            show: true,
                            type: "scroll",
                            orient: 'vertical',
                            align: 'left',
                            left: "10%",
                            bottom: 0,
                            data: ['监控器故障', '通讯故障'],
                            textStyle: {
                                color: '#fff'
                            }
                        },
                        {
                            show: true,
                            type: "scroll",
                            orient: 'vertical',
                            align: 'left',
                            left: "40%",
                            bottom: 0,
                            data: ['交流总故障', '防雷器故障'],
                            textStyle: {
                                color: '#fff'
                            }
                        },
                        {
                            show: true,
                            type: "scroll",
                            orient: 'vertical',
                            align: 'left',
                            left: "70%",
                            bottom: 0,
                            data: ['开关柜故障', '直流总故障'],
                            textStyle: {
                                color: '#fff'
                            }
                        },
                    ],
                    graphic: [{
                        z: 4,
                        type: 'image',
                        id: 'logo',
                        left: (width - realWidth / 5) / (2 * width) * 100 + '%',
                        top: (height - realWidth / 5) / (2 * height) * 100 + '%',
                        bounding: 'raw',
                        rotation: 0, //旋转
                        scale: [1.0, 1.0], //缩放
                        style: {
                            image: sigh,
                            width: realWidth / 5,
                            height: realWidth / 5,
                            opacity: 1,
                        }
                    }],
                    series: [{
                            name: '',
                            type: 'pie',
                            radius: ['40%', '50%'],
                            avoidLabelOverlap: false,
                            itemStyle: {
                                color(params) {
                                    return data[params.dataIndex].color;
                                },
                            },
                            label: {
                                height: 34,
                                overflow: 'none',
                                distanceToLabelLine: 0,
                                formatter: '{a|{b}}\n{hr|}\n{value|{d}%}',
                                rich: {
                                    a: {
                                        fontSize: chartFontsize(16),
                                        color: '#fff',
                                    },
                                    hr: {
                                        width: '100%',
                                        height: 1,
                                        backgroundColor: '#0073C5'
                                    },
                                    value: {
                                        fontSize: chartFontsize(18),
                                        color: '#CE6D28',
                                        fontWeight: 'bold',
                                        padding: [5, 0, 0, 0]
                                    }
                                },
                            },
                            labelLine: {
                                length: 30,
                                length2: 10,
                                lineStyle: {
                                    color: '#0073C5',
                                    width: 1,
                                }
                            },
                            data: data,
                        },
                        {
                            name: "ring5",
                            type: 'custom',
                            coordinateSystem: "none",
                            renderItem: function (params, api) {
                                return {
                                    type: 'arc',
                                    shape: {
                                        cx: api.getWidth() / 2,
                                        cy: api.getHeight() / 2,
                                        r: Math.min(api.getWidth(), api.getHeight()) / 2 * radius,
                                        startAngle: (292.5 + angle) * Math.PI / 180,
                                        endAngle: (337.5 + angle) * Math.PI / 180
                                    },
                                    style: {
                                        stroke: color,
                                        fill: "transparent",
                                        lineWidth: lineWidth
                                    },
                                    silent: true
                                };
                            },
                            data: [0]
                        },
                        {
                            name: "ring5",
                            type: 'custom',
                            coordinateSystem: "none",
                            renderItem: function (params, api) {
                                return {
                                    type: 'arc',
                                    shape: {
                                        cx: api.getWidth() / 2,
                                        cy: api.getHeight() / 2,
                                        r: Math.min(api.getWidth(), api.getHeight()) / 2 * radius,
                                        startAngle: (22.5 + angle) * Math.PI / 180,
                                        endAngle: (67.5 + angle) * Math.PI / 180
                                    },
                                    style: {
                                        stroke: color,
                                        fill: "transparent",
                                        lineWidth: lineWidth
                                    },
                                    silent: true
                                };
                            },
                            data: [0]
                        },
                        {
                            name: "ring5",
                            type: 'custom',
                            coordinateSystem: "none",
                            renderItem: function (params, api) {
                                return {
                                    type: 'arc',
                                    shape: {
                                        cx: api.getWidth() / 2,
                                        cy: api.getHeight() / 2,
                                        r: Math.min(api.getWidth(), api.getHeight()) / 2 * radius,
                                        startAngle: (112.5 + angle) * Math.PI / 180,
                                        endAngle: (157.5 + angle) * Math.PI / 180
                                    },
                                    style: {
                                        stroke: color,
                                        fill: "transparent",
                                        lineWidth: lineWidth
                                    },
                                    silent: true
                                };
                            },
                            data: [0]
                        },
                        {
                            name: "ring5",
                            type: 'custom',
                            coordinateSystem: "none",
                            renderItem: function (params, api) {
                                return {
                                    type: 'arc',
                                    shape: {
                                        cx: api.getWidth() / 2,
                                        cy: api.getHeight() / 2,
                                        r: Math.min(api.getWidth(), api.getHeight()) / 2 * radius,
                                        startAngle: (200.5 + angle) * Math.PI / 180,
                                        endAngle: (245.5 + angle) * Math.PI / 180
                                    },
                                    style: {
                                        stroke: color,
                                        fill: "transparent",
                                        lineWidth: lineWidth
                                    },
                                    silent: true
                                };
                            },
                            data: [0]
                        },
                        {
                            name: "ring5",
                            type: 'custom',
                            coordinateSystem: "none",
                            renderItem: function (params, api) {
                                return {
                                    type: 'arc',
                                    shape: {
                                        cx: api.getWidth() / 2,
                                        cy: api.getHeight() / 2,
                                        r: Math.min(api.getWidth(), api.getHeight()) / 2 * radius,
                                        startAngle: 0 * Math.PI / 180,
                                        endAngle: 360 * Math.PI / 180
                                    },
                                    style: {
                                        stroke: color,
                                        fill: "transparent",
                                        lineWidth: 1
                                    },
                                    silent: true
                                };
                            },
                            data: [0]
                        },
                        {
                            name: '',
                            type: 'pie',
                            radius: [0, '35%'],
                            avoidLabelOverlap: false,
                            label: {
                                show: false,
                                position: 'center'
                            },
                            emphasis: {
                                label: {
                                    show: false,
                                    fontSize: '40',
                                    fontWeight: 'bold'
                                }
                            },
                            labelLine: {
                                show: false
                            },
                            data: [0],
                            itemStyle: {
                                color: '#007ED3'
                            }
                        }
                    ]
                };
                // 设置配置项
                this.setOption(option);
            },
            setData(sendData) {
                if (sendData) {
                    this.$options.chartData = sendData;
                    this.organizeData(sendData)
                } else {
                    this.postData()
                    setInterval(() => {
                        this.postData()
                    }, 3000)
                }
            },
            postData() {
                let userId = localStorage.getItem('userId');
                let params = {
                    userId: userId
                }
                powerAlarmError(params).then((res) => {
                    if (res.data.code == 1) {
                        let optionData = [{
                                value: 0,
                                name: '通讯故障',
                                color: '#5062DE'
                            },
                            {
                                value: 0,
                                name: '直流总故障',
                                color: '#FD5E02'
                            },
                            {
                                value: 0,
                                name: '防雷器故障',
                                color: '#8C6BFA'
                            },
                            {
                                value: 0,
                                name: '开关柜故障',
                                color: '#F58881'
                            },
                            {
                                value: 0,
                                name: '监控器故障',
                                color: '#EDE611'
                            },
                            {
                                value: 0,
                                name: '交流总故障',
                                color: '#43F9FD'
                            },
                        ]
                        let resData = res.data.data;
                        for (let key in resData) {
                            optionData.map(item => {
                                if (item.name == key) {
                                    item.value = resData[key]
                                }
                            })
                        }
                        this.$options.chartData = optionData;
                        this.organizeData(optionData)
                    }
                }).catch((err) => {
                    console.log(err)
                });
            },
            resize() {
                setTimeout(() => {
                    this.$options.chart.resize();
                    if (JSON.stringify(this.$options.chartData) != '{}') {
                        this.setData(this.$options.chartData);
                    }
                }, 300)
            }
        },
        mounted() {
            // 基于准备好的dom,初始化echarts实例
            this.$options.chart = echarts.init(this.$refs.chart);
import * as echarts from 'echarts';
import sigh from './images/sigh.png';
import {
   chartFontsize
} from '@/assets/js/chartFontsize';
import { WebSocketClass } from '@/assets/js/socket'
import { checkboxs } from '@/assets/js/powerInfoData'
export default {
   name: "CustomPie",
   chart: "",
   chartData: {},
   data() {
      return {
         websock: null
      }
   },
   methods: {
      findParents(node, select) {
         var parent = node.parentNode;
         if (parent === null || parent.className.indexOf(select) != -1) {
            return parent;
         } else {
            return this.findParents(parent, select);
         }
      },
      dblclick(e) {
         this.isAllScreen = !this.isAllScreen
         let parents = this.findParents(e.currentTarget, 'vdr')
         if (this.isAllScreen) {
            this.parentsStyle = JSON.parse(JSON.stringify(parents.style));
            parents.style.transform = 'none';
            parents.style.width = '100%';
            parents.style.height = '100%';
            parents.style.position = 'fixed';
            parents.style.left = 0;
            parents.style.right = 0;
            parents.style.bottom = 0;
            parents.style.top = 0;
            parents.style.zIndex = 99999;
         } else {
            parents.style.transform = this.parentsStyle.transform;
            parents.style.width = this.parentsStyle.width;
            parents.style.height = this.parentsStyle.height;
            parents.style.position = this.parentsStyle.position;
            parents.style.left = 'initial';
            parents.style.right = 'initial';
            parents.style.bottom = 'initial';
            parents.style.top = 'initial';
            parents.style.zIndex = 'auto';
         }
         this.$options.chart.resize();
      },
      toParentPage(value) {
         if (typeof (value) == 'string') {
            window.parent.parent.postMessage({
               cmd: "syncPage",
               params: {
                  pageInfo: {
                     label: "电源实时告警",
                     name: "powerRealtimeInfo",
                     src: '#/powerRealtimeInfo/?alarmType=' + value,
                     closable: true
                  },
               }
            }, "*");
         }
      },
      setOption(opt) {
         this.$options.chart.setOption(opt);
         this.$options.chart.on('click', (params) => {
            let name = params.name;
            checkboxs.gz.map(item => {
               if (item.label == name) {
                  this.toParentPage(item.value)
               }
            })
         })
      },
      organizeData(data) {
         let angle = 0;
         let color = "#007CD0";
         let radius = 0.55;
         let lineWidth = 4;
         let width = this.$refs.chart.offsetWidth;
         let height = this.$refs.chart.offsetHeight;
         let realWidth = width > height ? height : width;
         let option = {
            legend: [{
               show: true,
               type: "scroll",
               orient: 'vertical',
               align: 'left',
               left: "10%",
               bottom: 0,
               data: ['监控器故障', '通讯故障'],
               textStyle: {
                  color: '#fff'
               }
            },
            {
               show: true,
               type: "scroll",
               orient: 'vertical',
               align: 'left',
               left: "40%",
               bottom: 0,
               data: ['交流总故障', '防雷器故障'],
               textStyle: {
                  color: '#fff'
               }
            },
            {
               show: true,
               type: "scroll",
               orient: 'vertical',
               align: 'left',
               left: "70%",
               bottom: 0,
               data: ['开关柜故障', '直流总故障'],
               textStyle: {
                  color: '#fff'
               }
            },
            ],
            graphic: [{
               z: 4,
               type: 'image',
               id: 'logo',
               left: (width - realWidth / 5) / (2 * width) * 100 + '%',
               top: (height - realWidth / 5) / (2 * height) * 100 + '%',
               bounding: 'raw',
               rotation: 0, //旋转
               scale: [1.0, 1.0], //缩放
               style: {
                  image: sigh,
                  width: realWidth / 5,
                  height: realWidth / 5,
                  opacity: 1,
               }
            }],
            series: [{
               name: '',
               type: 'pie',
               radius: ['40%', '50%'],
               avoidLabelOverlap: false,
               itemStyle: {
                  color(params) {
                     return data[params.dataIndex].color;
                  },
               },
               label: {
                  height: 34,
                  overflow: 'none',
                  distanceToLabelLine: 0,
                  formatter: '{a|{b}}\n{hr|}\n{value|{d}%}',
                  rich: {
                     a: {
                        fontSize: chartFontsize(16),
                        color: '#fff',
                     },
                     hr: {
                        width: '100%',
                        height: 1,
                        backgroundColor: '#0073C5'
                     },
                     value: {
                        fontSize: chartFontsize(18),
                        color: '#CE6D28',
                        fontWeight: 'bold',
                        padding: [5, 0, 0, 0]
                     }
                  },
               },
               labelLine: {
                  length: 30,
                  length2: 10,
                  lineStyle: {
                     color: '#0073C5',
                     width: 1,
                  }
               },
               data: data,
            },
            {
               name: "ring5",
               type: 'custom',
               coordinateSystem: "none",
               renderItem: function (params, api) {
                  return {
                     type: 'arc',
                     shape: {
                        cx: api.getWidth() / 2,
                        cy: api.getHeight() / 2,
                        r: Math.min(api.getWidth(), api.getHeight()) / 2 * radius,
                        startAngle: (292.5 + angle) * Math.PI / 180,
                        endAngle: (337.5 + angle) * Math.PI / 180
                     },
                     style: {
                        stroke: color,
                        fill: "transparent",
                        lineWidth: lineWidth
                     },
                     silent: true
                  };
               },
               data: [0]
            },
            {
               name: "ring5",
               type: 'custom',
               coordinateSystem: "none",
               renderItem: function (params, api) {
                  return {
                     type: 'arc',
                     shape: {
                        cx: api.getWidth() / 2,
                        cy: api.getHeight() / 2,
                        r: Math.min(api.getWidth(), api.getHeight()) / 2 * radius,
                        startAngle: (22.5 + angle) * Math.PI / 180,
                        endAngle: (67.5 + angle) * Math.PI / 180
                     },
                     style: {
                        stroke: color,
                        fill: "transparent",
                        lineWidth: lineWidth
                     },
                     silent: true
                  };
               },
               data: [0]
            },
            {
               name: "ring5",
               type: 'custom',
               coordinateSystem: "none",
               renderItem: function (params, api) {
                  return {
                     type: 'arc',
                     shape: {
                        cx: api.getWidth() / 2,
                        cy: api.getHeight() / 2,
                        r: Math.min(api.getWidth(), api.getHeight()) / 2 * radius,
                        startAngle: (112.5 + angle) * Math.PI / 180,
                        endAngle: (157.5 + angle) * Math.PI / 180
                     },
                     style: {
                        stroke: color,
                        fill: "transparent",
                        lineWidth: lineWidth
                     },
                     silent: true
                  };
               },
               data: [0]
            },
            {
               name: "ring5",
               type: 'custom',
               coordinateSystem: "none",
               renderItem: function (params, api) {
                  return {
                     type: 'arc',
                     shape: {
                        cx: api.getWidth() / 2,
                        cy: api.getHeight() / 2,
                        r: Math.min(api.getWidth(), api.getHeight()) / 2 * radius,
                        startAngle: (200.5 + angle) * Math.PI / 180,
                        endAngle: (245.5 + angle) * Math.PI / 180
                     },
                     style: {
                        stroke: color,
                        fill: "transparent",
                        lineWidth: lineWidth
                     },
                     silent: true
                  };
               },
               data: [0]
            },
            {
               name: "ring5",
               type: 'custom',
               coordinateSystem: "none",
               renderItem: function (params, api) {
                  return {
                     type: 'arc',
                     shape: {
                        cx: api.getWidth() / 2,
                        cy: api.getHeight() / 2,
                        r: Math.min(api.getWidth(), api.getHeight()) / 2 * radius,
                        startAngle: 0 * Math.PI / 180,
                        endAngle: 360 * Math.PI / 180
                     },
                     style: {
                        stroke: color,
                        fill: "transparent",
                        lineWidth: 1
                     },
                     silent: true
                  };
               },
               data: [0]
            },
            {
               name: '',
               type: 'pie',
               radius: [0, '35%'],
               avoidLabelOverlap: false,
               label: {
                  show: false,
                  position: 'center'
               },
               emphasis: {
                  label: {
                     show: false,
                     fontSize: '40',
                     fontWeight: 'bold'
                  }
               },
               labelLine: {
                  show: false
               },
               data: [0],
               itemStyle: {
                  color: '#007ED3'
               }
            }
            ]
         };
         // 设置配置项
         this.setOption(option);
      },
      setData(sendData) {
         if (sendData) {
            this.$options.chartData = sendData;
            this.organizeData(sendData)
         } else {
            this.postData()
         }
      },
      postData() {
         let userId = localStorage.getItem('userId');
         this.websock = new WebSocketClass(`/screen/powerAlarm/error/${userId}`, this.wsMessage)
      },
      wsMessage(res) {
         if (res.code == 1) {
            let optionData = [{
               value: 0,
               name: '通讯故障',
               color: '#5062DE'
            },
            {
               value: 0,
               name: '直流总故障',
               color: '#FD5E02'
            },
            {
               value: 0,
               name: '防雷器故障',
               color: '#8C6BFA'
            },
            {
               value: 0,
               name: '开关柜故障',
               color: '#F58881'
            },
            {
               value: 0,
               name: '监控器故障',
               color: '#EDE611'
            },
            {
               value: 0,
               name: '交流总故障',
               color: '#43F9FD'
            },
            ]
            let resData = res.data;
            for (let key in resData) {
               optionData.map(item => {
                  if (item.name == key) {
                     item.value = resData[key]
                  }
               })
            }
            this.$options.chartData = optionData;
            this.organizeData(optionData)
         }
      },
      outClear() {
         this.websock.closeMyself()
         this.websock = null
         window.removeEventListener('resize', this.resize);
      },
      resize() {
         setTimeout(() => {
            this.$options.chart.resize();
            if (JSON.stringify(this.$options.chartData) != '{}') {
               this.setData(this.$options.chartData);
            }
         }, 300)
      }
   },
   mounted() {
      // 基于准备好的dom,初始化echarts实例
      this.$options.chart = echarts.init(this.$refs.chart);
            window.addEventListener('resize', this.resize);
        },
        destroyed() {
            window.removeEventListener('resize', this.resize);
        }
    }
      window.addEventListener('resize', this.resize);
   },
   destroyed() {
      window.removeEventListener('resize', this.resize);
   }
}
</script>
<style scoped>
</style>