Flot chart - 如何在线悬停时触发事件

gor*_*dyr 5 jquery canvas flot

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

这很好用,当你将鼠标悬停在上面或拖动一个点时,我还有一个显示Y值的工具提示.

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

我似乎无法找到一种方法来向行本身添加悬停事件,并且似乎没有本机方法.

有谁知道我可能会如何实现这一目标?

谢谢.

编辑:这是一个jsFiddle,包括我正在使用的工具提示创建代码:

的jsfiddle

当你将鼠标悬停在一个实际的数据点上时,你可以看到一个工具提示呈现,但是当我将鼠标悬停在数据点之间的线上时,我希望找到一种触发方式来渲染单独的工具提示.注意:这个小提琴不包括我的自定义代码来动态添加和拖动数据点,因为这个问题的代码太多了.

Mat*_*hew 5

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

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

function lineDistance( p1x, p1y,p2x, p2y ) {
    return Math.sqrt( (p2x - p1x)*(p2x - p1x) + (p2y-p1y)*(p2y-p1y) );
}
Run Code Online (Sandbox Code Playgroud)

假设距离光标C最近的两个点是A和B,那么距离AB应该相等AC + BC.

所以要确定它是否在线:Math.abs(AB-(AC+BC)) < SomeThreshold.使用阈值实质上是在光标可以落入其中的行周围绘制一个框.

然后在plothover(jsFiddle)中扩展你的代码

$(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('');
           }
       }
  });
Run Code Online (Sandbox Code Playgroud)

这里没有做的事情:

  1. 更合适地检查边缘情况 - 上面假设第一个和最后一个点位于图形的边缘.
  2. 在第二个图表中添加回来
  3. 使用像bubblesort这样的方法来查找前/后索引,从而提高数据集搜索性能.
  4. 请注意,我将x轴缩小了10000.数字太大,前两个点之间的差距很大,使得y轴差异无关紧要(结果在这两个点之间始终为零).

请注意,添加第二个图表将要求您找到两个图形的最近点,并检查它是否落在任一行上.如果您的线条靠近或相交,您可以只设置一条优先线.如果你很难再添加第二行,我可以稍后帮忙.