0

我正在尝试创建一个交互式组织结构图,这样当我单击一个框时,该框会重新定位在 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>
4

1 回答 1

0

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

于 2013-04-29T10:34:22.780 回答