用中断的线检测最靠近鼠标指针的线

时间:2013-08-21 15:47:14

标签: javascript svg d3.js

当用户将鼠标移到线上时,我已经构建了一条包含3行的d3折线图,并突出显示了一条线。事实证明,以这种方式选择线是非常困难的。所以我试着编写一个代码来检测最接近鼠标的线(垂直尺寸)。这很好用:

http://plnkr.co/edit/7CD1KtqUJVnUF4KgFmUm?p=preview

我现在的问题是,如果这些行在开头被“中断”,这就行不通。

http://plnkr.co/edit/0as4QOYVYO0dhZIjGx86?p=preview

我在行函数中添加了defined()调用:

var line0 = d3.svg.line()
    .interpolate("cardinal")
    .x(function(d,i) {return x(i);})
    .y(function(d) {return y(d);});
var line1 = d3.svg.line()
    .interpolate("cardinal")
    .x(function(d,i) {return x(i);})
    .y(function(d) {return y(d);})
    .defined(function (d,i) {return i > 1;});   // <- Here ...
var line2 = d3.svg.line()
    .interpolate("cardinal")
    .x(function(d,i) {return x(i);})
    .y(function(d) {return y(d);})
    .defined(function (d,i) {return i > 3;});   // <- and here.

同样的问题,如果这些行以不同的x值开头,我在这里模拟了一点hackish:

http://plnkr.co/edit/hOtXOmQapYsuYgf9HkD3?p=preview

线条,我显示连接测量值,如果缺少测量值,则线路被中断。所以这些中断可以无处不在。你知道这个问题的解决方案吗?

3 个答案:

答案 0 :(得分:3)

我建议你绘制成对的线,第一个是你现在正在绘制的线,但是指针事件:无,然后第二个(具有相同的坐标)将是可见性:隐藏但是一个笔划和一个合理的笔划宽度,因此很容易选择。

当用户将鼠标悬停在隐藏线上时,您可以处理它,就好像他是在可见线上徘徊一样。

答案 1 :(得分:1)

好的,这是我没有隐藏线的最终解决方案:

http://plnkr.co/edit/mGIUnwNNZxtuyobAWs0P?p=preview

数据格式有点具体,但可以很容易地进行调整。

答案 2 :(得分:0)

我通过为每条可见线添加一条隐藏线并在隐藏线上应用问题中显示的函数来解决它。我添加了一些要点,以确保每条隐藏线从图表的左侧开始,没有中断并在图表的末尾结束。

在此图像中,我将隐藏线以低饱和度显示,并标记了这些额外点。除了添加的起点和终点,它们非常接近原始点,并且它似乎与basismonotone插值效果很好:

extra points

  1. 计算最低和最高x值。
  2. 添加额外的数据记录(使用shift()和push()对数据进行“迭代”)并为每个额外点设置s: true
  3. 将线路功能复制为两个线路功能(lineHiddenlineVisible)。
  4. 将条件!record.s添加到defined()的{​​{1}}函数。
  5. 使用两个线函数为每个系列绘制一条可见线和一条隐藏线,并隐藏隐藏线。将这些行放在两个变量中:linieVisible
  6. 在隐藏线上使用问题中显示的功能,但在可见线上突出显示。
  7. 下一个任务是,如果它在鼠标位置被中断,则不突出显示一行......

    修改

    可以通过创建数组

    来解决这个问题
    var hiddenLines = [...], visibleLines = [...]

    可以使用比例函数interruptions = [ [<x pos left>, <x pos right>, <series id>], ... ] 计算x位置。

    在鼠标悬停中,我遍历该数组进行查找,这些行中断只使用其他行。