<!-- 排名组件 -->
<template>
  <div>
    <div style="margin: 0 0 10px 3%;">
      TopNum：<el-input-number
        size="small"
        v-model="rankNums"
        :min="3"
        :max="pkgList && pkgList.length ? pkgList.length : 10"
        @change="rankChange"
      ></el-input-number>
      <font style="font=size:8px;color:#CCCC;margin-left: 10px;">
        {{
          "范围：(3 ≤ TopNum ≤ " +
            (pkgList && pkgList.length ? pkgList.length : 10) +
            ")"
        }}
      </font>
    </div>
    <slot></slot>
    <div ref="RankChart" :style="{ height: '360px', width: '80vw' }"></div>
    <slot name="bottom"></slot>
  </div>
</template>

<script>
import echarts from "echarts";
import setOption from "./option";

//原先是定义归因接口，后面才发现不是的，sqlid区分使用一个请求就够了
import { getAttributeGraphApi } from "@/api/report";

export default {
  name: "ZxRankChart",
  data() {
    return {
      chart: null, //排名表格数据初始化
      rankNums: 10, //需要展示的排名数
      timeLines: [], //图标下面的时间切换所需数据
      pkgPage: [
        // [{name:value},{name:value},{name:value}],
        // [{name:value},{name:value}]
      ],
      pkgList: []
    };
  },
  mounted() {
    this.chart = echarts.init(this.$refs.RankChart); //这里是为了获得容器所在位置
  },
  methods: {
    /**
     *  @method getChartsData
     *  父组件调用此方法，传递过来参数请求图表数据
     *    参数说明：
     *    @param {Array} queryDate 数组接收开始-结束时间，时间格式YYYY-MM-DD
     *    @param {String} agentMethod   投放方式
     *    @return
     */
    getChartsData(queryDate, agentMethod, pkgList) {
      //替换包名所需参数
      this.pkgList = pkgList;
      //这两个参数需要调整，默认是""，但是查询全部需要替换为"#ALL#"
      agentMethod = agentMethod === "" ? "#ALL#" : agentMethod;
      let params = {
        agentMethod: agentMethod,
        startDate: queryDate[0]
      };
      //判断查询的是一天的还是一天以上的数据
      if (queryDate[0] === queryDate[1]) {
        //按小时查询
        params["sqlId"] = 1110;
        this.setChartsData(params);
      } else {
        //按天查询
        params["sqlId"] = 1111;
        params["endDate"] = queryDate[1];
        this.setChartsData(params);
      }
    },
    /**
     * @method setChartsData
     *      可通过参数params.sqlId 来区分按小时（1110）还是按天（1111）查询
     *      @param {Object} params 请求参数
     */
    setChartsData(params) {
      getAttributeGraphApi(params)
        .then(res => {
          //请求结果响应判断
          if (res.status != 200) {
            this.$message.error(`Top排名响应出错，错误代码：${res.status}`);
            console.log("Top排名响应错误：", res);
            return;
          }
          //更换数据前先清空之前的数据
          this.timeLines = [];
          this.pkgPage = [];
          this.chart.clear();
          //请求数据是否为空
          if (res.result.data.length == 0) {
            this.$message.info("Top排名没有查询到数据！");
            return;
          }
          //判断是按天还是还小时查询
          if (params.sqlId == 1110) {
            this.isOneDay(res.result.data);
          } else if (params.sqlId == 1111) {
            //处理获取的原始数据，整合为可用数据，时间线是天
            this.timeLines = res.result.data.map(itm => {
              itm.info = itm.info.split(",");
              let onePkgPage = [];
              itm.info.map(inf => {
                if (inf.split(":")[0] === "#ALL#") return; //排除掉汇总字段
                let name = this.swapPkgName(inf.split(":")[0]);
                let val = parseFloat(inf.split(":")[1]);
                onePkgPage.push({ name: name, value: val });
              });
              this.pkgPage.push(onePkgPage);
              return itm.datadate;
            });
            //删除小时中的最后一个时间段，这里会影响按天查询的初始时间显示
            delete setOption.option.baseOption.timeline.currentIndex;
            //重绘图形
            this.initRankChart();
          }
        })
        .catch(err => {
          this.$message.error(`请求错误：${err}`);
          console.log(err);
        });
    },
    /**
     * @method swapPkgName 将包名参数替换为包名汉字
     *    @param pkg 包参数
     */
    swapPkgName(pkg) {
      let name = this.pkgList.find(itm => itm.value === pkg);
      return name ? name.label : pkg;
    },
    /**
     * 一天数据的展示按小时展示
     * @method isOneDay
     *  @param res 请求接口返回的图表所需的数据
     */
    isOneDay(res) {
      //按小时排序，有些数据是乱序的
      res.sort((a, b) => {
        return a.hours - b.hours;
      });
      //处理获取的原始数据，整合为可用数据，这里基本都是处理按小时计的
      this.timeLines = res.map(itm => {
        itm.info = itm.info.split(",");
        let onePkgPage = [];
        itm.info.map(inf => {
          if (inf.split(":")[0] === "#ALL#") return; //排除掉汇总字段
          let name = this.swapPkgName(inf.split(":")[0]);
          let val = parseFloat(inf.split(":")[1]);
          onePkgPage.push({ name: name, value: val });
        });
        this.pkgPage.push(onePkgPage);
        return itm.hours;
      });
      //求差值
      for (let i = this.pkgPage.length - 1; i > 0; i--) {
        this.pkgPage[i] = this.pkgPage[i].map(itm => {
          let val = this.pkgPage[i - 1].find(idx => idx.name === itm.name);
          if (val) {
            itm.value = Math.round((itm.value - val.value) * 100) / 100;
          }
          return itm;
        });
      }
      //这里按小时排序时设置轴线时间线为最后一个时间段
      setOption.option.baseOption.timeline["currentIndex"] =
        this.timeLines.length - 1;
      //重新绘图
      this.initRankChart();
    },
    /**
     * @method top数据变更重新绘图
     */
    rankChange() {
      //重新绘图
      this.initRankChart();
    },
    /**
     * @method 绘图
     */
    initRankChart() {
      //重置数据
      setOption.option.options = [];
      //设置每个时段的数据流
      for (let n = 0; n < this.timeLines.length; n++) {
        let res = [];
        for (let j = 0; j < this.pkgPage[n].length; j++) {
          res.push({
            name: this.pkgPage[n][j].name,
            value: this.pkgPage[n][j].value
          });
        }
        //选择展示的TOP数据条数
        if (this.rankNums) {
          res = res
            .sort(function(a, b) {
              return b.value - a.value;
            })
            .slice(0, this.rankNums);
        }
        //数据排序
        res.sort(function(a, b) {
          return b.value - a.value;
        });

        setOption.option.options.push({
          title: {
            text: (() => {
              let title = this.timeLines[n];
              if (this.timeLines[n].length < 3) {
                title += " 时";
              } else {
                let ary = title.split("-");
                title = ary[0] + "年" + ary[1] + "月" + ary[2] + "日";
              }
              return title;
            })()
          },
          xAxis: {
            data: res.map(itm => itm.name)
          },
          series: [
            {
              data: res.map(itm => itm.value)
            },
            {
              data: res.map(itm => itm.value)
            }
          ]
        });
      }
      setOption.option.baseOption.timeline["data"] = this.timeLines;
      this.chart.setOption(setOption.option, true);
    }
  }
};
</script>

<style></style>
