2016-11-30 73 views
4

圖中的節點鏈接圖中的節點上一個自鏈接可以做到你需要在同一個節點上繪製多個鏈接?這裏描述瞭如何利用節點鏈接圖多個自邊緣D3

我試圖根據存在的自我鏈接的數量向它添加一個'旋轉'。 由於代碼鏈接的例子,我做了以下修改:

function tick() { 
    link.attr("d", function(d) { 
    var x1 = d.source.x, 
    y1 = d.source.y, 
    x2 = d.target.x, 
    y2 = d.target.y, 
    dx = x2 - x1, 
    dy = y2 - y1, 
    dr = Math.sqrt(dx * dx + dy * dy), 

    // Defaults for normal edge. 
    drx = dr, 
    dry = dr, 
    xRotation = 0, // degrees 
    largeArc = 0, // 1 or 0 
    sweep = 1; // 1 or 0 

    // Self edge. 
    if (x1 === x2 && y1 === y2) { 
    // Fiddle with this angle to get loop oriented. 
    var index = getIndexOfDuplicateEdge(); 
    var degree = 360/numberOfDuplicateEdges(); 
    var degreeForIndex = degree * index; 


    xRotation = degreeForIndex; // Previously: -45; 

    // Needs to be 1. 
    largeArc = 1; 

    // Change sweep to change orientation of loop. 
    //sweep = 0; // I also tried to change it based on index % 2 

    // Make drx and dry different to get an ellipse 
    // instead of a circle. 
    drx = 30; 
    dry = 20; 

    // For whatever reason the arc collapses to a point if the beginning 
    // and ending points of the arc are the same, so kludge it. 
    x2 = x2 + 1; 
    y2 = y2 + 1; 
    } 

return "M" + x1 + "," + y1 + "A" + drx + "," + dry + " " + xRotation + "," + largeArc + "," + sweep + " " + x2 + "," + y2; 
}); 

這不會畫我的橢圓預期,我無法找到一個方法來處理這個問題。基於SVG from Mozilla,大弧必須是1.掃描可以是0或1,並且會「反射」我的省略號。我可以在90-180之間使用xRotation,掃描0/1將覆蓋180度的圈。但是,我沒有找到在其他180度位置繪製省略號的方法。

自鏈接的數量可能會有所不同,我總是希望在省略號之間具有「最佳」分佈。

理想的情況下,它應該看起來像:

Self-Linking edges for a node

回答

4

的想法是劃分圈成許多部分花瓣的花了。然後計算圓上每個花瓣的起點和終點,並在這些點上擬合一個橢圓。

您可以使用下面的代碼片段就實現這一目標:(函數假設你有id爲「svgthing」一個SVG元素)

function radtodeg(angle) { 
    return angle * (180/Math.PI); 
} 

function flower(center_x, center_y, num_self_edges, start_angle, end_angle, radius, length) { 

    var angle_sector = end_angle - start_angle; 

    var num_points = num_self_edges * 2; 

    var angle_per_point = angle_sector/num_points; 
    var angle_per_sector = angle_per_point * 2; 

    var str_builder = []; 

    for(var angle = start_angle; angle < end_angle; angle += angle_per_sector) { 
    var start_sector_angle = angle; 
    var end_sector_angle = angle + angle_per_point; 

    var mid_sector_angle = angle + angle_per_point/2; 

    var start_x = center_x + (radius * Math.cos(start_sector_angle)); 
    var start_y = center_y + (radius * Math.sin(start_sector_angle)); 
    var end_x = center_x + (radius * Math.cos(end_sector_angle)); 
    var end_y = center_y + (radius * Math.sin(end_sector_angle)); 

    var mid_x = center_x + (radius * Math.cos(mid_sector_angle)); 
    var mid_y = center_y + (radius * Math.sin(mid_sector_angle)); 

     str_builder.push("<path d='"); 
    str_builder.push("M" + start_x + " " + start_y + ","); 
    str_builder.push("A " + length + " 1 " + radtodeg(mid_sector_angle) + " 0 1 " + end_x + " " + end_y); 
    str_builder.push("'/>\n"); 

    str_builder.push("<circle cx='" + start_x + "' cy='" + start_y + "' r='5' />\n"); 
    str_builder.push("<circle cx='" + end_x + "' cy='" + end_y + "' r='5'/>\n"); 
    str_builder.push("<circle cx='" + mid_x + "' cy='" + mid_y + "' r='5'/>\n"); 
    } 

    str_builder.push("<circle cx='" + center_x + "' cy='" + center_y + "' r='" + radius + "' />\n"); 

    $("#svgthing").html(str_builder.join("")); 
} 

flower(60, 50, 8, 0, 2 * Math.PI, 50, 10); 

的例子通話將產生8個花瓣的花朵。