【问题标题】:D3 how to make dynamic sequential transitions work using transform/translate and offset coordinates?D3如何使用变换/平移和偏移坐标使动态顺序转换工作?
【发布时间】:2013-04-29 00:13:23
【问题描述】:

我正在尝试创建一个交互式组织结构图,这样当我单击一个框时,该框将重新定位在 SVG 容器的中心,并且所有其他元素也会转换但保持相同相对 位置。因此,如果您单击列表中的顶部框,它们都会一起向下移动。然后,如果您单击其中一个较低的框,它们都会一起向上移动,但始终使所选框位于中心。如果你点击一个已经在中间的盒子,它不应该移动,但此刻它们正在飞来飞去。

我在第一次点击时就可以正常工作,但在随后的每次点击中,这些框都会开始飞来飞去。我正在使用鼠标侦听器获取当前位置并计算偏移量以使我输入到变换/翻译中的选定框居中。我认为这是奇怪行为的来源,因为偏移量计算正确(通过 console.log 查看)但应用的转换不等于这个计算。

我已经阅读了很多关于转换/翻译的帖子,但它们似乎都适用于单个转换,而不是多个顺序转换。我曾尝试在每次新转换之前使用 .attr(transform, null) 但这不起作用。我还尝试动态提取所选组件的当前 x,y,然后使用偏移值更新这些属性,但这也不起作用。我真的坚持这一点,非常感谢任何帮助!

谢谢, 标清

<script type="text/javascript">


var cwidth = 1000;
var cheight = 500;
var bwidth = 100;
var bheight = 50;

// container definition
var svgContainer = d3.select("body").append("svg")
                    .attr("width",cwidth)
                    .attr("height",cheight)
                    .on("mousemove", mousemove); 

// Background gray rectangle
svgContainer.append("svg:rect")
.attr("x",0)
.attr("y",0)
.attr("width",cwidth)
.attr("height",cheight)
.style("fill", "lightgrey");                                 

// data
var secondData = [
   { "idx": 1, "name": "Commercial" },
   { "idx": 2, "name": "Finance" },
   { "idx": 3, "name": "Operations" },
   { "idx": 4, "name": "Business Services" }
];

var secondElements = secondData.length;

// group definition
var secondNodes = svgContainer.append("g")
       .attr("class", "nodes")
       .selectAll("rect")
       .data(secondData)
       .enter()
       .append("g")
       .attr("transform", function(d, i) {
         d.x = 300;             
         d.y = ((cheight/secondElements)*d.idx)-bheight;
         return "translate(" + d.x + "," + d.y + ")"; 
       });

// Add elements to the previously added g element.
secondNodes.append("rect")
    .attr("class", "node")
    .attr("height", bheight)
    .attr("width", bwidth)
    .style("stroke", "gray")
    .style("fill", "white")
    .attr("y", function() {return -(bheight/2);})
    .on("mouseover", function(){d3.select(this).style("fill", "aliceblue");})
    .on("mouseout", function(){d3.select(this).style("fill", "white");})
    .on("mousedown", center);

// Add a text element to the previously added g element.
secondNodes.append("text")
    .attr("text-anchor", "left")
    .attr("x", 15)
    .attr("y",5)
    .text(function(d) {return d.name;});

// gets current coordinates for transition 
var current = [0,0];
var xshift = 0;
var yshift = 0;

// get offset to centre from current mouse location
function mousemove() {
  //console.log(d3.mouse(this));
current = d3.mouse(this);
xshift = 500 - current[0];
yshift = 250 - current[1];
}

//applies transitions
function center(d) {

secondNodes.selectAll("rect")
    .transition()            
    .delay(0)            
    .duration(500)
    .attr("transform", "translate(" + xshift + "," + yshift + ")")
    .each("end", function() {
        secondNodes.selectAll("text")
            .transition()            
            .delay(0)            
            .duration(0)
            .attr("transform", null);   
    });

}


</script>

【问题讨论】:

    标签: d3.js transform


    【解决方案1】:

    如果您希望所有内容保持其相对位置,在我看来,更容易做的事情是将所有内容包含在 g 元素中,您可以将其设置为 transform 属性一。也就是说,您不必移动许多元素,而只需移动顶级容器。处理点击的代码几乎保持不变,只是您只需要在该元素上设置 transform 属性。

    【讨论】:

      猜你喜欢
      • 2017-05-15
      • 1970-01-01
      • 1970-01-01
      • 2013-08-20
      • 1970-01-01
      • 2011-12-20
      • 2019-12-01
      • 2020-08-26
      • 1970-01-01
      相关资源
      最近更新 更多