The Mouse click event in HighCharts is being managed by both the Series handler and Point handler simultaneously

For my project, I have set up mouse click event handlers for both Series and Points.

plotOptions: {
    series: {
        cursor: 'pointer',
        events: {
            click: function (event) {
                console.log(event);
                alert('series line clicked');
            }
        },
        point: {
            events: {
                click: function(event) {
                    alert('series point clicked');
                }
            }
        }
    }
},

I am facing an issue where when a user clicks on the line, both the line click event handler and the point event handler are triggered. I want only one of them to be called based on whether the user clicks on the line or the point directly. What additional configurations do I need to include?

Link to working code example

Answer №1

To work around this issue, you can utilize jQuery to monitor click events on points and also listen for click events on lines from the highcharts handler:

jQuery point click event listener:

$(".highcharts-point").click(function(event) {
    console.log("jQuery point.click",event);
    // This prevents the event from propagating to the series click handler
    event.stopPropagation();
})

Highcharts series click handler:

plotOptions: {
    series: {
        cursor: 'pointer',
        events: {
            click: function (event) {
                console.log("series.click",event);
            }
        }
    }
},

Take a look at this fiddle: https://jsfiddle.net/beaver71/ysnc4sk8/

Answer №2

The function responsible for triggering these events is referred to as onContainerClick. It triggers both the series event followed by the point event. Here is an outline of how it works:

onContainerClick: function(e) {
    var chart = this.chart,
        hoverPoint = chart.hoverPoint,
        plotLeft = chart.plotLeft,
        plotTop = chart.plotTop;

    e = this.normalize(e);

    if (!chart.cancelClick) {

        // On tracker click, trigger the series and point events. #783, #1583
        if (hoverPoint && this.inClass(e.target, 'highcharts-tracker')) {

            // the series click event
            fireEvent(hoverPoint.series, 'click', extend(e, {
                point: hoverPoint
            }));

            // the point click event
            if (chart.hoverPoint) { 
                hoverPoint.firePointEvent('click', e);
            }

        } else {
            extend(e, this.getCoordinates(e));

            // fire a click event in the chart
            if (chart.isInsidePlot(e.chartX - plotLeft, e.chartY - plotTop)) {
                fireEvent(chart, 'click', e);
            }
        }


    }
},

This code serves as a wrapper for the onContainerClick method, designed to only trigger one event at a time:

(function(H) {
  var occ = H.Pointer.prototype.onContainerClick;
  H.Pointer.prototype.onContainerClick = function(e) {
    if(e.target.classList.value.indexOf('highcharts-point') >= 0) {
      e = this.normalize(e);
      this.chart.hoverPoint.firePointEvent('click', e);
    }
    else if (e.target.classList.value.indexOf('highcharts-tracker') >= 0) {
      e = this.normalize(e);
      H.fireEvent(this.chart.hoverPoint.series, 'click',H.extend(e, {
        point: this.chart.hoverPoint
      }));
    }
    else {
      occ.call(this, e);
    }
  }
})(Highcharts)

See the functionality in action:

(function(H){
  var occ = H.Pointer.prototype.onContainerClick;
  H.Pointer.prototype.onContainerClick = function(e) {
    if(e.target.classList.value.indexOf('highcharts-point') >= 0) {
      e = this.normalize(e);
      this.chart.hoverPoint.firePointEvent('click', e);
    }
    else if (e.target.classList.value.indexOf('highcharts-tracker') >= 0) {
      e = this.normalize(e);
      H.fireEvent(this.chart.hoverPoint.series, 'click',H.extend(e, {
        point: this.chart.hoverPoint
      }));
    }
    else {
      occ.call(this, e);
    }
  }
})(Highcharts)

Highcharts.chart('container', {
    xAxis: {
        categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    },

    plotOptions: {
        series: {
            cursor: 'pointer',
            events: {
                click: function (event) {
                    console.log('series event')                    
                }
            },
            point: {
                events: {
                    click: function(event) {
                        console.log('point event')                    
                    }
                }
            }
        }
    },

    series: [{
        data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
    }]
});
<script src="https://code.highcharts.com/highcharts.src.js"></script>

<div id="container" style="height: 400px"></div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

ReactJS is unable to locate a valid DOM element within the target container

I recently embarked on my journey to learn ReactJS and I celebrated successfully writing my first code. However, when I encountered the same pattern with components, an error popped up stating _Invariant Violation: registerComponent(...): Target container ...

Updating Socket.io with multiple data emissions upon refresh or reload

I'm facing an issue that is very similar to this problem: https://github.com/rethinkdb/rethinkdb/issues/6503 Whenever I connect for the first time, it only logs once. Upon refreshing, it logs twice. Subsequent refreshes result in an additional log ea ...

Encountering Reference Error while Using AWS Amplify with Nuxt.js: Navigator Undefined

Currently, I am experimenting with Nuxt.js and AWS Amplify to leverage the benefits of SSR/SEO for my project. I have successfully integrated Amplify into my project and followed the "Manual Configuration" steps outlined in the Amplify Docs to set it up. ...

Utilizing VueJS to transfer information for constructing a pricing plan chart

This is my first experience with VueJS, so I would greatly appreciate any advice or alternative methods to solve the issue. You can view my progress so far here. I am working on creating a pricing plan table where users can explore four different payment ...

Restricting href Usage Based on Session

I find myself in a challenging situation without a clear solution at hand. Within this code, I am utilizing a link and a button for which I need to save the page in a database. Therefore, creating a server control is not an option as it will not be render ...

How can you handle events on DOM elements that haven't been created yet in JavaScript?

In my JavaScript module, I have the following code: EntryController = function$entry(args) { MainView(); $('#target').click(function() { alert('Handler called!'); }); } The MainView() function includes a callback ...

Storing information within a Express application using Postgres

Recently, I've been delving into the world of Express and experimenting with a program that allows users to create events and invite others. While I know about using join tables to retrieve data, I'm curious if there's a way to organize the ...

I recently installed bootstrap, jquery, and popper.js on my live server, but to my surprise, nothing was appearing on the screen. Despite compiling the

After successfully installing bootstrap, jquery, and popper.js, I encountered an issue on my live server where nothing was displaying. Oddly enough, no errors were detected after compiling the code. import { createApp } from 'vue' import App from ...

The function array.map() is not functioning as anticipated when trying to display the <li> element within a React component

I'm having trouble rendering multiple <li> components using the map() function. No content is being displayed on the screen and I'm not receiving any error messages, so I'm unsure of what the issue might be. reviewCard = revie ...

The process of setting up a carousel for tables using jQuery

I can successfully implement jquery for an image carousel, but now I need to find a way to create a sliding table format. Any assistance on this matter would be greatly appreciated. Here is the code I currently have: <ul> <li><a style= ...

What is the best way to connect the imagemap shape with the checkbox?

I need assistance with synchronizing an imagemap collection of shapes and checkboxes. How can I ensure that clicking on a shape selects the corresponding checkbox, and vice versa? Imagemap: <div class="map_container"> <%= image_tag("maps/main ...

Ways to verify if a minimum of three letters in each variable correspond

let nameOne = 'chris|'; let nameTwo = 'christiana'; To use JavaScript, what is the best way to determine if three or more letters match between both variables? ...

The dynamic Vue.js transitions and effects are like a magic

I am using a v-for to render multiple child components: <div v-for="(pass) in scoringPass" :key="pass.decision"> <Pass :pass="pass"/> </div> Each of these child components contains a transition tag: &l ...

Ways to make React detect a click event triggered by Jquery

I'm currently utilizing dabeng/OrgChart within a React application. The functionality I am looking to achieve is when a user clicks on a node, instead of Jquery populating an input box, I want React to save the selected node in state. I have attempte ...

What is the process for creating a server-side API call?

I've designed a front-end application that uses an API to retrieve data. The problem I'm facing is that in order to access the API, I need to use an API Key. If I include the API key in the client-side code, it will be visible to users. How can I ...

The scrolling event on the div is not triggering

I'm struggling with this piece of code: const listElm = document.querySelector('#infinite-list'); listElm.addEventListener('scroll', e => { if(listElm.scrollTop + listElm.clientHeight >= listElm.scrollHeight) { th ...

Utilizing the Jquery ready method in conjunction with the load function

While utilizing the ready() method to access the DOM, I encountered an issue where jQuery was returning undefined when trying to access an element. Even after nesting the ready() function inside $(window).on("load", function()), there were still instances ...

Exploring objects as strings to retrieve data with Javascript

In a scenario where I receive an object of varying length that I do not control, I am required to extract specific data from it. The response I receive is in the form of a formatted string: { "questionId": 18196101, "externalQuestionId": "bcc38f7 ...

Utilizing JQuery for real-time total updates

When a new div is created by clicking a button, I want to dynamically maintain an order system where the first div is labeled as 1 of 1, then as more divs are added it should change to 1 of 2, and so on. If a div is deleted, the numbering should reset back ...

What is the best way to retrieve the column that comes after a specific column?

I have a specific column and I want to extract the subsequent column in the dataset. nhood,column,variablecolumn Treasure Island,3,5 McLaren Park,1,2 Tenderloin,28,112 Lakeshore,14,8 Chinatown,15,103 Although I know the name of the second column, the na ...