<template>
  <div :id="id" class="world-map"></div>
</template>
<script>
import 'd3';
import * as d3 from 'd3';
import 'topojson';
import { throttle } from '@/util/throttle';

export default {
  name: 'world-map',
  props: {
    mapData: {
      type: Object,
      default: () => ({})
    },
    points: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      id: this.randomString(),
      color1: '#f6f9fc',
      color2: '#adb5bd',
      highlightFillColor: '#ced4da',
      borderColor: 'white',
      highlightBorderColor: 'white',
      bubbleHighlightFillColor: '#11cdef',
      bubbleFillColor: '#fb6340'
    };
  },
  methods: {
    generateColors(length) {
      return d3
        .scaleLinear()
        .domain([0, length])
        .range([this.color1, this.color2]);
    },
    generateMapColors() {
      let mapDataValues = Object.values(this.mapData);
      let maxVal = Math.max(...mapDataValues);
      let colors = this.generateColors(maxVal);
      let mapData = {};
      let fills = {
        defaultFill: '#EDF0F2'
      };
      for (let key in this.mapData) {
        let val = this.mapData[key];
        fills[key] = colors(val);
        mapData[key] = {
          fillKey: key,
          value: val
        };
      }
      return {
        mapData,
        fills
      };
    },
    async initVectorMap() {
      let DataMap = await import('datamaps');
      DataMap = DataMap.default || DataMap
      let { fills, mapData } = this.generateMapColors();
      let worldMap = new DataMap({
        scope: 'world',
        element: document.getElementById(this.id),
        fills,
        data: mapData,
        responsive: true,
        geographyConfig: {
          borderColor: this.borderColor,
          borderWidth: 1,
          borderOpacity: 1,
          highlightFillColor: this.highlightFillColor,
          highlightBorderColor: this.highlightBorderColor,
          highlightBorderWidth: 1,
          highlightBorderOpacity: 1
        }
      });
      let bubbleOptions = {
        radius: 2,
        borderWidth: 4,
        highlightBorderWidth: 4,
        fillKey: this.bubbleFillColor,
        fillColor: this.bubbleFillColor,
        borderColor: this.bubbleFillColor,
        highlightFillColor: this.bubbleHighlightFillColor,
        highlightBorderColor: this.bubbleHighlightFillColor
      }
      let bubblePoints = this.points.map(point => {
        return {
          ...bubbleOptions,
          ...point
        }
      })
      worldMap.bubbles(bubblePoints, {
        popupTemplate: function(geo, data) {
          return '<div class="hoverinfo">' + data.name
        }
      });
      let resizeFunc = worldMap.resize.bind(worldMap);
      window.addEventListener(
        'resize',
        () => {
          throttle(resizeFunc, 40);
        },
        false
      );
    },
    randomString() {
      let text = "";
      let possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

      for (let i = 0; i < 5; i++)
        text += possible.charAt(Math.floor(Math.random() * possible.length));

      return text;
    }
  },
  async mounted() {
    this.initVectorMap();
  }
};
</script>
<style></style>