<!--
 * @Author: changjun
 * @FilePath: /yuan-qingdao-zld-browser/src/components/chart/CircularDiagram/CircularDiagram.vue
 * @Date: 2022-08-27 15:51:36
 * @Description: 
 * @LastEditTime: 2022-09-14 14:36:38
 * @LastEditors: changjun
-->
<script setup lang="ts">
import { Ref, defineProps, watchEffect } from 'vue';
import type { EChartsOption } from 'echarts'
import { useECharts } from '../../../hooks/web/useECharts';
import { colorList, mergeOptions } from '../../../components/chart/options/index'
import { isObject } from '../../../utils/is';
const chartRef = ref<HTMLDivElement | null>(null);
const { setOptions, getInstance, echarts } = useECharts(chartRef as Ref<HTMLDivElement>);

/**
 * @author changjun
 * @description 基础组件-环形图组件
 * @prop { String } name 关联图表的series
 * @prop { Array } chartData 图表数据
 * @prop { Boolean } manual 手动设置 结合otherOptions
 * @prop { Object } otherOptions 手动设置一些其它的设置 结合manual
 * @prop { Function } legendFormatter 图例自定义显示函数
 * @date 2022/08/29
 */

/**
 * @desc: 环形图图表组件
 * @author: changjun
 */

interface CircularDiagramChartProps {
  /**
   * 名称，关联图表的 series
   */
  name : string
  /**
   * 图表数据
   */
  chartData: any[],
  tooltipValueFormatter?: any;
  /**
   * 格式化图例显示函数 用于需要显示图例名称之外内容的时候
   */
  legendFormatter?: string | ((name: string) => string);
  /**
	 * 是否需要手动设置一些其它的设置，需要结合otherOptions才能起作用
	 */
	manual?: boolean,
  pieCenter?: string[],
  radius?: string[]
	/**
	 * 手动设置一些其它的设置，需要结合manual才能起作用
	 */
	otherOptions?: EChartsOption,
  legendLeft?: string,
  legendRight?: string,
  legendTop?: string,
  labelWidth?: string,
  chartClass?: string,
  legendClass?: string,
  legendLayout?: string,
  otherType?: string,
}

const { 
  name = '', 
  chartData = [], 
  legendFormatter = (name) => name,  
  manual = false, 
  otherOptions = {},
  pieCenter = ['25%', '50%'],
  radius = ['50%', '70%'],
  chartClass = '',
  legendClass = '',
  labelWidth = 'default',
  legendLeft = '0',
  legendRight = '0',
  legendTop = '35%',
  legendLayout = 'horizontal',
  otherType = 'default',
  tooltipValueFormatter = (val) => val,
} = defineProps<CircularDiagramChartProps>()


let options: EChartsOption = {

  tooltip: {
    show: true,
    borderColor: 'transparent',
    valueFormatter: unref(tooltipValueFormatter),
  },

  color: colorList,

  grid: {
    top: '5%'
  },

  legend: {
    show: false,
    top: 'middle',
    left: 'middle',
    orient: 'vertical',
    itemGap: 25,
    icon: 'circle',
    backgroundColor: 'transparent',
    itemWidth: 8,
    itemHeight: 8,
    height: '65%',
    padding: [0, 0, 0, 0],
    textStyle: {
      rich: {
        subtitle: {
          fontSize: 12,
          color: 'rgba(0,0,0,0.4)',
          padding: [0, 0, 0, 20],
          align: 'right',
          width: 70
        },
        title: {
          fontSize: 14,
          color: 'rgba(0,0,0,0.65)',
          backgroundColor: 'transparent',
        }
      },
      color: 'rgba(0,0,0,0.65)',
      fontSize: '14px'
    }
  },

  series: [
    {
      name: '',
      type: 'pie',
      center: unref(pieCenter),
      radius: unref(radius),
      label: {
        show: false
      },
      data: chartData,
      showEmptyCircle: true,
    }
  ]
}



let activeList = ref([]) as any // 定义一个激活的状态表
const initChartDataActiveList = () => {
   const list = unref(chartData).map((item) => {
    return item.name
  })
  activeList.value = list
}


async function initChart() {
  options.series![0].name = unref(name)
  options.series![0].data = unref(chartData)
  // @ts-ignore
  options.legend!.formatter = unref(legendFormatter)
  options.series![0].center = unref(pieCenter)
  options.series![0].radius = unref(radius)
  // 如果是手动设置模式的话
	if(unref(manual) && isObject(unref(otherOptions))){
		options = mergeOptions(options, unref(otherOptions))
	}
  initChartDataActiveList()
  console.log(activeList, 'activeList')
  setOptions(options);
}

onMounted(() => {
  initChart()
})

watchEffect(() => {
  initChart()
})


const handleClick = (name) => {
  const instance = getInstance();
  if (instance) {
    instance.dispatchAction({
      type: 'legendToggleSelect',
      name: name
    })
    if(unref(activeList).includes(name)){
      activeList.value = unref(activeList).filter((item) => item !== name)
    }else{
      activeList.value = [...unref(activeList), name]
    }
  }
}


const handleHover = (name) => {
  const instance = getInstance();
  if (instance) {
    instance.dispatchAction({
      type: 'highlight',
      name: name
    })
  }
}

const handleHoverLeave = (name) => {
  const instance = getInstance();
  if (instance) {
    instance.dispatchAction({
      type: 'downplay',
      name: name
    })
  }
}


const getLabelWidth = computed(() => {
  return unref(labelWidth) === 'default' ? 'width-default' : 'width-self'
})

const getLegendStyle = computed(() => {
  const _style = {
    right: unref(legendRight),
    top: unref(legendTop),
  } as any
  if(unref(legendLeft) !== '0'){
    _style.left = unref(legendLeft)
  }
  return _style
})


const getLegendClass = computed(() => {
  let _class = `${unref(legendClass)}`
  if(unref(legendLayout) === 'vertical'){
    _class += ' legend-vertical'
  }
  return _class
})

</script>

<template>
  <div class="chart" :class="chartClass" ref="chartRef" :style="{ width: '100%', height: '100%' }"></div>
  <div v-if="otherType == 'default'" class="custom-circle-legend" :class="getLegendClass" :style="getLegendStyle">
    <div class="custom-circle-legend-item"  @mouseover="handleHover(item.name)"  @mouseleave="handleHoverLeave(item.name)" :class="activeList.includes(item.name) ? 'is-active': 'is-unactive'" v-for="(item,index) in chartData" @click="handleClick(item.name)">
      <div class="circle-icon" :style="{ background: activeList.includes(item.name) ? colorList[index] : '#ddd'}"></div>
      <div class="circle-icon-flex">
        <div class="legend-label" :class="getLabelWidth">{{ item.name }}</div>
        <div class="legend-value">{{ item.valueFormat ||  item.value}}</div>
      </div>
    </div>
  </div>
  <div v-if="otherType == 'one'" class="custom-circle-legend-one" :class="getLegendClass" :style="getLegendStyle">
    <div class="custom-circle-legend-item custom-circle-legend-item-center"  @mouseover="handleHover(item.name)"  @mouseleave="handleHoverLeave(item.name)" :class="activeList.includes(item.name) ? 'is-active': 'is-unactive'" v-for="(item,index) in chartData" @click="handleClick(item.name)">
      <div class="circle-icon" :style="{ background: activeList.includes(item.name) ? colorList[index] : '#ddd'}"></div>
      <div class="circle-icon-flex">
        <div class="legend-label" :class="getLabelWidth">{{ item.name }}</div>
        <div class="legend-value">{{ item.valueFormat ||  item.value}}{{item.unit}}</div>
      </div>
    </div>
  </div>
</template>


<style lang="scss">
.custom-circle-legend {
  position: absolute;
  width: 50%;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
 
}

.custom-circle-legend-item{
    display: flex;
    align-items: center;
    width: 48%;
    margin-bottom: 12px;
    margin-right: 2%;
    cursor: pointer;
    .circle-icon-flex {
      display: flex;
      align-items: center;
      // justify-content: space-between;
      width: 100%;
    }
    .circle-icon{
      width: 6px;
      height: 6px;
      border-radius: 6px;
      flex-shrink: 0;
      margin-right: 5px;
      background: #ddd;
    }

    .legend-label{
      font-size: 12px;
      color: rgba(0,0,0,0.65);
      // padding: 0 20px 0 0;
      width: 50%;
      // margin-right: 20px;
    }

    .width-self{
      min-width: 0;
    }
    
    .legend-value {
      font-size: 12px;
      color: rgba(0,0,0,0.4);
      // min-width: 120px;
      // margin-left: 30px;
    }
  }
.custom-circle-legend-item-center {
  width: 100%;
}
.custom-circle-legend-item.is-active{
  .legend-label{
    color: rgba(0,0,0,0.65);
  }
  .legend-value{
    color: rgba(0,0,0,0.4);
  }
}

.custom-circle-legend-item.is-unactive{
  .circle-icon{
    background: #ddd;
  }
  .legend-label{
    color: #ddd;
  }
  .legend-value {
    color: #ddd;
  }
}

.custom-circle-legend.legend-vertical{
  display: flex;
  flex-direction: column;
  
}

.custom-circle-legend-one {
  position: absolute;
  width: 50%;
}
</style>
