添加链接到X-Label Chart.js

时间:2016-01-21 08:30:08

标签: javascript chart.js

我希望能够在Chart.js bar 图表中链接x标签。我已经搜索得非常彻底,最后试图找到我自己的解决方案:因为标签对应于它们正上方的条形图而Chart.js有一个内置的getBarsAtEvent(evt)方法,我尝试创建一个事件如果用户没有点击图表 - 这个新事件的pageX和pageY直接位于初始点击之上,这样如果用户点击了标签,则新事件将模拟条形图上的点击。

但是,反复调用getBarsAtEvent(createdClickEvent)会给我一个Uncaught TypeError("无法读取属性' getBoundingClientRect' of null"),这必须意味着getBarsAtEvent方法,当被调用时我模拟的点击,实际上并没有返回任何内容。

非常感谢任何建议或替代方法,提前谢谢。

2 个答案:

答案 0 :(得分:3)

另一种方法是确定实际点击用户的点,并根据该点计算点击了哪个标签。为此,您将需要有关创建的图表的一些信息,并且必须进行一些计算。

下面是一种方法,这是一个Fiddle这个代码/方法。希望它有所帮助。

    $("#canvas").click( 
       function(evt){
            var ctx = document.getElementById("canvas").getContext("2d");
            // from the endPoint we get the end of the bars area
            var base = myBar.scale.endPoint;
            var height = myBar.chart.height;
            var width = myBar.chart.width;
            // only call if event is under the xAxis
            if(evt.pageY > base){
                // how many xLabels we have
                var count = myBar.scale.valuesCount;
                var padding_left = myBar.scale.xScalePaddingLeft;
                var padding_right = myBar.scale.xScalePaddingRight;
                // calculate width for each label
                var xwidth = (width-padding_left-padding_right)/count;
                // determine what label were clicked on AND PUT IT INTO bar_index 
                var bar_index = (evt.offsetX - padding_left) / xwidth;
                // don't call for padding areas
                if(bar_index > 0 & bar_index < count){
                    bar_index = parseInt(bar_index);
                    // either get label from barChartData
                    console.log("barChartData:" + barChartData.labels[bar_index]);
                    // or from current data
                    var ret = [];
                    for (var i = 0; i < myBar.datasets[0].bars.length; i++) {
                        ret.push(myBar.datasets[0].bars[i].label)
                    };
                    console.log("current data:" + ret[bar_index]);
                    // based on the label you can call any function
                }
            }
       }
);   

答案 1 :(得分:1)

我修改了iecs的回答以使用chartjs 2.7.1

var that = this;
this.chart = new Chart($("#chart"), {
    type: 'bar',
    data: {
        labels: labels,
        datasets: datasets
    },
    options: {
        events: ["mousemove", "mouseout", "click", "touchstart", "touchmove", "touchend"],
        onClick: function(e, data) {
            var ctx = $("#chart")[0].getContext("2d");
            var base = that.chart.chartArea.bottom;
            var height = that.chart.chart.height;
            var width = that.chart.chart.scales['x-axis-0'].width;
            var offset = $('#chart').offset().top - $(window).scrollTop();
            if(e.pageY > base + offset){
                var count = that.chart.scales['x-axis-0'].ticks.length;
                var padding_left = that.chart.scales['x-axis-0'].paddingLeft;
                var padding_right = that.chart.scales['x-axis-0'].paddingRight;
                var xwidth = (width-padding_left-padding_right)/count;
                // don't call for padding areas
                var bar_index = (e.offsetX - padding_left - that.chart.scales['y-axis-0'].width) / xwidth;
                if(bar_index > 0 & bar_index < count){
                    bar_index = Math.floor(bar_index);
                    console.log(bar_index);
                }
            }
        }
    }
});

主要区别是:

  • 较新版本的chartjs使用chart.scales数组而不是带有一堆值的chart.scale
  • 我不得不从x偏移量减去chart.scales ['y-axis-0']。width以获得正确的bar_index
  • 我将parseInt更改为Math.floor,只是个人偏好

如果您希望将鼠标悬停在光标上时更改光标,请将“悬停”添加到events数组中,然后添加到选项中:

onHover: function(e) {
    var ctx = $("#chart")[0].getContext("2d");
    var base = that.chart.chartArea.bottom;
    var height = that.chart.chart.height;
    var width = that.chart.chart.scales['x-axis-0'].width;
    var yOffset = $('#chart').offset().top - $(window).scrollTop();
    var xOffset = $('#chart').offset().left - $(window).scrollLeft();

    var left = xOffset + that.chart.scales['x-axis-0'].paddingLeft + that.chart.scales['x-axis-0'].left;
    var right = xOffset + that.chart.scales['x-axis-0'].paddingRight  + that.chart.scales['x-axis-0'].left + width;

    if(e.pageY > base + yOffset && e.pageX > left && e.pageX < right){
            e.target.style.cursor = 'pointer';
    }
    else {
        e.target.style.cursor = 'default';
    }
}