vue.jshighchartshighmapsdrilldown

Drilldown in Map with Vue.js


I'm trying to use the Drilldown in Map (vue-Highchart), but cannot get it working.

like this: https://www.highcharts.com/maps/demo/map-drilldown

Anyone have any examples of this in Vue.js? Please.

Tks.


Solution

  • 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.