<template>
  <div ref="chart" :style="chartStyle"></div>
</template>

<script>
/**
 * 饼状图
 * 因为 legend, titleType模拟圆心（title和subtitle）变种太大，提供了默认值供覆写
 * 调整width/height来处理legend的位置和现实更方便（调整center_x/center_y容易导致截断）
 * titleType存在即显示默认圆心
 * 
  <!-- 基础用法 -->
  <pie-chart-plus 
    :seriesData="pieChartOptions.seriesData"
  ></pie-chart-plus>
  
  <!-- 全量配置 -->
  <pie-chart-plus 
    :seriesData="pieChartOptions.seriesData" 
    width="800" 
    height="400" 
    theme="light" 
    :color="['#f00', '#0f0', '#00f']" 
    :radius="['30%', '75%']" 
    center_x="50%" 
    center_y="50%" 
    :legend="{ orient: 'vertical', bottom: 'center', right: 10 }" 
    titleType="场景1" 
    label 
    borderWidth="2" 
    roseType="radius"
  ></pie-chart-plus>
**/

import * as echarts from 'echarts';

export default {
  name: 'PieChartPlus',
  props: {
    // 系列数据 (数组对象)
    seriesData: {
      type: Array,
      required: true
    },
    // 图表宽度(支持 400（px） '100%' '100vh'等格式)
    width: {
      type: [String, Number],
      default: '100%'
    },
    // 图表高度
    height: {
      type: [String, Number],
      default: '400px'
    },
    // 主题 (可选值: 'dark', 'light', 自定义主题)
    theme: {
      type: String,
      default: 'light'
    },
    // 调色盘
    color: {
      type: Array,
      default: () => ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc']
    },
    // 圆环内外半径
    radius: {
      type: Array,
      default: () => ['0%', '75%']
    },
    // 中心点：影响center和title的位置
    center_x: {
      type: [String],
      default: '50%'
    },
    center_y: {
      type: [String],
      default: '50%'
    },
    // 图例--支持覆写调整
    legend: {
      type: Object,
      default: () => ({
        orient: 'horizontal', // horizontal-水平(默认) vertical-垂直
        top: '0%',
        left: 'center',
      })
    },
    // 用title.text和用title.subtext模拟圆环内部的样式
    // 处理标题的整块差异：因为无法使用插槽且情况复杂多变，null custom1 custom2 custom3 自定义类型进行匹配
    titleType: {
      type: String,
      default: null
    },
    // 标签显示
    label: {
      type: Boolean,
      default: false
    },
    // 扇区间隔
    borderWidth: {
      type: [String, Number],
      default: 0
    },
    // 图表类型：默认普通类型 radius ——南丁格尔, area ——基础南丁格尔（占比相同）
    roseType: {
      type: String,
      default: null
    },
  },
  data() {
    return {
      chartInstance: null
    };
  },
  computed: {
    chartStyle() {
      const parseDimension = (value) => {
        if (typeof value === 'number') {
          // 数字类型，添加 px 单位
          return `${value}px`;
        } else if (typeof value === 'string') {
          // 字符串类型，检查是否需要添加 px 单位
          const numericValue = parseFloat(value);
          if (!isNaN(numericValue) && value.trim() === numericValue.toString()) {
            // 纯数字字符串，添加 px 单位
            return `${numericValue}px`;
          }
          // 已经包含单位（如 '100%' 或 '400px'），直接返回
          return value;
        }
        // 默认值
        return '100%';
      };

      return {
        width: parseDimension(this.width),
        height: parseDimension(this.height)
      };
    }
  },
  watch: {
    seriesData: 'updateChart',
    theme: 'initChart'
  },
  mounted() {
    this.initChart();
  },
  beforeDestroy() {
    this.disposeChart();
  },
  methods: {
    // 初始化
    initChart() {
      // 主题切换需要销毁
      if (this.chartInstance) {
        this.disposeChart();
      }
      this.chartInstance = echarts.init(this.$refs.chart, this.theme);
      this.updateChart();
      window.addEventListener('resize', this.resizeChart);
    },
    // 销毁
    disposeChart() {
      if (this.chartInstance) {
        this.chartInstance.dispose();
        this.chartInstance = null;
      }
      window.removeEventListener('resize', this.resizeChart);
    },
    // 监听缩放
    resizeChart() {
      if (this.chartInstance) {
        this.chartInstance.resize();
      }
    },
    // 更新图表
    updateChart() {
      if (!this.chartInstance) return;
      const option = this.getOption();
      this.chartInstance.setOption(option);
    },
    // 加载配置
    getOption() {
      let seriesObj = {
        type: 'pie',
        radius: this.radius,
        center: [this.center_x, this.center_y],
        data: this.seriesData,
        label: {
          show: this.label,
          position: 'outside',
          formatter: (params) => {
            return `${params.name}\n${params.value}(${params.percent.toFixed(0)}%)`;
          }
        },
        itemStyle: {
          borderWidth: this.borderWidth,
        },
        minAngle: 5, // 最小角度
      }

      if (this.roseType && ['radius', 'area'].includes(this.roseType)) {
        seriesObj.roseType = this.roseType;
      }
      // 只能枚举几个类型，供选择
      let title = null
      // 提供一个默认基础版
      if (this.titleType !== null) {
        title = {
          text: '统计量',
          subtext: this.calculateTotal(),
          left: 'center',
          top: '43%', // center是text居中，并不是包含subtext的整体居中
          textStyle: {
            fontSize: 16,
            fontWeight: 'normal',
          },
          subtextStyle: {
            fontSize: 24,
            fontWeight: 'bold',
            color: '#ee6666'
          }
        }
      }
      // 枚举几个类型/场景，进行匹配或覆写
      switch (this.titleType) {
        case '场景1':
          title.xxx = 'xxx'
          break;
        case '场景2':
          title.xxx = 'xxx'
          break;
      }

      return {
        backgroundColor: 'transparent', // 背景选用传入，放弃默认背景色
        // 提示框
        tooltip: {
          trigger: 'item', // 饼图使用item触发
          formatter: '{b}: {c} ({d}%)' // 提示框格式
        },
        // 调色盘
        color: this.color,
        // 图例
        legend: this.legend,
        // 标题(模拟圆心)
        title,
        // 数据集
        series: [seriesObj],
      };
    },
    // 计算数据总和
    calculateTotal() {
      return this.seriesData.reduce((sum, item) => sum + item.value, 0);
    },
  }
};
</script>

<style scoped></style>