Skip to content
Advertisement

Highmaps js, on Hover display additional data

I’m working with the map of Paraguay. I added an input select to select different years and the maps changes according to my selection.

The thing is, my data always comes in this format:

const departments = [
  {agrupacion: 'Asunción', col2015: 0, col2016: 0, col2017: 0, col2018: 0},
  {agrupacion: 'Total', col2015: 105.1, col2016: 108, col2017: 112.2, col2018: 106.9},
  {agrupacion: 'Hombre', col2015: 103, col2016: 106.7, col2017: 115, col2018: 106.8},
  {agrupacion: 'Mujer', col2015: 107.2, col2016: 109.3, col2017: 109.4, col2018: 107.1},
  {agrupacion: 'Concepción', col2015: 0, col2016: 0, col2017: 0, col2018: 0},
  {agrupacion: 'Total', col2015: 77.8, col2016: 79.4, col2017: 82.9, col2018: 74.3},
  {agrupacion: 'Hombre', col2015: 76.4, col2016: 80.2, col2017: 81.3, col2018: 71.5},
  {agrupacion: 'Mujer', col2015: 79.3, col2016: 78.5, col2017: 84.6, col2018: 77.2},
  {agrupacion: 'San Pedro', col2015: 0, col2016: 0, col2017: 0, col2018: 0},
  {agrupacion: 'Total', col2015: 76.8, col2016: 77.7, col2017: 77.2, col2018: 70.2},
  {agrupacion: 'Hombre', col2015: 77.2, col2016: 79.1, col2017: 79.8, col2018: 69.5},
  {agrupacion: 'Mujer', col2015: 76.3, col2016: 76.3, col2017: 74.5, col2018: 70.9},
  {agrupacion: 'Cordillera', col2015: 0, col2016: 0, col2017: 0, col2018: 0},
  {agrupacion: 'Total', col2015: 77.9, col2016: 77.5, col2017: 75.6, col2018: 67.5},
  {agrupacion: 'Hombre', col2015: 76.4, col2016: 78.1, col2017: 73.7, col2018: 67.5},
  {agrupacion: 'Mujer', col2015: 79.5, col2016: 76.7, col2017: 77.6, col2018: 67.5},
  {agrupacion: 'Guairá', col2015: 0, col2016: 0, col2017: 0, col2018: 0},
  {agrupacion: 'Total', col2015: 67.8, col2016: 64.8, col2017: 67.3, col2018: 63.2},
  {agrupacion: 'Hombre', col2015: 66.6, col2016: 65.9, col2017: 66.5, col2018: 63.5},
  {agrupacion: 'Mujer', col2015: 69, col2016: 63.7, col2017: 68.2, col2018: 62.9},
  {agrupacion: 'Caaguazú', col2015: 0, col2016: 0, col2017: 0, col2018: 0},
  {agrupacion: 'Total', col2015: 75, col2016: 74.5, col2017: 76.5, col2018: 73.2},
  {agrupacion: 'Hombre', col2015: 75.3, col2016: 73.4, col2017: 75.4, col2018: 72.6},
  {agrupacion: 'Mujer', col2015: 74.7, col2016: 75.7, col2017: 77.6, col2018: 73.9},
  {agrupacion: 'Caazapá', col2015: 0, col2016: 0, col2017: 0, col2018: 0},
  {agrupacion: 'Total', col2015: 63.6, col2016: 56.6, col2017: 59.8, col2018: 57.1},
  {agrupacion: 'Hombre', col2015: 63.9, col2016: 55.6, col2017: 59.6, col2018: 57.4},
  {agrupacion: 'Mujer', col2015: 63.2, col2016: 57.5, col2017: 59.9, col2018: 56.8},
  {agrupacion: 'Itapúa', col2015: 0, col2016: 0, col2017: 0, col2018: 0},
  {agrupacion: 'Total', col2015: 74.3, col2016: 69.6, col2017: 66.2, col2018: 63.7},
  {agrupacion: 'Hombre', col2015: 73.6, col2016: 69.1, col2017: 67.7, col2018: 65.4},
  {agrupacion: 'Mujer', col2015: 75.2, col2016: 70.1, col2017: 64.7, col2018: 62},
  {agrupacion: 'Misiones', col2015: 0, col2016: 0, col2017: 0, col2018: 0},
  {agrupacion: 'Total', col2015: 79.4, col2016: 74.6, col2017: 79.2, col2018: 72.9},
  {agrupacion: 'Hombre', col2015: 81.3, col2016: 72.7, col2017: 77.9, col2018: 72.9},
  {agrupacion: 'Mujer', col2015: 77.4, col2016: 76.5, col2017: 80.5, col2018: 72.9},
  {agrupacion: 'Paraguarí', col2015: 0, col2016: 0, col2017: 0, col2018: 0},
  {agrupacion: 'Total', col2015: 67.2, col2016: 66, col2017: 63.5, col2018: 62.7},
  {agrupacion: 'Hombre', col2015: 67.7, col2016: 67.2, col2017: 65, col2018: 62.3},
  {agrupacion: 'Mujer', col2015: 66.7, col2016: 64.8, col2017: 62, col2018: 63.1},
  {agrupacion: 'Alto Paraná', col2015: 0, col2016: 0, col2017: 0, col2018: 0},
  {agrupacion: 'Total', col2015: 98.9, col2016: 92.8, col2017: 94.2, col2018: 92.3},
  {agrupacion: 'Hombre', col2015: 97, col2016: 93.4, col2017: 94.3, col2018: 92.5},
  {agrupacion: 'Mujer', col2015: 100.8, col2016: 92.2, col2017: 94.2, col2018: 92.1},
  {agrupacion: 'Central', col2015: 0, col2016: 0, col2017: 0, col2018: 0},
  {agrupacion: 'Total', col2015: 87, col2016: 85.2, col2017: 90.3, col2018: 83.5},
  {agrupacion: 'Hombre', col2015: 86.6, col2016: 84.5, col2017: 90.6, col2018: 83.5},
  {agrupacion: 'Mujer', col2015: 87.5, col2016: 86, col2017: 90, col2018: 83.4},
  {agrupacion: 'Ñeembucú', col2015: 0, col2016: 0, col2017: 0, col2018: 0},
  {agrupacion: 'Total', col2015: 68.4, col2016: 67, col2017: 70.3, col2018: 69.9},
  {agrupacion: 'Hombre', col2015: 63.9, col2016: 69.8, col2017: 69.7, col2018: 65.5},
  {agrupacion: 'Mujer', col2015: 73.1, col2016: 64.1, col2017: 70.9, col2018: 74.5},
  {agrupacion: 'Amambay', col2015: 0, col2016: 0, col2017: 0, col2018: 0},
  {agrupacion: 'Total', col2015: 98, col2016: 100.4, col2017: 100.8, col2018: 95.1},
  {agrupacion: 'Hombre', col2015: 99.8, col2016: 100.5, col2017: 101.9, col2018: 97.5},
  {agrupacion: 'Mujer', col2015: 96.1, col2016: 100.3, col2017: 99.6, col2018: 92.5},
  {agrupacion: 'Canindeyú', col2015: 0, col2016: 0, col2017: 0, col2018: 0},
  {agrupacion: 'Total', col2015: 79.5, col2016: 82.3, col2017: 85, col2018: 82.2},
  {agrupacion: 'Hombre', col2015: 77.6, col2016: 79.9, col2017: 82.2, col2018: 82.1},
  {agrupacion: 'Mujer', col2015: 81.5, col2016: 84.7, col2017: 88, col2018: 82.4},
  {agrupacion: 'Presidente Hayes', col2015: 0, col2016: 0, col2017: 0, col2018: 0},
  {agrupacion: 'Total', col2015: 82, col2016: 81.8, col2017: 87.5, col2018: 78},
  {agrupacion: 'Hombre', col2015: 82.9, col2016: 78.6, col2017: 88.5, col2018: 81.3},
  {agrupacion: 'Mujer', col2015: 81.1, col2016: 85.2, col2017: 86.4, col2018: 74.6},
  {agrupacion: 'Boquerón', col2015: 0, col2016: 0, col2017: 0, col2018: 0},
  {agrupacion: 'Total', col2015: 99.3, col2016: 103.7, col2017: 97.6, col2018: 111.1},
  {agrupacion: 'Hombre', col2015: 98.2, col2016: 107.4, col2017: 100.8, col2018: 112.3},
  {agrupacion: 'Mujer', col2015: 100.4, col2016: 99.8, col2017: 94.3, col2018: 109.8},
  {agrupacion: 'Alto Paraguay', col2015: 0, col2016: 0, col2017: 0, col2018: 0},
  {agrupacion: 'Total', col2015: 83, col2016: 75.2, col2017: 88.7, col2018: 81.6},
  {agrupacion: 'Hombre', col2015: 88, col2016: 77, col2017: 92, col2018: 90.1},
  {agrupacion: 'Mujer', col2015: 77.7, col2016: 73.4, col2017: 85.2, col2018: 72.9}];

With the help of this function I’m able to switch the values for the map according to selection and change the array to a format that I can use in my highmaps:

  let selected;
  let selection;
  $("#example-select").change(function() {
    const map_data = [];
        var selection = 'col' + this.value;
    selected = departments.map(e => ({
      name: e.agrupacion,
      data: e[selection]
    }));

    $.each(selected, function(key, value) {
       map_data.push([data_replace(value.name), value.data]);
      
    });
    
    
    
    //Create the chart
    Highcharts.mapChart('container_map', {
      chart: {
        map: topology
      },

      title: {
        text: 'Highcharts Maps basic demo'
      },

      subtitle: {
        text: 'Source map: <a href="http://code.highcharts.com/mapdata/countries/py/py-all.topo.json">Paraguay</a>'
      },

      mapNavigation: {
        enabled: true,
        buttonOptions: {
          verticalAlign: 'bottom'
        }
      },

      colorAxis: {
        min: 0,
        color:'#BADA55'
      },

      series: [{
        data: map_data,
        name: 'Random data',
        states: {
          hover: {
            color: '#BADA55'
          }
        },
        dataLabels: {
          enabled: true,
          format: '{point.name}'
        }
      }]
    });
  });
})();

This is my data_replace function:

function data_replace (data){
    switch(data) {
    case 'Concepción':
        return 'py-cn'//concepcion
    break;
    case 'San Pedro':
        return 'py-sp'//san pedro
    break;
    case 'Cordillera':
      return 'py-cr'//cordillera
    break;
    case 'Guairá':
        return 'py-gu'//guaira
    break;
    case 'Caaguazú':
        return 'py-cg'//caaguazu
    break;
    case 'Caazapá':
        return 'py-cz'//caazapa
    break;
    case 'Itapúa':
        return 'py-it'//itapua
    break;
    case 'Misiones':
        return 'py-mi'//misiones
    break;
    case 'Paraguarí':
        return 'py-pg'//paraguari
    break;
    case 'Alto Paraná':
        return 'py-aa'//alto parana
    break;
    case 'Central':
        return 'py-ce'//central
    break;
    case 'Ñeembucú':
        return 'py-ne'//ñeembucu
    break;
    case 'Amambay':
        return 'py-am'//amambay
    break;
    case 'Canindeyú':
        return 'py-cy'//canindeyu
    break;
    case 'Presidente Hayes':
        return 'py-ph'//presidente hayes
    break;
    case 'Boquerón':
        return 'py-bq'//boqueron
    break;
    case 'Alto Paraguay':
        return 'py-ag'//alto paraguay
    break;
    case 'Asunción':
        return 'py-as'//asuncion
    break;
    default:
        return data//return default value
    break;
  } 

}

This gives me

console.log(map_data);

the following output:

[["py-as", 0], ["Total", 105.1], ["Hombre", 103], ["Mujer", 107.2], ["py-cn", 0], ["Total", 77.8], ["Hombre", 76.4], ["Mujer", 79.3], ["py-sp", 0], ["Total", 76.8], ["Hombre", 77.2], ["Mujer", 76.3], ["py-cr", 0], ["Total", 77.9], ["Hombre", 76.4], ["Mujer", 79.5], ["py-gu", 0], ["Total", 67.8], ["Hombre", 66.6], ["Mujer", 69], ["py-cg", 0], ["Total", 75], ["Hombre", 75.3], ["Mujer", 74.7], ["py-cz", 0], ["Total", 63.6], ["Hombre", 63.9], ["Mujer", 63.2], ["py-it", 0], ["Total", 74.3], ["Hombre", 73.6], ["Mujer", 75.2], ["py-mi", 0], ["Total", 79.4], ["Hombre", 81.3], ["Mujer", 77.4], ["py-pg", 0], ["Total", 67.2], ["Hombre", 67.7], ["Mujer", 66.7], ["py-aa", 0], ["Total", 98.9], ["Hombre", 97], ["Mujer", 100.8], ["py-ce", 0], ["Total", 87], ["Hombre", 86.6], ["Mujer", 87.5], ["py-ne", 0], ["Total", 68.4], ["Hombre", 63.9], ["Mujer", 73.1], ["py-am", 0], ["Total", 98], ["Hombre", 99.8], ["Mujer", 96.1], ["py-cy", 0], ["Total", 79.5], ["Hombre", 77.6], ["Mujer", 81.5], ["py-ph", 0], ["Total", 82], ["Hombre", 82.9], ["Mujer", 81.1], ["py-bq", 0], ["Total", 99.3], ["Hombre", 98.2], ["Mujer", 100.4], ["py-ag", 0], ["Total", 83], ["Hombre", 88], ["Mujer", 77.7]]

Is there a way I can work with that output so that when I hover on my map it displays the labels like this?

For example I hover over at “Asunción” and it displays the data like this(while year 2015 is selected):

Asunción
Total: 105.1
Hombre: 103
Mujer: 107.2

Here is my demo: https://jsfiddle.net/kenpy/x7635dfz/28/

Advertisement

Answer

First of all, you need to convert your data to a readable format for Highcharts.

API: https://api.highcharts.com/highmaps/series.map.data

For example, create separate arrays for each year:

let data2015 = [
    ['py-ag', 10, 20, 30],
    ['py-bq', 40, 50, 60]
  ];  

let data2016 = [
    ['py-ag', 15, 25, 35],
    ['py-bq', 45, 55, 65]
  ];

The additional data needs to be connected to the chart, by the series.keys:

API: https://api.highcharts.com/highcharts/plotOptions.series.keys

plotOptions: {
  series: {
    keys: ['hc-key', 'total', 'hombre', 'mujer']
}

Then, you can easily refer to this data in the tooltip.formatter

API: https://api.highcharts.com/highcharts/tooltip.formatter

tooltip: {
  formatter: function() {
    let point = this.point;
    return '<b>' + point.name + '</b><br>' + 'Total: ' + point.options.total + '<br>' + 'Hombre: ' + point.options.hombre + '<br>' + 'Mujer: ' + point.options.mujer
  }
}

For updating data by drop-down list use series.update method:

API: https://api.highcharts.com/class-reference/Highcharts.Series#update

  document.getElementById('select').onchange = function() {
    let option = this.value;
    if (option === 'data2015') {
      chart.series[0].update({
        data: data2015,
        name: '2015'
      });
    }
    if (option === 'data2016') {
      chart.series[0].update({
        data: data2016,
        name: '2016'
      });
    }
  };

Demo: https://jsfiddle.net/BlackLabel/41phgcen/

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement