Jquery Flot图表-如何在线悬停触发事件

Jquery Flot图表-如何在线悬停触发事件,jquery,canvas,flot,Jquery,Canvas,Flot,我已经为jQuery Flot图表编写了一个插件,它允许您通过单击图表的线条来动态添加数据点,通过右键单击删除数据点,还允许在画布上拖动这些点 这很好,我还有一个工具提示,当您将鼠标悬停在某个点上或拖动该点时,它会显示Y值 我想做的是,当用户将鼠标悬停在显示消息“左键单击以添加数据点”的行上时,显示第二个工具提示 我似乎找不到向行本身添加悬停事件的方法,而且似乎没有本机方法 有人知道我如何才能做到这一点吗 多谢各位 编辑:下面是一个JSFIDLE,其中包含我正在使用的工具提示创建代码: 正如您

我已经为jQuery Flot图表编写了一个插件,它允许您通过单击图表的线条来动态添加数据点,通过右键单击删除数据点,还允许在画布上拖动这些点

这很好,我还有一个工具提示,当您将鼠标悬停在某个点上或拖动该点时,它会显示Y值

我想做的是,当用户将鼠标悬停在显示消息“左键单击以添加数据点”的行上时,显示第二个工具提示

我似乎找不到向行本身添加悬停事件的方法,而且似乎没有本机方法

有人知道我如何才能做到这一点吗

多谢各位

编辑:下面是一个JSFIDLE,其中包含我正在使用的工具提示创建代码:


正如您看到的,当您将鼠标悬停在实际数据点上时,工具提示会呈现,但是我想找到一种方法,当您将鼠标悬停在数据点之间的直线上时,可以触发单独的工具提示呈现。注意:这个提琴不包括我的自定义代码来动态添加和拖动数据点,因为对于这个问题来说,这将是太多的代码。

因此,基本上,当光标的位置满足光标位于图表上一条线上的要求时,我们希望有条件地显示工具提示。由于直线不是一个实体,我们可以使用它。您需要计算光标两侧最近两点之间的直线,然后查看当前位置是否位于该直线上。我简化了你的例子:

用于计算两点之间距离的函数:

function lineDistance( p1x, p1y,p2x, p2y ) {
    return Math.sqrt( (p2x - p1x)*(p2x - p1x) + (p2y-p1y)*(p2y-p1y) );
}
假设离光标C最近的两点是A和B,则距离
AB
应等于
AC+BC

因此,要确定它是否在线:
Math.abs(AB-(AC+BC))
。使用阈值实质上是围绕光标可以落在其中的线绘制一个框

然后在
绘图悬停(
)中扩展代码

$(占位符).bind(“plothover”、函数(事件、位置、项目){
如果(项目){
var-tipText;
if(opts.xaxis.mode==“time”| | opts.xaxes[0]。mode==“time”){
tipText=stringFormat(to.content,item,timestampToDate);
}否则{
tipText=stringFormat(to.content,item);
}
$tip.html(tipText.css)({
左:tiposition.x+到.shifts.x,
顶部:tiposition.y+to.shifts.y
}).show();
}否则{
//延长线悬停时间
var series=plot.getData();
变量xBeforeIndex=0;
var-xAfterIndex=-1;
风险值阈值=0.0000025;
var i=1;
而(i系列[0]。数据[i][0]){
xBeforeIndex=i;
}else if(xAfterIndex==-1){
xAfterIndex=i;
}
i++;
}
在线上的变量=
线距(
系列[0]。数据[xBeforeIndex][0]/10000,系列[0]。数据[xBeforeIndex][1],
位置x/10000,位置y)
+线距(位置x/10000,位置y,
系列[0]。数据[xAfterIndex][0]/10000,系列[0]。数据[xAfterIndex][1])
-线距(
系列[0]。数据[xBeforeIndex][0]/10000,系列[0]。数据[xBeforeIndex][1],
系列[0]。数据[xAfterIndex][0]/10000,系列[0]。数据[xAfterIndex][1]);
if(数学绝对值(在线)<阈值){
tipText=“找到行”;
$tip.html(tipText.css)({
左:tiposition.x+到.shifts.x,
顶部:tiposition.y+to.shifts.y
}).show();
}否则{
$tip.hide().html(“”);
}
}
});
这里没有做的事情:

  • 更恰当地检查边情况-以上假设第一个点和最后一个点位于图形的边上
  • 在第二张图中加回去
  • 使用bubblesort之类的方法查找before/after索引,提高数据集搜索性能
  • 请注意,我正在将x轴缩小10000。数字太大,前两个点之间的大间隙使得y轴差异不显著(这两个点之间的结果始终为零)

  • 注意,添加第二个图形将要求您找到两个图形的最近点,并检查它是否落在任一行上。如果你的线很近或相交,你可以把其中一条作为优先线。如果您在添加第二行时遇到困难,我可以稍后提供帮助。

    用户如何将鼠标悬停在工具提示上?当你无法控制焦点时,工具提示不会消失吗?如果您展示一个示例,我可以帮助您了解数据点的工具提示是通过使用flot的本机“plothover”事件呈现的,当用户将鼠标悬停在数据点上时会触发该事件。然而,该线路本身似乎没有此类事件。举个例子,这篇文章很难写,因为它与我正在开发的应用程序紧密集成。不过,我会看看我能做些什么。即使是JSFIDLE也能做到,但我知道这可能是个问题hard@Somesh我添加了一个fiddle,它不包含用于拖动和动态添加数据点的所有自定义代码。不过,就问题的目的而言,这应已足够。谢谢。我不知道这个问题有多老。不过这是一个有趣的问题,希望它对其他人仍然有用。谢谢,这真的很有帮助!
    $(placeholder).bind("plothover", function (event, pos, item) {
        if (item) {
            var tipText;
    
            if (opts.xaxis.mode === "time" || opts.xaxes[0].mode === "time") {
                tipText = stringFormat(to.content, item, timestampToDate);
            } else {
                tipText = stringFormat(to.content, item);
            }
    
            $tip.html(tipText).css({
                left: tipPosition.x + to.shifts.x,
                top: tipPosition.y + to.shifts.y
                }).show();
        } else {
             // Extended for line hover
             var series = plot.getData();
             var xBeforeIndex = 0;
             var xAfterIndex = -1;
             var Threshold = 0.0000025;
             var i = 1;
             while (i <= series[0].data.length && xAfterIndex==-1) {
                 if (xAfterIndex == -1 && pos.x > series[0].data[i][0]) {
                     xBeforeIndex = i;
                 } else if (xAfterIndex == -1) {
                     xAfterIndex = i;
                 }
                 i++;
             }
    
             var onTheLine = 
                 lineDistance(
                    series[0].data[xBeforeIndex][0]/10000,series[0].data[xBeforeIndex][1], 
                    pos.x/10000, pos.y)
                 +lineDistance(pos.x/10000, pos.y,
                    series[0].data[xAfterIndex][0]/10000,series[0].data[xAfterIndex][1])
                 -lineDistance(
                    series[0].data[xBeforeIndex][0]/10000,series[0].data[xBeforeIndex][1],
                    series[0].data[xAfterIndex][0]/10000,series[0].data[xAfterIndex][1]);
    
              if (Math.abs(onTheLine) < Threshold) {
                  tipText = "Found Line";
                  $tip.html(tipText).css({
                      left: tipPosition.x + to.shifts.x,
                      top: tipPosition.y + to.shifts.y
                      }).show();
               } else {
                   $tip.hide().html('');
               }
           }
      });