Опция onClick для диаграммы Рикши

Мне было интересно, действительно ли есть некорректная поддержка события onclick в точке данных, или мне нужно изменить библиотеку, чтобы она работала. Я просмотрел некоторые части исходного кода, и я не видел ничего, что позволяет связывать пользовательские действия с кликом. Учебник на их сайте также не показывает эту опцию (http://code.shutterstock.com/rickshaw/).

Любая помощь приветствуется. В настоящее время я оцениваю между флотом, рикшей и флот2. До сих пор ни один из них не удовлетворял всем требованиям, и я очень удивлен, за исключением флота, нет возможности для пользовательского события onClick в других библиотеках. Я видел, что некоторые люди добавили некоторый хакерский способ для flotr2, но это очень специфично только для гистограмм.

Ответы

Ответ 1

Это немного взломать, но у меня было такое же требование. У меня уже был объект HoverDetail, поэтому я подключился к событию onShow объекта HoverDetail, чтобы сохранить значение метки элемента x.

(Это было в приложении angular, поэтому я устанавливаю переменную в области)

var hoverDetail = new Rickshaw.Graph.HoverDetail({
    onShow: function(event){
        scope.data.activeDate = $(".x_label").text();
    },
    graph: graph
});

Затем я подключил нормальный обработчик кликов к графику и получил доступ к переменной, хранящейся в обработчике onShow.

Для получения дополнительной информации о том, как работать с объектом HoverDetail и другими конструкциями Rickshaw, посмотрите этот скринкаст: http://tagtree.tv/d3-with-rickshaw-and-angular

Ответ 2

Я получил это из HoverDetail, который, похоже, работает до сих пор:

Rickshaw.namespace('Rickshaw.Graph.ClickDetail');
Rickshaw.Graph.ClickDetail = Rickshaw.Class.create({

    initialize: function (args) {
        this.graph = args.graph;
        this.clickHandler = args.clickHandler || function(data){};
        this.lastEvent = null;
        this._addListeners();
    },

    update: function (e) {

        e = e || this.lastEvent;
        if (!e) return;
        this.lastEvent = e;

        if (!e.target.nodeName.match(/^(path|svg|rect|circle)$/)) return;

        var graph = this.graph;

        var eventX = e.offsetX || e.layerX;
        var eventY = e.offsetY || e.layerY;

        var j = 0;
        var points = [];
        var nearestPoint;
        var nearestValue;

        this.graph.series.active().forEach(function (series) {

            var data = this.graph.stackedData[j++];

            if (!data.length)
                return;

            var domainX = graph.x.invert(eventX);

            var domainIndexScale = d3.scale.linear()
                .domain([data[0].x, data.slice(-1)[0].x])
                .range([0, data.length - 1]);

            var approximateIndex = Math.round(domainIndexScale(domainX));
            if (approximateIndex == data.length - 1) approximateIndex--;

            var dataIndex = Math.min(approximateIndex || 0, data.length - 1);

            for (var i = approximateIndex; i < data.length - 1;) {

                if (!data[i] || !data[i + 1]) break;

                if (data[i].x <= domainX && data[i + 1].x > domainX) {
                    dataIndex = Math.abs(domainX - data[i].x) < Math.abs(domainX - data[i + 1].x) ? i : i + 1;
                    break;
                }

                if (data[i + 1].x <= domainX) {
                    i++
                } else {
                    i--
                }
            }

            if (dataIndex < 0) dataIndex = 0;
            var value = data[dataIndex];
            var distance = Math.sqrt(
                Math.pow(Math.abs(graph.x(value.x) - eventX), 2) +
                Math.pow(Math.abs(graph.y(value.y + value.y0) - eventY), 2)
            );

            if (!nearestPoint || distance < nearestPoint.distance) {
                nearestValue = value;
            }
        }, this);
        if(nearestValue){
            this.clickHandler(nearestValue);
        }
    },

    render: function (args) {
        // Do nothing
    },

    _addListeners: function () {
        this.graph.element.addEventListener(
            'click',
            function (e) {
                this.update(e);
            }.bind(this),
            false
        );
    }
});

Использование:

 new Rickshaw.Graph.ClickDetail({
            graph: graph,
            clickHandler: function(value){
                alert(value.x + ' ' + value.y);
            }
        });

Ответ 3

Вы пробовали HighCharts.js? Его библиотека javascript, которая используется для создания целых диаграмм и графиков.

http://www.highcharts.com/

Вы можете настроить onclick-событие для вызова функции javascript с использованием HighCharts.

Ответ 4

$('#chart').on('click', 'svg rect' ,function() {
        x = $(this)[0].__data__.x; //The value of x
        y = $(this)[0].__data__.y; //The value of y
        });

Пробовал и тестировал;)