user15299
user15299

Reputation: 133

Highcharts : How do I keep the marker formatting and make the click event fire with a 5K+ point scatter plot?

We are running into an issue where our scatter chart starts to act abnormally when we reach 5,000 points on the screen. Specifically, at 5k+ points, the point event 'click' will stop firing when we click on a point, and our point formatting (fillColor & symbol) is lost.

4999 points: http://jsfiddle.net/xrpf0pfq/7/

$(function() {

// Prepare the data
var data = [],
    n = 4999, // < 5K points
    i;
for (i = 0; i < n; i += 1) {
    data.push([
        Math.pow(Math.random(), 2) * 100,
        Math.pow(Math.random(), 2) * 100
    ]);
}

if (!Highcharts.Series.prototype.renderCanvas) {
    console.error('Module not loaded');
    return;
}

console.time('scatter');
console.time('asyncRender');
$('#container').highcharts({

    chart: {
        zoomType: 'xy'
    },

    xAxis: {
        min: 0,
        max: 100,
        gridLineWidth: 1
    },

    yAxis: {
        // Renders faster when we don't have to compute min and max
        min: 0,
        max: 100,
        minPadding: 0,
        maxPadding: 0
    },

    title: {
        text: 'Scatter chart with ' + Highcharts.numberFormat(data.length, 0, ' ') + ' points'
    },
    legend: {
        enabled: false
    },
    series: [{
        type: 'scatter',
        data: data,
        marker: {
            radius: 5,
            symbol: 'triangle', //shows correctly 
            fillColor: 'rgba(128,0,128,1)' //shows correctly
        },
        point: {
            events: {
                click: function() {
                    alert("click"); //event is fired correctly

                }
            }
        },
        tooltip: {
                enable: false,
            followPointer: false,
            pointFormat: '[{point.x:.1f}, {point.y:.1f}]'
        },
        events: {
            renderedCanvas: function() {
                console.timeEnd('asyncRender');
            }
        }
    }]

});
console.timeEnd('scatter');

});

5000 points: http://jsfiddle.net/xrpf0pfq/10/

$(function() {

// Prepare the data
var data = [],
    n = 5000, // 5K points
    i;
for (i = 0; i < n; i += 1) {
    data.push([
        Math.pow(Math.random(), 2) * 100,
        Math.pow(Math.random(), 2) * 100
    ]);
}

if (!Highcharts.Series.prototype.renderCanvas) {
    console.error('Module not loaded');
    return;
}

console.time('scatter');
console.time('asyncRender');
$('#container').highcharts({

    chart: {
        zoomType: 'xy'
    },

    xAxis: {
        min: 0,
        max: 100,
        gridLineWidth: 1
    },

    yAxis: {
        // Renders faster when we don't have to compute min and max
        min: 0,
        max: 100,
        minPadding: 0,
        maxPadding: 0
    },

    title: {
        text: 'Scatter chart with ' + Highcharts.numberFormat(data.length, 0, ' ') + ' points'
    },
    legend: {
        enabled: false
    },
    series: [{
        type: 'scatter',
        data: data,
        marker: {
            radius: 5,
            symbol: 'triangle', //marker shape not showing 
            fillColor: 'rgba(128,0,128,1)' //color not showing
        },
        point: {
            events: {
                click: function() {
                    alert("click"); //click even not firing

                }
            }
        },
        tooltip: {
                enable: false,
            followPointer: false,
            pointFormat: '[{point.x:.1f}, {point.y:.1f}]'
        },
        events: {
            renderedCanvas: function() {
                console.timeEnd('asyncRender');
            }
        }
    }]

});
console.timeEnd('scatter');

});

Is there way to keep the marker formatting and make the click event fire when you have 5K or more points on a scatter plot?

Upvotes: 2

Views: 1038

Answers (2)

Stefan Jelner
Stefan Jelner

Reputation: 111

Ran accross the same problem. The halo-workaround didn't work for me, because i wanted to get the click event for the recently highlighted point, even if it is not directly clicked. Highcharts has the ability to highlight the nearest point if you point anywhere on the chart. My workaround is, to use the tooltip formatter to store the x value away and then use it on the global click event for the chart.

See the fiddle:

http://jsfiddle.net/StefanJelner/a1m0wuy6/

var recent = false;
$('#container').highcharts({
    chart: {
        events: {
            click: function() {
            console.log('chart click', recent);
          }
        }
    },
    tooltip: {
        formatter: function() {
            recent = this.x;
            return 'The value for <b>' + this.x +
            '</b> is <b>' + this.y + '</b>';
        }
    },
    plotOptions: {
        series: {
            point: {
                events: {
                    click: function (e) {
                        console.log('point click', e); // never happens
                    }
                }
            }
        }
    }
});

This should also work for Version 6.

Upvotes: 0

pawel_d
pawel_d

Reputation: 3070

Apparently, this behaviour is caused by boost module. Look at the example without it: http://jsfiddle.net/xrpf0pfq/12/. You can check in a source code of a boost module (http://code.highcharts.com/modules/boost.src.js) that the boostThreshold property is set with value 5000. You can set boostThreshold by yourself, check out the example: http://jsfiddle.net/xrpf0pfq/16/.

plotOptions: {
    series: {
        boostThreshold: 8001
    }
}

Also, not working click event with boost module is a known issue (beside, it is not good idea to click on a point where there are thousands of them and they are densely populated). There is a workaround for that though, take a look at this topic on GitHub: https://github.com/highcharts/highcharts/issues/4569. As Paweł mentioned, to make click event work with a huge amount of points, you need to enable halo and make it clickable (here is an example with boost module loaded and with more points than boostThreshold value but with click event working: http://jsfiddle.net/xrpf0pfq/17/).

mouseOver: function() {
    if (this.series.halo) {
        this.series.halo.attr({'class': 'highcharts-tracker'}).toFront();
    }
}

Regards.

Upvotes: 4

Related Questions