<!--
 * @Author: changjun
 * @FilePath: /yuan-qingdao-zld-browser/src/components/chart/BarChart/BarChart.vue
 * @Date: 2022-08-29 16:06:58
 * @Description: 
 * @LastEditTime: 2023-04-25 11:26:52
 * @LastEditors: 李佐宁
-->
<script setup lang="ts">
import { Ref, defineProps, watchEffect } from "vue";
import type { EChartsOption } from "echarts";
import { bigNumberTransform } from "@/utils/utils";
import { useECharts } from "@/hooks/web/useECharts";
import {
  colorList,
  mergeOptions,
  getBarChartThemeColor,
  getCommonTheme,
} from "@/components/chart/options/index";
import { getThemeColor } from "@/components/chart/options/theme";
import { isObject } from "@/utils/is";
import img1 from "@/assets/image/monitor.png";
const chartRef = ref<HTMLDivElement | null>(null);
const { setOptions, getInstance, echarts } = useECharts(
  chartRef as Ref<HTMLDivElement>
);
import useEchartsAutoTooltip from "@/components/chart/logic/useEchartsAutoTooltip";
import { isArray } from "@vue/shared";
const yaTheme = localStorage.getItem("YA_THEME");
const themeColor = getThemeColor();
console.log(yaTheme, "jasper");
/**
 * @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;
  xAxisData: any[];
  theme?: string;
  autotip?: 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;
  legendTop?: number;
  legendRight?: number;
  gridBottom?: number;
  tooltipFormatter?:
    | string
    | ((params: any, ticket: any, callback: any) => string);
  pictorialBar?: boolean;
  isShowSide?: boolean;
}

let {
  xAxisData = [],
  title = "",
  chartData = [],
  legendFormatter = (name) => name,
  manual = false,
  theme = "light",
  italics = false,
  otherOptions = {},
  colors = [],
  barGradientColor = [],
  xInterval = 0,
  stack = false,
  tooltipValueFormatter = (val) => bigNumberTransform(val),
  autotip = false,
  legendTop = 16,
  legendRight = 0,
  gridBottom = 0,
  tooltipFormatter = "",
  pictorialBar = false,
  isShowSide = false,
} = 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: 0,
    textStyle: {
      fontSize: 12,
      color: yaTheme === "light" ? "rgba(0, 0, 0, 0.4)" : "#8CECFF",
      fontWeight: 400,
    },
  },

  tooltip: {
    trigger: "axis",
    axisPointer: {
      type: "shadow",
    },
    textStyle: {
      color: unref(commonChartTheme).tooltip.textStyle.color,
    },
    formatter: function (params) {
      let _resHtml = "";
      const axisValue = params[0]?.axisValue;
      const _unit = "";
      params.forEach((item) => {
        let { color, seriesName, value, seriesType } = item;
        if (seriesType !== "bar") {
          return;
        }
        seriesName = seriesName.split("（")[0];
        _resHtml += `<div class="line-chart-tool-item">
            <div class="line-chart-tool-info">
              <div class="line-chart-tool-item-icon" style="background: ${color}"></div>
              <div class="line-chart-tool-item-name">${seriesName}</div>
            </div>
            <div class="line-chart-tool-item-value">${value}</div>
				</div>`;
      });
      return `<div class="bar-chart-tool-bg">
			<div class="line-chart-tool-bg-subtitle">${axisValue}</div>
			<div class="line-chart-tool-bg-content">
				${_resHtml}
			</div>
		</div>`;
    },
    valueFormatter: unref(tooltipValueFormatter),
    show: true,
    confine: true,
    backgroundColor: unref(tooltipFormatter)
      ? "transparent"
      : unref(commonChartTheme).tooltip.backgroundColor,
    borderColor: "transparent",
    extraCssText: "border-radius: 4px;",
  },

  grid: {
    top: 55,
    left: 0,
    right: 24,
    bottom: unref(gridBottom),
    containLabel: true,
    backgroundColor: "rgba(0,172,236,0.08)",
    show: true,
    borderWidth: 0,
  },

  legend: {
    top: unref(legendTop), // 距离容器上边界的距离
    right: unref(legendRight), // 距离容器右边界的距离
    itemWidth: 12, // 图例宽度
    itemHeight: 12, // 图例高度
    itemGap: 16, // 图例间距
    icon: "roundRect",
    // 图例文字的样式
    textStyle: {
      fontSize: 12,
      fontWeight: 400,
      color:
        yaTheme === "light"
          ? "rgba(0, 0, 0, 0.4)"
          : yaTheme === "jasper"
          ? "#fff"
          : "#8CECFF",
    },
    formatter: unref(legendFormatter),
  },
  xAxis: [
    {
      data: unref(xAxisData),
      axisLabel: {
        fontSize: 10,
        fontWeight: 400,
        color: yaTheme === "light" ? "rgba(0, 0, 0, 0.4)" : "#8CECFF",
        interval: unref(xInterval),
        rotate: unref(italics) ? 60 : 0,
      },
      axisTick: { show: false },
      axisLine: {
        show: true,
        lineStyle: {
          color: "rgba(154, 239, 255, 0.22)",
          width: 1,
        },
      },
    },
  ],

  yAxis: [
    {
      type: "value",
      minInterval: 1,
      min: 5,
      nameTextStyle: {
        fontSize: 12,
        color: yaTheme === "light" ? "rgba(0, 0, 0, 0.4)" : "#96A2B5",
        padding: [0, 0, 0, 50],
      },
      axisLabel: {
        fontSize: 10,
        fontWeight: 400,
        color: yaTheme === "light" ? "rgba(0, 0, 0, 0.4)" : "#8CECFF",
        formatter: function (value) {
          if (value >= 100000000) {
            return value / 100000000 + "亿";
            // } else if (value >= 10000000) {
            //   return value / 10000000 + "千万";
            // } else if (value >= 1000000) {
            //   return value / 1000000 + "百万";
            // } else if (value >= 100000) {
            //   return value / 100000 + "十万";
          } else if (value >= 10000) {
            return value / 10000 + "万";
          } else {
            return value;
          }
        },
      },
      splitLine: {
        // 坐标轴分割线
        show: false,
        lineStyle: { color: yaTheme === "light" ? "#f4f4f4" : "#32496D" }, // 分割线颜色
      },
      axisLine: {
        show: true,
        lineStyle: {
          color: "rgba(154, 239, 255, 0.22)",
          width: 1,
        },
      },
    },
  ],

  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: isArray(_colors[index])
          ? {
              type: "linear",
              x: 0,
              y: 0,
              x2: 0,
              y2: 1,
              colorStops: [
                {
                  offset: 0,
                  color: _colors[index][0], // 0% 处的颜色
                },
                {
                  offset: 1,
                  color: _colors[index][1], // 100% 处的颜色
                },
              ],
              global: false,
            }
          : _colors[index],
        borderRadius: [2, 2, 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(() => {
  if (unref(chartData).length === 0) return;
  options.series = getSeriesData(unref(chartData));
  options.xAxis![0].data = unref(xAxisData);
  options.xAxis[0].axisLabel.interval = unref(xInterval);
  let yAXisValue = null;
  chartData.forEach((item) => {
    yAXisValue = item.data.find((item) => Number(item) > 0) || yAXisValue;
  });
  options.yAxis![0].min = yAXisValue ? 0 : 5;
  // @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));
  }
  if (unref(autotip)) {
    if (stopAutoShowFun) {
      stopAutoShowFun();
    }
    openAutoTooltip();
  }
  if (options.series.length > 1) {
    let yAxis = JSON.parse(JSON.stringify(options.yAxis[0]));
    options.yAxis[1] = yAxis;
    options.yAxis = options.yAxis.map((item, index) => {
      item.name = options.series[index].until;
      return item;
    });
  }
  if (unref(pictorialBar)) {
    let maxData = 0;
    options.series[0].data.forEach((item) => {
      maxData = Math.max(maxData, item);
    });
    let maxDataArr = new Array(options.series[0].data.length).fill(maxData);
    options.series.push(
      {
        type: "pictorialBar",
        itemStyle: {
          normal: {
            color: "rgba(19, 56, 85, 1)",
            borderWidth: 0,
          },
        },
        symbolRepeat: "fixed",
        symbolMargin: 2,
        symbol: "rect",
        symbolClip: true,
        symbolPosition: "start",
        symbolSize: ["100%", 3],
        symbolOffset: [0, -1],
        data: maxDataArr,
        barWidth: options.series[0].barWidth,
        z: 0,
        zlevel: 1,
      },
      {
        type: "pictorialBar",
        itemStyle: {
          normal: {
            color: "rgba(17, 47, 70, 1)",
            borderWidth: 0,
          },
        },
        symbolRepeat: "fixed",
        symbolMargin: 2,
        symbol: "rect",
        symbolClip: true,
        symbolPosition: "start",
        symbolSize: ["100%", 3],
        symbolOffset: [0, -1],
        data: options.series[0].data,
        barWidth: options.series[0].barWidth,
        z: 0,
        zlevel: 1,
      }
    );
  }
  isShowSide && initXside();
  setOptions(options);
});

// 增加手柄
function initXside() {
  // maxSpan/minSpan 40显示个数为5，后面可以动态设置
  options.dataZoom = {
    type: "slider",
    showDetail: false, //即拖拽时候滚动条两侧不显示信息 默认true
    realtime: true, //拖动滚动条时是否动态的更新图表数据
    height: 20, //滚动条高度
    maxSpan: 40,
    minSpan: 40,
    handleSize: "100%", // 两侧手柄的大小
    backgroundColor: "#32496D", // 滚动条背景色
    borderColor: "#32496D", // 滚动条边框色
    bottom: 0, // 滚动条位置
    handleIcon: "image://" + img1,
    dataBackground: {
      lineStyle: {
        color: "rgba(84, 188, 255, 1)", // 滚动条内线颜色
      },
    },
    moveHandleSize: 0, // 移动手柄高度
  };
}

function openAutoTooltip() {
  const instance = getInstance();
  const { stopAutoShow } = useEchartsAutoTooltip(instance, options);
  stopAutoShowFun = stopAutoShow;
}

onUnmounted(() => {
  stopAutoShowFun && stopAutoShowFun();
});
</script>

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

<style lang="scss">
.bar-chart-tool-bg {
  // background: rgba(9, 103, 138, 0.8);
  // padding: 9px 12px;
  // border-radius: 3px;
  // color: #fff;
  // font-size: 12px;
  // font-weight: 400;
  // min-width: 150px;
  .line-chart-tool-bg-subtitle {
    font-weight: bold;
  }
  .line-chart-tool-info {
    display: flex;
    align-items: center;
  }
  .line-chart-tool-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    .line-chart-tool-item-icon {
      width: 9px;
      height: 9px;
      border-radius: 50%;
      margin-right: 5px;
    }
    .line-chart-tool-item-value {
      font-weight: 400;
      margin-left: 10px;
      // font-family: YouSheBiaoTiHei;
    }
  }
}
</style>
