Highcharts:如何保持标记格式并使用 5K+ 点散点图触发点击事件?

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

我们 运行 遇到一个问题,当我们在屏幕上达到 5,000 点时,我们的散点图开始出现异常行为。具体来说,在 5k+ 点时,点事件 'click' 将在我们单击一个点时停止触发,并且我们的点格式(填充颜色和符号)丢失。

4999 点: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 点: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');

});

有没有办法保持标记格式并在散点图上有 5K 或更多点时触发点击事件?

显然,此行为是由升压模块引起的。看看没有它的例子: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
    }
}

此外,无法使用 boost 模块的点击事件是一个已知问题(此外,点击一个有数千个且人口密集的点并不是一个好主意)。不过有一个解决方法,请查看 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();
    }
}

此致。

运行 遇到同样的问题。 halo-workaround 对我不起作用,因为我想获取最近突出显示的点的点击事件,即使它不是直接点击的。如果您指向图表上的任意位置,Highcharts 能够突出显示最近的点。我的解决方法是,使用工具提示格式化程序将 x 值存储起来,然后在图表的全局点击事件中使用它。

参见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
                    }
                }
            }
        }
    }
});

这也适用于版本 6。