我在玩这个代码:https://jsfiddle.net/netquik/e3jp2k5o/37/
首先创建了一个插件,当鼠标悬停在图表栏上时,可以在x轴上高亮显示标签(刻度)(现在使用mousemove)。然后我尝试在外部触发图表和工具提示的setActiveElements。而且看起来像预期的那样工作。
expected result
我的问题是我不能找到一种方法来“更新”数据标签在同一时间,所以它可以显示我的数据标签。在代码中,你可以看到我尝试手动启用$datalabels的一些$context属性,但没有成功。在外部setActiveElements之后,我在调试中看到,数据标签在图表更新后会自动触发,并尝试
display: function (context) {
return context.active; // display labels if active
},
但即使chart中的元素是“active”,也会返回假context. active。可能是交互模式的问题?谢谢你的帮助。trigger result without datalabel
var SCRIPTOBJ = null;
var LABEL = ["Gino", "Samantha", "Vercingetorige"];
var DATA = [5, 28, 500];
var MAX = Math.max(...DATA);
var ctx = $('#stat');
Chart.defaults.font.size = 14;
Chart.register(ChartDataLabels);
var lastLabelH = null;
var stat = new Chart(ctx, {
type: 'bar',
data: {
labels: LABEL,
datasets: [{
minBarLength: 15,
barPercentage: 1,
label: '# VOTES',
data: DATA,
backgroundColor: [
'rgba(255, 99, 132, 0.5)',
'rgba(54, 162, 235, 0.5)',
'rgba(255, 206, 86, 0.5)',
'rgba(75, 192, 192, 0.5)',
'rgba(153, 102, 255, 0.5)',
'rgba(255, 159, 64, 0.5)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
hoverBackgroundColor: [
'rgba(255, 99, 132, 1.0)',
'rgba(54, 162, 235, 1.0)',
'rgba(255, 206, 86, 1.0)',
'rgba(75, 192, 192, 1.0)',
'rgba(153, 102, 255, 1.0)',
'rgba(255, 159, 64, 1.0)'
],
borderWidth: 1
}]
},
plugins: [{
id: 'LabelHighlight',
beforeEvent(c, args, pluginOptions) {
const event = args.event;
if (event.type === 'mouseout') {
if (lastLabelH != null) {
//c.scales.x._labelItems[lastLabelH].color = "rgba(255, 159, 64, 1)";
c.update();
lastLabelH = null;
}
} else if (event.type === 'mousemove') {
if (c._active.length > 0) {
let labelindex = c._active[0].index;
if (c.scales.x._labelItems) {
let label = c.scales.x._labelItems[labelindex];
label.color = "rgba(255, 255, 64, 1)";
}
if (lastLabelH != null && lastLabelH != labelindex) {
if (c.scales.x._labelItems) {
c.scales.x._labelItems[lastLabelH].color = "rgba(255, 159, 64, 1)";
}
}
lastLabelH = labelindex;
} else {
if (lastLabelH != null) {
if (c.scales.x._labelItems) {
c.scales.x._labelItems[lastLabelH].color = "rgba(255, 159, 64, 1)";
}
lastLabelH = null;
}
}
}
}
}],
options: {
responsive: false,
interaction: {
mode: 'index',
intersect: true
},
/* onHover: function (event, elements, c) {
if (elements && elements.length) {
if (c._active.length > 0) {
let labelindex = c._active[0].index;
let label = c.scales.x._labelItems[labelindex];
label.color = "rgba(255, 255, 64, 1)";
lastLabelH = labelindex;
}
} else {
if (lastLabelH != null) {
c.scales.x._labelItems[lastLabelH].color = "rgba(255, 159, 64, 1)";
lastLabelH = null;
}
}
}, */
layout: {
padding: {
top: 50,
left: 0,
right: 0,
bottom: 0
}
},
indexAxis: 'x',
scales: {
x: {
beginAtZero: true,
ticks: {
display: true,
color: 'rgba(255, 159, 64, 1)',
autoSkip: false,
maxRotation: 90,
minRotation: 90,
labelOffset: -8,
textStrokeColor: 'rgba(0, 0, 0, 0.5)',
textStrokeWidth: '2',
font: {
weight: 'bold',
family: 'Arial',
size: 16
},
align: 'start'
}
},
y: {
max: MAX + 1,
beginAtZero: true,
ticks: {
color: 'rgba(255, 159, 64, 1)',
stepSize: 1
}
}
},
plugins: {
legend: {
display: false
},
datalabels: {
listeners: {
enter: function(context) {
// Receives `enter` events for any labels of any dataset. Indices of the
// clicked label are: `context.datasetIndex` and `context.dataIndex`.
// For example, we can modify keep track of the hovered state and
// return `true` to update the label and re-render the chart.
context.hovered = true;
return true;
},
leave: function(context) {
// Receives `leave` events for any labels of any dataset.
context.hovered = false;
return true;
}
},
display: function(context) {
return context.active; // display labels with an odd index
},
font: {
size: '24px'
},
padding: '6',
align: 'end',
anchor: 'end',
borderRadius: 4,
backgroundColor: function(context) {
return context.active ? context.dataset.hoverBackgroundColor : context.dataset.backgroundColor;
},
borderColor: function(context) {
return context.dataset.borderColor;
},
borderWidth: 1,
color: 'rgb(253, 225, 186)',
textShadowBlur: 4,
textShadowColor: 'rgb(0, 0, 0)',
formatter: Math.round
}
}
}
});
if (stat) {
console.log(stat);
$('#activate').click(function() {
if (stat.getActiveElements().length > 0) {
stat.setActiveElements([]);
} else {
stat.setActiveElements([{
datasetIndex: 0,
index: 2,
}]);
//stat.$datalabels._hovered = true;
stat.$datalabels._datasets[0][1]._el.$context.active = true;
stat.$datalabels._datasets[0][1].$context.active = true;
stat.$datalabels._labels[1].$context.active = true;
stat.$datalabels._labels[1]._el.active = true;
stat.$datalabels._labels[1]._el.$context.active = true;
stat.$datalabels._datasets[0][1].update(stat.$datalabels._datasets[0][1].$context);
stat.$datalabels._labels[1].update(stat.$datalabels._labels[1].$context);
}
const tooltip = stat.tooltip;
if (tooltip.getActiveElements().length > 0) {
tooltip.setActiveElements([], {
x: 0,
y: 0
});
} else {
const chartArea = stat.chartArea;
tooltip.setActiveElements([{
datasetIndex: 0,
index: 2,
}], {
x: (chartArea.left + chartArea.right) / 2,
y: (chartArea.top + chartArea.bottom) / 2,
});
}
stat.update();
});
}
1条答案
按热度按时间nfzehxib1#
找到了一个解决方案我只是修改了数据标签的显示函数,集成了我的外部变量lastLabelH
不得不修改颜色函数,以便在设置null时更新lastLabelH,我还从外部触发器添加颜色标签
更新jsfiddle https://jsfiddle.net/netquik/e3jp2k5o/41/