英文:
highlight a "selected" slice of chart.js pie as being hovered when clicked
问题
I'm working on a project with a chart.js pie. The final idea is to make the pie keep the hover animation to show that this part is activated for a search on a table until the search is reset via a button.
The pie normally shows the animation when hover and hide when mouse leave. I would like to know how to make the hover animation stay on if mouse click on when hovering over a part of the pie. I'm trying to highlight a "selected" slice as being hovered.
I manage to get the information about the click, but for the animation, I don't manage to make the “hovering” animation stay on.
英文:
I'm working on a project with a chart.js pie. The final idea is to make the pie keep the hover animation to show that this part is activated for a search on a table until the search is reset via a button.
The pie normally shows the animation when hover and hide when mouse leave. I would like to know how to make the hover animation stay on if mouse click on when hovering over a part of the pie. I'm trying to highlight a "selected" slice as being hovered.
I manage to get the information about the click, but for the animation, I don't manage to make the “hovering” animation stay on.
const foods = [
{ value: 60, label: 'Orange' },
{ value: 40, label: 'Banana' },
{ value: 20, label: 'Strawberry' },
];
const data = {
labels: foods.map(food => food.label),
datasets: [
{
label: 'Foods',
data: foods.map(food => food.value),
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
],
hoverBackgroundColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
],
borderWidth: 0,
hoverOffset: 4
},
],
};
const ctx = document.getElementById('myChart').getContext('2d');
new Chart(ctx, {
type: 'pie',
data
});
.myChartDiv {
max-width: 600px;
max-height: 400px;
}
<script src="https://npmcdn.com/chart.js@latest/dist/chart.umd.js"></script>
<div class="myChartDiv">
<canvas id="myChart" width="600" height="400"></canvas>
</div>
If anybody already made the hover display stay on, I would love to know how.
答案1
得分: 0
以下是您提供的内容的中文翻译部分:
-
在评论中分享,这里是一个用例的可能解决方案,作为起点。
简短描述:- 在图表级别添加了
onClick
选项,以选择数据元素。 - 添加了自定义交互,以添加悬停的元素(按点模式)和选定的项目(如果有的话)。
- 添加了自定义插件,以保持选定的项目,即使鼠标移出图表区域和画布。
如所述,这是一个起点,可以根据需要添加自己的逻辑(例如,如何取消选择项目)。
- 在图表级别添加了
let selected;
Chart.Interaction.modes.pointSelected = function(chart, e, options, useFinalPosition) {
const activeElements = [];
if (selected) {
activeElements.push(selected);
}
const pointItems = Chart.Interaction.modes.point(chart, e, {intersect: true}, useFinalPosition);
if (pointItems.length) {
if (selected) {
activeElements.push(...pointItems.filter(e => e.index !== selected.index));
} else {
activeElements.push(...pointItems);
}
}
return activeElements;
};
const foods = [
{ value: 60, label: 'Orange' },
{ value: 40, label: 'Banana' },
{ value: 20, label: 'Strawberry' },
];
const data = {
labels: foods.map(food => food.label),
datasets: [
{
label: 'Foods',
data: foods.map(food => food.value),
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
],
hoverBackgroundColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
],
borderWidth: 0,
hoverOffset: 4
},
],
};
const options = {
responsive: true,
interaction: {
mode: 'pointSelected',
intersect: true
},
onClick(event, el, chart) {
const elements = chart.getElementsAtEventForMode(event, 'point', {intersect: true}, true);
if (elements.length) {
selected = elements[0];
}
},
plugins: {
tooltip: {
callbacks: {
title(items) {
return items.map(e => e.label).join(' and ');
},
label(item) {
return item.label + ': ' + item.formattedValue;
}
}
}
}
};
const plugin = {
id: 'hl',
afterEvent(chart, args) {
const event = args.event;
if (event.type === 'mouseout' && selected) {
chart.setActiveElements([selected]);
chart.tooltip.setActiveElements([selected]);
chart.update();
}
}
}
const ctx = document.getElementById('myChart').getContext('2d');
new Chart(ctx, {
type: 'pie',
plugins: [plugin],
data,
options
});
.myChartDiv {
max-width: 600px;
max-height: 400px;
}
<script src="https://npmcdn.com/chart.js@latest/dist/chart.umd.js"></script>
<div class="myChartDiv">
<canvas id="myChart" width="600" height="400"></canvas>
</div>
编辑:显示工具提示。
英文:
As shared in comments, here a possible solution for the use case, as starting point.
Short description:
- added
onClick
option at chart level in order to select the data element - added a custom interaction in order to add the hovered elements (by point mode) and the selected item (if there is)
- add a custom plugin to maintain the selected item even if the mouse is out of the chart area and canvas.
As written, it's a starting point that it can be customized adding own logic (i.e. how to de-select the item).
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
let selected;
Chart.Interaction.modes.pointSelected = function(chart, e, options, useFinalPosition) {
const activeElements = [];
if (selected) {
activeElements.push(selected);
}
const pointItems = Chart.Interaction.modes.point(chart, e, {intersect: true}, useFinalPosition);
if (pointItems.length) {
if (selected) {
activeElements.push(...pointItems.filter(e => e.index !== selected.index));
} else {
activeElements.push(...pointItems);
}
}
return activeElements;
};
const foods = [
{ value: 60, label: 'Orange' },
{ value: 40, label: 'Banana' },
{ value: 20, label: 'Strawberry' },
];
const data = {
labels: foods.map(food => food.label),
datasets: [
{
label: 'Foods',
data: foods.map(food => food.value),
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
],
hoverBackgroundColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
],
borderWidth: 0,
hoverOffset: 4
},
],
};
const options = {
responsive: true,
interaction: {
mode: 'pointSelected',
intersect: true
},
onClick(event, el, chart) {
const elements = chart.getElementsAtEventForMode(event, 'point', {intersect: true}, true);
if (elements.length) {
selected = elements[0];
}
},
plugins: {
tooltip: {
callbacks: {
title(items) {
return items.map(e => e.label).join(' and ');
},
label(item) {
return item.label +': '+item.formattedValue;
}
}
}
}
};
const plugin = {
id: 'hl',
afterEvent(chart, args) {
const event = args.event;
if (event.type === 'mouseout' && selected) {
chart.setActiveElements([selected]);
chart.tooltip.setActiveElements([selected]);
chart.update();
}
}
}
const ctx = document.getElementById('myChart').getContext('2d');
new Chart(ctx, {
type: 'pie',
plugins: [plugin],
data,
options
});
<!-- language: lang-css -->
.myChartDiv {
max-width: 600px;
max-height: 400px;
}
<!-- language: lang-html -->
<script src="https://npmcdn.com/chart.js@latest/dist/chart.umd.js"></script>
<div class="myChartDiv">
<canvas id="myChart" width="600" height="400"></canvas>
</div>
<!-- end snippet -->
EDIT: show tooltip
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论