【问题标题】:Add Link to X-Label Chart.js添加指向 X-Label Chart.js 的链接
【发布时间】:2016-01-21 08:30:08
【问题描述】:

我希望能够在 Chart.js bar 图表中链接 x-labels。我已经进行了相当彻底的搜索,最终试图提出我自己的解决方案:因为标签对应于它们正上方的条形图,并且 Chart.js 有一个内置的 getBarsAtEvent(evt) 方法,我尝试创建一个事件,如果用户没有点击图表 - 这个新事件在初始点击的正上方有pageXpageY,这样如果用户点击了标签,新事件将模拟对条形图的点击。

但是,反复调用getBarsAtEvent(createdClickEvent) 会给我一个Uncaught TypeError ("Cannot read property 'getBoundingClientRect' of null"),这一定意味着getBarsAtEvent 方法在我的模拟点击上调用时实际上并没有返回任何内容。

任何建议或替代方法将不胜感激,在此先感谢。

【问题讨论】:

    标签: javascript chart.js


    【解决方案1】:

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

    下面是这样做的一种方法,这里是带有此代码/方法的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
                    }
                }
           }
    );   
    

    【讨论】:

    • 我做了一些修改,但你的逻辑是完美的 - 非常感谢。也非常感谢您代码中的 cmets!
    • 您对如何使标签可搜索文本有什么建议吗?我希望能够在 control+F 浏览器搜索中找到它们。
    【解决方案2】:

    我修改了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,只是个人喜好

    如果您希望光标在悬停在它们上时发生变化,请将“悬停”添加到事件数组中,并将其添加到选项中:

    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';
        }
    }
    

    【讨论】:

    • 我的图表的创建看起来与此不同
    猜你喜欢
    • 1970-01-01
    • 2020-08-15
    • 2013-01-28
    • 2020-12-11
    • 2015-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多