<!--
 * @Title: 
 * @Description: 
 * @version: 
 * @Author: wzs
 * @Date: 2023-02-10 16:03:08
 * @LastEditors: wzs
 * @LastEditTime: 2023-02-27 15:03:03
-->
<template>
  <div :class="className" :style="{ height: height, width: width }" />
</template>
<script>
// import path from 'path';
import { deepMerge, deepClone } from './util/index';
import config from './config/index';
import themes from './theme/index';
import { toRgb } from './util/color';
import resize from './util/resize';

import * as echarts from 'echarts';
// import 'echarts-liquidfill';
export default {
  name: 'ElChart',
  mixins: [resize],
  props: {
    className: {
      type: String,
      default: 'chart'
    },
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '300px'
    },
    dataset: {
      type: [Object, Array],
      default: function() {
        return {};
      }
    },
    option: {
      type: Object,
      default: () => {
        return {};
      }
    },
    type: {
      type: String,
      default: 'bar'
    },
    theme: {
      type: String,
      default: 'easyv'
    },
    title: {
      type: [Object, String, null],
      default: null
    },
    legend: {
      type: [Object, null],
      default: null
    },
    grid: {
      type: [Object, null],
      default: null
    },
    xAxis: {
      type: [Object, null],
      default: null
    },
    yAxis: {
      type: [Object, null],
      default: null
    },
    polar: {
      type: [Object, null],
      default: null
    },
    radiusAxis: {
      type: [Object, null],
      default: null
    },
    angleAxis: {
      type: [Object, null],
      default: null
    },
    radar: {
      type: [Object, null],
      default: null
    },
    dataZoom: {
      type: [Object, null],
      default: null
    },
    visualMap: {
      type: [Object, null],
      default: null
    },
    tooltip: {
      type: [Object, null],
      default: null
    },
    axisPointer: {
      type: [Object, null],
      default: null
    },
    toolbox: {
      type: [Object, null],
      default: null
    },
    brush: {
      type: [Object, null],
      default: null
    },
    geo: {
      type: [Object, null],
      default: null
    },
    parallel: {
      type: [Object, null],
      default: null
    },
    parallelAxis: {
      type: [Object, null],
      default: null
    },
    singleAxis: {
      type: [Object, null],
      default: null
    },
    timeline: {
      type: [Object, null],
      default: null
    },
    series: {
      type: [Object, Array, null],
      default: null
    },
    color: {
      type: [Object, Array, null],
      default: null
    }
  },
  data() {
    return {
      chart: null,
      defaultOption: null,
      defaultTheme: null
    };
  },
  computed: {
    mergedOption: {
      get: function() {
        // console.log(this.option);
        if (
          JSON.stringify(this.defaultOption) === '{}' &&
          JSON.stringify(this.option) === '{}'
        ) {
          console.log('%cel-chart: 请传入参数option', 'color: red;');
        }
        return deepMerge(
          deepClone(this.defaultOption, true),
          this.option || []
        );
      },
      set: function(val) {
        // console.log(this.option);
        this.initChart();
      }
    },
    watchChanges() {
      return {
        theme: this.theme,
        title: this.title,
        legend: this.legend,
        grid: this.grid,
        xAxis: this.xAxis,
        yAxis: this.yAxis,
        polar: this.polar,
        radiusAxis: this.radiusAxis,
        angleAxis: this.angleAxis,
        radar: this.radar,
        dataZoom: this.dataZoom,
        visualMap: this.visualMap,
        tooltip: this.tooltip,
        axisPointer: this.axisPointer,
        toolbox: this.toolbox,
        brush: this.brush,
        geo: this.geo,
        parallel: this.parallel,
        parallelAxis: this.parallelAxis,
        singleAxis: this.singleAxis,
        timeline: this.timeline,
        series: this.series,
        color: this.color
      };
    }
  },
  watch: {
    dataset: {
      handler(val) {
        this.setDataset();
      },
      deep: true
    },
    watchChanges: {
      handler(val) {
        this.setOption();
      },
      deep: true
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.loadConfig();
    });
  },
  beforeDestroy() {
    if (!this.chart) {
      return;
    }
    this.chart.dispose();
    this.chart = null;
  },
  methods: {
    /**
     * @name: 加载默认配置
     * @description: 根据type类型加载默认配置
     * @return {*}
     */
    loadConfig() {
      const that = this;
      const type = that.type;
      const theme = that.theme;
      that.defaultOption = config[type] ? config[type] : {};
      that.defaultTheme = themes[theme];
      that.setOption();
      that.setDataset();
    },
    setOption() {
      const option = {};
      if (this.grid) {
        option.grid = this.grid;
      }
      if (this.title) {
        option.title = {
          text: this.title
        };
      }
      if (this.legend) {
        option.legend = this.legend;
      }
      if (this.xAxis) {
        option.xAxis = this.xAxis;
      }
      if (this.yAxis) {
        option.yAxis = this.yAxis;
      }
      if (this.polar) {
        option.polar = this.polar;
      }
      if (this.radiusAxis) {
        option.radiusAxis = this.radiusAxis;
      }
      if (this.angleAxis) {
        option.angleAxis = this.angleAxis;
      }
      if (this.radar) {
        option.radar = this.radar;
      }
      if (this.dataZoom) {
        option.dataZoom = this.dataZoom;
      }
      if (this.visualMap) {
        option.visualMap = this.visualMap;
      }
      if (this.tooltip) {
        option.tooltip = this.tooltip;
      }
      if (this.axisPointer) {
        option.axisPointer = this.axisPointer;
      }
      if (this.toolbox) {
        option.toolbox = this.toolbox;
      }
      if (this.brush) {
        option.brush = this.brush;
      }
      if (this.geo) {
        option.geo = this.geo;
      }
      if (this.parallel) {
        option.parallel = this.parallel;
      }
      if (this.parallelAxis) {
        option.parallelAxis = this.parallelAxis;
      }
      if (this.singleAxis) {
        option.singleAxis = this.singleAxis;
      }
      if (this.timeline) {
        option.timeline = this.timeline;
      }
      if (this.series) {
        option.series = this.series;
      }
      if (this.color) {
        option.color = this.color;
      }
      this.mergedOption = deepMerge(this.mergedOption, option);
    },
    /**
     * @name: 设置数据集
     * @description: 根据数据集的格式及type类型判断设置数据集
     * @return {*}
     */
    setDataset() {
      const mergedOption = this.mergedOption;
      if (
        Object.prototype.toString.call(this.dataset) === '[object Array]' &&
        this.dataset.length > 0
      ) {
        // 数据集是数组
        mergedOption.dataset = this.dataset;
      } else if (
        Object.prototype.toString.call(this.dataset) === '[object Object]' &&
        this.dataset &&
        this.dataset.source &&
        this.dataset.source.length > 0
      ) {
        mergedOption.dataset = this.dataset;
        // 数据集是对象
      }

      if (this.type === 'liquidFill') {
        // 水滴图
        mergedOption.series[0].data = [mergedOption.dataset.source[0].value];
      } else if (this.type === 'percentRing') {
        // 百分比环形图
        const value = mergedOption.dataset.source[0].value;
        // console.log(value);
        mergedOption.title.text = '{a|' + value + '}{c|%}';
        mergedOption.series[0].data[0].value = value;
        mergedOption.series[0].data[1].value = 100 - value;
      } else if (this.type === 'topThree') {
        mergedOption.dataset.source.map((item, index) => {
          mergedOption.series[0].data[index].name = item.name;
          mergedOption.series[0].data[index].value = item.value;
        });
      } else if (this.type === 'jade') {
        const theme = this.defaultTheme.theme;
        // 设置坐标名称
        mergedOption.radiusAxis.data = mergedOption.dataset.source.map(
          item => item.name
        );
        mergedOption.dataset.source.map((item, i) => {
          let colorStart = null;
          let colorEnd = null;
          if (typeof theme.color[i] === 'object') {
            colorStart = theme.color[i].colorStops[0].color;
            colorEnd = theme.color[i].colorStops[1].color;
          } else {
            colorStart = theme.color[i];
          }
          mergedOption.series[0].data.push({
            name: item.name,
            value: item.value,
            itemStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: toRgb(colorStart, 1) },
                {
                  offset: 1,
                  color: toRgb(colorEnd ? colorEnd : colorStart, 0.6)
                }
              ])
            }
          });
        });
      } else if (this.type === 'ring') {
        if (mergedOption.title.text) {
          mergedOption.series[0].name = mergedOption.title.text;
        }
        if (!mergedOption.legend.formatter) {
          mergedOption.legend.formatter = name => {
            var obj = this.dataset.source.find(e => e.name === name);
            return obj.name + '：' + obj.value.toLocaleString() + '万元';
          };
        }
      } else {
        const dataLen = mergedOption.dataset.dimensions.length;
        const series = [];
        for (let i = 0; i < dataLen - 1; i++) {
          const seriesItem = deepClone(mergedOption.series[0]);
          series[i] = mergedOption.series[i] ? deepMerge(deepClone(seriesItem), mergedOption.series[i]) : seriesItem;
        }
        mergedOption.series = series;
      }
      // console.log(mergedOption);
      this.mergedOption = mergedOption;
    },
    /**
     * @name: 初始化及更新图表
     * @description: 初始化及更新图表
     * @return {*}
     */
    initChart() {
      if (!this.chart) {
        this.chart = echarts.init(this.$el, this.defaultTheme.theme);
      }
      // console.log(this.mergedOption);
      this.chart.setOption(this.mergedOption, {
        notMerge: true,
        lazyUpdate: true
      });
      if (this._events.redirect) {
        this.chart.on('click', (params) => {
          console.log(this);
          this.$emit('redirect', params);
          params.event.stop();
        });
      }

    }
  }
};
</script>