我正在创建一个模块,使用raphael以图形方式显示工作流,这些数据从数据库中获取数据。为此,我创建了一个名为“FlowEdit”的类,并根据raphael创建了移动,向上和拖动功能。
但是在移动功能中,当我尝试使用对象引用访问连接列表时,我无法引用它,它会给出未定义的错误。
班级代码如下: -
//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;
}
};
使用上面的代码,我能够绘制图形&amp;拖动项目,但是当我拖动项目时,连接的路径不会沿着它拖动。所以我在做错了。为了建立连接,我使用了与raphael演示相同的代码。
答案 0 :(得分: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(); } );
答案 1 :(得分:0)
您好我找到了问题的答案。 在移动函数中,我返回另一个函数,在调用drag时,我在move函数中给出了object参数,因此传递了当前对象的上下文。现在改变移动功能是: -
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);