D3.js语义缩放和平移示例不起作用

时间:2013-02-02 21:08:16

标签: svg d3.js zoom pan

我正在尝试为D3.js实现SVG Semantic Zoom和Pan示例的一个版本,找到here。我正在尝试使用Dendrogram / tree(例如here),按照Mike Bostock(here)的建议。目标就像这个jsFiddle其他一个线程mentioned,除了没有奇怪的节点/路径解除链接行为。我的个人尝试位于here

我在使用Mike的代码时遇到Firebug中的错误,关于“无法翻译(NaN,NaN)”,因此我将缩放功能中的代码更改为如下所示。但是,这种行为很奇怪。现在1)我的路径不缩放/移动,2)我只能从右下方 - 左上方平移节点(如果我尝试从左下方平移 - 右上方,节点仍然沿着LR-UL移动方向)。

var vis = d3.select("#tree").append("svg:svg")
              .attr("viewBox", "0 0 600 600")
              .attr("width", w + m[1] + m[3])
              .attr("height", h + m[0] + m[2])
              .append("svg:g")
              .attr("transform", "translate(" + m[3] + "," + m[0] + ")")
              .call(d3.behavior.zoom().x(x).y(y).scaleExtent([1,8]).on("zoom",zoom));

// zoom in / out
function zoom() {
    var nodes = vis.selectAll("g.node");
    nodes.attr("transform", transform);
}

function transform(d) {
    return "translate(" + x(d.y) + "," + y(d.x) + ")";
}

我尝试按照提及abovejsFiddle的Google网上论坛帖子中提供的其他解决方案,但我没有取得多大进展。在我的代码中包含来自jsFiddle的路径链接和translate()函数可以让我缩放路径 - 除了1)它们垂直翻转(某处x和y转置不能正常工作); 2)路径不以与节点相同的速率缩放(可能与#1相关),因此它们变为“未链接”; 3)当我平移时,路径现在向所有方向平移,但节点不移动。当我单击一个节点以展开树时,路径会重新调整并自行修复,因此更新代码似乎工作得更好(但我不知道如何识别/复制其中的工作部分)。请参阅我的代码here

function zoom(d) {
    var nodes = vis.selectAll("g.node");
    nodes.attr("transform", transform);

    // Update the links...
    var link = vis.selectAll("path.link");
    link.attr("d", translate);
}

function transform(d) {
    return "translate(" + x(d.y) + "," + x(d.x) + ")";
}

function translate(d) {
    var sourceX = x(d.target.parent.y);
    var sourceY = y(d.target.parent.x);
    var targetX = x(d.target.y);
    var targetY = (sourceX + targetX)/2;
    var linkTargetY = y(d.target.x0);
    var result = "M"+sourceX+","+sourceY+" C"+targetX+","+sourceY+" "+targetY+","+y(d.target.x0)+" "+targetX+","+linkTargetY+"";
    //console.log(result);

   return result;

我的问题是:

  • 我可以看一下树形图/树上缩放/平移的工作示例吗?
  • 根据我上面的代码,任何人都可以确定路径被翻转的位置/方式吗?我在绘制SVG Cubic Bezier曲线的translate()函数中尝试了各种排列,但似乎没有任何工作正常。同样,我的jsFiddle是here
  • 任何问题排查提示或想法,为什么只能部分平移?

谢谢大家的帮助!

1 个答案:

答案 0 :(得分:2)

你有一个非常好的实现,出了一个主要的错字:

function transform(d) {
    return "translate(" + x(d.y) + "," + x(d.x) + ")";
}

应该是

function transform(d) {
    return "translate(" + x(d.y) + "," + y(d.x) + ")";
}

要让你的路径不翻转,你应该可能没有颠倒y轴:

y = d3.scale.linear().domain([0, h]).range([h, 0])

更改为

y = d3.scale.linear().domain([0, h]).range([0, h])

修正在这里:http://jsfiddle.net/6kEpp/2/。但是为了将来参考,您可能应该让x轴在x值上运行,而y轴在y值上运行,或者你只是真的让自己感到困惑。

最后评论以完善您的实施:

  1. 从默认渲染(或打开/关闭节点后)到缩放实现的贝塞尔图中有一点跳跃。你只需要让它们具有相同的bezier功能,当你玩它时它会感觉好多了。
  2. 根据现有节点的相对移动,您需要在图表重绘后更新缩放矢量。否则,在打开/关闭节点后尝试再次缩放时会突然跳转。