Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

highcharts: stop chart from trapping mouse events, or capture mouse click on the ENTIRE chart

Tags:

highcharts

All,

I'm using HighCharts in a web app I'm working on, and generally, I like it very much.

However, I'm having a hard time figuring out how capture a mouse click on the ENTIRE chart.

In other words - I'd like to know when the user clicks ANYWHERE on the chart (e.g., the plot area, the title, the x- or y-axis, the margins and padding around the chart elements, etc.)

Or, I'd like to disable events altogether, so I can trap the event in the container itself.

More detailed version...

I have a DIV that contains my HighChart.

I want to know if the user clicks ANYWHERE within that DIV.

So - initially I tried attaching an "onclick" event to the DIV, but that never gets fired, presumably because the click is getting trapped by the HighChart.

So, in the code that sets up the HighChart, I added this:

var chart = new Highcharts.Chart({
    chart: {
        renderTo: "container",
        events: {
            click: function(event) {
                // do something
            }
        },
        ...
    }
    ...
});

This works OK IF the user clicks somewhere within the plot area, but not if she clicks anywhere else in the chart (e.g., the x-axis, the y-axis, the title, the padding around the chart elements, etc.)

So - how can I make the ENTIRE chart clickable?

Many thanks in advance!

like image 860
mattstuehler Avatar asked Jul 23 '12 18:07

mattstuehler


2 Answers

I had this same issue.

Using the webkit inspector I can see that Highcharts binds a click event to the chart container (the div with the 'highcharts-container' class), and this seems to interfere with clicking.

Provided you don't want any of the functionality in that click event, you can remove it by setting

chart.container.onclick = null;

Otherwise, you'll need to use the built-in highcharts event properties to set your callbacks. As the OP noted, there is an 'events' property for the chart object, which should trigger when clicking the plot background. There is also an event property for the plot options which triggers when clicking the series itself.

For example, for area plots:

var chart = new Highcharts.Chart({
    ...
    plotOptions: {
        area: {
            events: {
                click: function(event) {
                    // do something
                }
            },
        ...
        }
    }
    ...
});

More more info see: http://www.highcharts.com/ref/#plotOptions-area-events

like image 66
grahamgilchrist Avatar answered Oct 26 '22 13:10

grahamgilchrist


I ran into this, and wrote an extension/plugin for highcharts 3 that bubbles click events out of highcharts:

/*global Highcharts*/
(function (Highcharts) {
    "use strict";

    Highcharts.wrap(Highcharts.Pointer.prototype, 'onContainerClick', function (original, e) {
        var pointer = this,
            parent = pointer.chart.container.parentNode,
            bubbleUp = true;

        // Add a method to the event to allow event handlers to prevent propagation if desired
        e.swallowByHighCharts = function() { bubbleUp = false; };

        // Call the original event
        original.apply(this, Array.prototype.slice.call(arguments, 1));

        // Trigger the event on the container's parent (to bubble the event out of highcharts)
        // unless the user wanted to stop it
        if (bubbleUp && typeof parent !== 'undefined' && parent) {
            jQuery(pointer.chart.container.parentNode).trigger(e);
        }
    });

}(Highcharts));

With this added, all click events are bubbled out of the highcharts container. Triggering it on the container itself causes a ton of looping due to how highcharts and jquery interact with event firing, and at least in my case I didn't actually have any handlers on the element used as a render target anyway.

The extra bit about swallowByHighCharts allows for disabling the new behavior if needed - ie,

config = {
    chart: { ... }
    plotOptions: {
        series: {
            point: {
                events: {
                    click: function(e) {
                        // Don't pass along clicks on series points for one reason or another
                        e.swallowByHighCharts();
                    }
                }
            }
        }
    }
}
like image 37
mrusinak Avatar answered Oct 26 '22 12:10

mrusinak