BinaryJay
Posts: 2
Joined: Wed Sep 11, 2024 11:26 pm

GeoHeatmap Series not Varying by colorAxis

I am working on a map using the projection example as a base. I have added a series using the "afterAnimate" function via the chart.addSeries() method. The dataset loads with the lon,lat,value for the points in the dataset and renders as a solid color. I haven't been able to get it to follow the details in the colorAxis definition.

Here's the afterAnimate code loading the data via addSeries

Code: Select all

const afterAnimate = e => {
        const chart = e.target.chart;

        if (!chart.get('OvalData')) {
            chart.addSeries({
                type: 'geoheatmap',
                name: 'OvalData',
                animation: false,
                id: 'OvalData',
                colsize: 2,
                rowsize: 2,
                data: getOvalData()
            }, false);
            
            chart.redraw(false);
        }
    };
Here's the basemap details with the plot options for the geoheatmap

Code: Select all

Highcharts.getJSON(
        'https://code.highcharts.com/mapdata/custom/world.topo.json',
        topology => {

            const chart = Highcharts.mapChart('container', {
                chart: {
                    backgroundColor: 'rgba(0,0,0,0.1)',
                    map: topology
                },
                
                title: {
                    text: ''
                },

                legend: {
                    enabled: false
                },

                mapNavigation: {
                    enabled: false,
                    enableDoubleClickZoomTo: false,
                    buttonOptions: {
                        verticalAlign: 'bottom'
                    }
                },

                mapView: {
                    maxZoom: 3,
                    projection: {
                        name: 'Orthographic',
                        rotation: userLoc
                    }
                },
                
                tooltip: {
                    animation: false,
                    pointFormat: '{point.name}: {point.value}',
                    borderRadius: 10,
                    borderWidth: 2,
                    enabled: false,
                    enableMouseTracking: false
                },

                plotOptions: {
                    series: {
                        allowPointSelect: true,
                        nullColor: '#BFCFAD',
                        states: {
                            hover: {
                                enabled: false
                            },
                            inactive: {
                                enabled: false
                            },
                            select: {
                                enabled: false
                            }
                        },
                        animation: {
                            duration: 250
                        },
                        clip: false
                    },

                    geoheatmap: {
                        colorAxis: {
                            min: 0,
                            max: 100,
                            labels: {
                                enabled: false
                            },
                            stops: [
                                [0, 'rgba(9, 185, 0, .05)'],
                                [0.16, 'rgba(9, 185, 0, .1)'],
                                [0.33, 'rgba(9, 185, 0, .4)'],
                                [0.5, 'rgba(249, 204, 60, .7)'],
                                [0.66, 'rgba(243, 165, 46, .8)'],
                                [0.83, 'rgba(238, 104, 47, .8)'],
                                [1, 'rgba(219, 62, 45, .9)']
                            ]
                        },
                        clip: false
                    }
                },

                series: [{
                    name: 'Graticule',
                    id: 'graticule',
                    type: 'mapline',
                    data: getGraticule(),
                    nullColor: 'rgba(0, 0, 0, 0.05)',
                    enableMouseTracking: false
                }, {
                    data,
                    /*joinBy: 'name',
                    name: 'NothingYet',*/
                    dataLabels: {
                        enabled: false,
                        format: '{point.name}'
                    },
                    events: {
                        afterAnimate
                    }
                }]
                
            });

            // Render a circle filled with a radial gradient behind the globe to
            // make it appear as the sea around the continents
            const renderSea = () => {
                let verb = 'animate';
                if (!chart.sea) {
                    chart.sea = chart.renderer
                        .circle()
                        .attr({
                            fill: {
                                radialGradient: {
                                    cx: 0.4,
                                    cy: 0.4,
                                    r: 1
                                },
                                stops: [
                                    [0, 'lightblue'],
                                    [1, '#005477']
                                ]
                            },
                            zIndex: -1
                        })
                        .add(chart.get('graticule').group);
                    verb = 'attr';
                }

                const bounds = chart.get('graticule').bounds,
                    p1 = chart.mapView.projectedUnitsToPixels({
                        x: bounds.x1,
                        y: bounds.y1
                    }),
                    p2 = chart.mapView.projectedUnitsToPixels({
                        x: bounds.x2,
                        y: bounds.y2
                    });
                chart.sea[verb]({
                    cx: (p1.x + p2.x) / 2,
                    cy: (p1.y + p2.y) / 2,
                    r: Math.min(p2.x - p1.x, p1.y - p2.y) / 2
                });
            };
            renderSea();
            Highcharts.addEvent(chart, 'redraw', renderSea);
        }
    );
I'm at a loss as how to approach this. Please advise.
andrzej.b
Posts: 134
Joined: Mon Jul 15, 2024 12:34 pm

Re: GeoHeatmap Series not Varying by colorAxis

Hi @BinaryJay,

Welcome to our forum and thanks for contacting us with your question!

I see one issue with your config: you try to specify color Axis within plotOptions, while you should be doing it in the root of the config. In plotOptions this option has a different meaning, please see the API reference.

I prepared a sample demo with your colorAxis config moved to the root of config: https://jsfiddle.net/BlackLabel/pyh9eb1L/

Let me know if that is what you were looking for!

Best regards,
Andrzej
BinaryJay
Posts: 2
Joined: Wed Sep 11, 2024 11:26 pm

Re: GeoHeatmap Series not Varying by colorAxis

I had tried that, following the documentation, but in my case the heatmap is not being applied when the series is being added using chart.addSeries. I attempted every combination of placement for colorAxis configuration and wasn't able to get to anything but rendering a solid color.

I reworked the map to put the ovalData in as part of the main map definition and this works when displaying the heatmap. My next step though is to add a shadow to the map tracking the sun's location and I would want to position the shadow beneath the heatmap in its z-index. I'm not sure how to accomplish this. It would seem I'll need to create the shadow as an svg, I have the calculation for the shadow center lon/lat, radius and such but struggling with the layering and placement in coords for the shadow. Any recommendations on this approach?
andrzej.b
Posts: 134
Joined: Mon Jul 15, 2024 12:34 pm

Re: GeoHeatmap Series not Varying by colorAxis

Hi @BinaryJay,

The best way to get the layering behaviour with maps is to set/define series with them one after the other, starting from the bottom layer.
Take for instance this demo: https://www.highcharts.com/demo/maps/mappoint-mapmarker
In the series config part, the first series draws blue borders on the coastline, the second draws countries, the third adds blue mappoints, and the last adds red ones and the order matters.

Also, taking a look at this property: fitToGeometry and an example demo there might be helpful.

Please let me know if I can be of any further assistance.

Best regards,
Andrzej

Return to “Highcharts Maps”