D3.js 使用d3的缩放和平移功能

D3.js 使用d3的缩放和平移功能,d3.js,visualization,D3.js,Visualization,我试图使用d3的平移/缩放功能在屏幕上绘制方框,这样当你点击一个方框时,就会出现一个新的方框,并将其余的方框向右移动,使新的方框位于画布的中心。平移将允许我滚动所有我绘制的框 这是我的JSFIDLE: 这是我初始化缩放/平移的代码: 调用(d3.behavior.zoom().on(“zoom”,redraw)) 这是我画盒子的代码: function drawBox(x, y) { var boxGroup = canvas.append("g"); boxGroup.appe

我试图使用d3的平移/缩放功能在屏幕上绘制方框,这样当你点击一个方框时,就会出现一个新的方框,并将其余的方框向右移动,使新的方框位于画布的中心。平移将允许我滚动所有我绘制的框

这是我的JSFIDLE:

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

这是我画盒子的代码:

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个框后发生)


谢谢,谢谢你的任何提示

我认为在
transform
方面存在一些混乱。对于单个元素,
transform
属性是静态的,而不是累积的-因此设置
.attr('transform',“translate(300,0)”)
多次在第一次之后都没有效果。看起来新框的放置逻辑已关闭

如果您退后一步(假设我理解您的意图),此处所需的定位逻辑非常简单:

  • 每次添加一个新框时,所有框都会向右移动120px,因此它需要一个
    x
    -翻译
    120*计数器

  • 新框需要从新帧位置偏移,因此它们需要
    x
    设置
    -120*计数器

  • 缩放需要考虑当前画布偏移

  • (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) 可以添加到您的
    重画处理程序中:

    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 + ")");
    }
    

    请参见此处的工作提示:

    听起来您最好使用标准更新行为(即在新位置重新绘制方框),而不是使用缩放/平移。特别是,您的平移取决于光标的位置,如果我理解正确的话,这不是您想要的。非常感谢,这正是我想要的!有没有一种方法可以修复缩放,使您可以实际缩放光标所在的位置?我认为您可以通过在缩放开始时将鼠标位置设置为“未测试”来实现这一点。
    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 + ")");
    }