<template>
  <div class="m-chart">
    <canvas id="myChart" width="400" height="260"></canvas>
  </div>
</template>

<script>
import nextTick from "dai-js/tools/nextTick";
// ios下字体渲染有bug
const fontFamily = "PingFang SC";
const fontSize = 14;

let chart;
let srcData = [];

let textShapeList = [];
const addTextShape = () => {
  if (textShapeList.length > 0) {
    textShapeList.forEach((item) => {
      item.remove(true);
    });
    textShapeList = [];
  }
  // 添加折线上文本
  const canvas = chart.get("canvas");
  const group = canvas.addGroup();
  const shapes = {};

  function addFn(list) {
    const listLength = list.length;
    list.forEach(function (obj, index) {
      // 避免显示太多，乱七八糟
      if (listLength > 7 && index > 0 && index < listLength - 1) {
        if (index % Math.ceil(listLength / 5) != 0) {
          return;
        }
      }

      const offsetX = 6;
      const offsetY = 1;
      const point = chart.getPosition(obj);
      const text = group.addShape("text", {
        attrs: {
          x: obj.type === "支持" ? point.x + 2 * offsetX : point.x - offsetX,
          y: point.y + offsetY,
          text: obj.value,
          textAlign: "center",
          textBaseline: "bottom",
          fill: "#333",
          fontWeight: 500,
          fontFamily,
          fontSize,
        },
      });

      textShapeList.push(text); // 缓存该 shape, 便于后续查找
    });
  }
  srcData.sort((a, b) => {
    return new Date(a.date).getTime() - new Date(b.date).getTime();
  });
  let supData = srcData.filter((item) => item.type == "支持");
  let oppData = srcData.filter((item) => item.type == "反对");
  addFn(supData);
  addFn(oppData);
};

const iniChart = function (config, srcData) {
  chart = new window.F2.Chart({
    id: "myChart",
    ...config,
  });

  const supColor = "#FFDA0E";
  const oppColor = "#00E5ED";

  chart.source(srcData, {
    date: {
      range: [0, 1],
      type: "timeCat",
      mask: "MM-DD",
    },
    value: {
      // type: "linear",
    },
  });
  // 设置坐标轴
  chart.axis("date", {
    line: {
      lineWidth: 1,
      stroke: "#E7EEEE",
    },
    label: {
      fontWeight: 500,
      fontSize,
      fill: "#B5B7BF",
      textBaseline: "middle",
    },
    labelOffset: 25,
    country: {
      range: [0.1, 0.9], // 配置 range 范围，使左右两边不留边距
    },
    grid: null,
  });
  chart.axis("value", {
    line: {
      lineWidth: 1,
      stroke: "#E7EEEE",
    },
    labelOffset: 20,
    label: {
      fontWeight: 500,
      fontSize,
      fill: "#B5B7BF",
    },
  });
  // 类别标识区
  chart.legend({
    position: "bottom",
    align: "center",
    offsetY: -30,
    custom: true,
    nameStyle: {
      fill: "#999",
      fontWeight: 500,
      fontSize,
    },
    itemWidth: 150,
    wordSpace: 25,
    items: [
      {
        name: "支持",
        marker(x, y, r, ctx) {
          ctx.lineWidth = 10;
          ctx.strokeStyle = supColor;
          ctx.moveTo(x - r - 15, y);
          ctx.lineTo(x + r + 15, y);
          ctx.stroke();
          ctx.fill();
        },
      },
      {
        name: "反对",
        marker(x, y, r, ctx) {
          ctx.lineWidth = 10;
          ctx.strokeStyle = oppColor;
          ctx.moveTo(x - r - 15, y);
          ctx.lineTo(x + r + 15, y);
          ctx.stroke();
          ctx.fill();
        },
      },
    ],
  });
  // 添加折线
  chart
    .line()
    .position("date*value")
    .color("type", (type) => {
      if (type === "支持") {
        return supColor;
      }
      return oppColor;
    })
    .style("type", {
      lineWidth: 1,
    })
    .animate();
  chart.render();

  addTextShape();

  // 注意：需要把chart return 出来
  return chart;
};

export default {
  name: "chart",
  props: {
    list: {
      type: Array,
      default: () => {
        return [];
      },
    },
    config: {
      type: Object,
      default: () => {
        return {};
      },
    },
  },
  data() {
    return {
      iniLoading: false,
    };
  },
  watch: {
    list(data) {
      chart.changeData(data);
      srcData = data;
      addTextShape();
    },
  },
  async created() {
    await nextTick(200);
    iniChart(this.config, this.list);
    await nextTick(200);
    this.iniLoading = true;
  },
};
</script>

<style lang="scss" scoped></style>
