Javascript 使用chart.js检测部分图表上的悬停事件

Javascript 使用chart.js检测部分图表上的悬停事件,javascript,chart.js,Javascript,Chart.js,我已经使用chart.js制作了一个饼图,我想检测段何时悬停在上面。我已经找到了大量关于操纵鼠标悬停在线段上时显示的工具提示的文档,但是没有关于在工具提示出现时执行其他操作的文档。这可能吗?不可能。 ChartJS API中没有任何内容可以覆盖或扩展工具提示 但是,一个解决方案… 您可以修改Chart.Tooltip类的draw方法。这将允许您在工具提示通常由ChartJS呈现时“执行其他操作” 要关联的绘图方法从源的第1351行开始: 我知道这已经得到了公认的答案,我不确定这是否满足您的用例,

我已经使用chart.js制作了一个饼图,我想检测段何时悬停在上面。我已经找到了大量关于操纵鼠标悬停在线段上时显示的工具提示的文档,但是没有关于在工具提示出现时执行其他操作的文档。这可能吗?

不可能。

ChartJS API中没有任何内容可以覆盖或扩展工具提示

但是,一个解决方案…

您可以修改
Chart.Tooltip
类的
draw
方法。这将允许您在工具提示通常由ChartJS呈现时“执行其他操作”

要关联的绘图方法从源的第1351行开始:


我知道这已经得到了公认的答案,我不确定这是否满足您的用例,但Chart js发布了一个更新(可能是一个月前左右),允许自定义工具提示。这允许在通常绘制工具提示时运行自定义函数。他们在GitHub的示例部分有一个示例

简而言之,您定义了一个自定义函数

 Chart.defaults.global.customTooltips = function(tooltip){//do what you want}
下面是他们在示例中给出的示例,在html工具提示中添加了额外的文本。我看到的唯一恼人的事情是,没有提供触发此工具提示的段/点/条,这将非常方便,因为您可以在了解此信息的情况下对图形执行某些操作,但您得到了工具提示数据,这意味着您可以改为使用它

Chart.defaults.global.customTooltips=函数(工具提示){
//工具提示元素
var tooltipEl=$(“#chartjs工具提示”);
//如果没有工具提示,则隐藏
如果(!工具提示){
工具管道({
不透明度:0
});
返回;
}
//设置插入符号位置
工具管道removeClass(“上下”);
tooltipEl.addClass(tooltip.yAlign);
//设置文本
html(tooltip.text+“任意自定义”);
//在第页上查找Y位置
var-top;
如果(tooltip.yAlign=='over'){
top=tooltip.y-tooltip.caretHeight-tooltip.caretadding;
}否则{
顶部=tooltip.y+tooltip.caretHeight+tooltip.CareTAdding;
}
//显示、定位和设置字体样式
工具管道({
不透明度:1,
左:tooltip.chart.canvas.offsetLeft+tooltip.x+'px',
顶部:tooltip.chart.canvas.offsetTop+top+'px',
fontFamily:tooltip.fontFamily,
fontSize:tooltip.fontSize,
fontStyle:tooltip.fontStyle,
});
};
变量数据=[{
价值:300,
颜色:#F7464A“,
亮点:“FF5A5E”,
标签:“红色”
}, {
价值:50,
颜色:“46BFBD”,
亮点:“5AD3D1”,
标签:“绿色”
}, {
数值:100,
颜色:“FDB45C”,
亮点:“FFC870”,
标签:“黄色”
}, {
价值:40,
颜色:“949FB1”,
亮点:“A8B3C5”,
标签:“灰色”
}, {
数值:120,
颜色:“4D5360”,
亮点:“616774”,
标签:“深灰色”
}];
var ctx1=document.getElementById(“图表区域1”).getContext(“2d”);
window.myPie=新图表(ctx1).Pie(pieData);
var ctx2=document.getElementById(“图表区域2”).getContext(“2d”);
window.myPie=新图表(ctx2).Pie(pieData)
#帆布支架{
宽度:100%;
边缘顶部:50px;
文本对齐:居中;
}
#chartjs工具提示{
不透明度:1;
位置:绝对位置;
背景:rgba(0,0,0,7);
颜色:白色;
填充:3倍;
边界半径:3px;
-webkit过渡:所有.1s易用性;
过渡:全部1秒轻松;
指针事件:无;
-webkit转换:转换(-50%,0);
转换:转换(-50%,0);
}
#下面是chartjs-tooltip.com{
-webkit转换:转换(-50%,0);
转换:转换(-50%,0);
}
#chartjs工具提示。如下:之前{
边框:实心;
边框颜色:#111透明;
边框颜色:rgba(0,0,0,8)透明;
边框宽度:0 8px 8px 8px;
底部:1米;
内容:“;
显示:块;
左:50%;
位置:绝对位置;
z指数:99;
-webkit转换:翻译(-50%,-100%);
转换:转换(-50%,-100%);
}
#上面的chartjs-tooltip.com{
-webkit转换:翻译(-50%,-100%);
转换:转换(-50%,-100%);
}
#chartjs工具提示。上图:之前{
边框:实心;
边框颜色:#111透明;
边框颜色:rgba(0,0,0,8)透明;
边框宽度:8px 8px 0 8px;
底部:1米;
内容:“;
显示:块;
左:50%;
最高:100%;
位置:绝对位置;
z指数:99;
-webkit转换:转换(-50%,0);
转换:转换(-50%,0);
}

我的做法稍微简单一些: 假设您已经有了一些定义画布的代码,比如 canvas=document.getElementById(“图表”)并且您的饼图是
window.myPie
。您可以使用onmousemove javascript事件或jQuery悬停

canvas.onmousemove = function(evt) {
    var el = window.myPie.getElementsAtEvent(evt);
    //do something with the el object to display other information
    //elsewhere on the page
}

在我的例子中,根据
el[0]的值高亮显示一个表行。如果使用customTooltip也发现了一个小技巧,则索引

。我搜索了一个解决方案,如果用户将鼠标移到某个值上并显示工具提示,则可以获取事件。主要是我喜欢在一个不同的框架中呈现一些细节信息,除了原始的绘图值

var options = {            
  customTooltips: function (tooltip)
  {
    if (!tooltip) return;

    tooltip.custom = false;
    tooltip.draw();
    OnEntrySelected(tooltip.title);
    tooltip.custom = this;
  }
}
自定义工具提示是使用tooltip.draw()绘制的,但这将调用自定义方法。我将其设置为false以避免递归循环,调用默认行为并获取回调所需的数据(OnEntrySelected),在本例中,该数据是x轴标签的字符串。每当显示工具提示时,都会触发此事件

对于v2.0版本:

Chart.defaults.global.hover.onHover = function(x) {
  if(x[0]) {
    var index = x[0]._index;
    // Place here your code
  }
};
更新2
onHover : (event, activeElements) => {

    if (activeElements.length > 0) {

            // get active chart element
            let elt = activeElements[0];

            // retrieve element label
            let lbl = elt._model.label;

            // Get element value
            let elt_index = elt._chart.tooltip._data.labels.indexOf(lbl);
            let val = elt._chart.tooltip._data.datasets[0].data[elt_index];

           // trigger your event here :
           // ex for vuejs : this.$emit('element-hovered', { label : lbl, value : val });

       }
       else {
           // No active elements
       }

   }