2017-04-25 12 views
0

d3.jsを多く使用しており、最近linearScale関数について考えています。呼び出し可能メソッドを使用してオブジェクトを作成する方法ですが、関数のように呼び出すこともできます

それはあなたがこれを行うことができます:私の知る限り

var x = d3.scaleLinear() 
    .domain([10, 130]) 
    .range([0, 960]); 

x(20); // 80 
x(50); // 320 

を:

  • xはd3.scaleLinear(の戻り値を保持している)
  • Xオブジェクトに似ていますなぜなら、xは 'x(20)'のように呼び出すことができ、戻り値を得ることができるからです。

d3の実装方法に関する詳細な情報は必要ありません.d3はこれを実現するためのAPIの最初の例です。

私はjavascriptで同様のものを実装することに興味があり、最も簡単な形式で必要なデザインパターンを知りたいと思います。

私はd3のソースコードを見てみましたが、余分な機能がたくさんあり、複数のファイルに分割されています。特に私が探しているものを見つけるのは難しいそれが何であるかは分かりません。どんな助けでも大歓迎です。

+1

のようなチャートを呼び出すことができます:いいえ。 'x'は実際に' .range'が返したものです。 – Cerbrus

+0

@Cerbrus私は.domainと.rangeメソッドをどちらの順序でも連鎖できるので、.rangeは 'this'を返します。 – Martha

+1

[JavaScriptクロージャ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures)をご覧ください。 –

答えて

2

最初に注意しなければならないのは、JavaScript関数では、プロパティが付加されたオブジェクトだけであることです。これらのプロパティには他の関数を含めることができます。

基本的にscaleLinear()は、APIオブジェクトとしても使用される関数を返します。

APIオブジェクト/関数に付随する関数は、カプセル化クロージャによって作成された内部状態を取得または設定するために使用されます。

APIオブジェクト/関数に添付された関数は、通常、呼び出しの連鎖を可能にするAPIインスタンスを返します。

次の例は、このようなことがどのように展開されるのかを明らかにしてくれることを願っています。

function Greet() { 
 
    var person = ''; 
 
    var message = 'Hello'; 
 

 
    var api = function() { 
 
    console.log(message + ' ' + person); 
 
    return api; 
 
    }; 
 

 
    api.person = function (value) { 
 
    // if nothing is passed into function act as getter 
 
    if (!arguments.length) return person; 
 
    // otherwise set the value 
 
    person = value; 
 
    // return the api function for more chaining or calling 
 
    return api; 
 
    }; 
 

 
    api.message = function (value) { 
 
    if (!arguments.length) return message; 
 
    message = value; 
 
    return api; 
 
    }; 
 

 
    return api; 
 
} 
 
    
 
var greeter = Greet().person('Daniel'); 
 

 
greeter(); // 'Hello Daniel' 
 

 
greeter.message('Whaddup').person('Martha')(); // 'Whaddup Martha'

私はマイク・ボストック(D3の作成者が)彼は細部のかなりのビットでこのパターンを対象とブログ記事を書いたことを思い出し:https://bost.ocks.org/mike/chart/

0

私が見つけましたthis tutorial非常に実用的

私はこのアプローチのための何らかの種類の定型文を持っています

function getChart(params) { 
 
    // exposed variables 
 
    var attrs = { 
 
     svgWidth: 400, 
 
     svgHeight: 400, 
 
     marginTop: 5, 
 
     marginBottom: 5, 
 
     marginRight: 5, 
 
     marginLeft: 5, 
 
     data: null 
 
    }; 
 

 

 
    /*############### IF EXISTS OVERWRITE ATTRIBUTES FROM PASSED PARAM ####### */ 
 

 
    var attrKeys = Object.keys(attrs); 
 
    attrKeys.forEach(function (key) { 
 
     if (params && params[key]) { 
 
      attrs[key] = params[key]; 
 
     } 
 
    }) 
 

 

 
    //innerFunctions 
 
    var updateData; 
 

 

 
    //main chart object 
 
    var chart = function (selection) { 
 
     selection.each(function() { 
 

 
      //calculated properties 
 
      var calc = {} 
 

 
      calc.chartLeftMargin = attrs.marginLeft; 
 
      calc.chartTopMargin = attrs.marginTop; 
 

 
      calc.chartWidth = attrs.svgWidth - attrs.marginRight - calc.chartLeftMargin; 
 
      calc.chartHeight = attrs.svgHeight - attrs.marginBottom - calc.chartTopMargin; 
 

 
      //drawing 
 
      var svg = d3.select(this) 
 
       .append('svg') 
 
       .attr('width', attrs.svgWidth) 
 
       .attr('height', attrs.svgHeight) 
 
      // .attr("viewBox", "0 0 " + attrs.svgWidth + " " + attrs.svgHeight) 
 
      // .attr("preserveAspectRatio", "xMidYMid meet") 
 

 

 
      var chart = svg.append('g') 
 
       .attr('width', calc.chartWidth) 
 
       .attr('height', calc.chartHeight) 
 
       .attr('transform', 'translate(' + (calc.chartLeftMargin) + ',' + calc.chartTopMargin + ')') 
 

 

 

 

 

 
      // smoothly handle data updating 
 
      updateData = function() { 
 

 

 
      } 
 

 

 
     }); 
 
    } 
 

 

 
    //exposed variable funcs 
 
    chart.data = function (value) { 
 
     if (!arguments.length) return attrs.data; 
 
     attrs.data = value; 
 
     if (typeof updateData === 'function') { 
 
      updateData(); 
 
     } 
 
     return chart; 
 
    } 
 

 
    chart.width = function (value) { 
 
     if (!arguments.length) return attrs.svgWidth; 
 
     attrs.svgWidth = value; 
 
     return chart; 
 
    } 
 

 
    chart.height = function (value) { 
 
     if (!arguments.length) return attrs.svgHeight; 
 
     attrs.svgHeight = value; 
 
     return chart; 
 
    } 
 

 

 
    return chart; 
 
}

次に、あなたは_ ")xはd3.scaleLinear(の戻り値を保持している" _その

関連する問題