Search code examples
vue.jsredrawhighmaps

Vue.js - Highmaps - Redraw map on series change


I have a highmaps 'chart' and the only thing that I want is to redraw the whole map inside an external function. Let me explain better. The map draws itself immediatly when the page loads up but I fetch some data from an external service and set it to a variable. Then I would like to just redraw the chart so that the new data appears in the map itself. Below is my code.

<template>
  <div>
    <highmaps :options="chartOptions"></highmaps>
  </div>
</template>

<script>
  import axios from 'axios';
  import HighCharts from 'vue-highcharts';
  import json from '../map.json'

  let regions = [];

    export default {
    data: function () {
      return {
        chartOptions: {
          chart: {
            map: json, // The map data is taken from the .json file imported above
          },
            map: {
              /* hc-a2 is the specific code used, you can find all codes in the map.json file */
              joinBy: ['hc-key', 'code'],
              allAreas: false,
              tooltip: {
                headerFormat: '',
                pointFormat: '{point.name}: <b>{series.name}</b>'
             },
          series: [
            {
              borderColor: '#a0451c',
              cursor: 'pointer',
              name: 'ERROR',
              color: "red",
              data: regions.map(function (code) {
                return {code: code};
              }),
            }
          ],
        }
    },
    created: function(){
      let app = this;

      /* Ajax call to get all parameters from database */
      axios.get('http://localhost:8080/devices')
        .then(function (response) {
          region.push(response.parameter)

          /* I would like to redraw the chart right here */
        }).catch(function (error){
        console.error("Download Devices ERROR: " + error);
      })
    }
  }
</script>

As you can see I import my map and the regions variable is set to an empty array. Doing this results in the map having only the borders and no region is colored in red. After that there is the created:function() function that is used to make the ajax call and retrieve data. After that I just save the data pushing it into the array and then obviously nothing happens but I would like to redraw the map so that the newly imported data will be shown. Down here is the image of what I would like to create.

enter image description here

If you have any idea on how to implement a thing like this or just want to suggest a better way of handling the problem, please comment.

Thanks in advance for the help. Cheers!


Solution

  • After a few days without any answer I found some marginal help online and came to a pretty satisfying conclusion on this problem so I hope it can help someone else.

    So the first thing I did was to understand how created and mounted were different in Vue.js. I used the keyword created at first when working on this project. Because of that, inside this function, I placed my ajax call that gave me data which I then loaded inside the 'chart' by using the .addSeries method of the chart itself.

    To reference the chart itself I used this: let chart: this.$refs.highcharts.chart. This searches for the field refs in any of your components/html elements and links it to the variable. So in the html there was something like this:

    <template>
      <div>
        <highmaps :options="chartOptions" ref="highcharts"></highmaps>
      </div>
    </template>
    

    The real problem was that the chart didn't even start rendering while all this process was going on so I changed the created keyword with mounted which means that it executes all the code when all of the components are correctly mounted and so my chart would be already rendered.

    To give you (maybe) a better idea of what I am talking about I will post some code down below

    mounted: function(){
      let errorRegions = [];
      let chart = this.$refs.highcharts.chart;
    
      axios.get('localhost:8080/foo').then(function(response)
      {
        /* Code to work on data */
        response.forEach(function(device){
          errorRegions.push(device);
        }
        chart.addSeries({
          name: "ERROR",
          color: "red",
          data: errorRegions
        }
        /* ...Some more code... */
      })
    }
    

    And this is the result (have been adding some more series in the same exact manner)

    End result

    Really hoping I have been of help to someone else. Cheers!