使用d3的缩放和平移功能

时间:2013-06-29 06:43:30

标签: d3.js visualization

我正在尝试使用d3的平移/缩放功能在屏幕上绘制框,这样当您单击一个框时,会出现一个新框并将其余框移到右侧,以便新框是在画布的中心。平移将允许我滚动浏览我绘制的所有框。

这是我的jsfiddle:http://jsfiddle.net/uUTBE/1/

这是我的初始化缩放/平移的代码:     svg.call(d3.behavior.zoom()。on(“zoom”,redraw));

function redraw() {
    d3.select(".canvas").attr("transform",
        "translate(" + d3.event.translate + ")" 
        + " scale(" + d3.event.scale + ")");
}

这是我绘制框的代码:

function drawBox(x, y) {
    var boxGroup = canvas.append("g");
    boxGroup.append("rect")
        .attr("x", x)
        .attr("y", y)
        .attr("height", 100)
        .attr("width", 100)
        .attr("fill", function () {
            var i = Math.floor(Math.random() * 4);
            if (i === 1) return "red";
            else if (i === 2) return "blue";
           else if (i === 3) return "yellow";
           else return "green";
        })
        .on("click", function () {
            counter++;
            d3.select(".canvas")
              .transition()
              .duration(1000)
              .attr('transform', "translate(300,0)");
         drawBox(x - counter * 120, y);
        });
}

我有这个小提琴的多个问题,但我的两个主要问题是:

1)我如何做到这一点,当我第二次点击一个新的盒子时盒子相应地移动(即当我点击盒子时,旧盒子向右移动并出现一个新盒子,但是当我点击新框,旧框不会向右移动。

2)为什么当我点击新框时,较新的框之间有很大的间距? (仅在尝试在屏幕上放置3个框后才会发生。)

感谢任何提示表示赞赏!

1 个答案:

答案 0 :(得分:2)

我认为围绕transform存在一些混淆。对于单个元素,transform属性是静态的,而不是累积的 - 因此多次设置.attr('transform', "translate(300,0)")将在第一次后无效。看起来您的新盒子的放置逻辑也已关闭。

如果您退后一步(假设我理解您要做的事情),这里所需的定位逻辑非常简单:

  1. 每次添加新框时,框架所有框都移动120px,因此需要x - 120 * counter的翻译。

  2. 新框需要偏离新的框架位置,因此需要设置x -120 * counter

  3. 缩放需要考虑当前画布偏移量。

  4. 上面的

    (1)可以在你的点击处理程序中完成:

    canvas
      .transition()
      .duration(1000)
      .attr('transform', "translate(" + (offset * counter) + ",0)");
    

    (2)非常容易应用于您正在包装框中的g元素:

    var boxGroup = canvas.append("g")
        .attr('transform', 'translate(' + (-offset * counter)  + ',0)');
    

    (3)可以添加到您的redraw处理程序中:

    function redraw() {
        var translation = d3.event.translate,
            newx = translation[0] + offset * counter,
            newy = translation[1];
        canvas.attr("transform",
            "translate(" + newx + "," + newy + ")" + " scale(" + d3.event.scale + ")");
    }
    

    请在此处查看工作小提琴:http://jsfiddle.net/nrabinowitz/p3m8A/