[英]Make Chart.js Radar labels clickable
Thanks Pogrindis. 感谢Pogrindis。 Answer here works for Chart.js v2.1: Chart.js click on labels, using bar chart 这里的答案适用于Chart.js v2.1: Chart.js使用条形图单击标签
To make that work for Chart.js v5.0+, add the following function back into the Chart.js code. 为了使它适用于Chart.js v5.0 +,请将以下函数重新添加到Chart.js代码中。
LinearRadialScale = Chart.LinearScaleBase.extend({...}) LinearRadialScale = Chart.LinearScaleBase.extend({...})
getValueCount: function() {
return this.chart.data.labels.length;
}
I came up with a solution for this for version 2.8.0 by copying the label position calculations from the RadialLinear scale into an event handler. 通过将RadialLinear标尺的标签位置计算复制到事件处理程序中,我为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;
}
}
};
JSFiddle here: JSFiddle在这里:
https://jsfiddle.net/simoncoggins/7r08uLk9/ https://jsfiddle.net/simoncoggins/7r08uLk9/
The downside of this approach is it that it will break if the core labelling implementation changes in the future. 这种方法的缺点是,如果将来核心标签实现发生更改,它将无法使用。 It would be better if the library separated the calculation of label position from its rendering and started exposing the position info via the API. 如果库将标签位置的计算与其呈现分离,并开始通过API公开位置信息,将会更好。 Then this solution could be greatly simplified and would be more robust to library changes. 然后,可以大大简化此解决方案,并且对库更改更健壮。
I've opened a ticket offering to make that change here: 我已经打开了一张机票,可以在这里进行更改:
https://github.com/chartjs/Chart.js/issues/6549 https://github.com/chartjs/Chart.js/issues/6549
Please comment on that issue if it would be useful to you. 如果对您有用,请对此问题发表评论。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.