D3线路交叉口

时间:2013-04-03 21:34:28

标签: svg d3.js

我正在使用D3而且我遇到了一些问题。基本上,我有一个小区域图表,其域名基于画笔更改(类似于此示例:http://bl.ocks.org/mbostock/1667367)。我创建了一条可以拖动的线,我希望做的是提供一条工具提示,这条线与区域图相交。我创建了一个函数,它根据行的x值将图表中的数据一分为二,并返回最接近的数据点...问题是这并不总是与参考线对齐,特别是如果画笔设置得非常小,因此在面积图中只插入了几个点。这是我正在谈论的图像。 line intersection problem

所以,我的问题是有可能以某种方式创建一个路径线交叉函数,它将确定两条路径相遇的确切位置,并返回一个可用于工具提示的值?我目前正在使用的功能是......但就像我说的那样,当刷子设置为一个小区域时,这似乎不太好。

function ref_move(d) {
     var x0 = x.invert(d.x -35),
        i = bisectDate(data, x0, 1),
        d0 = data[i - 1],
        d1 = data[i],
        d = x0 - d0.date > d1.date - x0 ? d1 : d0;

        ref_tooltip.attr("transform", "translate(" + (x(d.date) + margin.left) + "," +   (y(d.Light) + light_offset) + ")");
  }

我已就此问题做过一些研究,并没有提出太多解决方案。有一个由Kevin Lindsey编写的图书馆,它进行了某种交叉测试(http://www.kevlindev.com/geometry/2D/intersections/index.htm)......但它是在大约9年前编写的......并且不确定它是否仍然是最新的。另外,有一个例子,你可以在路径上找到一个点(http://bl.ocks.org/mbostock/1705868),但是,我想知道如何找到沿着路径的点,它靠近参考线?有没有人对如何解决这个问题有任何想法?提前谢谢。

2 个答案:

答案 0 :(得分:0)

感谢您的链接。有兴趣获得其他解决方法。事实证明,我想出来......主要是使用一些插值。你知道我知道d0和d1是参考线两侧的点,它们对应于我从CSV文件中获知的数据。所以,基本上我只需要找出这两点之间参考线的位置来计算加权百分比......然后将两个权重乘以两个已知点的y值然后你得到它。我的新功能如下所示:

function ref_move(d) {
     var x0 = x.invert(d.x -35),
        i = bisectDate(data, x0, 1),
        d0 = data[i - 1],
        d1 = data[i],
        span = (x(d1.date) - x(d0.date)),
        weight = (x(x0) - x(d0.date))/span,
        newy = (d1.Light * weight) + (d0.Light * (1.0-weight));

        ref_tooltip.attr("transform", "translate(" + (x(x0) + margin.left) + "," + (y(newy) + light_offset) + ")");
 }

这似乎解决了我的问题。谢谢您的帮助。如果有其他方法可以解决它,我会很好奇。再次感谢。

答案 1 :(得分:0)

对于KenlinDel库我设法使用D3找到两个路径的交点,但是其他形状有问题, 我正在做的实际解决方案是

chordshapes = Array()
svg.selectAll("g.Chords")
     .data(data)
     ..attr("d", function (d,i) {
                                 var shape = new Path() // from D2.js
                                 //get the path
                                 var pathStr = chrod(innerRadius, d.source, d.target)
                                 //Initialize a new path object
                                 shape.parseData(pathStr) 
                                 chordshapes[i] = shape;
                                 return pathStr;
                             })

所以这里的chordShapes包含每个路径的Path对象, 然后当我点击例如画笔时,我可以为画笔矩形创建另一个形状并检查交点如下

........
var intersect Intersection.intersectShapes(chordshapes[i], brushShape)
if(intersect.points.length >0) {
 ..........
}