ReportPreviewModal.vue 5.25 KB
<template>
  <div>
    <BasicModal
      destroyOnClose
      v-bind="$attrs"
      width="60rem"
      :height="heightNum"
      @register="register"
      title="报表趋势图"
      :showOkBtn="false"
    >
      <div :class="[initChartData.length % 2 !== 0 ? '' : 'wrapper']">
        <div
          v-if="initChartData.length > 0"
          :class="[initChartData.length % 2 !== 0 ? '' : 'chart-style']"
        >
          <div
            :class="[
              initChartData.length % 2 !== 0 ? '' : 'inner',
              initChartData.length % 2 !== 0 ? '' : 'item',
            ]"
            v-for="(item, index) in initChartData"
            :key="index"
          >
            <p style="display: none">{{ item }}</p>
            <div :id="`chart${index}`" :style="{ height, width }"></div>
          </div>
        </div>
        <div v-else style="display: flex; justify-content: center; align-items: center">
          <div style="position: relative; left: 0rem; top: 3rem">暂无数据</div>
        </div>
      </div>
    </BasicModal>
  </div>
</template>
<script setup lang="ts">
  import { ref, PropType, nextTick } from 'vue';
  import { BasicModal, useModalInner } from '/@/components/Modal';
  import * as echarts from 'echarts';
  import { exportViewChartApi } from '/@/api/export/exportManager';
  import moment from 'moment';

  defineProps({
    width: {
      type: String as PropType<string>,
      default: '100%',
    },
    height: {
      type: String as PropType<string>,
      default: '400px',
    },
  });
  defineEmits(['register']);
  const heightNum = ref(800);
  const getItem: any = ref([]);
  const initChartData: any = ref([]);
  //生成随机颜色
  let getRandomColor = function () {
    return (
      'rgb(' +
      Math.round(Math.random() * 255) +
      ',' +
      Math.round(Math.random() * 255) +
      ',' +
      Math.round(Math.random() * 10) +
      ')'
    );
  };
  const [register, { setModalProps }] = useModalInner(async (data) => {
    setModalProps({ loading: true });
    try {
      const entityId = data.record.executeCondition?.executeAttributes.map((m) => m?.device);
      let key = data.record.executeCondition?.executeAttributes.map((m) => m?.attributes);
      let params: any = {};
      params = {
        ...data.record.executeCondition?.executeCondition,
        ...{
          keys: key.length !== 0 ? key.join(',') : '',
        },
      };
      const result = await exportViewChartApi(entityId[0], params);
      getItem.value = Object.entries(result).map((item) => {
        const [attr, val] = item;
        return { attr, val };
      });
      //服务端返回值
      initChartData.value = getItem.value.map((item): any => {
        const seriesData = item.val.map((m1) => Number(m1.value));
        return {
          attr: item.attr,
          lengendData: [item.attr],
          xAxisData: item.val.map((m) => moment(m.ts).format('YYYY-MM-DD HH:mm:ss')),
          seriesData: [
            {
              name: item.attr,
              type: 'line',
              data: seriesData,
              lineStyle: {
                color: getRandomColor(),
              },
            },
          ],
        };
      });
      nextTick(() => {
        initChartData.value.forEach((item, index) => {
          let myChart = echarts.init(document.getElementById(`chart${index}`) as HTMLElement);
          let myOption = {
            title: {
              text: `${item.attr}趋势图`,
              subtext: `${item.attr}`,
              left: 'left',
            },
            tooltip: {
              trigger: 'axis',
            },
            legend: {
              data: item.lengendData,
              top: '20px',
            },
            toolbox: {},
            grid: {
              left: '8%',
              right: '8%',
              bottom: '12%',
              containLabel: true,
            },
            dataZoom: [
              {
                type: 'slider',
                show: true,
                startValue: 0,
                endValue: 5,
                height: '30',
                bottom: '4%',
              },
            ],
            xAxis: {
              type: 'category',
              data: item.xAxisData,
              boundaryGap: false,
              axisPointer: { type: 'shadow' },
              axisLabel: {
                interval: 0, 
                rotate: 65,
                textStyle: {
                  color: '#000',
                  fontSize: 10,
                },
              },
              axisLine: {
                show: true,
                interval: 0,
                lineStyle: {
                  color: 'RGB(210,221,217)',
                },
              },
            },
            yAxis: {
              type: 'value',
              boundaryGap: false,
            },
            series: item.seriesData,
          };
          myChart.setOption(myOption);
          //自适应
          window.addEventListener('resize', () => {
            myChart.resize();
          });
        });
      });
    } finally {
      setModalProps({ loading: false });
    }
  });
</script>
<style lang="less" scoped>
  @import url('./ReportPreviewModal.less');
  .chart-style {
    display: flex;
    flex-wrap: wrap;
    width: 825px;
    margin-top: 10px;
    justify-content: space-between;
  }
</style>