<!--
 * @Author: changjun
 * @FilePath: /yuan-qingdao-zld-browser/src/components/chart/RoseChart/RoseChart.vue
 * @Date: 2022-09-01 14:25:35
 * @Description: 
 * @LastEditTime: 2023-09-07 20:15:44
 * @LastEditors: 曹文丽
-->
<script setup lang="ts">
import { Ref, defineProps, watchEffect, onMounted, ref } from "vue";
import type { EChartsOption } from "echarts";
import { useECharts } from "../../../hooks/web/useECharts";
import { bigNumberTransform } from "../../../utils/utils";
import {
  getThemeColor,
  mergeOptions,
  getCommonTheme,
  getRoseChartThemeColor,
} from "../../../components/chart/options/index";
import { isObject } from "../../../utils/is";
// import { value } from "dom7";
import { mapMapping } from "../../../assets/map/provinceData";
const mapData = mapMapping();
const yaTheme = localStorage.getItem("YA_THEME");
const colorList = getThemeColor().colorList;
const chartRef = ref<HTMLDivElement | null>(null);
const { setOptions, getInstance, echarts } = useECharts(
  chartRef as Ref<HTMLDivElement>
);

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

interface RoseChartProps {
  /**
   * 名称，关联图表的 series
   */
  name: string;
  /**
   * 图表数据
   */
  chartData: any[];
  theme?: string;
  theme1?: boolean;
  colors?: string[];
  /**
   * 格式化图例显示函数 用于需要显示图例名称之外内容的时候
   */
  legendFormatter?: string | ((name: string) => string);
  labelFormatter?: string | ((name: string) => string);
  /**
   * 是否需要手动设置一些其它的设置，需要结合otherOptions才能起作用
   */
  manual?: boolean;
  pieCenter?: string[];
  radius?: string[];
  /**
   * 手动设置一些其它的设置，需要结合manual才能起作用
   */
  otherOptions?: EChartsOption;
  labelShow?: boolean;
  legendLeft?: string;
  legendRight?: string;
  legendTop?: string;
  labelWidth?: string;
  chartClass?: string;
  legendClass?: string;
  legendShow?: boolean;
  borderRadius?: number;
  borderWidth?: number;
  borderColor?: string;
  labelLineShow?: boolean;
  defaultType?: string;
  labelColor?: string;
  textColor?: string;
  textValueColor?: string;
  minMargin?: Number;
  tooltipValueFormatter?: any;
  tooltipFormatter?:
  | string
  | ((params: any, ticket: any, callback: any) => string);
}

const {
  name = "",
  chartData = [],
  manual = false,
  otherOptions = {},
  pieCenter = ["50%", "50%"],
  radius = ["5%", "60%"],
  colors = [],
  chartClass = "",
  labelShow = true,
  legendClass = "",
  labelWidth = "default",
  legendLeft = "0",
  legendRight = "0",
  legendTop = "35%",
  legendShow = true,
  theme = "light",
  labelFormatter = "",
  borderRadius = 5,
  borderWidth = 3,
  borderColor,
  labelLineShow = true,
  defaultType = "",
  tooltipFormatter = "",
  tooltipValueFormatter = (val) => bigNumberTransform(val),
  theme1 = false,
  labelColor = '',
  textColor = '',
  textValueColor = '',
  minMargin = 10
} = defineProps<RoseChartProps>();

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

const currentColors = computed(() => {
  if (unref(colors).length > 0) {
    return unref(colors);
  }
  return unref(currentTheme).colorList;
}) as any;

const currentRoseChartThemeColor = computed(() => {
  console.log(unref(theme), "------------");
  if (unref(theme1)) {
    return getRoseChartThemeColor("dark");
  } else {
    return getRoseChartThemeColor(unref(theme));
  }
}) as any;

let options: EChartsOption = {
  tooltip: {
    show: true,
    confine: true,
    backgroundColor: unref(tooltipFormatter)
      ? "transparent"
      : unref(currentTheme).tooltip.backgroundColor,
    textStyle: {
      color: unref(currentTheme).tooltip.textStyle.color,
    },
    trigger: "item",
    position: "top",
    borderColor: "transparent",
    extraCssText: "0px 0px 8px 0px rgba(0,0,0,0.2);border-radius: 4px;",
    valueFormatter: unref(tooltipValueFormatter),
    formatter: function (param) {
      //还原正常值
      return (
        "<span style='display: inline-block;width: 10px;height: 10px;background: " +
        param.color +
        ";border-radius: 100%;margin-right: 5px'></span>" +
        param.name +
        "&nbsp;&nbsp;&nbsp;" +
        param.data.realValue +
        "&nbsp;&nbsp;&nbsp;" +
        (parseFloat(param.data.percent) >= 0 ? param.data.percent + "%" : "")
      );
    },
  },
  legend: {
    show: false,
  },
  color: unref(currentColors),

  grid: {
    top: "5%",
    left: 0,
  },

  series: [
    {
      name: "",
      type: "pie",
      roseType: "area",
      center: unref(pieCenter),
      radius: unref(radius),
      // minAngle: 20,
      labelLine: {
        show: unref(labelLineShow),
        length: 1,
        length2: 5,
      },
      label: {
        show: unref(labelShow),
        color: yaTheme === "light" ? "rgba(0, 0, 0, 0.4)" : unref(labelColor) ? "rgba(255,255,255,0.4)" : "#96A2B5",
        lineHeight: 8,
        minMargin: unref(minMargin),
        rich: {
          name: {
            fontSize: 16,
            color: unref(textColor) ? unref(textColor) : unref(currentRoseChartThemeColor).rich.name,
            padding: [0, 0, 0, 0],
          },
          value: {
            fontSize: 14,
            color: unref(textValueColor) ? unref(textValueColor) : unref(currentRoseChartThemeColor).rich.value,
            padding: [0, 0, 0, 0],
          },
          percent: {
            fontSize: 14,
            color: unref(textValueColor) ? unref(textValueColor) : "rgba(255, 255, 255, 0.6)",
          },
        },
      },
      itemStyle: {
        borderRadius: unref(borderRadius),
        borderColor:
          unref(borderColor) || mapData?.en === "anhui" ? "#202b53" : "#001e3d",
        borderWidth: unref(borderWidth),
      },
      showEmptyCircle: true,
      emptyCircleStyle: {
        color:
          yaTheme === "light"
            ? unref(currentRoseChartThemeColor).emptyCircleStyle.color
            : "#4A6184",
      },
      data: chartData,
    },
  ],
};

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

async function initChart() {
  let maxNum = 0;
  var sumNumber = 0;
  unref(chartData).forEach((item) => {
    sumNumber += item.value;
    if (item.value >= maxNum) maxNum = item.value; //记录一个最大值
  });
  // 放大规则
  let number_sure = Math.round(maxNum * 0.2);
  options.series![0].data = unref(chartData).map((item) => {
    const value = item.value;
    return Object.assign({}, item, {
      realValue: bigNumberTransform(value),
      value: number_sure + value,
    });
  });
  options.series![0].name = unref(name);
  // options.series![0].data = unref(chartData);
  options.series![0].center = unref(pieCenter);
  options.series![0].radius = unref(radius);
  options.series![0].label.show = unref(labelShow);
  if (unref(labelFormatter)) {
    options.series![0].label.formatter = unref(labelFormatter);
  }
  if (unref(tooltipFormatter)) {
    // @ts-ignore
    options.tooltip!.formatter = unref(tooltipFormatter);
  }
  options.color = unref(currentColors);
  initChartDataActiveList();
  // 如果是手动设置模式的话
  if (unref(manual) && isObject(unref(otherOptions))) {
    options = mergeOptions(options, unref(otherOptions));
  }
  setOptions(options);
  console.log(unref(currentRoseChartThemeColor), "---------");
}

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

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

const handleClick = (name) => {
  const instance = getInstance();
  if (instance) {
    instance.dispatchAction({
      type: "legendToggleSelect",
      name: name,
    });
    console.log(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;
});
</script>

<template>
  <div class="chart-flex">
    <div class="chart" :class="chartClass" ref="chartRef"
      :style="{ width: defaultType == 'two' ? '60%' : '100%', height: '100%' }"></div>
    <div class="custom-rose-legend" v-if="legendShow" :class="legendClass" :style="getLegendStyle">
      <div class="custom-rose-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"
        :key="index" @click="handleClick(item.name)">
        <div style="display: flex; align-items: center">
          <div class="circle-icon" :style="{
            background: activeList.includes(item.name)
              ? colorList[index]
              : '#ddd',
          }"></div>
          <div class="legend-label" :class="{
            getLabelWidth,
          }">
            {{ item.name }}
          </div>
        </div>
        <div class="legend-value">
          {{ bigNumberTransform(item.valueFormat || item.value) }}
          <span v-if="item.percentage">（{{ item.percentage }}）</span>
        </div>
      </div>
    </div>
  </div>
</template>

<style lang="scss">
.chart-flex {
  display: flex;
  align-items: center;
  justify-content: unset;
  width: 100%;
  height: 100%;
  position: relative;
}

.custom-rose-legend {
  position: absolute;
  width: 40%;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;

  .custom-rose-legend-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    margin-bottom: 12px;
    padding-right: 20px;
    cursor: pointer;

    .circle-icon {
      width: 6px;
      height: 6px;
      border-radius: 6px;
      flex-shrink: 0;
      margin-right: 5px;
      background: #ddd;
    }

    .legend-label {
      font-size: 14px;
      color: rgba(140, 236, 255, 1);
      // min-width: 70%;
      // max-width: 80%;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    .width-self {
      min-width: 0;
    }

    .legend-value {
      font-size: 12px;
      color: rgba(154, 239, 255, 1);
      margin-left: 8px;
      font-family: YouSheBiaoTiHei;
    }
  }
}

.custom-rose-legend-item.is-active {
  .legend-label {
    color: rgba(140, 236, 255, 1);
  }

  .legend-value {
    color: rgba(154, 239, 255, 1);
  }
}

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

  .legend-label {
    color: #ddd;
  }

  .legend-value {
    color: #ddd;
  }
}

.custom-rose-legend .custom-rose-legend-item:last-child {
  margin-bottom: 0 !important;
}

.rose-linechart-tooltip {
  padding: 6px 10px;
  box-sizing: border-box;
  border-radius: 4px;
  display: flex;
  flex-direction: column;

  .rose-linechart-flex {
    display: flex;
    align-items: center;
  }

  &-subtitle {
    font-size: 12px;
    font-weight: 600;
    color: rgba(0, 0, 0, 0.65);
    line-height: 1;
  }

  &-content {
    &-item {
      display: flex;
      align-items: center;
      margin-top: 8px;

      &-icon {
        width: 6px;
        height: 6px;
        border-radius: 6px;
        margin-right: 5px;
        position: relative;
        top: 2px;
      }

      &-name {
        font-size: 12px;
        color: rgba(0, 0, 0, 0.65);
        margin-right: 8px;
      }

      &-value {
        font-size: 12px;
        color: rgba(0, 0, 0, 0.4);
        text-align: right;
      }
    }
  }
}

.rose-linechart-tooltip {
  background: rgba(9, 103, 138, 0.8);
  padding: 9px 12px;
  border-radius: 3px;
  color: #fff;
  font-size: 12px;
  font-weight: 400;
  min-width: 150px;
  padding-top: 12px;

  .rose-linechart-tooltip-content-item-icon {
    // margin-top: 12px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
  }

  .rose-linechart-tooltip-subtitle {
    color: #fff;
    font-size: 12px;
    // margin-top: 12px;
  }

  .rose-linechart-tooltip-content-item-value {
    font-weight: 400;
    color: #fff;
  }
}

.line-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>
