0

この例の force-directed graphに基づいて D3.js でグラフを作成しましたが、ノード間に直線を作成するのではなく、SVG パス要素を使用して曲線を作成しています。個々のリンクのデータ構造には、リンクが接続されているノードを表すソースターゲットが含まれます。また、リンク データ構造には、パスを定義するポイントの配列を含むline要素も含まれます。リンクのデータ構造は次のようになります。

{
    id:4,        
    type:"link", 
    fixed:true, 
    source: {
                id:1, 
                name: "A",
                type:"node", 
                x:226, 
                y:190, 
                fixed:1, 
                index:0, 
                weight:1, 
            }, 
    target: {
                id:2, 
                name: "B",
                type:"node", 
                x:910, 
                y:85, 
                fixed:1, 
                index:1, 
                weight:1, 
            }, 
    line:[{x:387, y:69}, {x:541.5, y:179}, {x:696, y:179}]
}

オン ティックイベント ハンドラーでは、参照d.source.x 、d.source.yおよびd.target.x、 d.target を使用して、ノードAおよびBの現在のx 座標y座標を取得しています。 y . また、ノード A ( d.lineの最初の要素) とノード B ( d.lineの最後の要素) の初期位置もあります。私がやろうとしているのは、ノードABの位置に加えられた変更に基づいて、最初と最後のポイントの間のポイントを再計算することです。

これが私のon tickイベントハンドラーです:

force.on("tick", function() {
svg.selectAll("g.node").attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
    svg.selectAll("g.link .line").attr("d", function(d) { 
         var xOffset = 0, // Want to calculate this 
             yOffset = 0; // Want to calculate this
         var line = [ ];
         for (var i=0; i<d.line.length; i++) {
             if (i==0) {
                  line[line.length] = { x : d.source.x, y: d.source.y }
             }
             else if (i==d.line.length-1) {
                  line[line.length] =  { x : d.target.x, y: d.target.y }
             }
             else {
                  line[line.length] = { x: d.line[i].x + xOffset, y: d.line[i].y + yOffset }
             }
         }
         return self.lineGenerator(line);
     })
 });    

パスの中央にある点のx 座標y座標をオフセットしないと、ノード A または B がドラッグされたときにこれらの点が静的なままになります。ノードがドラッグされたときにパスが正しく移動/回転するように、xOffsetyOffsetを計算する方法を説明できる人はいますか? または、誰かが D3.js でこれを達成するためのより良い (「より簡単な」!) 方法を知っている場合は、私に知らせてください。

アップデート:

チャートコンストラクターのラインジェネレーターコードは次のとおりです。

this.lineGenerator = d3.svg.line() .x(function(d) { return dx; }) .y(function(d) { return dy; }) .interpolate("cardinal");

いくつかの画像で問題を説明させてください。うまくいけば、私が抱えている問題がより明確になります。線が直線であるという問題ではありません。私の線は線ジェネレーターによって湾曲していますが、ノードをドラッグするときに曲線もドラッグしたいのです。したがって、ノードの位置に加えられた変更を反映するために、線上のすべてのポイントを更新する必要があります。つまり、移動するノードによってパスが歪んではなりません。

だから、写真で。この状況を考えると:

ここに画像の説明を入力

ノード B を左下にドラッグすると、次のようになります。

ここに画像の説明を入力

(なお、これは画像編集ソフトで回転させたので、背景も回転しています)

代わりに、次のようなものを取得しています。

ここに画像の説明を入力

ノード B が移動されたときに、線の 1 つの中間点が静的なままであり、曲線が歪んでいることに注意してください。これは私が起こらないようにしようとしていることです。

うまくいけば、これで問題がより明確になります。

4

0 に答える 0