2017-10-07 66 views
2

我創建Fimily樹,它似乎工作正常,除了鏈接。當我拖動節點時他們沒有更新。鏈接結束只是模式不同的方向,並沒有遵循節點。D3:更新路徑鏈接位置

另外,當我點擊節點它的筆觸改變,但也改變文本筆畫,裏面矩形,我需要改變只rect筆畫。

我準備Feedly

<!DOCTYPE html> 
<html lang="en"> 
    <head> 
    <meta charset="utf-8"> 

    <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> 
    </head> 

    <body> 

<script> 



var margin = {top: 100, right: 50, bottom: 50, left: 50}, 
    width = 1800 - margin.left - margin.right, 
    height = 400 - margin.top - margin.bottom, 
    boxWidth = 140, 
    boxHeight = 80; 
    boxHSpace = 200, 
    boxVSpace = 70, 
    links = []; 

var svg = d3.select("body") 
    .attr("bgcolor", "#2c2c2c") 
    .append("svg") 
    .attr("width", width + margin.left + margin.right) 
    .attr("height", height + margin.top + margin.bottom) 
    .append("g") 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 


var datas; 

datas = setPositions(buildDataAssocArray(getData())); 

var node = svg.selectAll(".node") 
    .data(d3.entries(datas)) 
    .enter() 
    .append("g"); 


function dragmove(d) { 
    var x = d3.event.x; 
    var y = d3.event.y; 

    d3.select(this).attr("transform", "translate(" + x + "," + y + ")"); 
    console.log(d); 
    datas[d.key].x=x; 
    datas[d.key].y=y; 

    link.attr("d", connect); 
} 

// Define drag beavior 
    var drag = d3.behavior.drag() 
     .on("drag", dragmove) 
     .origin(function() { 
      var t = d3.transform(d3.select(this).attr("transform")); 
      return {x: t.translate[0], y: t.translate[1]}; 
     }); 

    node.call(drag) 
    .on("click", click); 

    var selected; 
    function click(){  
     if(!selected){ 
     selected = this; 
     d3.select(selected).style('stroke', 'white'); 
     } 
     else { 
     d3.select(selected).style('stroke', 'black'); 
     selected = this; 
     d3.select(selected).style('stroke', 'white'); 
     } 
    }  


    node.append("rect") 
     .attr("width", boxWidth) 
     .attr("height", boxHeight) 
     .attr("fill", "tan") 
     .attr("x", function(d) { return d.value.x - 70; }) 
     .attr("y", function(d) { return height - d.value.y - 40; }) 
     .style("cursor", "pointer"); 


    node.append("text") 
     .attr("font-size", "16px") 
     .attr("fill", "black") 
     .attr("x", function(d) { return d.value.x; }) 
     .attr("y", function(d) { return height - d.value.y - 15; }) 
     .style("text-anchor", "middle") 
     .text(function(d) { return d.value.name; }) 


    var link = svg.selectAll(".link") 
     .data(getLinks()) 
     .enter() 
     .insert("path", "g") 
     .attr("fill", "none") 
     .attr("stroke", "#000") 
     .attr("stroke", "#000") 
     .attr("shape-rendering", "crispEdges") 
     .attr("d", connect); 

    function connect(d, i) { 
     console.log(d); 
     return  "M" + d.source.x + "," + (height - d.source.y) 
       + "V" + (height - (3*d.source.y + 4*d.target.y)/7) 
       + "H" + d.target.x 
       + "V" + (height - d.target.y); 
    }; 

    function getLinks() { 
     return links ; 
    } 


function setPositions(datas) 
{ 
    var fams=getFamily(); 


     var x=200 ,y=100; 

    fams.forEach(function(item, i, arr) { 


     item.childs.forEach(function(child, i1, arr1) { 
      console.log(child); 
      datas[child].x = x; 
      datas[child].y = y; 
      links.push({"source" : datas[child], "target" : datas[item.husb]}); 
      links.push({"source" : datas[child], "target" : datas[item.wife]}); 
     }); 

     x+=100; 
     y+=100; 

     datas[item.husb].x = x-100; 
     datas[item.husb].y = y+100; 
     datas[item.wife].x = x+100; 
     datas[item.wife].y = y+100; 

     x+=100; 
     y+=100; 

    }); 

    return datas; 
} 


function getFamily() { 
    return [ 
    { 
     "husb": "003", 
     "wife": "002", 
     "childs": ["001"] 
     } 
]; 
} 

function buildDataAssocArray(adatas) { 
    var datas = adatas; 
    var dArray = []; 
    datas.forEach(function(item, i, arr) { 
       item.x=0; 
       item.y=0; 
     dArray[item.id] = item; 
    }); 
    return dArray; 
} 

//console.log(buildDataAssocArray()); 

function getData() { 
    return [ 
    { 
     "id" : "001", 
     "name": "Алтунин Василий", 
     "mother" : "002", 
     "father" : "003", 
     "child" : null, 
    }, 
    { 
     "id" : "002", 
     "name": "Алтунина Елена", 
     "mother" : "004", 
     "father" : "005", 
     "child" : "001", 
    }, 
    { 
     "id" : "003", 
     "name": "Алтунин Владимир", 
     "mother" : "006", 
     "father" : "007", 
     "child" : "001", 
    }, 
    ]; 
}; 

</script> 

    </body> 
</html> 

解決:

這導致feedle

+0

什麼又是什麼問題? –

+0

如果您將ony節點拖動到新的位置,則鏈接到此節點不會遵循它。 –

+1

所以你的線條不會跟隨拖動的內容,而內容中的文本會變成白色 - 你不想要的東西? –

回答

4

在你拖動功能:

分別註冊阻力x和y inavriable dx和dy。

function dragmove(d) { 
    var x = d3.event.x; 
    var y = d3.event.y; 

    d3.select(this).attr("transform", "translate(" + x + "," + y + ")"); 

    datas[d.key].dx =d3.event.x; 
    datas[d.key].dy =d3.event.y; 
    link.attr("d", connect); 
} 

現在,當您爲該行設置d屬性時,請考慮拖動函數中計算的dx和dy。

function connect(d, i) { 
    var dsx=d.source.dx ? d.source.dx:0; 
    var dsy=d.source.dy ? d.source.dy:0; 
    var dtx=d.target.dx ? d.target.dx:0; 
    var dty=d.target.dy ? d.target.dy:0; 
    return  "M" + (d.source.x + dsx) + "," + (height - d.source.y +dsy) 
      + "V" + (height - (3*(d.source.y+dsy) + 4*(d.target.y +dty))/7) 
      + "H" + (d.target.x+dtx) 
      + "V" + (height - (d.target.y- dty)); 
}; 

但是我建議你使用d3.interpolate而不是在connect函數中進行計算。

工作代碼here

+0

它的工作,但與錯誤。嘗試將情人rect移到低右,然後移動其中一個上方,鏈接以奇怪的方式移動 –

+0

是的連接的計算是不正確的.. :( – Cyril

+2

你需要-dty在最後V –

1

您可以直接訪問rect作爲childNodes對象:

function click() { 
    if (!selected) { 
     selected = this; 
     d3.select(selected.childNodes[0]).style('stroke', 'white'); 
    } else { 
     d3.select(selected.childNodes[0]).style('stroke', 'black'); 
     selected = this; 
     d3.select(selected.childNodes[0]).style('stroke', 'white'); 
    } 
} 

JSFiddle