Javascript 使Chart.js雷达标签可点击

Javascript 使Chart.js雷达标签可点击,javascript,charts,chart.js,Javascript,Charts,Chart.js,有没有人能让Chart.js雷达周界周围的标签可以点击 似乎没有一个立竿见影的解决方案 谢谢波格里迪斯。这里的答案适用于Chart.js v2.1: 为了使Chart.js v5.0+能够正常工作,请将以下函数添加回Chart.js代码中 LinearDialScale=Chart.LinearScaleBase.extend({…}) 我为版本2.8.0提出了一个解决方案,将标签位置计算从径向刻度复制到事件处理程序中 document.getElementById("myChart").onc

有没有人能让Chart.js雷达周界周围的标签可以点击

似乎没有一个立竿见影的解决方案


谢谢波格里迪斯。这里的答案适用于Chart.js v2.1:

为了使Chart.js v5.0+能够正常工作,请将以下函数添加回Chart.js代码中

LinearDialScale=Chart.LinearScaleBase.extend({…})


我为版本2.8.0提出了一个解决方案,将标签位置计算从径向刻度复制到事件处理程序中

document.getElementById("myChart").onclick = function (e) {
    var helpers = Chart.helpers;
    var scale = myRadarChart.scale;
    var opts = scale.options;
    var tickOpts = opts.ticks;

    // Position of click relative to canvas.
    var mouseX = e.offsetX;
    var mouseY = e.offsetY;

    var labelPadding = 5; // number pixels to expand label bounding box by

    // get the label render position
    // calcs taken from drawPointLabels() in scale.radialLinear.js
    var tickBackdropHeight = (tickOpts.display && opts.display) ?
        helpers.valueOrDefault(tickOpts.fontSize, Chart.defaults.global.defaultFontSize)
        + 5: 0;
    var outerDistance = scale.getDistanceFromCenterForValue(opts.ticks.reverse ? scale.min : scale.max);
    for (var i = 0; i < scale.pointLabels.length; i++) {
        // Extra spacing for top value due to axis labels
        var extra = (i === 0 ? tickBackdropHeight / 2 : 0);
        var pointLabelPosition = scale.getPointPosition(i, outerDistance + extra + 5);

        // get label size info.
        // TODO fix width=0 calc in Brave?
        // https://github.com/brave/brave-browser/issues/1738
        var plSize = scale._pointLabelSizes[i];

        // get label textAlign info
        var angleRadians = scale.getIndexAngle(i);
        var angle = helpers.toDegrees(angleRadians);
        var textAlign = 'right';
        if (angle == 0 || angle == 180) {
            textAlign = 'center';
        } else if (angle < 180) {
            textAlign = 'left';
        }

        // get label vertical offset info
        // also from drawPointLabels() calcs
        var verticalTextOffset = 0;
        if (angle === 90 || angle === 270) {
            verticalTextOffset = plSize.h / 2;
        } else if (angle > 270 || angle < 90) {
            verticalTextOffset = plSize.h;
        }

        // Calculate bounding box based on textAlign
        var labelTop = pointLabelPosition.y - verticalTextOffset - labelPadding;
        var labelHeight = 2*labelPadding + plSize.h;
        var labelBottom = labelTop + labelHeight;

        var labelWidth = plSize.w + 2*labelPadding;
        var labelLeft;
        switch (textAlign) {
        case 'center':
          var labelLeft = pointLabelPosition.x - labelWidth/2;
          break;
        case 'left':
          var labelLeft = pointLabelPosition.x - labelPadding;

          break;
        case 'right':
          var labelLeft = pointLabelPosition.x - labelWidth + labelPadding;
          break;
        default:
          console.log('ERROR: unknown textAlign '+textAlign);
        }
        var labelRight = labelLeft + labelWidth;

        // Render a rectangle for testing purposes
        ctx.save();
        ctx.strokeStyle = 'red';
        ctx.lineWidth = 1;
        ctx.strokeRect(labelLeft, labelTop, labelWidth, labelHeight);
        ctx.restore();

        // compare to the current click
        if (mouseX >= labelLeft && mouseX <= labelRight && mouseY <= labelBottom && mouseY >= labelTop) {
            alert(scale.pointLabels[i]+' clicked');
            // Break loop to prevent multiple clicks, if they overlap we take the first one.
            break;
        }
    }
};
document.getElementById(“myChart”).onclick=function(e){
var helpers=Chart.helpers;
var刻度=myRadarChart.scale;
var opts=scale.options;
var tickOpts=opts.ticks;
//单击相对于画布的位置。
var mouseX=e.offsetX;
var mouseY=e.offsetY;
var labelPadding=5;//按像素数展开标签边界框
//获取标签渲染位置
//计算取自scale.radialLinear.js中的drawPointLabels()
var tickBackdropHeight=(tickOpts.display&&opts.display)?
helpers.valuerDefault(tickOpts.fontSize、Chart.defaults.global.defaultFontSize)
+ 5: 0;
var outerInstance=scale.getDistanceFromCenterForValue(opts.ticks.reverse?scale.min:scale.max);
对于(变量i=0;i270 | |角度<90){
垂直文本偏移=plSize.h;
}
//基于textAlign计算边界框
var labelTop=pointLabelPosition.y-垂直文本偏移量-labelPadding;
var labelHeight=2*labelPadding+plSize.h;
var labelBottom=labelTop+labelHeight;
var labelWidth=plSize.w+2*labelPadding;
var labelLeft;
开关(文本对齐){
案例“中心”:
var labelLeft=pointLabelPosition.x-labelWidth/2;
打破
案例“左”:
var labelLeft=pointLabelPosition.x-labelPadding;
打破
案例“正确”:
var labelLeft=pointLabelPosition.x-labelWidth+labelPadding;
打破
违约:
log('错误:未知textAlign'+textAlign');
}
var labelRight=labelLeft+labelWidth;
//渲染矩形以进行测试
ctx.save();
ctx.strokeStyle=‘红色’;
ctx.lineWidth=1;
ctx.strokeRect(标签英尺、标签顶、标签宽度、标签高度);
ctx.restore();
//与当前单击进行比较

如果(mouseX>=labelLeft&&mouseX)你指的是标签吗?同时请显示你尝试过的内容,它们的位置..因此你可以添加点击事件..相关:该链接可能是我要寻找的圣杯..不应该在我的搜索中包括雷达..brb幸运的是它在“getValueCount”处中断假设您不知道这是否是Chart.js中不推荐使用的函数?您看不到对它的引用。
document.getElementById("myChart").onclick = function (e) {
    var helpers = Chart.helpers;
    var scale = myRadarChart.scale;
    var opts = scale.options;
    var tickOpts = opts.ticks;

    // Position of click relative to canvas.
    var mouseX = e.offsetX;
    var mouseY = e.offsetY;

    var labelPadding = 5; // number pixels to expand label bounding box by

    // get the label render position
    // calcs taken from drawPointLabels() in scale.radialLinear.js
    var tickBackdropHeight = (tickOpts.display && opts.display) ?
        helpers.valueOrDefault(tickOpts.fontSize, Chart.defaults.global.defaultFontSize)
        + 5: 0;
    var outerDistance = scale.getDistanceFromCenterForValue(opts.ticks.reverse ? scale.min : scale.max);
    for (var i = 0; i < scale.pointLabels.length; i++) {
        // Extra spacing for top value due to axis labels
        var extra = (i === 0 ? tickBackdropHeight / 2 : 0);
        var pointLabelPosition = scale.getPointPosition(i, outerDistance + extra + 5);

        // get label size info.
        // TODO fix width=0 calc in Brave?
        // https://github.com/brave/brave-browser/issues/1738
        var plSize = scale._pointLabelSizes[i];

        // get label textAlign info
        var angleRadians = scale.getIndexAngle(i);
        var angle = helpers.toDegrees(angleRadians);
        var textAlign = 'right';
        if (angle == 0 || angle == 180) {
            textAlign = 'center';
        } else if (angle < 180) {
            textAlign = 'left';
        }

        // get label vertical offset info
        // also from drawPointLabels() calcs
        var verticalTextOffset = 0;
        if (angle === 90 || angle === 270) {
            verticalTextOffset = plSize.h / 2;
        } else if (angle > 270 || angle < 90) {
            verticalTextOffset = plSize.h;
        }

        // Calculate bounding box based on textAlign
        var labelTop = pointLabelPosition.y - verticalTextOffset - labelPadding;
        var labelHeight = 2*labelPadding + plSize.h;
        var labelBottom = labelTop + labelHeight;

        var labelWidth = plSize.w + 2*labelPadding;
        var labelLeft;
        switch (textAlign) {
        case 'center':
          var labelLeft = pointLabelPosition.x - labelWidth/2;
          break;
        case 'left':
          var labelLeft = pointLabelPosition.x - labelPadding;

          break;
        case 'right':
          var labelLeft = pointLabelPosition.x - labelWidth + labelPadding;
          break;
        default:
          console.log('ERROR: unknown textAlign '+textAlign);
        }
        var labelRight = labelLeft + labelWidth;

        // Render a rectangle for testing purposes
        ctx.save();
        ctx.strokeStyle = 'red';
        ctx.lineWidth = 1;
        ctx.strokeRect(labelLeft, labelTop, labelWidth, labelHeight);
        ctx.restore();

        // compare to the current click
        if (mouseX >= labelLeft && mouseX <= labelRight && mouseY <= labelBottom && mouseY >= labelTop) {
            alert(scale.pointLabels[i]+' clicked');
            // Break loop to prevent multiple clicks, if they overlap we take the first one.
            break;
        }
    }
};