2016-04-19 23 views
0

我試圖在強制佈局中使用上升筆畫寬度屬性製作路徑。如果目標值高於源值,則目標端的鏈接應該更寬。具有上升筆畫寬度的路徑

,我能找到的唯一的例子是這樣的=>http://jsfiddle.net/bfzsaL3m/2/

我也碰到這個問題Decreasing Polyline Stroke Width來了。它說這不能完成,但有點舊。

現在我的代碼使用.style("stroke-width", function(d) { return Math.sqrt(d.value); }) 所以,任何幫助表示讚賞。 這裏是我的簡單的小提琴:

https://jsfiddle.net/tekh27my/

+0

這似乎是SV​​G/D3唯一的問題?如果是這樣,那麼帆布標籤可以被刪除,以避免不必要的「噪音」 – K3N

+0

對不起,在另一個問題,它說,它可以用畫布完成,所以我把標籤,如果有人知道使用畫布的另一個解決方案。 – echonax

+0

啊,在那種情況下沒問題。 – K3N

回答

2

要在畫布可變寬度的多段線,你就必須做兩件事情之一:

  • 計算沿着地擠出折線運行新路徑中央。這必須考慮連接,角度,內角處的封閉點,外角處添加的三角形或弧線等(這可以應用於SVG和canvas的路徑)。
  • 繪製多段線分段,這意味着對於每個段您增加/減少用「圓」模式連接段的厚度。對於較長的部分,您還需要插入該部分以避免陡峭的更改。

後者將是兩個最簡單的解決方案:

var ctx = c.getContext("2d"), 
 
    line = [116,34,116,37,116,39,116,49,119,71,126,103,140,141,160,181,190,224,226,263,263, 
 
      293,312,316,363,327,416,328,458,322,491,313,515,295,537,272,557,244,570, 
 
      224,580,208,586,196,591,188,595,182,596,178,598,176,601,174,604,172,605,171], 
 
    line2 = [],   // the interpolated segments 
 
    maxSubSeg = 16,  // number of sub-segements 
 
    minThick = 2,  // taper thickness 
 
    maxThick = 16; 
 

 
// interpolate the line to create more segments 
 
for(var i = 0; i < line.length - 2; i += 2) { 
 
    var x1 = line[i],  // get line positions 
 
     y1 = line[i+1], 
 
     x2 = line[i+2], 
 
     y2 = line[i+3]; 
 
    
 
    for(var j = 0; j < maxSubSeg; j++) { 
 
    line2.push(
 
     x1 + (x2-x1) * (j/maxSubSeg), // interpolate X 
 
     y1 + (y2-y1) * (j/maxSubSeg) // interpolate Y 
 
    ) 
 
    } 
 
} 
 

 
// render new line 
 
ctx.lineCap = "round"; 
 

 
for(var i = 0; i < line2.length - 2; i += 2) { 
 
    ctx.beginPath(); 
 
    ctx.moveTo(line2[i], line2[i+1]); 
 
    ctx.lineTo(line2[i+2], line2[i+3]); 
 
    ctx.lineWidth = minThick + maxThick * (i/line2.length); // use length as t [0,1] 
 
    ctx.stroke(); 
 
}
<canvas id=c width=640 height=400></canvas>

1

如果有人想知道如何做到這一點。這裏是我的小提琴:

https://jsfiddle.net/tekh27my/2/

我已經計算出路徑的M和L屬性打鉤功能:

d3.selectAll(".link") 
     .attr("d", function (d) { 

       var radius = 10; 

        if(d.target.x > d.source.x && d.target.y < d.source.y){ 
         return "M" + d.source.x + "," + d.source.y + " L" + (d.target.x - radius) + "," + (d.target.y - radius) + " L" + (d.target.x + radius) + "," + (d.target.y + radius) + " L" + d.source.x + ", " + d.source.y; 
        }else if(d.target.x < d.source.x && d.target.y > d.source.y){ 
         return "M" + d.source.x + "," + d.source.y + " L" + (d.target.x + radius) + "," + (d.target.y + radius) + " L" + (d.target.x - radius) + "," + (d.target.y - radius) + " L" + d.source.x + ", " + d.source.y; 
        }else{ 
         return "M" + d.source.x + "," + d.source.y + " L" + (d.target.x - radius) + "," + (d.target.y + radius) + " L" + (d.target.x + radius) + "," + (d.target.y - radius) + " L" + d.source.x + ", " + d.source.y;} 
      }); 
相關問題