0

データベースからデータを取得する raphael を使用して、ワークフローをグラフィカルに視覚化するモジュールを作成しています。このために、「FlowEdit」というクラスを作成し、ラファエルに従って移動、上、ドラッグ機能を作成しました。

しかし、移動関数では、オブジェクト参照を使用して接続リストにアクセスしようとすると、参照できないため、未定義のエラーが発生します。

クラスのコードは次のとおりです:-

        //class definition
        function FlowView(list) {
        this.list = list;
        this.connections = [];
        this.r = Raphael("holder", 1400, 500);
        this.shapes = [];
        this.texts = [];
        this.y_center = 500 / 2;
        //box size
        this.r_width = 60;
        this.r_height = 40;
        // To define virtual regions
        this.x_offset = 50;
        this.y_offset = 40;
        this.x_start = 40;
        //this.color, this.tempS, this.tempT;
        //Define position in y direction
        this.top_count = [0];
        this.bottom_count = [0];
        //Initialize Top_count & Bottom_Count Arrays
        for (var i = 0; i < this.list.length; i++) {
            this.top_count.push(0);
            this.bottom_count.push(0);
        }
    }
    ;

    // Give starting points from list
    FlowView.prototype.start_point = function () {
        var start_list = [];
        for (var i in this.list) {
            if (this.list[i][1] == this.list[i][2][0]) {
                start_list.push(this.list[i][1]);
            }
        }
        return start_list;
    };

    //For Finding index of an element in list
    FlowView.prototype.index_of = function (curr_point) {
        for (var i in this.list) {
            if (this.list[i][1] == curr_point) {
                return i;
            }
        }
    };

    //add next function
    FlowView.prototype.add_next = function () {
        for (var i in this.list) {
            if (this.list[i][3][0] == "NULL") {
                //For all last nodes add same to their next
                this.list[i][3][0] = this.list[i][1];
            }
            if (this.list[i][3].length == 0) {
                //For all last nodes add same to their next
                this.list[i][3].push(this.list[i][1]);
            }
        }
    };

    //For given next of all nodes add previous to those nodes
    FlowView.prototype.add_previous = function () {
        for (var i in this.list) {
            for (var j in this.list[i][3]) {
                //For all next add current node to their previous list
                var curr_index = this.index_of(this.list[i][3][j]);
                if (this.list[curr_index][2].indexOf(this.list[i][1]) == -1 && (curr_index != i)) {
                    this.list[curr_index][2].push(this.list[i][1]);
                }
            }
        }
        //Add previous of all start node
        for (var i in this.list) {
            if (this.list[i][2].length == 0) {
                this.list[i][2].push(this.list[i][1]);
            }
        }
    };


    //Region update recursively
    FlowView.prototype.region_update = function (curr_index) {
        if (this.list[curr_index][1] != this.list[curr_index][3][0]) {
            for (var i in this.list[curr_index][3]) {
                var next_index = this.index_of(this.list[curr_index][3][i]);
                if (this.list[next_index][0] < this.list[curr_index][0] + 1) {
                    this.list[next_index][0] = this.list[curr_index][0] + 1;
                    this.region_update(next_index);
                }
            }
        }
    };

    //Draw the workflow for given data structure
    FlowView.prototype.construct = function () {
        var open = this.start_point();
        var close = [];

        while (open.length != 0) {
            var curr_point = open.shift();
            var curr_index = this.index_of(curr_point);
            //document.write(curr_index);
            //draw box
            var curr_region = this.list[curr_index][0];
            //document.write(curr_region);
            var x_cord = parseInt(curr_region) * (this.x_offset + this.r_width) + this.x_start;
            //document.write(x_start);
            var y_cord = 0;

            if (this.top_count[curr_region] == 0 && this.bottom_count[curr_region] == 0) {
                y_cord = this.y_center - this.r_height / 2;
                this.top_count[curr_region] = 1;
                this.bottom_count[curr_region] = 1;
            }
            else if (this.top_count[curr_region] <= this.bottom_count[curr_region]) {
                y_cord = this.y_center - this.r_height / 2 - this.top_count[curr_region] * (this.y_offset + this.r_height);
                this.top_count[curr_region] = this.top_count[curr_region] + 1;
            }
            else {
                y_cord = this.y_center + this.r_height / 2 + this.bottom_count[curr_region] * (this.y_offset + this.r_height) - this.r_height;
                this.bottom_count[curr_region] = this.bottom_count[curr_region] + 1;
            }

            //drawing the box
            this.shapes[this.list[curr_index][1]] = this.r.rect(x_cord, y_cord, this.r_width, this.r_height, 10);
            this.texts[this.list[curr_index][1]] = this.r.text(x_cord + this.r_width / 2, y_cord + this.r_height / 2, this.list[curr_index][1]);
            // Adding next nodes to open list
            for (var i in this.list[curr_index][3]) {
                //If not in open than add to open
                if (this.list[curr_index][3][0] != this.list[curr_index][1]) {
                    if (open.indexOf(this.list[curr_index][3][i]) == -1 && close.indexOf(this.list[curr_index][3][i]) == -1) {
                        open.push(this.list[curr_index][3][i]);
                    }
                }
            }
            //Increasing region index for each next node
            this.region_update(curr_index);
            close.push(curr_point);
            //document.write(open.toString()+"</br>");
            //document.write(close.toString()+"</br>");
        }
        for (var j in this.list) {
            if (this.list[j][1] != this.list[j][3][0]) {
                for (var i in this.list[j][3]) {
                    //make link for each previous
                    if (close.indexOf(this.list[j][3][i]) != -1) {
                                 this.connections.push(this.r.connection(this.shapes[this.list[j][1]], this.shapes[this.list[j][3][i]], "bcd"));
                    }
                }
            }
        }
    };

    FlowView.prototype.dragger = function () {
        // Original cords for main element
        this.ox = this.type == "ellipse" ? this.attr("cx") : this.attr("x");
        this.oy = this.type == "ellipse" ? this.attr("cy") : this.attr("y");
        if (this.type != "text") this.animate({"fill-opacity":.2}, 500);

        // Original co-ords for pair element
        this.pair.ox = this.pair.type == "ellipse" ? this.pair.attr("cx") : this.pair.attr("x");
        this.pair.oy = this.pair.type == "ellipse" ? this.pair.attr("cy") : this.pair.attr("y");
        if (this.pair.type != "text") this.pair.animate({"fill-opacity":.2}, 500);
    };

    FlowView.prototype.move = function (dx, dy) {
        // Move main element
        var att = this.type == "ellipse" ? {cx:this.ox + dx, cy:this.oy + dy} :
        {x:this.ox + dx, y:this.oy + dy};
        this.attr(att);
        // Move paired element
        att = this.pair.type == "ellipse" ? {cx:this.pair.ox + dx, cy:this.pair.oy + dy} :
        {x:this.pair.ox + dx, y:this.pair.oy + dy};
        this.pair.attr(att);
        //document.write("adass");
        //document.write(x_offset);
        // Move connections
        for (var i = this.connections.length; i--;) {
             this.r.connection(this.connections[i]);
        }
        this.r.safari();
    };


    FlowView.prototype.up = function () {
        // Fade original element on mouse up
        if (this.type != "text") this.animate({"fill-opacity":0}, 500);

        // Fade paired element on mouse up
        if (this.pair.type != "text") this.pair.animate({"fill-opacity":0}, 500);
        // Move connections
    };


    FlowView.prototype.drag_initialize = function () {

        for (var i in this.shapes) {
            var color = Raphael.getColor();
            var tempS = this.shapes[i].attr({fill:color, stroke:color, "fill-opacity":0, "stroke-width":2, cursor:"move"});
            var tempT = this.texts[i].attr({fill:color, stroke:"none", "font-size":15, cursor:"move"});
            this.shapes[i].drag(this.move, this.dragger, this.up);
            this.texts[i].drag(this.move, this.dragger, this.up);

            // Associate the elements
            tempS.pair = tempT;
            tempT.pair = tempS;
        }
    };

上記のコードを使用すると、グラフを描画してアイテムをドラッグできますが、アイテムをドラッグすると、接続されたパスがそれに沿ってドラッグされません。接続を作成するために、ラファエルのデモで指定されたのと同じコードを使用しました..

4

2 に答える 2

0

これはよくある煩わしさですが、幸いなことに、非常に簡単な解決策があります。

問題: Raphael は指定された関数 (this.move、this.dragger、および this.up) を使用していますが、オブジェクトのコンテキストで呼び出していません。したがって、オブジェクトを参照する代わりに、この変数は実際にはウィンドウを参照しています。決定的に役に立ちません。

解決策: 関数クロージャーを使用して、オブジェクト インスタンスへの参照をバインドします。これで drag_initialize 関数を更新します。

var self = this;
this.shapes[i].drag(function(){ self.move(); }, function() { self.dragger(); }, function() { self.up(); } );
this.texts[i].drag(function() { self.move(); }, function() { self.dragger(); }, function() { self.up(); } );
于 2012-06-20T16:41:10.740 に答える
0

こんにちは、問題の答えを見つけました。移動関数で別の関数を返し、ドラッグを呼び出している間、移動関数でオブジェクト引数を指定するため、現在のオブジェクトのコンテキストが渡されます。変更された移動機能は次のとおりです:-

    FlowView.prototype.move = function (obj) {

        // Move main element
        return function(dx, dy){
            var att = this.type == "ellipse" ? {cx:this.ox + dx, cy:this.oy + dy} :
            {x:this.ox + dx, y:this.oy + dy};
            this.attr(att);
            // Move paired element
            att = this.pair.type == "ellipse" ? {cx:this.pair.ox + dx, cy:this.pair.oy + dy} :
            {x:this.pair.ox + dx, y:this.pair.oy + dy};
            this.pair.attr(att);
            // Move connections
            for (var i = obj.connections.length; i--;) {
                obj.r.connection(obj.connections[i]);
            }
            obj.r.safari();
        }
    };

そしてドラッグを呼び出す

    this.shapes[i].drag(this.move(this), this.dragger, this.up);
    this.texts[i].drag(this.move(this), this.dragger, this.up);
于 2012-06-21T11:37:47.050 に答える