この例の 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の最後の要素) の初期位置もあります。私がやろうとしているのは、ノードAとBの位置に加えられた変更に基づいて、最初と最後のポイントの間のポイントを再計算することです。
これが私の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 がドラッグされたときにこれらの点が静的なままになります。ノードがドラッグされたときにパスが正しく移動/回転するように、xOffsetとyOffsetを計算する方法を説明できる人はいますか? または、誰かが D3.js でこれを達成するためのより良い (「より簡単な」!) 方法を知っている場合は、私に知らせてください。
アップデート:
チャートコンストラクターのラインジェネレーターコードは次のとおりです。
this.lineGenerator = d3.svg.line() .x(function(d) { return dx; }) .y(function(d) { return dy; }) .interpolate("cardinal");
いくつかの画像で問題を説明させてください。うまくいけば、私が抱えている問題がより明確になります。線が直線であるという問題ではありません。私の線は線ジェネレーターによって湾曲していますが、ノードをドラッグするときに曲線もドラッグしたいのです。したがって、ノードの位置に加えられた変更を反映するために、線上のすべてのポイントを更新する必要があります。つまり、移動するノードによってパスが歪んではなりません。
だから、写真で。この状況を考えると:
ノード B を左下にドラッグすると、次のようになります。
(なお、これは画像編集ソフトで回転させたので、背景も回転しています)
代わりに、次のようなものを取得しています。
ノード B が移動されたときに、線の 1 つの中間点が静的なままであり、曲線が歪んでいることに注意してください。これは私が起こらないようにしようとしていることです。
うまくいけば、これで問題がより明確になります。