36

次のコードを検討してください。

var svg = d3.select('#somediv').append("svg").attr("width", w).attr("height", h);

このコードを次のようにリファクタリングしたいと思います。

var svg = makesvg(w, h);
d3.select("#somediv").append(svg);

最初のバージョンで示した状況とは対照的に、この 2 番目のバージョンでは「svg」オブジェクトappend を作成しないことに注意してください。に追加するだけd3.select("#somediv")です。

問題は、関数をどのように実装するかmakesvgです。appendこれは、次のようなことを行うことができるため、これを行うことなく「svg」オブジェクトをインスタンス化する方法という問題に帰着します。

function makesvg(width, height) {
  return _makesvg().attr("width", w).attr("height", h);
}

私の質問は、_makesvg()上記の架空の工場に相当する一般的なものは何ですか?

4

6 に答える 6

31

以下を使用できます。

var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');

の使用に注意してくださいcreateElementNS。これが必要なのは、svg要素がほとんどの HTML 要素と同じ XHTML 名前空間にないためです。

このコードは、svgD3 を使用するかどうかに関係なく、新しい要素を作成し、その単一の要素に対して選択を作成します。

これは、次のように、わずかに簡潔にすることができますが、より明確になり、エラーが発生しにくくなります。

var svg = document.createElementNS(d3.ns.prefix.svg, 'svg');
于 2013-11-13T10:21:22.797 に答える
24

少し時間を節約するために、d3.ns.prefix.svgを使用できます。

var svg = document.createElementNS(d3.ns.prefix.svg, 'svg');
于 2014-01-13T21:18:10.367 に答える
8

添付されていないグループ要素を作成する関数の例を次に示します。

function createSomething(){
  return function(){
    var group = d3.select(document.createElementNS(d3.ns.prefix.svg, 'g'));
    // Add stuff...
    return group.node();
  }
}

次のように呼び出すことができます。

node.append(createSomething());

説明

折りたたみ可能なツリーをレンダリングしていて、トグルとして円形の境界線を持つプラス/マイナスのアイコンが必要だとしましょう。描画関数はすでに巨大であるため、独自の関数でプラス記号を描画するためのコードが必要です。draw/update メソッドが適切な配置を処理します。

1 つのオプションは、既存のコンテナーを関数に渡すことです。

createPlus(node).attr({
  x: 10,
  y: 10
});

function createPlus(node){
  var group = node.append('g');
  // Add stuff...
  return group;
}

@Drew と @Paul の手法を適用して、添付されていない要素を作成することで、これを改善できます。

node.append(createPlus())
    .attr({
      x: 10,
      y: 10
    });

function createPlus(){
  var group = d3.select(document.createElementNS(d3.ns.prefix.svg, 'g'));
  // Add stuff...
  return group;
}

append()ただし、文字列または関数のいずれかが必要なため、エラーがスローされます。

名前は、定数文字列として、または追加する DOM 要素を返す関数として指定できます。

したがって、次のように変更します。

node.append(function(){
  return createPlus();
});

しかし、それでもうまくいきません。次のエラーが発生します。

TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.

幸いなことに、selection.node()どちらが機能するかを見つけました!確かに、私には理由がわかりません。

function createPlus(){
  var group = d3.select(document.createElementNS(d3.ns.prefix.svg, 'g'));
  // Add stuff...
  return group.node();
}

createPlus匿名関数を次のように移動することで、もう少し時間を節約できます。

node.append(createPlus())

function createPlus(){
  return function(){
    var group = d3.select(document.createElementNS(d3.ns.prefix.svg, 'g'));
    // Add stuff...
    return group.node();
  }
}
于 2015-05-29T20:09:05.253 に答える