Kunal
Kunal

Reputation: 236

Plotly.js - Click event on category label of bar chart

Is it possible to get click event on category label (xticks) of bar chart plotted using Plotly.js? I know its possible to get click event on actual bars but I am looking for click event on category label under bar. In below image I am looking for click event on 'giraffes'. Thanks for the help in advance.enter image description here

Upvotes: 0

Views: 1213

Answers (2)

Mauro Mascia
Mauro Mascia

Reputation: 445

In this comment https://github.com/plotly/plotly.js/issues/65#issuecomment-350672387

I give a workaround, because for now there is no native way to satisfy your request.

This is the code for Angular (but it can be easily adapted to vanilla JS).

import * as d3 from 'd3';

export class AngularCustomComponent {

    // contructor and other methods here..

    plotlyClickEvents() {
        /**
         * Distinguish between single and double click
         * @see http://bl.ocks.org/ropeladder/83915942ac42f17c087a82001418f2ee
         */
        function clickcancel() {
            let dispatcher = d3.dispatch('click', 'dblclick');
            function cc(selection) {
                let down, tolerance = 5, last, wait = null, args;

                // euclidean distance
                function dist(a, b) {
                    return Math.sqrt(Math.pow(a[0] - b[0], 2) + Math.pow(a[1] - b[1], 2));
                }

                selection.on('mousedown', function() {
                    down = d3.mouse(document.body);
                    last = +new Date();
                    args = arguments;
                });

                selection.on('mouseup', function() {
                    if (dist(down, d3.mouse(document.body)) > tolerance) {
                        return;
                    }
                    else {
                        if (wait) {
                            window.clearTimeout(wait);
                            wait = null;
                            dispatcher.apply("dblclick", this, args);
                        }
                        else {
                            wait = window.setTimeout((function() {
                                return function() {
                                    dispatcher.apply("click", this, args);
                                    wait = null;
                                };
                            })(), 300);
                        }
                    }
                });
            };

            // Copies a variable number of methods from source to target.
            let d3rebind = function(target, source, method) {
                let i = 1, n = arguments.length;
                while (++i < n) target[method] = d3_rebind(target, source, source[method]);
                return target;
            };

            // Method is assumed to be a standard D3 getter-setter:
            // If passed with no arguments, gets the value.
            // If passed with arguments, sets the value and returns the target.
            function d3_rebind(target, source, method) {
                return function() {
                    let value = method.apply(source, arguments);
                    return value === source ? target : value;
                };
            }

            return d3rebind(cc, dispatcher, 'on');
        }

        return clickcancel();
    }

    onBarChartXAxisClick() {
        let self = this;
        let item = null;

        d3.select("#your-parent-element-identifier").
            select('.cartesianlayer')
                .select('.xaxislayer-above')
                    .selectAll('.xtick > *').each(function(e) {
            // @see https://hstefanski.wordpress.com/2015/10/25/responding-to-d3-events-in-typescript/
            // but `d3.select(d3.event.currentTarget)` does not work in this case.
            // To workaround see https://stackoverflow.com/a/40314241

            item = d3.select(this);

            // @NOTE: the element of the x-axis is a <text> and does not have the
            // attribute "pointer-events". Without this attribute is not possibile
            // to listen for mouse events, and for that we have to add it.
            item.attr('pointer-events', 'all');

            const cc = self.plotlyClickEvents();
            item.call(cc);

            cc.on('click', (d, index) => {
                // Do something
            });
        });
    }

}

Upvotes: 1

Kunal
Kunal

Reputation: 236

Currently there is no click event on category labels.

Upvotes: 0

Related Questions