1

私は多くのプロジェクトで D3 視覚化ライブラリを使用しており、プロジェクトごとに大量のボイラープレート コードをコピー アンド ペーストしていることに気づきました。たとえば、ほとんどのプロジェクトは次のように始まります。

var margin = {top: 20, right: 10, bottom: 30, left: 60},
    width = 960,
    height = 500;

var svg = d3.select(container_id).append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom);

この種のコードの後、すべてのプロジェクトは分岐します。D3 の利点の 1 つは、新しいプロジェクトごとに専門的で創造的なコーディングを行うことです。

ボイラープレート コードの軽量ラッパーを作成して、毎回楽しい部分にスキップできるようにしたいのですが、そうするうちに、複雑で再利用可能な Javascript オブジェクトを適切に作成する方法がよくわからないことに気付きました。これが私が始めたものです:

var d3mill = function() {
    var margin = {top: 20, right: 10, bottom: 30, left: 60},
        width = 960,
        height = 500;

    var svg = d3.select(container_id).append("svg")
       .attr("width", width + margin.left + margin.right)
       .attr("height", height + margin.top + margin.bottom);

    return {
        svg: function() { return svg; },
        call: function(f) { f(); }
    };
};

私はこれができるようになりたいと思います:

 var d3m = d3mill();
 var test = function() {
     console.log(svg);
 };
 d3.call(test);

関数を渡すと、インスタンスcall()のクロージャ内で関数が起動し、定義されると思いました。d3millsvg

svg()上記の関数のように、クロージャ内のすべての変数を外部に公開するのは、非常に時間の無駄です。外部関数がここで動作することを許可する正しい方法は何ですか?

4

3 に答える 3

0

以下は、テスト内で必要な変数へのアクセスも提供します。

var d3mill = function() {
    this.margin = {top: 20, right: 10, bottom: 30, left: 60},
        width = 960,
        height = 500;

    this.svg = d3.select(container_id).append("svg")
       .attr("width", width + margin.left + margin.right)
       .attr("height", height + margin.top + margin.bottom);

};


var d3m = new d3mill();
var test = function() {
  console.log(this.svg);
};
test.call(d3m);
于 2013-06-06T22:03:54.323 に答える
0

コンストラクタ関数として使用することもできます。

var D3Mill = (function() {
    var defaults = {
        margin: { top: 20, right: 10, bottom: 30, left: 60 },
        width: 960,
        height: 500
    };

    function num(i, def) {
        return ("number" === typeof i) ? i : def;
    }

    function D3Mill(container_id, opts) {
        opts = opts || {};
        // Use opts.xxx or default.xxx if no opts provided
        // Expose all values as this.xxx
        var margin = this.margin = (opts.margin || defaults.margin);
        var width  = this.width  = num(opts.width,  defaults.width);
        var height = this.height = num(opts.height, defaults.height);
        this.svg = d3.select(container_id).append("svg")
           .attr("width", width + margin.left + margin.right)
           .attr("height", height + margin.top + margin.bottom);
    }

    D3Mill.prototype.perform = function(f) { return f.call(this); };

    return D3Mill;
}());

var d3m = new D3Mill("my_container_id");
// or
var opts = {
    width: 1,
    height: 1,
    margin: { ... }
};
var d3m = new D3Mill("my_container_id", opts);

var test = function() {
    console.log(this.svg, this.margin, this.width, this.height);
};
d3m.perform(test);
于 2013-06-06T21:58:27.753 に答える