在径向树中实现鱼眼失真时的转换问题

时间:2013-12-30 13:07:44

标签: d3.js fisheye

基本上,我试图将d3鱼眼失真算法应用于径向树。我相信我遇到的问题围绕这样一个事实,即被喂入鱼眼失真的坐标是由d3.layout.tree计算的坐标。但实际的坐标已经通过g变换进行了调整。因此,鱼眼失真产生的坐标需要调整回g变换。

例如:

// re-setting the projection according to fisheye coords
diagonal.projection(function(d) { d.fisheye = fisheye(d); return [d.fisheye.y, d.fisheye.x / 180 * Math.PI]; })

我一直在尝试这个......这里是fiddle

我有点亲近......感谢帮助。

1 个答案:

答案 0 :(得分:5)

按照我在评论中建议的方向,这就是结果:

http://fiddle.jshell.net/7TPhq/7/

我没有使用旋转和平移来定位节点,而是创建了两个基于三角函数的函数来计算数据(x,y)值的水平和垂直位置,这些值被视为极坐标。

然后我必须设置鱼眼功能,将我的定位功能用作“访问者”功能,而不是直接阅读d.xd.y。不幸的是,你用于鱼眼的基本插件没有包含获取和设置x / y访问器功能的方法,所以我也必须修改它。我很惊讶它还没有在代码中;它是大多数d3布局对象的标准功能。

(当我设置github时,我将不得不做一个拉取请求来添加它。我需要弄清楚鱼眼刻度/缩放功能是如何工作的 - 尽管 - 我从这个例子中取出了因为你没有使用它。)

定位功能如下:

function getHPosition(d){
    //calculate the transformed (Cartesian) position (H, V)
    //(without fisheye effect)
    //from the polar coordinates (x,y) where 
    //x is the angle
    //y is the distance from (radius,radius)
    //See http://www.engineeringtoolbox.com/converting-cartesian-polar-coordinates-d_1347.html

    return (d.y)*Math.cos(d.x);
}
function getVPosition(d){
    return (d.y)*Math.sin(d.x);
};

这些函数用于设置节点和链接的原始位置,然后一旦鱼眼开始使用它们在内部使用这些函数,将结果(如果合适的话有失真)返回为d.fisheye.x和{{1 }}。

例如,对于链接,这意味着投影设置d.fisheye.y函数用于初始化:

d3.svg.diagonal

但是这样更新:

var diagonal = d3.svg.diagonal()
    .projection(function(d) { 
        return [getHPosition(d), getVPosition(d)]; 
});

还有其他一些小变化:

我稍微简化了绘图区域的尺寸。

我添加了一个带diagonal.projection(function(d) { d.fisheye = fisheye(d); return [d.fisheye.x, d.fisheye.y]; }); 的背景矩形,这样当鼠标在节点和空白背景之间移动时,鱼眼不会打开和关闭。

没有打扰旋转文本(因为节点组不再旋转,默认情况下不会发生),但您可以轻松地在单个文本上添加旋转变换元件。

最后,这个让我感到困难的时间超过了我想承认的,Javascript trig函数的角度必须是弧度。无法弄清楚为什么我的布局是so ugly, with overlapping lines。我认为这与在pointer-events:all;d3.svg.diagonal()之间切换有关,并花了很多时间尝试反向触发和各种各样的事情......