<template>
  <div id="noise">
    <div class="side-area">
      <Title text="设备总览"></Title>
      <ShadowContainer>
        <div class="chart-container">
          <img class="custom-chart" src="@/assets/chart.png" />
          <div ref="deviceChart" id="device-chart"></div>
        </div>
      </ShadowContainer>
      <Title text="近30日噪音"></Title>
      <ShadowContainer>
        <div class="chart-container">
          <img class="custom-chart" src="@/assets/chart.png" />
          <div ref="noiseChart" id="noise-chart"></div>
        </div>
      </ShadowContainer>
      <Title text="近30日AQI"></Title>
      <ShadowContainer>
        <div v-for="(iType, index) in noiseTypes" :key="index" class="i-type">
          <div class="i-type-name">
            {{ iType.name }}
          </div>
          <div class="slider">
            <el-progress
              v-if="!isNaN(iType.value)"
              :percentage="computedPercentage(iType.value, 30)"
              :color="iType.color"
              :show-text="false"
              define-back-color="#183C6B"
            ></el-progress>
          </div>
          <div class="i-type-count">
            <span>{{ iType.value }}</span>
            天
          </div>
        </div>
      </ShadowContainer>
    </div>
    <div class="mid-area">
      <Title text="实时监测" type="long"></Title>
      <ShadowContainer>
        <div class="monitor">
          <div class="lt-status">
            <el-divider></el-divider>
            <el-progress
              v-if="currentMonitorStatis.pm10.percentage"
              type="circle"
              :percentage="Number(currentMonitorStatis.pm10.percentage)"
              :format="
                (value) => formatText(value, currentMonitorStatis.pm10.value)
              "
              :color="currentMonitorStatis.pm10.color"
              :stroke-width="12"
            ></el-progress>
            <div class="status-unit">
              pm 10 / <span style="font-size: 12px; color: #6d94bf">ug/m³</span>
            </div>
            <el-divider></el-divider>
            <el-progress
              v-if="currentMonitorStatis.pm25.percentage"
              type="circle"
              :percentage="Number(currentMonitorStatis.pm25.percentage)"
              :format="
                (value) => formatText(value, currentMonitorStatis.pm25.value)
              "
              :color="currentMonitorStatis.pm25.color"
              :stroke-width="12"
            ></el-progress>
            <div class="status-unit">
              pm 2.5 /
              <span style="font-size: 12px; color: #6d94bf">ug/m³</span>
            </div>

            <el-divider></el-divider>
            <el-progress
              v-if="currentMonitorStatis.noise.percentage"
              type="circle"
              :percentage="Number(currentMonitorStatis.noise.percentage)"
              :format="
                (value) => formatText(value, currentMonitorStatis.noise.value)
              "
              :color="currentMonitorStatis.noise.color"
              :stroke-width="12"
            ></el-progress>
            <div class="status-unit">
              噪音 / <span style="font-size: 12px; color: #6d94bf">分贝</span>
            </div>

            <el-divider></el-divider>
          </div>
          <div class="mid-aqi">
            <div class="aqi-background">
              <div id="aqi-quality-chart" ref="aqiQualityChart"></div>
            </div>
            <div class="aqi-level">
              <div class="aqi-level-line">
                <div
                  v-for="(color, index) in currentMonitorStatis.aqi.level_list"
                  :key="index"
                  :style="{ background: color.color }"
                ></div>
              </div>
              <div class="aqi-level-text">
                <div
                  v-for="(aqi_level, index) in currentMonitorStatis.aqi
                    .level_list"
                  :key="index"
                >
                  {{ aqi_level.name }}
                </div>
              </div>
            </div>
          </div>
          <div class="rt-status">
            <el-divider></el-divider>
            <div class="rt-single-status">
              <div class="left-des">
                <div>温度</div>
                <img src="@/assets/noise/icon_f_san@2x.png" alt="" />
              </div>
              <div class="rt-value">
                <span>{{ currentMonitorStatis.temperature }}</span
                >℃
              </div>
            </div>
            <el-divider> </el-divider>
            <div class="rt-single-status">
              <div class="left-des">
                <div>湿度</div>
                <img src="@/assets/noise/icon_f_si@2x.png" alt="" />
              </div>
              <div class="rt-value">
                <span>{{ currentMonitorStatis.humidity }}</span
                >%
              </div>
            </div>
            <el-divider> </el-divider>
            <div class="rt-single-status">
              <div class="left-des">
                <div>风速</div>
                <img src="@/assets/noise/icon_f_wu@2x.png" alt="" />
              </div>
              <div class="rt-value">
                <span>{{ currentMonitorStatis.wind_speed }}</span
                >m/s
              </div>
            </div>
            <el-divider> </el-divider>
            <div class="rt-single-status">
              <div class="left-des">
                <div>数据采集</div>
                <img src="@/assets/noise/icon_f_liu@2x.png" alt="" />
              </div>
              <div
                class="rt-value"
                style="line-height: 20px; padding-top: 16px"
              >
                {{
                  currentMonitorStatis.log_time &&
                  currentMonitorStatis.log_time.split(" ")[0]
                }}
                <br />
                {{
                  currentMonitorStatis.log_time &&
                  currentMonitorStatis.log_time.split(" ")[1]
                }}
              </div>
            </div>
            <el-divider> </el-divider>
          </div>
        </div>
      </ShadowContainer>
      <Title text="今日AQI" type="long"></Title>
      <ShadowContainer>
        <div id="aqi-chart" ref="aqiChart"></div>
      </ShadowContainer>
    </div>
    <div class="side-area">
      <Title text="近30日报警信息"></Title>
      <ShadowContainer>
        <div class="warp">
          <div
            class="warn-title"
            v-for="(warn, index) in warnings"
            :key="index"
          >
            <div class="warn-text">
              <el-tooltip
                class="item"
                effect="dark"
                :content="warn.alarm_content"
              >
                <div class="overflowed">
                  {{ warn.alarm_content }}
                </div>
              </el-tooltip>
            </div>
            <div class="warn-time">{{ warn.log_time }}</div>
          </div>
        </div>
      </ShadowContainer>
      <Title text="扬尘噪音"></Title>
      <ShadowContainer>
        <div style="height: 570px">
          <div
            class="noise-monitor"
            v-for="(monitor, index) in noiseMonitors"
            :key="index"
          >
            <img src="@/assets/noise/icon_e_qi@2x.png" alt="" />
            {{ monitor.device_name }}
          </div>
        </div>
      </ShadowContainer>
    </div>
  </div>
</template>
<script>
import {
  getDeviceTotalStatus,
  getNearMonthStatis,
  getCurrentMonitorStatis,
  getNoiseDeviceList,
  getTodayAqiLineChartData,
  getWarningMessageList,
} from "@/api/index";
export default {
  name: "Noise",
  data() {
    return {
      pieChartData: [],
      noiseData: [],
      noiseTypes: [],
      warnings: [],
      noiseMonitors: [],
      classOption: {
        singleHeight: 36,
      },
      currentMonitorStatis: {
        aqi: {
          level_list: [],
        },
        pm10: {},
        pm25: {},
        noise: {},
      },
      aqiLineChartData: [],
    };
  },
  computed: {},
  methods: {
    computedPercentage(value, max) {
      return Number(
        Number(Number(Number(value) / Number(max)) * 100).toFixed(2)
      );
    },
    getTime(ts) {
      let date = new Date(ts);
      let year = date.getFullYear();
      let month = date.getMonth() + 1;
      let day = date.getDate();
      month = month > 9 ? month : "0" + month;
      day = day < 10 ? "0" + day : day;
      let today = year + "-" + month + "-" + day;

      let hour = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
      let min =
        date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
      let sec =
        date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
      return `${today} ${hour}:${min}:${sec}`;
    },
    renderDeviceChart() {
      const pieData = [...this.pieChartData];
      const chart = this.$echarts.init(this.$refs.deviceChart);
      let total = 0;
      pieData.map((item) => {
        total += item.value;
      });
      const option = {
        title: {
          x: "27%", //X坐标
          y: "35%",
          text: total,
          subtext: "总数",
          textAlign: "center",
          textStyle: {
            //标题样式
            fontSize: 30,
            fontWeight: "bolder",
            color: "#00fcff",
          },
          subtextStyle: {
            //副标题样式
            fontSize: 16,
            fontWeight: "bolder",
            color: "rgba(255,255,255,0.7)",
          },
        },
        tooltip: {
          trigger: "item",
        },
        legend: {
          itemHeight: 12,
          itemWidth: 12,
          icon: "rect",
          right: "10%",
          top: "20%",
          orient: "vertical",
          itemGap: 20,
          textStyle: {
            color: "inherit",
            rich: {
              a: {
                fontSize: 14,
                align: "left",
              },
              b: {
                fontSize: 20,
                align: "left",
                lineHeight: 25,
              },
            },
          },
          formatter: (name) => {
            let data = pieData;
            let target;
            for (let i = 0, l = data.length; i < l; i++) {
              if (data[i].name == name) {
                target = data[i].value;
              }
            }
            let arr = [`{a|${name}}`, `{b|${target}} 台`];
            return arr.join("   ");
          },
        },
        series: [
          {
            type: "pie",
            radius: ["80%", "90%"],
            center: ["28%", "50%"],
            avoidLabelOverlap: false,
            itemStyle: {
              borderRadius: 20,
              borderWidth: 4,
            },
            label: {
              show: false,
              position: "center",
            },

            data: pieData,
          },
        ],
      };
      chart.setOption(option);
      this.$nextTick(() => {
        // 解决echarts图表放大溢出父容器
        const resizeOb = new ResizeObserver((entries) => {
          for (const entry of entries) {
            this.$echarts.getInstanceByDom(entry.target).resize();
          }
        });
        resizeOb.observe(document.getElementById("device-chart"));
      });
    },
    renderNoiseChart() {
      const chartData = [...this.noiseData];
      const chart = this.$echarts.init(this.$refs.noiseChart);
      const option = {
        title: {
          x: "27%", //X坐标
          y: "32%",
          subtext: "近30日\n噪音情况",
          textAlign: "center",
          subtextStyle: {
            //副标题样式
            fontSize: 16,
            fontWeight: "bolder",
            lineHeight: 24,
            color: "rgba(255,255,255,0.7)",
          },
        },
        tooltip: {
          trigger: "item",
        },
        legend: {
          itemHeight: 12,
          itemWidth: 12,
          icon: "rect",
          right: "10%",
          top: "30%",
          orient: "vertical",
          itemGap: 40,
          textStyle: {
            color: "inherit",
            rich: {
              a: {
                fontSize: 14,
                align: "left",
              },
              b: {
                fontSize: 20,
                align: "left",
                lineHeight: 25,
              },
            },
          },
          formatter: (name) => {
            let data = chartData;
            let target;
            for (let i = 0, l = data.length; i < l; i++) {
              if (data[i].name == name) {
                target = data[i].value;
              }
            }
            let arr = [`{a|${name}}`, `{b|${target}} 天`];
            return arr.join("   ");
          },
        },
        series: [
          {
            type: "pie",
            radius: ["80%", "90%"],
            center: ["28%", "50%"],
            avoidLabelOverlap: false,
            itemStyle: {
              borderRadius: 20,
              borderWidth: 4,
            },
            label: {
              show: false,
              position: "center",
            },

            data: chartData,
          },
        ],
      };
      chart.setOption(option);
      this.$nextTick(() => {
        // 解决echarts图表放大溢出父容器
        const resizeOb = new ResizeObserver((entries) => {
          for (const entry of entries) {
            this.$echarts.getInstanceByDom(entry.target).resize();
          }
        });
        resizeOb.observe(document.getElementById("noise-chart"));
      });
    },
    renderAQIChart() {
      const xAxisData = this.aqiLineChartData.map((item) => {
        return item.hour;
      });
      const yAxisData = this.aqiLineChartData.map((item) => {
        return item.aqi_value;
      });
      const chart = this.$echarts.init(this.$refs.aqiChart);
      const option = {
        color: ["#5E97F6"],
        grid: {
          top: 30,
          bottom: 30,
          left: 30,
          right: 30,
        },
        tooltip: {
          trigger: "axis",
        },
        xAxis: {
          type: "category",
          data: xAxisData,
          axisTick: { show: false },
          axisLabel: {
            fontSize: "12",
            color: "#c6def9",
          },
        },
        yAxis: {
          type: "value",
          axisLabel: {
            fontSize: "12",
            color: "#c6def9",
          },
          splitNumber: 4,
          splitLine: {
            lineStyle: {
              color: "rgba(95, 120, 144, 0.4)",
            },
          },
        },
        series: [
          {
            data: yAxisData,
            type: "line",
            smooth: true,
            areaStyle: {
              color: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [
                {
                  offset: 0,
                  color: "#5E97F6",
                },
                {
                  offset: 1,
                  color: "rgba(0,0,0,0)",
                },
              ]),
            },
          },
        ],
      };
      chart.setOption(option);
      this.$nextTick(() => {
        // 解决echarts图表放大溢出父容器
        const resizeOb = new ResizeObserver((entries) => {
          for (const entry of entries) {
            this.$echarts.getInstanceByDom(entry.target).resize();
          }
        });
        resizeOb.observe(document.getElementById("aqi-chart"));
      });
    },
    formatText(value, text) {
      return String(text);
    },
    renderAqiQualityChart() {
      const chart = this.$echarts.init(this.$refs.aqiQualityChart);
      const option = {
        title: {
          x: "49%", //X坐标
          y: "64%",
          subtext: this.currentMonitorStatis.aqi.level,
          textAlign: "center",
          subtextStyle: {
            //副标题样式
            fontSize: 24,
            fontWeight: "bolder",
            lineHeight: 24,
            color: this.currentMonitorStatis.aqi.color,
          },
        },
        series: [
          {
            type: "gauge",
            center: ["50%", "60%"],
            startAngle: 230,
            endAngle: -50,
            min: 0,
            max: 100,
            itemStyle: {
              color: this.currentMonitorStatis.aqi.color,
            },
            progress: {
              show: true,
              width: 30,
            },
            pointer: {
              show: false,
            },
            axisLine: {
              lineStyle: {
                width: 30,
                color: [[1, "#183C6B"]],
              },
            },
            axisTick: {
              distance: -45,
              splitNumber: 5,
              lineStyle: {
                width: 2,
                color: "#183C6B",
              },
            },
            splitLine: {
              show: false,
            },
            axisLabel: {
              show: false,
            },
            anchor: {
              show: false,
            },
            title: {
              show: false,
            },
            detail: {
              valueAnimation: true,
              width: "60%",
              lineHeight: 40,
              borderRadius: 8,
              offsetCenter: [0, -10],
              fontSize: 46,
              fontWeight: "bolder",
              formatter: () => {
                return this.currentMonitorStatis.aqi.value;
              },
              color: "#fff",
            },
            data: [
              {
                value: Number(this.currentMonitorStatis.aqi.percentage),
              },
            ],
          },
        ],
      };
      chart.setOption(option);
      this.$nextTick(() => {
        // 解决echarts图表放大溢出父容器
        const resizeOb = new ResizeObserver((entries) => {
          for (const entry of entries) {
            this.$echarts.getInstanceByDom(entry.target).resize();
          }
        });
        resizeOb.observe(document.getElementById("aqi-quality-chart"));
      });
    },
    getNoiseData() {
      getDeviceTotalStatus({ top_cat: 9 }).then((res) => {
        this.pieChartData = res.data;
        this.renderDeviceChart();
      });
      getNearMonthStatis({
        start_log_time: this.getTime(new Date().getTime() - 2592000000),
        end_log_time: this.getTime(new Date().getTime()),
      }).then((res) => {
        this.noiseData = res.data.noise_data;
        this.noiseTypes = res.data.aqi_data;
        this.renderNoiseChart();
      });
      getCurrentMonitorStatis().then((res) => {
        this.currentMonitorStatis = res.data;
        this.$nextTick(() => {
          this.renderAqiQualityChart();
        });
      });
      getTodayAqiLineChartData().then((res) => {
        this.aqiLineChartData = res.data;
        this.$nextTick(() => {
          this.renderAQIChart();
        });
      });
      getWarningMessageList({
        start_log_time: this.getTime(new Date().getTime() - 2592000000),
        end_log_time: this.getTime(new Date().getTime()),
      }).then((res) => {
        this.warnings = res.data;
      });
      getNoiseDeviceList({ top_cat: 9 }).then((res) => {
        this.noiseMonitors = res.data;
      });
    },
  },
  mounted() {
    this.getNoiseData();
  },
};
</script>
<style lang="less" scoped>
#noise {
  padding: 12px 20px;
  display: flex;
  justify-content: space-between;
  .side-area {
    width: 25%;
  }
  .mid-area {
    width: calc(50% - 40px);
    margin: 0 20px;
  }
}
.chart-container {
  position: relative;
  .custom-chart {
    position: absolute;
    width: 30%;
    top: 50%;
    transform: translateY(-50%);
    left: 13%;
  }
}
#device-chart,
#noise-chart {
  width: 100%;
  height: 210px;
}
.i-type {
  display: flex;
  font-size: 14px;
  color: #c6def9;
  padding: 3px;
  .slider {
    width: 70%;
    vertical-align: top;
  }
  .i-type-name,
  .i-type-count {
    width: 15%;
    vertical-align: top;
    line-height: 30px;
    text-align: right;
    span {
      font-size: 16px;
    }
  }
  .i-type-count {
    width: 12%;
  }
  .i-type-name {
    padding-right: 12px;
  }
}
.el-progress {
  padding: 12px 0;
}
#aqi-chart {
  width: 100%;
  height: 214px;
}
.monitor {
  display: flex;
  justify-content: space-between;
  .lt-status,
  .rt-status {
    width: 20%;
    text-align: center;
  }
}
.el-divider {
  opacity: 0.3;
  background: #7e8ed4;
}
::v-deep .el-progress-circle__track {
  stroke: #183c6b;
}
::v-deep .el-progress__text {
  font-size: 16px;
  color: #c6def9 !important;
}
::v-deep .el-progress-circle {
  width: 88px !important;
  height: 88px !important;
}
.rt-single-status {
  display: flex;
  padding: 7px 0;
  .left-des {
    text-align: center;
    width: 64px;
    div {
      margin-bottom: 12px;
      font-size: 16px;
      color: #22c3ed;
    }
  }
  img {
    width: 40px;
    vertical-align: top;
  }
  .rt-value {
    width: calc(100% - 64px);
    font-size: 12px;
    color: #c6def9;
    opacity: 0.8;
    line-height: 72px;
    span {
      font-size: 26px;
      margin-right: 12px;
    }
  }
}
.status-unit {
  font-size: 16px;
  color: #c6def9;
  text-align: center;
}
::v-deep .el-divider--horizontal {
  margin: 16px 0;
}
.mid-aqi {
  width: 60%;
}
.aqi-background {
  height: 100%;
  background: url("@/assets/noise/img_bj.png") no-repeat;
  background-size: 80%;
  background-position: 50% 15%;
  zoom: 1.2;
}
#aqi-quality-chart {
  width: 100%;
  height: 300px;
}
.aqi-level {
  transform: translateY(-80px);
}
.aqi-level-line {
  width: 80%;
  margin: 0 auto;
  display: flex;
  margin-bottom: 12px;
  & > div {
    width: calc(100% / 6);
    height: 12px;
  }
  & > div:first-child {
    border-top-left-radius: 6px;
    border-bottom-left-radius: 6px;
  }
  & > div:last-child {
    border-top-right-radius: 6px;
    border-bottom-right-radius: 6px;
  }
}
.aqi-level-text {
  width: 80%;
  display: flex;
  margin: 0 auto;
  font-size: 14px;
  color: #c6def9;
  opacity: 0.8;
  & > div {
    width: calc(100% / 6);
    height: 12px;
    text-align: center;
  }
}
.warn-title {
  border-left: 2px solid;
  padding-left: 12px;
  font-size: 14px;
  color: #c6def9;
  display: flex;
  justify-content: space-between;
  margin-bottom: 18px;
  &:nth-child(3n-2) {
    border-color: #fd175d;
  }
  &:nth-child(3n-1) {
    border-color: #ab75ff;
  }
  &:nth-child(3n) {
    border-color: #ffbb37;
  }
  .warn-text {
    width: 60%;
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
  }
  .warn-time {
    width: 40%;
    text-align: right;
  }
}
.noise-monitor {
  font-size: 14px;
  color: #c6def9;
  margin-bottom: 18px;
  img {
    width: 20px;
    vertical-align: top;
  }
  &:last-child {
    margin-bottom: 0;
  }
}
.warp {
  width: 100%;
  height: 180px;
  overflow: hidden;
}
.overflowed {
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
}
</style>