簡體   English   中英

D3.js強制布局 - 邊緣標簽放置/旋轉

[英]D3.js force layout - edge label placement/rotation

我對D3.js很新,而且我一直在玩力布局。 我試過的一件事就是在鏈接上放置標簽。

一種方法是通過附加svg:text並手動計算translaterotate ,它可以直線工作。 但是,如果link是svg:path (例如arc),則不能按預期工作。 在這些情況下, svg:textPath是建議的解決方案。

本演示中 ,您可以看到通過svg:textPath向鏈接添加標簽的簡單實現。 唯一的問題是,如果源位於目標的右側,則文本以相反的方向呈現(從我們的角度來看,它從路徑的角度來看仍然是正確的)。 我的問題是,如何處理這個問題?

我想出的唯一“解決方案”是,在上述情況下手動交換源和目標。 在這里 ,你可以看到它幾乎可以工作。

在此輸入圖像描述

在交換發生的狀態下,您還可以看到弧線翻轉到另一側,這看起來並不正確。 :(

@LarsKotthoff是正確的, textPath必須遵循路徑的方向。 在這種情況下,路徑的方向不僅定義了弧形方向,而且定義了箭頭標記在末端的附着 - 這使得在飛行中交換方向變得棘手,因為您也必須移動標記。

更簡單的解決方案(盡管如果你有大量的鏈接可能不是最好的)是使用僅用於文本的不可見路徑“遮蔽”真實的鏈接路徑:

var link = svg.append("svg:g").selectAll("g.link")
    .data(force.links())
  .enter().append('g')
    .attr('class', 'link');

var linkPath = link.append("svg:path")
    .attr("class", function(d) { return "link " + d.type; })
    .attr("marker-end", function(d) { return "url(#" + d.type + ")"; });

var textPath = link.append("svg:path")
    .attr("id", function(d) { return d.source.index + "_" + d.target.index; })
    .attr("class", "textpath");

現在您有一個可以正確操作的獨立路徑。 正如您所注意到的,有兩個問題 - 您必須更改路徑方向,並且必須更改圓弧方向。 看起來你可以通過交換sweep-flag值在路徑命令字符串中執行此操作( 請參閱docs ),因此不是Arx,ry 0 0,1而是Arx,ry 0 0,1你有Arx,ry 0 0,0 您可以通過使用一個函數來創建路徑字符串來減少一些代碼重復:

function arcPath(leftHand, d) {
    var start = leftHand ? d.source : d.target,
        end = leftHand ? d.target : d.source,
        dx = end.x - start.x,
        dy = end.y - start.y,
        dr = Math.sqrt(dx * dx + dy * dy),
        sweep = leftHand ? 0 : 1;
    return "M" + start.x + "," + start.y + "A" + dr + "," + dr +
        " 0 0," + sweep + " " + end.x + "," + end.y;
}

然后,您可以單獨更新鏈接路徑和文本路徑:

linkPath.attr("d", function(d) {
    return arcPath(false, d);
});

textPath.attr("d", function(d) {
    return arcPath(d.source.x < d.target.x, d);
});

參見工作代碼: http//jsfiddle.net/nrabinowitz/VYaGg/2/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM