当我将“苹果”悬停在图例中时,如何使其他线条半透明?
对于 Chart.JS 2.x:
示例:https://jsfiddle.net/rn7ube7v/4/
我们需要在 2 个
dataset.borderColor
之间切换,其中 1 种颜色的 alpha 为 0.2
(20% 可见)和 1
(100% 可见)。
例如:使用 HSL 颜色为每个数据集循环彩虹,我们将常规颜色存储为
dataset.accentColor
和 dataset.accentFadedColor
(当未聚焦时)。
function steppedHslColor(ratio, alpha) {
return "hsla(" + 360 * ratio + ', 60%, 55%, ' + alpha + ')';
}
function colorizeDatasets(datasets) {
for (var i = 0; i < datasets.length; i++) {
var dataset = datasets[i]
dataset.accentColor = steppedHslColor(i / datasets.length, 1)
dataset.accentFadedColor = steppedHslColor(i / datasets.length, 0.2)
dataset.backgroundColor = dataset.accentColor
dataset.borderColor = dataset.accentColor
}
return datasets
}
colorizeDatasets(datasets)
然后我们钩住
options.legend.onHover(mouseEvent, legendItem)
以应用正确的颜色。
var myChart = new Chart(ctx, {
type: 'line',
data: {
datasets: datasets,
},
options: {
legend: {
onHover: function(e, legendItem) {
if (myChart.hoveringLegendIndex != legendItem.datasetIndex) {
myChart.hoveringLegendIndex = legendItem.datasetIndex
for (var i = 0; i < myChart.data.datasets.length; i++) {
var dataset = myChart.data.datasets[i]
if (i == legendItem.datasetIndex) {
dataset.borderColor = dataset.accentColor
} else {
dataset.borderColor = dataset.accentFadedColor
}
}
myChart.update()
}
}
},
},
});
不幸的是,没有
config.legend.onLeave
回调,所以我们需要挂接 canvas.onmousemove
并查看它是否离开图例区域。
myChart.hoveringLegendIndex = -1
myChart.canvas.addEventListener('mousemove', function(e) {
if (myChart.hoveringLegendIndex >= 0) {
if (e.layerX < myChart.legend.left || myChart.legend.right < e.layerX
|| e.layerY < myChart.legend.top || myChart.legend.bottom < e.layerY
) {
myChart.hoveringLegendIndex = -1
for (var i = 0; i < myChart.data.datasets.length; i++) {
var dataset = myChart.data.datasets[i]
dataset.borderColor = dataset.accentColor
}
myChart.update()
}
}
})
使用 Chart.js 4 获得更简单的解决方案:
我决定将其他线条灰化并使其半透明。我将初始颜色放入列表中,并执行了以下操作,以便可以重置颜色
onLeave
:
plugins: {
[...]
legend: {
onHover: (event, legendItem, legend) => {
const chart = legend.chart;
chart.config.data.datasets.forEach(d => {
if (legendItem.text !== d.label) {
d.backgroundColor = "rgba(200,200,200,0.2)";
d.borderColor = "rgba(200,200,200,0.2)"
}
})
chart.update()
},
onLeave: (event, legendItem, legend) => {
const chart = legend.chart;
let index = 0;
chart.config.data.datasets.forEach(d => {
d.backgroundColor = this.colors[index];
d.borderColor = this.colors[index];
index++;
})
chart.update();
}
},
},