Marcia Zavaleta
Marcia Zavaleta

Reputation: 11

Highmaps mappies with drilldown

I need to do a drilldown of mappies, from country to states: https://www.highcharts.com/maps/demo/map-pies

Actually I am using a custom map from Peru, but already with the example of USA would help me a lot showing me some solution. Is it possible to do this?

Upvotes: 0

Views: 1689

Answers (2)

Marcia Zavaleta
Marcia Zavaleta

Reputation: 11

Thank you Wojciech Chmiel !

I did my map with the help of your post.

// New map-pie series type that also allows lat/lon as center option.
// Also adds a sizeFormatter option to the series, to allow dynamic sizing
// of the pies.
Highcharts.seriesType('mappie', 'pie', {
  center: null, // Can't be array by default anymore
    clip: true, // For map navigation
    states: {
        hover: {
            halo: {
                size: 5
            }
        }
    },
    dataLabels: {
        enabled: false
    }
}, {
  getCenter: function() {
        var options = this.options,
            chart = this.chart,
            slicingRoom = 2 * (options.slicedOffset || 0);
        if (!options.center) {
            options.center = [null, null]; // Do the default here instead
        }
		// Replace lat/lon with plotX/plotY
		if (options.center.plotX !== undefined) {
		  options.center = [options.center.plotX, options.center.plotY];
		}
        // Handle dynamic size
        if (options.sizeFormatter) {
            options.size = options.sizeFormatter.call(this);
        }
        // Call parent function
        var result = Highcharts.seriesTypes.pie.prototype.getCenter.call(this);
        // Must correct for slicing room to get exact pixel pos
        result[0] -= slicingRoom;
        result[1] -= slicingRoom;
        return result;
    },
    translate: function (p) {
        this.options.center = this.userOptions.center;
        this.center = this.getCenter();
        return Highcharts.seriesTypes.pie.prototype.translate.call(this, p);
    }
});


var data = [
    // state, demVotes, repVotes, libVotes, grnVotes, sumVotes, winner, drilldown
        ['CAPLINA-OCONA', 729547, 1318255, 44467, 9391, 2101660, -1, 'aaa01'],
        ['CHAPARRA-CHINCHA', 116454, 163387, 18725, 5735, 304301, -1, 'aaa02'],
        ['CANETE-FORTALEZA', 1161167, 1252401, 106327, 34345, 2554240, -1, 'aaa03'],
        ['HUARMEY-CHICAMA', 380494, 684782, 29829, 9473, 1104578, -1, 'aaa04'],
        ['JEQUETEPEQUE-ZARUMILLA', 8577206, 4390272, 467370, 271047, 13705895, 1, 'aaa05'],
        ['MARANON', 1338870, 1202484, 144121, 38437, 2723912, 1, 'aaa06'],
        ['AMAZONAS', 897572, 673215, 48676, 22841, 1642304, 1, 'aaa07'],
        ['HUALLAGA', 235603, 185127, 14757, 6103, 441590, 1, 'aaa08'],
        ['UCAYALI', 282830, 12723, 4906, 4258, 304717, 1, 'aaa09'],
        ['MANTARO', 4504975, 4617886, 207043, 64399, 9394303, -1, 'aaa10'],
        ['PAMPAS-APURIMAC', 1877963, 2089104, 125306, 0, 4092373, -1, 'aaa11'],
        ['URUBAMBA-VILCANOTA', 266891, 128847, 15954, 12737, 424429, 1, 'aaa12'],
        ['MADRE DE DIOS', 189765, 409055, 28331, 8496, 635647, -1, 'aaa13'],
        ['TITICACA', 2977498, 2118179, 208682, 74112, 5378471, 1, 'aaa14']
  ],
  maxVotes = 0,
  demColor = 'rgba(74,131,240,0.80)',
  repColor = 'rgba(220,71,71,0.80)',
  libColor = 'rgba(240,190,50,0.80)',
  grnColor = 'rgba(90,200,90,0.80)';


// Compute max votes to find relative sizes of bubbles
Highcharts.each(data, function(row) {
  maxVotes = Math.max(maxVotes, row[5]);
});

// Build the chart
var chart = Highcharts.mapChart('container', {
  chart: {
        animation: false, // Disable animation, especially for zooming
		events: {
		  load: function() {
			addMapPie(this);
		  },
		  drilldown: function(e) {
			if (!e.seriesOptions) {
			  var chart = this,
				//mapKey = 'countries/us/' + e.point.drilldown + '-all',
				mapKey = 'paises/pe/' + e.point.drilldown,
				ruta = e.point.drilldown,
				// Handle error, the timeout is cleared on success
				fail = setTimeout(function() {
				  if (!Highcharts.maps[mapKey]) {
					chart.showLoading('<i class="icon-frown"></i> Failed loading ' + e.point.name);
					fail = setTimeout(function() {
					  chart.hideLoading();
					}, 1000);
				  }
				}, 3000);

			  // Show the spinner
			  chart.showLoading('<i class="icon-spinner icon-spin icon-3x"></i>'); // Font Awesome spinner

			  // Load the drilldown map
			  //$.getScript('https://code.highcharts.com/mapdata/' + mapKey + '.js', function() {
			  //$.getScript('http://test1.ana.gob.pe/prueba-mappies/' + ruta + '.js', function () {
        $.getScript('https://aplicaciones01.ana.gob.pe/mappies/' + ruta + '.js', function () {

				data = Highcharts.geojson(Highcharts.maps[mapKey]);

				// Set a non-random bogus value
				$.each(data, function(i) {
				  this.value = i;
				});

				chart.series.forEach(function(s) {
				  if (s.options.type === 'mappie') {
					s.hide();
				  }
				});

				// Hide loading and add series
				chart.hideLoading();
				clearTimeout(fail);
				chart.addSeriesAsDrilldown(e.point, {
				  name: e.point.name,
				  data: data,
				  dataLabels: {
					enabled: true,
					format: '{point.name}'
				  }
				});
			  });
			}

			this.setTitle(null, {
			  text: e.point.name
			});
		  },
		  drillup: function() {
			this.setTitle(null, {
			  text: ''
			});

			this.series.forEach(function(s) {
			  if (s.options.type === 'mappie') {
				s.show();
			  }
			});
		  }
		}
    },
  title: {
        text: 'Resultados'
    },

    colorAxis: {
        dataClasses: [{
            from: -1,
            to: 0,
            color: 'rgba(244,91,91,0.5)',
            name: 'Republican'
        }, {
            from: 0,
            to: 1,
            color: 'rgba(124,181,236,0.5)',
            name: 'Democrat'
        }, {
            from: 2,
            to: 3,
            name: 'Libertarian',
            color: libColor
        }, {
            from: 3,
            to: 4,
            name: 'Green',
            color: grnColor
        }]
    },

  mapNavigation: {
        enabled: true	//Para el zoom (+ -)
    },
    // Limit zoom range
    yAxis: {
        minRange: 2300
    },

    tooltip: {
        useHTML: true
    },

    // Default options for the pies
    plotOptions: {
        mappie: {
            borderColor: 'rgba(255,255,255,0.4)',
            borderWidth: 1,
            tooltip: {
                headerFormat: ''
            }
        }
    },

  series: [{
		mapData: Highcharts.maps['paises/pe/aaa-all'],
        data: data,
        name: 'States',
        borderColor: '#FFF',
        showInLegend: false,
        joinBy: ['name', 'id'],
        //keys: ['id', 'demVotes', 'repVotes', 'libVotes', 'grnVotes',
        //    'sumVotes', 'value', 'pieOffset'],
		keys: ['id', 'demVotes', 'repVotes', 'libVotes', 'grnVotes', 'sumVotes', 'value', 'drilldown'],
        tooltip: {
            headerFormat: '',
            pointFormatter: function () {
                var hoverVotes = this.hoverVotes; // Used by pie only
                return '<b>' + this.id + ' votes</b><br/>' +
                    Highcharts.map([
                        ['Democrats', this.demVotes, demColor],
                        ['Republicans', this.repVotes, repColor],
                        ['Libertarians', this.libVotes, libColor],
                        ['Green', this.grnVotes, grnColor]
                    ].sort(function (a, b) {
                        return b[1] - a[1]; // Sort tooltip by most votes
                    }), function (line) {
                        return '<span style="color:' + line[2] +
                            // Colorized bullet
                            '">\u25CF</span> ' +
                            // Party and votes
                            (line[0] === hoverVotes ? '<b>' : '') +
                            line[0] + ': ' +
                            Highcharts.numberFormat(line[1], 0) +
                            (line[0] === hoverVotes ? '</b>' : '') +
                            '<br/>';
                    }).join('') +
                    '<hr/>Total: ' + Highcharts.numberFormat(this.sumVotes, 0);
            }
        }
    }],

  drilldown: {
		activeDataLabelStyle: {
		  color: '#FFFFFF',
		  textDecoration: 'none',
		  textOutline: '1px #000000'
		},
		drillUpButton: {
		  relativeTo: 'spacingBox',
		  position: {
			x: 0,
			y: 60
		  }
		}
	 }
});


function addMapPie(chart) {
  // Add the pies after chart load, optionally with offset and connectors
  Highcharts.each(chart.series[0].points, function(state) {
    //if (!state.id) {
	if (!state.id || !state.properties) {
        return; // Skip points with no data, if any
    }

    var pieOffset = state.pieOffset || {},
        centerLat = parseFloat(state.properties.latitude),
        centerLon = parseFloat(state.properties.longitude);

    // Add the pie for this state
    chart.addSeries({
      type: 'mappie',
        name: state.id,
        zIndex: 6, // Keep pies above connector lines
        sizeFormatter: function () {
            var yAxis = this.chart.yAxis[0],
                zoomFactor = (yAxis.dataMax - yAxis.dataMin) /
                    (yAxis.max - yAxis.min);
            return Math.max(
                this.chart.chartWidth / 45 * zoomFactor, // Min size
                this.chart.chartWidth / 11 * zoomFactor * state.sumVotes / maxVotes
            );
        },
      /*****/
      tooltip: {
            // Use the state tooltip for the pies as well
            pointFormatter: function () {
                return state.series.tooltipOptions.pointFormatter.call({
                    id: state.id,
                    hoverVotes: this.name,
                    demVotes: state.demVotes,
                    repVotes: state.repVotes,
                    libVotes: state.libVotes,
                    grnVotes: state.grnVotes,
                    sumVotes: state.sumVotes
                });
            }
        },
      data: [{
            name: 'Democrats',
            y: state.demVotes,
            color: demColor
        }, {
            name: 'Republicans',
            y: state.repVotes,
            color: repColor
        }, {
            name: 'Libertarians',
            y: state.libVotes,
            color: libColor
        }, {
            name: 'Green',
            y: state.grnVotes,
            color: grnColor
        }],
      center: {
            /*lat: centerLat + (pieOffset.lat || 0),
            lon: centerLon + (pieOffset.lon || 0)*/
					plotX: state.plotX,
				plotY: state.plotY
        }
    }, false);
});
  // Only redraw once all pies and connectors have been added
  chart.redraw();
}
#container {
  min-width: 320px;
  max-width: 800px;
  height: 500px;
  margin: 1em auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.15/proj4.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/maps/modules/map.js"></script>

<script src="https://code.highcharts.com/modules/data.js"></script>
<script src="https://code.highcharts.com/modules/drilldown.js"></script>

<script src="https://code.highcharts.com/maps/modules/exporting.js"></script>
<script src="https://code.highcharts.com/maps/modules/offline-exporting.js"></script>
<script src="https://aplicaciones01.ana.gob.pe/mappies/AAA_psad56_simp.js"></script>

<link href="https://netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">

<div id="container"></div>

Here: - https://jsfiddle.net/JMarcia/w06k5zog/17/

Upvotes: 0

Wojciech Chmiel
Wojciech Chmiel

Reputation: 7372

I've made an example with mappie and drilldown to show you how to start and achieve it. I've added drilldown for California so only this state will work.

  1. Add drilldown module: https://code.highcharts.com/maps/modules/drilldown.js
  2. Each point should have a drilldown property set. You can add it to a point object or to data array (then keys array in series should point to it. API: https://api.highcharts.com/highmaps/plotOptions.series.keys)
  3. When drilldown event occurs hide or remove each mappie series and create it again on drillup event.

Code:

// New map-pie series type that also allows lat/lon as center option.
// Also adds a sizeFormatter option to the series, to allow dynamic sizing
// of the pies.
Highcharts.seriesType('mappie', 'pie', {
  center: null, // Can't be array by default anymore
  clip: true, // For map navigation
  states: {
    hover: {
      halo: {
        size: 5
      }
    }
  },
  dataLabels: {
    enabled: false
  }
}, {
  getCenter: function() {
    var options = this.options,
      chart = this.chart,
      slicingRoom = 2 * (options.slicedOffset || 0);
    if (!options.center) {
      options.center = [null, null]; // Do the default here instead
    }
    // Handle lat/lon support
    if (options.center.lat !== undefined) {
      var point = chart.fromLatLonToPoint(options.center);
      options.center = [
        chart.xAxis[0].toPixels(point.x, true),
        chart.yAxis[0].toPixels(point.y, true)
      ];
    }
    // Handle dynamic size
    if (options.sizeFormatter) {
      options.size = options.sizeFormatter.call(this);
    }
    // Call parent function
    var result = Highcharts.seriesTypes.pie.prototype.getCenter.call(this);
    // Must correct for slicing room to get exact pixel pos
    result[0] -= slicingRoom;
    result[1] -= slicingRoom;
    return result;
  },
  translate: function(p) {
    this.options.center = this.userOptions.center;
    this.center = this.getCenter();
    return Highcharts.seriesTypes.pie.prototype.translate.call(this, p);
  }
});


var data = [
    // state, demVotes, repVotes, libVotes, grnVotes, sumVotes, winner, offset config for pies
    ['Alabama', 729547, 1318255, 44467, 9391, 2101660, -1],
    ['Alaska', 116454, 163387, 18725, 5735, 304301, -1],
    ['Arizona', 1161167, 1252401, 106327, 34345, 2554240, -1],
    ['Arkansas', 380494, 684782, 29829, 9473, 1104578, -1],
    ['California', 8577206, 4390272, 467370, 271047, 13705895, 1, {
      lon: -1,
      drawConnector: false
    }, 'us-ca'],
    ['Colorado', 1338870, 1202484, 144121, 38437, 2723912, 1],
    ['Connecticut', 897572, 673215, 48676, 22841, 1642304, 1, {
      lat: -1.5,
      lon: 1
    }],
    ['Delaware', 235603, 185127, 14757, 6103, 441590, 1, {
      lat: -1.3,
      lon: 2
    }],
    ['District of Columbia', 282830, 12723, 4906, 4258, 304717, 1, {
      lat: -2,
      lon: 2
    }],
    ['Florida', 4504975, 4617886, 207043, 64399, 9394303, -1],
    ['Georgia', 1877963, 2089104, 125306, 0, 4092373, -1],
    ['Hawaii', 266891, 128847, 15954, 12737, 424429, 1, {
      lat: -0.5,
      lon: 0.5,
      drawConnector: false
    }],
    ['Idaho', 189765, 409055, 28331, 8496, 635647, -1],
    ['Illinois', 2977498, 2118179, 208682, 74112, 5378471, 1],
    ['Indiana', 1039126, 1557286, 133993, 7841, 2738246, -1],
    ['Iowa', 653669, 800983, 59186, 11479, 1525317, -1],
    ['Kansas', 427005, 671018, 55406, 23506, 1176935, -1],
    ['Kentucky', 628854, 1202971, 53752, 13913, 1899490, -1],
    ['Louisiana', 780154, 1178638, 37978, 14031, 2010801, -1],
    ['Maine', 352156, 332418, 37578, 13995, 736147, 1],
    ['Maryland', 1502820, 878615, 78225, 33380, 2493040, 1, {
      lon: 0.6,
      drawConnector: false
    }],
    ['Massachusetts', 1995196, 1090893, 138018, 47661, 3271768, 1, {
      lon: 3
    }],
    ['Michigan', 2268839, 2279543, 172136, 51463, 4771981, -1],
    ['Minnesota', 1367716, 1322951, 112972, 36985, 2840624, 1, {
      lon: -1,
      drawConnector: false
    }],
    ['Mississippi', 462127, 678284, 14411, 3595, 1158417, -1],
    ['Missouri', 1054889, 1585753, 96404, 25086, 2762132, -1],
    ['Montana', 174281, 273879, 28036, 7868, 484064, -1],
    ['Nebraska', 273185, 485372, 38746, 8337, 805640, -1],
    ['Nevada', 539260, 512058, 37384, 0, 1088702, 1],
    ['New Hampshire', 348526, 345790, 30694, 6465, 731475, 1],
    ['New Jersey', 1967444, 1509688, 72143, 37131, 3586406, 1, {
      lat: -1,
      lon: 1.2
    }],
    ['New Mexico', 380923, 316134, 74544, 9797, 781398, 1],
    ['New York', 4145376, 2638135, 162273, 100110, 7045894, 1],
    ['North Carolina', 2169496, 2345235, 130021, 1038, 4645790, -1],
    ['North Dakota', 93758, 216794, 21434, 378, 332364, -1],
    ['Ohio', 2320596, 2776683, 174266, 44310, 5315855, -1],
    ['Oklahoma', 420375, 949136, 83481, 0, 1452992, -1],
    ['Oregon', 991580, 774080, 93875, 49247, 1908782, 1],
    ['Pennsylvania', 2874136, 2945302, 144826, 49334, 6013598, -1],
    ['Rhode Island', 227062, 166454, 14700, 6171, 414387, 1, {
      lat: -0.7,
      lon: 1.7
    }],
    ['South Carolina', 855373, 1155389, 49204, 13034, 2073000, -1],
    ['South Dakota', 117442, 227701, 20845, 0, 365988, -1],
    ['Tennessee', 868853, 1519926, 70286, 15952, 2475017, -1],
    ['Texas', 3877868, 4685047, 283492, 71558, 8917965, -1],
    ['Utah', 222858, 375006, 39608, 7695, 645167, -1],
    ['Vermont', 178573, 95369, 10078, 6758, 290778, 1, {
      lat: 2
    }],
    ['Virginia', 1981473, 1769443, 118274, 27638, 3896828, 1],
    ['Washington', 1727840, 1210370, 160356, 57571, 3156137, 1],
    ['West Virginia', 187519, 486304, 22958, 8016, 704797, -1],
    ['Wisconsin', 1382947, 1407028, 106470, 31016, 2927461, -1],
    ['Wyoming', 55973, 174419, 13287, 2515, 246194, -1]
  ],
  maxVotes = 0,
  demColor = 'rgba(74,131,240,0.80)',
  repColor = 'rgba(220,71,71,0.80)',
  libColor = 'rgba(240,190,50,0.80)',
  grnColor = 'rgba(90,200,90,0.80)';


// Compute max votes to find relative sizes of bubbles
Highcharts.each(data, function(row) {
  maxVotes = Math.max(maxVotes, row[5]);
});

// Build the chart
var chart = Highcharts.mapChart('container', {
  chart: {
    animation: false, // Disable animation, especially for zooming
    events: {
      load: function() {
        addMapPie(this);
      },
      drilldown: function(e) {
        if (!e.seriesOptions) {
          var chart = this,
            mapKey = 'countries/us/' + e.point.drilldown + '-all',
            // Handle error, the timeout is cleared on success
            fail = setTimeout(function() {
              if (!Highcharts.maps[mapKey]) {
                chart.showLoading('<i class="icon-frown"></i> Failed loading ' + e.point.name);
                fail = setTimeout(function() {
                  chart.hideLoading();
                }, 1000);
              }
            }, 3000);

          // Show the spinner
          chart.showLoading('<i class="icon-spinner icon-spin icon-3x"></i>'); // Font Awesome spinner

          // Load the drilldown map
          $.getScript('https://code.highcharts.com/mapdata/' + mapKey + '.js', function() {

            data = Highcharts.geojson(Highcharts.maps[mapKey]);

            // Set a non-random bogus value
            $.each(data, function(i) {
              this.value = i;
            });

            chart.series.forEach(function(s) {
              if (s.options.type === 'mappie') {
                s.hide();
              }
            });

            // Hide loading and add series
            chart.hideLoading();
            clearTimeout(fail);
            chart.addSeriesAsDrilldown(e.point, {
              name: e.point.name,
              data: data,
              dataLabels: {
                enabled: true,
                format: '{point.name}'
              }
            });
          });
        }

        this.setTitle(null, {
          text: e.point.name
        });
      },
      drillup: function() {
        this.setTitle(null, {
          text: ''
        });

        this.series.forEach(function(s) {
          if (s.options.type === 'mappie') {
            s.show();
          }
        });
      }
    }
  },
  title: {
    text: 'USA 2016 Presidential Election Results'
  },

  colorAxis: {
    dataClasses: [{
      from: -1,
      to: 0,
      color: 'rgba(244,91,91,0.5)',
      name: 'Republican'
    }, {
      from: 0,
      to: 1,
      color: 'rgba(124,181,236,0.5)',
      name: 'Democrat'
    }, {
      from: 2,
      to: 3,
      name: 'Libertarian',
      color: libColor
    }, {
      from: 3,
      to: 4,
      name: 'Green',
      color: grnColor
    }]
  },

  mapNavigation: {
    enabled: true
  },
  // Limit zoom range
  yAxis: {
    minRange: 2300
  },

  tooltip: {
    useHTML: true
  },

  // Default options for the pies
  plotOptions: {
    mappie: {
      borderColor: 'rgba(255,255,255,0.4)',
      borderWidth: 1,
      tooltip: {
        headerFormat: ''
      }
    }
  },

  series: [{
    mapData: Highcharts.maps['countries/us/us-all'],
    data: data,
    name: 'States',
    borderColor: '#FFF',
    showInLegend: false,
    joinBy: ['name', 'id'],
    keys: ['id', 'demVotes', 'repVotes', 'libVotes', 'grnVotes',
      'sumVotes', 'value', 'pieOffset', 'drilldown'
    ],
    tooltip: {
      headerFormat: '',
      pointFormatter: function() {
        var hoverVotes = this.hoverVotes; // Used by pie only
        return '<b>' + this.id + ' votes</b><br/>' +
          Highcharts.map([
            ['Democrats', this.demVotes, demColor],
            ['Republicans', this.repVotes, repColor],
            ['Libertarians', this.libVotes, libColor],
            ['Green', this.grnVotes, grnColor]
          ].sort(function(a, b) {
            return b[1] - a[1]; // Sort tooltip by most votes
          }), function(line) {
            return '<span style="color:' + line[2] +
              // Colorized bullet
              '">\u25CF</span> ' +
              // Party and votes
              (line[0] === hoverVotes ? '<b>' : '') +
              line[0] + ': ' +
              Highcharts.numberFormat(line[1], 0) +
              (line[0] === hoverVotes ? '</b>' : '') +
              '<br/>';
          }).join('') +
          '<hr/>Total: ' + Highcharts.numberFormat(this.sumVotes, 0);
      }
    }
  }, {
    name: 'Separators',
    type: 'mapline',
    data: Highcharts.geojson(Highcharts.maps['countries/us/us-all'], 'mapline'),
    color: '#707070',
    showInLegend: false,
    enableMouseTracking: false
  }, {
    name: 'Connectors',
    type: 'mapline',
    color: 'rgba(130, 130, 130, 0.5)',
    zIndex: 5,
    showInLegend: false,
    enableMouseTracking: false
  }],

  drilldown: {
    activeDataLabelStyle: {
      color: '#FFFFFF',
      textDecoration: 'none',
      textOutline: '1px #000000'
    },
    drillUpButton: {
      relativeTo: 'spacingBox',
      position: {
        x: 0,
        y: 60
      }
    }
  }
});

function addMapPie(chart) {
  // Add the pies after chart load, optionally with offset and connectors
  Highcharts.each(chart.series[0].points, function(state) {
    if (!state.id) {
      return; // Skip points with no data, if any
    }

    var pieOffset = state.pieOffset || {},
      centerLat = parseFloat(state.properties.latitude),
      centerLon = parseFloat(state.properties.longitude);

    // Add the pie for this state
    chart.addSeries({
      type: 'mappie',
      name: state.id,
      zIndex: 6, // Keep pies above connector lines
      sizeFormatter: function() {
        var yAxis = this.chart.yAxis[0],
          zoomFactor = (yAxis.dataMax - yAxis.dataMin) /
          (yAxis.max - yAxis.min);
        return Math.max(
          this.chart.chartWidth / 45 * zoomFactor, // Min size
          this.chart.chartWidth / 11 * zoomFactor * state.sumVotes / maxVotes
        );
      },
      tooltip: {
        // Use the state tooltip for the pies as well
        pointFormatter: function() {
          return state.series.tooltipOptions.pointFormatter.call({
            id: state.id,
            hoverVotes: this.name,
            demVotes: state.demVotes,
            repVotes: state.repVotes,
            libVotes: state.libVotes,
            grnVotes: state.grnVotes,
            sumVotes: state.sumVotes
          });
        }
      },
      data: [{
        name: 'Democrats',
        y: state.demVotes,
        color: demColor
      }, {
        name: 'Republicans',
        y: state.repVotes,
        color: repColor
      }, {
        name: 'Libertarians',
        y: state.libVotes,
        color: libColor
      }, {
        name: 'Green',
        y: state.grnVotes,
        color: grnColor
      }],
      center: {
        lat: centerLat + (pieOffset.lat || 0),
        lon: centerLon + (pieOffset.lon || 0)
      }
    }, false);

    // Draw connector to state center if the pie has been offset
    if (pieOffset.drawConnector !== false) {
      var centerPoint = chart.fromLatLonToPoint({
          lat: centerLat,
          lon: centerLon
        }),
        offsetPoint = chart.fromLatLonToPoint({
          lat: centerLat + (pieOffset.lat || 0),
          lon: centerLon + (pieOffset.lon || 0)
        });
      chart.series[2].addPoint({
        name: state.id,
        path: 'M' + offsetPoint.x + ' ' + offsetPoint.y +
          'L' + centerPoint.x + ' ' + centerPoint.y
      }, false);
    }
  });
  // Only redraw once all pies and connectors have been added
  chart.redraw();
}
#container {
  min-width: 320px;
  max-width: 800px;
  height: 500px;
  margin: 1em auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.15/proj4.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/maps/modules/map.js"></script>
<script src="https://code.highcharts.com/maps/modules/data.js"></script>
<script src="https://code.highcharts.com/maps/modules/drilldown.js"></script>
<script src="https://code.highcharts.com/maps/modules/exporting.js"></script>
<script src="https://code.highcharts.com/maps/modules/offline-exporting.js"></script>
<script src="https://code.highcharts.com/mapdata/countries/us/us-all.js"></script>

<link href="https://netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">

<div id="container"></div>

Demo:


EDIT

To add mappies also to the first level of drilldown you have to remove mappies series form the main view of the map when drilldown event occurs and create new ones for drilled data. It's quite difficult to explain exactly how to make it, so I prepared an example where each drilled level has sample data (you can get them from a server the same as drilled map data). I hope this example will help and you will see what's going on there.

Demo:

Upvotes: 2

Related Questions