流程图 - 如何在线悬停时触发事件

发布于 2025-01-05 10:33:46 字数 512 浏览 1 评论 0原文

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

这工作正常,当您将鼠标悬停在一个点上或拖动一个点时,我还有一个显示 Y 值的工具提示。

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

我似乎找不到一种方法将悬停事件添加到该行本身,并且似乎没有本机方法。

有谁知道我该如何实现这一目标?

谢谢。

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

jsFiddle

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

I have written a plugin for jQuery Flot charts which allows you to dynamically add data points by clicking on the line of a chart, remove them by right clicking and also it allows the dragging of these points around the canvas.

This works fine and I also have a tooltip displaying the Y value when you hover over or drag a point around.

What I would like to do is display a second tooltip when a user hovers over a line showing the message "Left-click to add a data point".

I can't seem to find a way to add a hover event to the line itself and there doesn't appear to be a native method.

Does anyone know how I might go about achieving this?

Thank you.

EDIT: here is a jsFiddle that includes the tooltip creation code that I am using:

jsFiddle

as you can see a tooltip renders when you hover over an actual datapoint, however I would like to find a way to fire have a seperate tooltip rendered when you hover over the line inbetween the datapoints. NOTE: this fiddle does NOT include my custom code to add and drag the datapoints dynamically as it would be too much code for the purposes of this question.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

GRAY°灰色天空 2025-01-12 10:33:46

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

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

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)) Math.abs(AB-(AC+BC)) Math.abs(AB-(AC+BC)) 一些阈值。使用阈值本质上是在光标可以落在其中的线周围绘制一个框。

然后在 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('');
           }
       }
  });

这里没有完成的事情:

  1. 更适当地检查您的边缘情况 - 上面假设第一个和最后一个点位于图的边缘上。
  2. 添加回第二个图表
  3. 使用冒泡排序等方法查找之前/之后的索引,提高数据集搜索性能。
  4. 请注意,我将 x 轴缩小了 10000。数字太大,并且前两点之间的巨大间隙使得 y 轴差异微不足道(这两点之间的结果始终为零)。

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

So basically we are looking to conditionally display a tooltip when the position of the cursor meets the requirement that it is over a line on the chart. Since lines are not an entity we can work with you need calculate the line between the nearest two points on either side of your cursor and then see if your current position lies on it. I simplified your example a bit:

Function to calculate distance between two points:

function lineDistance( p1x, p1y,p2x, p2y ) {
    return Math.sqrt( (p2x - p1x)*(p2x - p1x) + (p2y-p1y)*(p2y-p1y) );
}

Assuming that your nearest two points are A and B to your cursor C then the distance AB should equal AC + BC.

So to determine if it is on the line: Math.abs(AB-(AC+BC)) < SomeThreshold. Using the threshold essentially draws a box around the line which the cursor can fall inside of.

Then extending your code in the 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('');
           }
       }
  });

Things not done here:

  1. Check your Edge cases more appropriately - the above assumes the first and last points are on the edges of the graph.
  2. Add back in your second graph
  3. Improve the data set searching performance using an approach like bubblesort to find the before/after indexes.
  4. Note that I am scaling down the x-axis by 10000. The numbers were too big and in the big gap between the first two points made the y-axis differences insignificant (the result was always zero between these two points).

Note, adding the second graph will require you to find the nearest points for both graphs and checking if it falls on either line. If your lines are close or intersecting you could just make one the priority line. If you struggle adding the second line back in I can help later.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文