2017-08-14 9 views
2

私は再利用可能なグラフに選択肢を渡し、d3.select('#id')の選択肢を渡すと値を返し、d3.selectAll('.class')の選択肢が渡された場合は値の配列を返します。私は現在、渡された引数をcontext._groups[0] instanceof NodeListと尋ねていますが、ドキュメント化されていないプロパティを使うと少し壊れているようです。選択肢がselectまたはselectAllから来るかどうかを判断する方法がありますか?d3.selectかd3.selectAllをチェックする

selection.size()は、選択の結果だけを示しています。どのように呼び出されたかはわかりません。

EDIT: ここでは、使用のコンテキストを示します。私はMike Bostockのreusable chart patternを使用しています。このインスタンスには、ドーナツのラベルを取得/設定するメソッドが含まれています。

このAPIの使用方法はprinciple of least astonishmentに従っています。結果は返されます。

var donut = APP.rotatingDonut(); 

// set label for one element 
d3.select('#donut1.donut') 
    .call(donut.label, 'Donut 1') 

d3.select('#donut2.donut') 
    .call(donut.label, 'Donut 2') 

// set label for multiple elements 
d3.selectAll('.donut.group-1') 
    .call(donut.label, 'Group 1 Donuts') 


// get label for one donut 
var donutOneLabel = d3.select('#donut1').call(donut.label) 
// donutOnelabel === 'Donut 1' 

// get label for multiple donuts 
var donutLables = d3.selectAll('.donut').call(donut.label) 
// donutLabels === ['Donut 1', 'Donut 2', 'Group 1 Donuts', 'Group 1 Donuts'] 

と内部メソッドの定義:

App.rotatingDonut = function() { 

    var label = d3.local(); 

    function donut() {} 

    donut.label = function(context, value) { 
    var returnArray; 
    var isList = context._groups[0] instanceof NodeList; 

    if (typeof value === 'undefined') { 

     // getter 
     returnArray = context.nodes() 
      .map(function (node) {return label.get(node);}); 

     return isList ? returnArray : returnArray[0]; 
    } 

    // settter 
    context.each(function() {label.set(this, value);}); 

    // allows method chaining 
    return donut; 
    }; 

    return donut 
} 
+0

とても面白くて面白い質問です。私はあなたが期待する答えではない答えを書いた。他の誰かが私を間違っていると証明したら、私はそれを喜んで削除します。 –

+0

ちょうど好奇心:*なぜ*あなたはこれをやっていますか?メソッドの型を知らせるだけで、関数に第2引数を渡すのはなぜですか?確かに、これは[XY問題]の強い候補です(https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) –

+0

私は完全に与えるために私のポストを更新しましたコンテキスト。ここでの目標は、このgetter/setterメソッドを実装する "最もd3のような"方法を見つけることです。 「最良の」答えは、その方法の1つについて同じことをするd3の例です。 –

答えて

2

さて、ここでS.O.で時々質問単純に答えがありません(それはhappened beforeを持っています)。

これはあなたの質問の場合のようです:"選択がselectまたはselectAllから来るかどうかを判断する方法は、より豊富に用意されていますか?"。おそらくいいえ。

ことを証明するために、のは、d3.selectd3.selectAllのソースコードを見てみましょう(重要:それらが互いに非常に異なっているではないselection.selectselection.selectAllを、あります)。

まず、d3.select:今

export default function(selector) { 
    return typeof selector === "string" 
     ? new Selection([[document.querySelector(selector)]], [document.documentElement]) 
     : new Selection([[selector]], root); 
} 

d3.selectAll

  1. d3.selectAllnullを受け入れる:あなたが見ることができるように

    export default function(selector) { 
        return typeof selector === "string" 
         ? new Selection([document.querySelectorAll(selector)], [document.documentElement]) 
         : new Selection([selector == null ? [] : selector], root); 
    } 
    

    、我々はここだけ違いがあります。それはあなたを助けません。

  2. d3.selectAllquerySelectorAllを使用し、d3.selectquerySelectorを使用します。あなたがquerySelectorAll以来、今では知っているように、第2の違いは、あなたに合っただけのものであること

は、深さ優先プリオーダートラバーサルを使用して(文書内の要素のリストを返します。指定されたセレクタのグループに一致するドキュメントのノードの名前。返されるオブジェクトは、NodeListです。(強調鉱山)

そして唯一querySelector ...:

は、指定されたセレクタ、またはセレクタのグループに一致する文書内の最初の要素を返します。

したがって、あなたが今使っているselection._groups[0] instanceof NodeList(あなたは良いアイデアではありませんこれは、_groupsを使用しているため、とハック)文書化されていないが作成した選択からd3.selectによって作成された選択を伝えるための唯一の方法であると思われますd3.selectAll

関連する問題