João Menighin
João Menighin

Reputation: 3235

Combine PieChart with Map

I'm trying to plot PieCharts over a map using Highcharts and Highmaps. I didn't find anything specific on this on the documentation neither I found examples on Web. I'm following this demo where I can draw mapbubles over the map. I would like to do exactly the same but with pie charts instead of map bubbles.

So far what I have is:

   $('.map').slideDown().highcharts('Map', {
        title: {
            text: null
        },
        mapNavigation: {
            enabled: true
        },
        series: [{ // First series, plot the map
            mapData: result,
            name: 'Random data'             
        }, { // Second serie, plot a pie chart on specific coordinates
            type: 'pie',
            dataLabels: {
                enabled: true
            },
            name: 'Cities',
            data: [{
                lat: -21.194476, 
                lon: -43.794456,
                y: 100,
                name: 'Barbacena'
            }, {
                lat: -21.194476, 
                lon: -43.794456,
                y: 50,
                name: 'Barbacena'
            }],
            maxSize: '12%'
        }],
        legend: {
            layout: 'vertical',
            align: 'left',
            verticalAlign: 'bottom'
        },
    });

The pie chart is plotted but it totally ignores the map. It is not draged around when I drag the map.

So, is there a built-in way in Highcharts of doing that?

Thanks in advance

Upvotes: 0

Views: 537

Answers (1)

morganfree
morganfree

Reputation: 12472

I've written a wrapper which allows to draw a pie chart according to lat/lon. More information on lat/lon on the website here.

The first step is to parse lat/lon to x/y which can be achieved by chart.fromLatLonToPoint(). After that it is needed to set a center of a pie chart. Center accepts pixels, so x/y values should be translate to pixels - it can be achieved with axis.toPixels() method.

Highcharts.wrap(Highcharts.seriesTypes.pie.prototype, 'getCenter', function(p) {
var centerOptions = this.options.center,
  centerLatLonOptions = this.options.centerLatLon,
  chart = this.chart,
  slicedOffset = this.options.slicedOffset,
  pos,
  lat,
  lon;

if (centerLatLonOptions && chart.fromLatLonToPoint) {
  pos = chart.fromLatLonToPoint({
    lat: centerLatLonOptions[0],
    lon: centerLatLonOptions[1]
  });

  centerOptions[0] = chart.xAxis[0].toPixels(pos.x, true) - 2 * slicedOffset;
  centerOptions[1] = chart.yAxis[0].toPixels(pos.y, true) - 2 * slicedOffset;
}

return p.call(this);
});

Re-center pie charts needs to be called on redraw, it allows a pie chart to stay in the correct position.

redraw: function() {
      if (!this.centeringPies) {
        this.centeringPies = true;

        this.series.forEach(function(serie) {
          if (serie.type === 'pie' && serie.options.centerLatLon) {
            serie.update({
              center: serie.getCenter()
            }, false);
          }
        });

        this.redraw(false);
        this.centeringPies = false;
      }
    },

Example: https://jsfiddle.net/qqyLb7qx/1/

A thing to do is to check if a pie chart is inside a plot area - and if it's not, hide it.

Upvotes: 1

Related Questions