9

次のような力のレイアウトグラフにノードを追加しています。

var node = vis.selectAll("circle.node")
    .data(nodes)
    .enter()
    .append("circle")
    .attr("class", "node")
    .attr("cx", function(d) { return d.x; })
    .attr("cy", function(d) { return d.y; })
    .attr("r", 5)
    .style("fill", function(d) { return fill(d.group); })
    .call(force.drag);

複合SVG要素をノードとして追加する方法はありますか?つまり、各円にハイパーリンクを追加したいので、次のようなものが必要になります。

<a href="whatever.com"><circle ...></circle></a>

4

2 に答える 2

33

「複合」要素の作成は、1つ以上の子を別の要素に追加するのと同じくらい簡単です。あなたの例では、データを選択した<a>要素にバインドし、それぞれ<a>に1<circle>つの子を与えます。

まず、の"a.node"代わりにを選択する必要があります"circle.node"。これは、ハイパーリンクが親要素になるためです。明らかな親要素がなく、データムごとに複数の要素を追加するだけの場合は<g>、SVGのグループ要素を使用します。

次に、<a>入力する選択範囲の各ノードに1つの要素を追加します。これにより、ハイパーリンクが作成されます。<circle>各ハイパーリンクの属性を設定した後、それに子を与えたいと思います。シンプル:を呼び出すだけ.append("circle")です。

var node = vis.selectAll("a.node")
    .data(nodes);

// The entering selection: create the new <a> elements here.
// These elements are automatically part of the update selection in "node".
var nodeEnter = node.enter().append("a")
    .attr("class", "node")
    .attr("xlink:href", "http://whatever.com")
    .call(force.drag);

// Appends a new <circle> element to each element in nodeEnter.
nodeEnter.append("circle")
    .attr("r", 5)
    .style("fill", function(d) { return fill(d.group); })

node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });

D3は主にノードの選択で動作することを忘れないでください。したがって.append()、入力する選択範囲を呼び出すことは、選択範囲内の各ノードが新しい子を取得することを意味します。強力なもの!

もう1つ、SVGには独自の<a>要素があります。これは私が上で言及したものです。これはHTMLのものとは異なります!通常、SVG要素はSVGでのみ使用し、HTMLはHTMLで使用します。

変数の命名を明確にすることを提案してくれた@mbostockに感謝します。

于 2012-02-11T11:34:22.590 に答える
11

Jason Daviesへの返信(stackoverflowは返信コメントの長さを制限するため…):すばらしい答えです。ただし、メソッドの連鎖には注意してください。通常node、内側の円要素ではなく、外側のアンカー要素を参照する必要があります。だから私は小さなバリエーションをお勧めします:

var node = vis.selectAll("a.node")
    .data(nodes)
  .enter().append("a")
    .attr("class", "node")
    .attr("xlink:href", "http://whatever.com")
    .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
    .call(force.drag);

node.append("circle")
    .attr("r", 5)
    .style("fill", function(d) { return fill(d.group); });

また、円のcx属性とcy属性を、含まれているアンカー要素の変換に置き換えました。どちらでも動作します。svg:a要素をsvg:g(どちらもコンテナー)として扱うことができます。これは、後でラベルを追加する場合に便利です。

于 2012-02-11T16:28:12.890 に答える