簡體   English   中英

在D3中移動固定節點

[英]Moving fixed nodes in D3

我在D3強制定向布局中設置了節點。 fixed = true。 如果我設置.x或.y值,節點本身不會移動到新位置。

這是我的功能:

function fixNode(idArray, locationX, locationY) {
    for ( x = 0; x < idArray.length; x++ ) {
        for ( y = 0; y < nodes.length; y++ ) {
            if (nodes[y].id == idArray[x]) {
                nodes[y].fixed = true;
                nodes[y].x = 50;
                nodes[y].y = 50;
                break;
            }
        }
    }
}

更新1:

這是基於傑森建議的工作函數:

function fixNode(idArray, locationX, locationY) {
    for ( x = 0; x < idArray.length; x++ ) {
        for ( y = 0; y < nodes.length; y++ ) {
            if (nodes[y].id == idArray[x]) {
                nodes[y].fixed = true;
                nodes[y].x = 50;
                nodes[y].y = 50;
                nodes[y].px = 50;
                nodes[y].py = 50;
                break;
            }
        }
    }
    tick();
}

力導向布局與實際渲染分離。 通常你有一個tick處理程序,它可以為布局算法的每個“tick”更新SVG元素的屬性(關於解耦的好處是你渲染到<canvas> ,或其他東西)。

因此,要回答您的問題,您只需直接調用此處理程序即可更新SVG元素的屬性。 例如,您的代碼可能如下所示:

var node = …; // append circle elements

var force = d3.layout.force()
    .nodes(…)
    .links(…)
    .on("tick", tick)
    .start();

function tick() {
  // Update positions of circle elements.
  node.attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; });
}

所以你可以隨時調用tick()並更新元素位置。

您可能想要調用force.tick() ,但這可以用作force.start()的同步替代方法:您可以重復調用它,每次調用都會執行布局算法的一個步驟。 但是,有一個內部alpha變量用於控制內部使用的模擬退火,一旦布局“冷卻”,該變量將為0並且對force.tick()進一步調用將不起作用。 (不可否認,如果force.tick()總是觸發一個tick事件而不管冷卻,那可能會很好,但這不是當前行為)。

正如您在注釋中正確指出的那樣,如果手動設置dxdy ,如果希望節點保持在某個位置,還應該將d.pxd.py設置為相同的值。

暫無
暫無

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

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