2013-04-29 85 views
0

我想創造一個互動的組織結構圖,這樣當我點擊那個框是SVG容器的中心和所有其他元素的過渡重新定位很好,但保持在相同的相對位置的箱子。所以如果你點擊列表中的頂部框,它們都會一起下移。然後,如果您點擊其中一個較低的框,它們將一起向上移動,但始終如此,所選框位於中心。如果你點擊一個已經在中間的盒子,它不應該移動,而是在他們飛到這個地方的那一刻。D3如何使用transform/translate和offset座標使動態順序轉換工作?

我已經得到了這個工作的第一次點擊,但在隨後的每次點擊框開始飛遍各地。我正在使用鼠標偵聽器來獲取當前位置並計算一個偏移量,以便將所饋入的所選框居中放置在變換/平移中。我認爲這是奇怪的行爲來自哪裏,因爲偏移量正確計算(通過console.log查看),但應用的轉換不等於此計算。

我已經閱讀了許多關於轉換/翻譯的文章,但它們似乎都適用於單個轉換,而不是多個順序轉換。我已經嘗試在每次新的轉換之前使用.attr(transform,null),但這不起作用。我也嘗試動態提取選定組件的當前x,y,然後用偏移量值更新這些屬性,但這也不起作用。我真的堅持這一點,任何幫助非常感謝!

感謝, SD

<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> 

回答

0

如果你想要的一切,以保持其相對位置,在我看來的東西更容易做的將是包括在g元素的一切,你可以設置的轉換屬性之一。也就是說,您不必移動很多元素,而只需移動頂級容器。用於處理點擊的代碼將保持幾乎相同,只不過您只需在該元素上設置transform屬性。