<template>
  <div class="echart-render chart-box">
    <h3 class="chart-title">{{ chartTitle }}</h3>
    <v-chart
      :options="chartOption"
      v-if="chartOption"
      autoresize
      ref="vueChart"
    ></v-chart>
    <p class="chart-none" v-else>暂无数据</p>
  </div>
</template>

<script>
import echarts from "echarts/lib/echarts";

export default {
  name: "echart-render",
  props: {
    chartType: {
      type: String,
      required: true,
      validator(value) {
        return (
          ["bar", "barReverse", "pie", "line", "barGroup", "lineGroup"].indexOf(
            value
          ) !== -1
        );
      }
    },
    chartData: {
      type: [Object, Array],
      required: true
    },
    chartTitle: {
      type: String,
      default: ""
    },
    chartColor: {
      type: Array,
      default() {
        return [
          "#22C0FF",
          "#41CD7D",
          "#FF7786",
          "#4E7CFF",
          "#6d32f9",
          "#dd7755"
        ];
      }
    }
  },
  data() {
    return {
      chartOption: null
    };
  },
  mounted() {
    this.getOptions();
  },
  methods: {
    getOptions() {
      const name = this.chartType[0].toUpperCase() + this.chartType.slice(1);
      this.chartOption = this[`get${name}Option`](this.chartData);
    },
    getLineOption(datas) {
      let labels = [],
        vals = [];
      datas.map(item => {
        labels.push(item.name);
        vals.push(item.value);
      });
      const linearColor = new echarts.graphic.LinearGradient(0, 1, 0, 0, [
        {
          offset: 1,
          color: "rgba(34,192,255,1)"
        },
        {
          offset: 0,
          color: "rgba(34,192,255,0)"
        }
      ]);

      return {
        grid: {
          top: "10%",
          bottom: "12%",
          left: "5%",
          right: "5%"
        },
        tooltip: {
          show: true,
          formatter: function(params) {
            return params.value + "%";
          }
        },
        xAxis: {
          type: "category",
          data: labels,
          splitLine: {
            show: true,
            lineStyle: {
              color: "rgba(231,234,241,1)"
            }
          },
          axisLine: {
            lineStyle: {
              color: "rgba(231,234,241,1)"
            }
          },
          axisLabel: {
            color: "#7C86A3",
            fontSize: 12,
            fontWeight: "bold"
          },
          axisTick: {
            show: false
          }
        },
        yAxis: {
          type: "value",
          splitLine: {
            show: true,
            lineStyle: {
              color: "rgba(231,234,241,1)"
            }
          },
          axisLine: {
            lineStyle: {
              color: "rgba(231,234,241,1)"
            }
          },
          axisLabel: {
            fontSize: 12,
            color: "#7C86A3",
            formatter: function(value, index) {
              return value + "%";
            }
          },
          axisTick: {
            show: false
          }
        },
        series: [
          {
            name: "数量",
            type: "line",
            smooth: true,
            data: vals,
            itemStyle: {
              color: "rgba(34, 192, 255, 1)"
            },
            lineStyle: {
              color: "rgba(34, 192, 255, 1)"
            },
            areaStyle: {
              color: linearColor
            }
          }
        ]
      };
    },
    getPieOption(datas) {
      if (!datas.chartLabels.length) return;
      const seriesData = datas.chartLabels.map(function(item, index) {
        return {
          name: item,
          value: datas.chartData[0][index]
        };
      });
      return {
        grid: {
          top: "24%",
          bottom: "10%"
        },
        tooltip: {
          trigger: "item",
          formatter: "{a} <br/>{b} : {c} ({d}%)"
        },
        legend: {
          show: true,
          itemGap: 20,
          itemWidth: 20,
          textStyle: {
            fontSize: 16
          }
        },
        series: [
          {
            name: "数量",
            type: "pie",
            radius: "70%",
            data: seriesData,
            label: {
              show: false
            },
            itemStyle: {
              emphasis: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: "rgba(0, 0, 0, 0.5)"
              }
            }
          }
        ]
      };
    },
    getBarOption(datas) {
      if (!datas.names.length) return;
      return {
        color: this.chartColor,
        grid: {
          top: "20%",
          bottom: "10%",
          left: "8%",
          right: "5%"
        },
        tooltip: {
          show: true
        },
        xAxis: {
          type: "category",
          data: datas.names,
          axisLine: {
            lineStyle: {
              color: "rgba(231,234,241,1)"
            }
          },
          axisLabel: {
            color: "#7C86A3",
            fontSize: 12,
            fontWeight: "bold"
          },
          axisTick: {
            show: false
          }
        },
        yAxis: {
          type: "value",
          splitLine: {
            show: true,
            lineStyle: {
              color: "rgba(231,234,241,1)"
            }
          },
          axisLine: {
            lineStyle: {
              color: "rgba(231,234,241,1)"
            }
          },
          axisLabel: {
            color: "#7C86A3",
            fontSize: 12,
            fontWeight: "bold"
          },
          axisTick: {
            show: false
          }
        },
        series: [
          {
            name: this.chartTitle || "值",
            type: "bar",
            barWidth: 16,
            data: datas.dataList,
            itemStyle: {
              barBorderRadius: 4
            }
          }
        ]
      };
    },
    getBarReverseOption(datas) {
      if (!datas.names.length) return;
      return {
        color: this.chartColor,
        grid: {
          top: "20%",
          bottom: "10%",
          left: "12%",
          right: "5%"
        },
        tooltip: {
          show: true
        },
        yAxis: {
          type: "category",
          data: datas.names,
          axisLine: {
            lineStyle: {
              color: "rgba(231,234,241,1)"
            }
          },
          splitLine: {
            show: true,
            lineStyle: {
              color: "rgba(231,234,241,1)"
            }
          },
          axisLabel: {
            color: "#7C86A3",
            fontSize: 12,
            fontWeight: "bold"
          },
          axisTick: {
            show: false
          }
        },
        xAxis: {
          type: "value",
          splitLine: {
            show: false,
            lineStyle: {
              color: "rgba(231,234,241,1)"
            }
          },
          axisLine: {
            lineStyle: {
              color: "rgba(231,234,241,1)"
            }
          },
          axisLabel: {
            color: "#7C86A3",
            fontSize: 12,
            fontWeight: "bold"
          },
          axisTick: {
            show: false
          }
        },
        series: [
          {
            name: this.chartTitle || "值",
            type: "bar",
            barWidth: 16,
            data: datas.dataList,
            itemStyle: {
              barBorderRadius: 4
            }
          }
        ]
      };
    },
    getBarGroupOption(datas) {
      if (!datas.names.length) return;
      const onePageMaxBarNum = 20;
      const barNum = datas.names.length * datas.dataList.length;
      const xAxis = datas.dataList.map(function(item) {
        return item.name;
      });
      const series = datas.names.map(function(name, index) {
        const data = datas.dataList.map(function(item) {
          return item.data[index];
        });
        return {
          name: name,
          type: "bar",
          data: data,
          barMaxWidth: 8,
          itemStyle: {
            barBorderRadius: 2
          }
          // label: {
          //   show: true,
          //   position: "top",
          //   fontSize: 12,
          //   color: "#333",
          //   formatter: function(params) {
          //     return params.value.toFixed(2) + "%";
          //   }
          // }
        };
      });

      const options = {
        color: this.chartColor,
        grid: {
          top: "20%",
          bottom: "10%",
          left: "8%",
          right: "5%"
        },
        tooltip: {
          show: true,
          trigger: "axis",
          axisPointer: {
            type: "shadow"
          },
          formatter: function(params) {
            const label = params[0].axisValueLabel;
            let infos = params.map(function(item) {
              return item.seriesName + "：" + item.value.toFixed(2) + "%";
            });
            infos.unshift(label);
            return infos.join("<br/>");
          }
        },
        legend: {
          data: datas.names,
          right: 0,
          itemWidth: 14,
          textStyle: {
            fontSize: 16
          }
        },
        xAxis: {
          type: "category",
          data: xAxis,
          axisLabel: {
            color: "#7C86A3",
            fontSize: 12,
            fontWeight: "bold"
          },
          axisTick: {
            show: false
          }
        },
        yAxis: {
          type: "value",
          splitLine: {
            show: true,
            lineStyle: {
              color: "rgba(231,234,241,1)"
            }
          },
          axisLine: {
            lineStyle: {
              color: "rgba(231,234,241,1)"
            }
          },
          axisLabel: {
            color: "#7C86A3",
            fontSize: 12,
            fontWeight: "bold",
            formatter: function(value, index) {
              return value + "%";
            }
          },
          axisTick: {
            show: false
          }
        },
        series: series
      };

      if (barNum > onePageMaxBarNum) {
        const zoomInitRange = Math.floor((onePageMaxBarNum * 100) / barNum);
        options.grid.bottom = "18%";
        options.dataZoom = [
          {
            type: "inside",
            start: 0,
            end: zoomInitRange
          },
          {
            type: "slider",
            start: 0,
            end: zoomInitRange,
            bottom: "0%"
          }
        ];
      }

      return options;
    },
    getLineGroupOption(datas) {
      if (!datas.length) return;
      const names = datas.map(function(item) {
        return item.name;
      });
      const xaxis = datas[0].dataList.map(function(item, index) {
        return index;
      });

      const series = datas.map(function(item) {
        return {
          name: item.name,
          type: "line",
          symbol: "circle",
          smooth: true,
          itemStyle: {
            emphasis: {
              color: "#333"
            }
          },
          data: item.dataList.map(function(num) {
            return num * num;
          })
        };
      });
      return {
        grid: {
          top: "15%",
          bottom: "12%"
        },
        tooltip: {
          show: true,
          trigger: "axis",
          axisPointer: {
            type: "shadow"
          },
          formatter: function(params) {
            const label = params[0].axisValueLabel;
            let infos = params.map(function(item) {
              return item.seriesName + "：" + Math.sqrt(item.value);
            });
            infos.unshift(label);
            return infos.join("<br/>");
          }
        },
        legend: {
          data: names,
          right: 0,
          itemWidth: 14,
          textStyle: {
            fontSize: 16
          }
        },
        xAxis: {
          type: "category",
          data: xaxis,
          axisLabel: {
            show: false,
            fontSize: 14
          },
          axisTick: {
            show: false
          }
        },
        yAxis: {
          type: "value",
          interval: 1,
          splitLine: {
            show: false
          },
          axisLabel: {
            fontSize: 14,
            formatter: function(value) {
              const num = Math.sqrt(value);
              return num % 1 ? "" : parseInt(num);
            }
          },
          axisTick: {
            show: false
          }
        },
        dataZoom: [
          {
            type: "inside",
            start: 0,
            end: 30
          },
          {
            type: "slider",
            start: 0,
            end: 30
          }
        ],
        series: series
      };
    }
  }
};
</script>
