<!--
 * @Author: changjun
 * @FilePath: /yuan-qingdao-zld-browser/src/components/chart/CustomChart/crossBarChart.vue
 * @Date: 2022-08-29 16:06:58
 * @Description: 
 * @LastEditTime: 2022-09-13 15:16:03
 * @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, getBarChartThemeColor, getCommonTheme } 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>);
import { useLineXAxisAuto } from '../logic/useLineXAxisAuto'

/**
 * @author changjun
 * @description 基础组件-柱状图组件
 * @prop { String } title 图表左上显示内容
 * @prop { Array } xAxisData x轴数据
 * @prop { Function } legendFormatter 图例自定义显示
 * @prop { Object } otherOptions 手动设置一些其它的设置 结合manual
 * @prop { Function } legendFormatter 图例自定义显示函数
 * @date 2022/08/29
 */
interface BarChartProps {
  title?: string,
  yAxisData: any[],
  theme?: string,
  autoXAxis?: boolean,
  /**
   * 图表数据
   */
  chartData: any[],
  /**
   * 格式化图例显示函数 用于需要显示图例名称之外内容的时候
   */
  legendFormatter?: string | ((name: string) => string);
  italics?: boolean,
  /**
   * 是否需要手动设置一些其它的设置，需要结合otherOptions才能起作用
   */
  manual?: boolean,
  /**
   * 手动设置色盘
   */
  colors?: string[],
  /**
   * 柱状图同一系列是否开启堆叠
   */
  stack?: boolean,
  tooltipValueFormatter?: any;
  /**
   * 手动设置一些其它的设置，需要结合manual才能起作用
   */
  otherOptions?: EChartsOption
  barGradientColor?: string[],
  xInterval?: number,
  gridTop?: string | number,
  gridBottom?: string | number,
  gridLeft?: string | number,
  gridRight?: string | number,
}

const {
  yAxisData = [],
  title = '',
  chartData = [],
  legendFormatter = (name) => name,
  manual = false,
  theme = 'light',
  otherOptions = {},
  colors = [],
  barGradientColor = [],
  stack = false,
  tooltipValueFormatter = (val) => val,
  autoXAxis = false,
  gridTop = 44,
  gridBottom = 24,
  gridLeft = 24,
  gridRight = 24
} = defineProps<BarChartProps>()


const currentTheme = computed(() => {
  return getBarChartThemeColor(unref(theme))
}) as any;


const commonChartTheme = computed(() => {
  return getCommonTheme(unref(theme))
}) as any

let options: EChartsOption = {
  title: {
    show: unref(title) ? true : false,
    text: unref(title),
    top: 16,
    left: 24,
    textStyle: {
      fontSize: 12,
      color: unref(currentTheme).titleColor,
      fontWeight: 400,
    }
  },

  tooltip: {
    trigger: 'axis',
    axisPointer: {
      type: 'shadow'
    },
    textStyle: {
      color: unref(commonChartTheme).tooltip.textStyle.color,
    },
    valueFormatter: unref(tooltipValueFormatter),
    show: true,
    confine: true,
    backgroundColor: 'rgba(35, 67, 107, .9)',
    borderColor: 'transparent',
    extraCssText: 'box-shadow: 4px 7px 15px 0px rgba(13,49,86,0.3);border-radius: 4px;'
  },

  grid: {
    top: unref(gridTop),
    left: unref(gridLeft),
    right: unref(gridRight),
    bottom: unref(gridBottom),
    containLabel: true
  },

  dataZoom: {
    type: 'slider',
    show: false,
    yAxisIndex: 0,
    startValue: 0,
    endValue: 6,
  },
  
  legend: {
    top: 16, // 距离容器上边界的距离
    right: 24, // 距离容器右边界的距离
    itemWidth: 12, // 图例宽度
    itemHeight: 12, // 图例高度
    itemGap: 16, // 图例间距
    icon: 'roundRect',
    // 图例文字的样式
    textStyle: {
      fontSize: 10,
      fontWeight: 400,
      color: unref(currentTheme).legendTextColor
    },
    formatter: unref(legendFormatter)
  },

  xAxis: [
    {
      type: 'value',
      axisLabel: {
        fontSize: 10,
        fontWeight: 400,
        color: unref(currentTheme).axisLabelColor,
      },
      axisTick: { show: false },
      axisLine: {
        show: true,
        lineStyle: {
          color: unref(currentTheme).axisLineColor
        }
      },
      splitLine: {
        show: false
      }
    }
  ],

  yAxis: [
    {
      data: [],
      axisLabel: {
        fontSize: 12,
        fontWeight: 400,
        color: unref(currentTheme).axisLabelColor,
        width: 100,
        // @ts-ignore
        overflow: 'break'
      },
      splitLine: {
        // 坐标轴分割线
        show: false,
      },
      axisLine: {
        show: true,
        lineStyle: {
          color: unref(currentTheme).axisLineColor
        }
      },
    }
  ],

  series: []
}


const getSeriesData = function (list) {
  const _colors = unref(colors).length > 0 ? unref(colors) : unref(currentTheme).colorList;
  return list.map((item, index) => {
    const newItem = {
      type: 'bar',
      barWidth: '30%',
      itemStyle: {
        color: _colors[index],
        borderRadius: [0, 0, 0, 0]
      },
    } as any

    if (unref(stack)) {
      newItem.stack = 'stack'
    }

    if (unref(barGradientColor).length > 0) {
      newItem.itemStyle.color = {
        type: 'linear',
        x: 0,
        y: 0,
        x2: 0,
        y2: 1,
        colorStops: [{
          offset: 0, color: unref(barGradientColor)[0] // 0% 处的颜色
        }, {
          offset: 1, color: unref(barGradientColor)[1] // 100% 处的颜色
        }],
        global: false
      }
    }
    return {
      ...newItem,
      ...item,
    }
  })
}

let stopAutoShowFun = null as any
watchEffect(() => {
  options.series = getSeriesData(unref(chartData))
  console.log('options', options)
  options.yAxis![0].data = unref(yAxisData)
  // @ts-ignore
  options.title!.text = unref(title)
  // @ts-ignore
  options.legend!.formatter = unref(legendFormatter)
  // 如果是手动设置模式的话
  if (unref(manual) && isObject(unref(otherOptions))) {
    options = mergeOptions(options, unref(otherOptions))
  }
  openAutoAxis()
  setOptions(options)
})

function openAutoAxis() {
  if (unref(autoXAxis) && unref(chartData).length > 0 && unref(yAxisData).length > 7) {
    if (stopAutoShowFun) {
      stopAutoShowFun()
    }
    const instance = getInstance();
    const { stopAutoSwipe } = useLineXAxisAuto(instance, options, unref(yAxisData))
    stopAutoShowFun = stopAutoSwipe
  }
}

</script>
  
<template>

  <div class="chart" ref="chartRef" :style="{ width: '100%', height: '100%' }"></div>

</template>
  