<template>
  <el-container v-loading="loading" class="th-charts-map-3d">
    <el-main>
      <v-chart
        ref="chart"
        class="th-echarts"
        :options="charOptions"
        autoresize
        v-on="$listeners"
        @click="onClick"
      />
    </el-main>
  </el-container>
</template>
<script>
import 'echarts-gl'
import VChart from 'vue-echarts'
import { registerMap } from 'echarts'
import 'echarts/lib/chart/map'
import 'echarts/lib/component/tooltip'
import 'echarts/lib/component/geo'
import detailTexture from './img/echart_map_bg.png'

export default {
  name: 'ThEchartsMap3d',
  components: {
    VChart
  },
  props: {
    // 加载状态
    loading: {
      type: Boolean,
      default: false
    },
    // 地图名称
    map: {
      type: String,
      default: ''
    },
    // 数据
    value: {
      type: Array,
      default: () => []
    },
    // 区域分片类型：color、realistic
    shading: {
      type: String,
      default: 'realistic'
    },
    // 背景颜色
    backgroundColor: {
      type: String,
      default: '#ffffff'
    },
    // 背景纹理图
    backgroundImage: {
      type: String,
      default: detailTexture
    },
    // 边框颜色
    borderColor: {
      type: String,
      default: 'rgba(0,255,255,1)'
    },
    // 是否禁用点击
    disabled: {
      type: Boolean,
      default: false
    },
    // 自定义地图数据
    customMaps: {
      type: Object,
      default: () => ({})
    }
  },
  data() {
    return {
      name: ''
    }
  },
  computed: {
    // 自定义地图数据
    getCustomMaps() {
      return {
        'chongqing': './mapJson/province/chongqing.json',
        'shanghai': './mapJson/province/shanghai.json',
        'beijing': './mapJson/province/beijing.json',
        'hebei': './mapJson/province/hebei.json',
        ...this.customMaps
      }
    },
    charOptions() {
      const itemStyle = {
        color: this.backgroundColor,
        borderColor: this.borderColor,
        borderWidth: 2,
        opacity: 1
      }
      const label = {
        show: true,
        textStyle: {
          color: '#fff',
          fontSize: 18,
          fontWeight: 'bold',
          opacity: 1,
          backgroundColor: 'transparent',
          borderColor: '#fff'
        }
      }
      const emphasis = {
        itemStyle: {
          color: '#FFCA3C'
        },
        label: {
          show: true,
          textStyle: {
            color: '#fff',
            fontSize: 18,
            fontWeight: 'bold',
            opacity: 1,
            backgroundColor: '#FF0032',
            borderColor: '#fff'
          }
        }
      }
      const light = {
        main: {
          color: '#fff', //光照颜色
          intensity: 1, //光照强度
          shadow: true, //是否显示阴影
          shadowQuality: 'high', //阴影质量 'low', 'medium', 'high', 'ultra'
          alpha: 50,
          beta: 10
        },
        postEffect: {
          bloom: {
            enable: true,
            bloomIntensity: 0.5
          }
        }
      }
      const viewControl = {
        distance: 140
      }
      const geo3D = []
      const geoItem = {
        show: true,
        map: this.map,
        data: this.value,
        itemStyle,
        emphasis,
        light,
        viewControl,
        shading: this.shading,
        realisticMaterial: {
          detailTexture: this.backgroundImage
        }
      }

      geo3D.push(geoItem)
      const series = []
      series.push({
        type: 'map3D',
        data: this.value,
        map: this.map,
        zlevel: 1,
        label,
        itemStyle: {
          opacity: 0
        },
        emphasis: {
          label: {
            show: true,
            textStyle: {
              ...label.textStyle,
              backgroundColor: '#FF0032'
            }
          }
        },
        light,
        viewControl
      })
      return {
        geo3D,
        series
      }
    }
  },
  watch: {
    // 单个区域时改变样式
    name(val) {
      const label = {
        show: true,
        textStyle: {
          color: 'transparent',
          fontSize: 18,
          fontWeight: 'bold',
          opacity: 1,
          borderColor: '#fff',
          backgroundColor: '#FF0032'
        }
      }
      const regions = [{
        name: val,
        itemStyle: {
          color: '#FFCA3C'
        },
        label,
        emphasis: {
          label
        }
      }]
      // 合并属性
      this.$refs.chart.mergeOptions(
        {
          geo3D: {
            regions
          }
        }
      )
    },
    // 切换地图
    map: {
      handler(val) {
        this.onChangeMap(val)
      },
      immediate: true
    }
  },
  methods: {
    // 切换地图
    onChangeMap(val) {
      if (val) {
        if (val in this.getCustomMaps) {
          const data = this.getCustomMaps[val]
          if (typeof data === 'string') {
            registerMap(val, require(`${data}`))
          } else if (typeof data === 'object') {
            registerMap(val, data)
          }
        } else if (val === 'china') {
          registerMap(val, require('echarts/map/json/china'))
        } else {
          registerMap(val, require(`echarts/map/json/province/${val}`))
        }
        if (this.$refs.chart) {
          this.$refs.chart.clear()
          this.$refs.chart.mergeOptions(this.charOptions, true)
        }
      }
    },
    // 点击区域事件
    onClick(e) {
      if (this.disabled) return
      if (e.name === this.name) {
        this.name = ''
      } else {
        this.name = e.name
      }
      this.$emit('click', {
        name: e.name,
        value: e.value,
        x: e.event.offsetX,
        y: e.event.offsetY,
        ...(e.data || {})
      })
    }
  }
}
</script>
