0

I'm having a problem with mouse events ('dblclick' and 'click') in Apache ECharts plugin. When I trigger mouse 'double click' event, it also triggers mouse 'click' event twice. How can I prevent action in 'click' event when 'dbl click' is triggered?

http://jsfiddle.net/jm6uqdzs/

myChart.off('click');
myChart.on('click', function (params) {
    console.log('click',params);
    // action when bar element is clicked
});

myChart.off('dblclick');
myChart.on('dblclick', function (params) {
    console.log('dobule click:', params);
    // action when bar element is double clicked
});

console log:

click {componentType: "series", componentSubType: "bar", componentIndex: 0, seriesType: "bar", seriesIndex: 0, …}
click {componentType: "series", componentSubType: "bar", componentIndex: 0, seriesType: "bar", seriesIndex: 0, …}
dobule click: {componentType: "series", componentSubType: "bar", componentIndex: 0, seriesType: "bar", seriesIndex: 0, …}

Thank you for your help!

Davithe
  • 1
  • 1

2 Answers2

0

I was facing the same issue and discovered the my chart was added to the DOM more than one time.

tamersalama
  • 4,093
  • 1
  • 32
  • 35
0

I think this is just an architecture problem. The click event happened, so no reason to filter it out. Double click is actually another immediate click under specific short time period.

So I would to react on click event with delay if double click didn't happened.

In case you want to prevent some internal action. In my case it was the drilling down when clicking on segments in the sunburst chart. I found the solution in their documentation (it is really neat and helpful).

It was just one property set to false value :)

https://echarts.apache.org/en/option.html#series-sunburst.nodeClick

In another words I would to expect that the click will trigger twice as that is what double click means.

The (legacy react) code deals with it like this:

canvasWrapperRef.current.ondblclick = e => {
    triggerOnDoubleClickEvent();
};

let dblclick_timeout = 0;

canvasWrapperRef.current.onclick = e => {
    if (dblclick_timeout === 0) {
        dblclick_timeout = setTimeout(() => {
            dblclick_timeout = 0;
            triggerOnClickEvent();
        }, 400);
    } else {
        clearTimeout(dblclick_timeout);
        dblclick_timeout = 0;
    }
};

Refactored version for React

I've done the hook what make the code more tidy and increase readability.

The hook:

export default () => {
    let doubleClickTimeout;
    return (callbackDoubleClick, callbackSingleClick, doubleClickTimeoutDelay) => {
        if (!doubleClickTimeout) {
            doubleClickTimeout = setTimeout(() => {
                doubleClickTimeout = 0;
                callbackSingleClick();
            }, doubleClickTimeoutDelay);
        } else {
            clearTimeout(doubleClickTimeout);
            doubleClickTimeout = 0;
            callbackDoubleClick();
        }
    };
};

And the code to use it is here:

import React from "react";
import useDoubleClickChecker from "./useDoubleClickChecker";

function Component(props) {
    ...
    const doubleClickChecker = useDoubleClickChecker();
    ...
    const [echartsEvetns] = React.useState({
        click: event => {
            doubleClickChecker(() => console.log("double click"), () => console.log("single click"), 400)
        },
        dblclick: event => {
            console.log("double click");
        },
    });
    ...
    return (
        <ReactECharts
            option={option}
            onEvents={echartsEvetns}
        />
    );
}

export default Component;

Now, you'll see the "double click" string in the browser's console twice. Is it not fun?

Just ignore one from the double click reaction.

dominikj111
  • 348
  • 5
  • 15