javascripthighchartsgeojsonproj4js

Highcharts / highmaps GeoJSON map appears distorted and squashed


I have created a simple chloropleth of UK regions in highcharts, inclusive of countries other than England (North East, Wales, West Midlands, etc.) and I am using this public domain GeoJSON map.

I am struggling to get the map to render correctly — the projection seems distorted and squashed regardless of the height and width of the div in which it is contained.

This is my map in codepen

From reading other threads of people having similar issues, it seems that an additional line needs to be inserted into the GEOjson text file establishing a hc-transform object. Highcharts documentation gives the following example:

"hc-transform": {
    "default": {
        "crs": "Your map projection in proj4 string format, as supported by pro4js"
    }
}

I have copied and pasted the relevant section from an existing map of the UK from the Highcharts map library, hoping that it would project my map the same as the demos, but to no avail - my chart remains squashed.

"crs": {"type":"name","properties":{"name":"urn:ogc:def:crs:EPSG:32630"}},"hc-transform":{"default":{"crs":"+proj=utm +zone=30 +datum=WGS84 +units=m +no_defs","scale":0.000578035606384,"jsonres":15.5,"jsonmarginX":-999,"jsonmarginY":9851.0,"xoffset":164769.517785,"yoffset":6747386.21622}},  

I don't know how to use QGIS to generate a proj4 string format. Any help appreciated!

Edit - here is the code for my chart:

(async () => {
    const data = [
        ['North East', 1536],
        ['North West', 3403],
        ['Yorkshire and the Humber', 629],
        ['East Midlands', 1120],
        ['West Midlands', 3562],
        ['East', 1239],
        ['London', 503],
        ['South East', 1632],
        ['South West', 972],
        ['Wales', 576],
        ['Scotland', 293],
        ['Northern Ireland', 269]
    ];

    const geojson = await fetch(
        'https://raw.githubusercontent.com/sophiemonk-cw/geojson/main/uk_regions.geojson'
    ).then(response => response.json());

  Highcharts.setOptions({
    lang: {
      thousandsSep: ','
  }
})
    Highcharts.mapChart('container', {
        chart: {
            map: geojson,
            style: {
              fontFamily: 'neue-haas-unica'
            }
        },
        title: {
            text: ''
        },
        colorAxis: {
            min: 269,
            max: 3562,
            tickPixelInterval: 50,
            minColor: '#CCF2ED',
            maxColor: '#5C328A'
        },
      
        tooltip: {
                pointFormat: '{point.name}{point.rgn19nm}: £{point.value}mn'
            },
      
        series: [{
            data: data.map(([name, value]) => ({ rgn19nm: name, value: value })),
            keys: ['rgn19nm', 'value'],
            joinBy: 'rgn19nm',
            name: 'GVA',
            mapData: geojson,
            borderWidth: 1,
            borderColor: '#fff',
            states: {
                hover: {
                    color: '#333',
                    borderWidth: 0,
                    animation: {
                      duration: 0
                },
                }
            },
            dataLabels: {
                enabled: false,
            }
        }]
    });
})();

Solution

  • All you need to do is add projection to your chart config:

    mapView: {
      projection: {
        name: 'WebMercator'
      }
    },
    

    Built-in projections are EqualEarth, LambertConformalConic, Miller, Orthographic and WebMercator.

    Demo: https://jsfiddle.net/BlackLabel/xa7qgv10/

    API Reference: https://api.highcharts.com/highmaps/mapView.projection