[Vuejs]-Drilldown in Map with Vue.js

0👍

Here is simple example of drilldown functionality(with vue-highcharts) which provides drilldown and drillup event from Vue-instance:

Vue.use(VueHighcharts, { Highcharts: Highcharts });

// helper script to load external script
let loadScript = function(url, onLoad){
    var scriptTag = document.createElement('script');
    scriptTag.src = url;
    scriptTag.onload = onLoad;
    scriptTag.onreadystatechange = onLoad;
    document.body.appendChild(scriptTag);
};

// simple chart options
var options = {
  chart: {},
	title: {
    text: 'Highcharts-Vue Map Drilldown Example'
  },

  subtitle: {
    text: '',
    floating: true,
    align: 'right',
    y: 50,
    style: {
      fontSize: '16px'
    }
  },

  legend: {
    layout: 'vertical',
    align: 'right',
    verticalAlign: 'middle'
  },

  colorAxis: {
    min: 0,
    minColor: '#E6E7E8',
    maxColor: '#005645'
  },

  mapNavigation: {
    enabled: true,
    buttonOptions: {
      verticalAlign: 'bottom'
    }
  },
  plotOptions: {
    map: {
      states: {
        hover: {
          color: '#EEDD66'
        }
      }
    }
  },
  drilldown: {
    activeDataLabelStyle: {
      color: '#FFFFFF',
      textDecoration: 'none',
      textOutline: '1px #000000'
    },
    drillUpButton: {
      relativeTo: 'plotBox',
      position: {
        x: 70,
        y: 280
      }
    }
  },
  series: [{
    data: Highcharts.geojson(Highcharts.maps['countries/us/us-all']).map((d, i) => {
    	d.drilldown = true;
      // set value just for example
      d.value = i;
      return d;
    }),
    name: 'USA',
    dataLabels: {
      enabled: true,
      format: '{point.properties.postal-code}'
    }
  }]
};

let vm = new Vue({
  el: '#app',
  data: {
  	isLoading: false,
    options: options
  },
  created() {
    // prepare events for chart from Vue instance
  	this.options.chart.events = {
      drilldown: this.drilldown.bind(this),
      drillup: this.drillup.bind(this)
    }
  },
  methods: {
  	drilldown(e) {
       let { chart } = this.$refs.highcharts;
    	 if (!e.seriesOptions) {
            mapKey = 'countries/us/' + e.point.properties['hc-key'] + '-all';
            if (Highcharts.maps[mapKey]) {
            	this.prepareDrilldownData(mapKey, e.point);
              return;
            }
            
          this.isLoading = true;
          loadScript('https://code.highcharts.com/mapdata/' + mapKey + '.js', () => {
              this.isLoading = false;
              this.prepareDrilldownData(mapKey, e.point);
          });
        }
        chart.setTitle(null, { text: e.point.name });
    },
    
    drillup(e) {
        let { chart } = this.$refs.highcharts;
        chart.setTitle(null, { text: '' });
    },
    
    prepareDrilldownData(mapKey, point) {
      let { chart } = this.$refs.highcharts;
      data = Highcharts.geojson(Highcharts.maps[mapKey]).map((d, i) => {
        // set value just for example
        d.value = i;
        return d;
      });
      chart.addSeriesAsDrilldown(point, {
        name: point.name,
        data: data,
        dataLabels: {
          enabled: true,
          format: '{point.name}'
        }
      });
    }
  }
});
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script src="https://code.highcharts.com/maps/highmaps.js"></script>
<script src="https://code.highcharts.com/maps/modules/drilldown.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-highcharts/dist/vue-highcharts.min.js"></script>
<script src="https://code.highcharts.com/mapdata/countries/us/us-all.js"></script>


<div id="app">
  <highmaps ref="highcharts" :options="options"></highmaps>
  <div v-if="isLoading" style="text-align: center; margin-top: 15px; font-size: 20px;">Loading...</div>
</div>

There is also jsfiddle if you want.

Leave a comment