Difference between revisions of "Template:Team:Groningen/JAVASCRIPTS/DependencyGraph"

(Created page with " Mainclass DependencyGraph: var DependencyGraph = function () { this.isLocked = false; this.stage = null; this.scene = null; this.label = null; this.roots = [];...")
 
m (test type)
Line 233: Line 233:
 
// 1 make nodes/popups 2 arrange 4 check success 5 make edges
 
// 1 make nodes/popups 2 arrange 4 check success 5 make edges
 
DependencyGraph.prototype.handleFileComplete = function (event) {
 
DependencyGraph.prototype.handleFileComplete = function (event) {
 +
console.log(event.item, event.item.type);
 
   var rawGraph = event.result;
 
   var rawGraph = event.result;
 
var popups = new createjs.Container();
 
var popups = new createjs.Container();

Revision as of 13:19, 8 November 2015

/*Mainclass DependencyGraph*/ var DependencyGraph = function () { this.isLocked = false; this.stage = null; this.scene = null;

   this.label = null;

this.roots = [];

   this.nodeMap = {};
   this.categoryMap = null;
   this.urlDomain = null;
   
   this.dx = 58;
   this.dy = 86;

};

DependencyGraph.prototype = { constructor: DependencyGraph, };

DependencyGraph.Cross = function () {

   var n = new createjs.Shape();
   n.graphics.setStrokeStyle(9, "square");
   n.graphics.beginStroke("#A83838");
   n.graphics.moveTo(0, -1.5 * 9);
   n.graphics.lineTo(0, 1.5 * 9);
   n.graphics.moveTo(-1.5 * 9, 0);
   n.graphics.lineTo(1.5 * 9, 0);
   n.rotation = 45;
   return n;

};

DependencyGraph.Cross.prototype = { constructor: DependencyGraph.Cross, };

DependencyGraph.Checkmark = function () {

   var n = new createjs.Shape();
   var rotxy = 0.5 * 9;
   n.graphics.setStrokeStyle(9, "square");
   n.graphics.beginStroke("#A29D52");
   n.graphics.moveTo(rotxy, rotxy + -1.5 * 9);
   n.graphics.lineTo(rotxy, rotxy);
   n.graphics.lineTo(rotxy + -2.5 * 9, rotxy);
   n.rotation = 45;
   return n;

};

DependencyGraph.Checkmark.prototype = { constructor: DependencyGraph.Checkmark, };

/*Subclass Edge*/ DependencyGraph.Edge = function (from, to, dx, dy) {

   var successColor = "#686868";
   var failColor = "#424242";
   var fromn = from.node;
   var ton = to.node;
   var edge = new createjs.Shape();
   var yoffset = (fromn.y - ton.y) * 2 / 3;
   edge.graphics.setStrokeStyle(9, "square");

edge.graphics.beginStroke(to.success ? successColor : failColor); edge.graphics.moveTo(fromn.x, fromn.y); edge.graphics.lineTo(fromn.x, fromn.y - yoffset); edge.graphics.lineTo(ton.x, fromn.y - yoffset); edge.graphics.lineTo(ton.x, ton.y);

return edge; };

DependencyGraph.Edge.prototype = { constructor: DependencyGraph.Edge, };

DependencyGraph.Node = function (popup, ctx) {

   var node = new createjs.Shape();
   node.graphics.beginFill("#2B2B2B").drawRect(-31/2, -31/2, 31, 31);
   node.setBounds(-31/2, -31/2, 31, 31);
   var show = function (event, popup) {
       popup.visible = true;
       if (this.popup != null && this.popup != popup) {
           this.popup.visible = false;
       };
       this.popup = popup;
   };
   node.on("mouseover", show, ctx, false, popup);
   popup.on("mouseover", show, ctx, false, popup);
   return node;

};

DependencyGraph.Node.prototype = { constructor: DependencyGraph.Node, };

DependencyGraph.NodePopup = function (date, title, link) {

   var container = new createjs.Container();
   var textColor = "#707070";
   var highlightColor = "#BABABA";
   var backgroundColor = "#333333";


   var xoffset = -58/2;
   var yoffset = -58/2;
   var name = new createjs.Text();

name.text = title; name.font = "normal 21px Arial"; name.color = textColor; name.x = 78 + xoffset; name.y = 24 + yoffset;

   var namew = name.getMeasuredWidth();
   var nameh = name.getMeasuredHeight();
   var hit = new createjs.Shape();
   hit.graphics.beginFill(backgroundColor).drawRect(0, 0, namew, nameh);
   name.hitArea = hit;
   var changeColor = function (event, color) {
       name.color = color;
   };
   name.on("mouseover", changeColor, null, false, highlightColor);
   name.on("mouseout", changeColor, null, false, textColor);
   name.on("click", function (event, link) {
       window.location.href = link;
   }, null, false, link);
   var cdate = new createjs.Text();

cdate.text = date; cdate.font = "normal 10px Arial"; cdate.color = textColor; cdate.x = 78 + xoffset; cdate.y = 12.2 + yoffset;

   var background = new createjs.Shape();

var w = Math.max(cdate.getMeasuredWidth(), namew) + 78 + 20;

   var h = 58;

background.graphics.beginFill(backgroundColor); background.graphics.drawRect(xoffset, yoffset, w, h); background.graphics.beginFill(highlightColor); background.graphics.drawRect(xoffset, yoffset, h, h);

   background.on("mouseout", function (event, item) {
       item.visible = false;
   }, null, false, container);
   container.addChild(background, cdate, name);
   container.visible = false;
   container.setBounds(0, 0, 0, 0);
   return container;

};

DependencyGraph.NodePopup.prototype = { constructor: DependencyGraph.NodePopup, };

DependencyGraph.RootNode = function (category, popup, ctx) {

   var container = new createjs.Container();
   
   var catLabel = new createjs.Text();
   catLabel.text = category;
   catLabel.font = "normal 21px Arial";
   catLabel.color = "#707070";
   catLabel.textAlign = "center";
   catLabel.textBaseline = "bottom";
   catLabel.rotation = 90;
   catLabel.x = -catLabel.getMeasuredHeight()/2;
   catLabel.y = -catLabel.getMeasuredWidth()/2 - 20 - 31/2;
   container.addChild(catLabel);
   
   var rootNode = new DependencyGraph.Node(popup, ctx);
   container.addChild(rootNode);
   return container;

};


DependencyGraph.RootNode.prototype = { constructor: DependencyGraph.RootNode, };

/*DependencyGraph Methods*/ DependencyGraph.prototype.Setup = function (settings) { if(this.isLocked) { return; } this.isLocked = true;

this.categoryMap = settings.categorymap; this.urlDomain = settings.urldomain;

this.stage = new createjs.Stage(settings.canvasid);

   this.stage.enableMouseOver();

this.scene = new createjs.Container();

var width = this.stage.canvas.width; var height = this.stage.canvas.height;

var dragBox = new createjs.Shape();

   dragBox.graphics.beginFill(settings.bgcolor).drawRect(0, 0, width, height);
   this.stage.addChild(dragBox);

this.stage.addChild(this.scene);

   var offset = new createjs.Point(0, 0);

var ondrag = function(event) {

   	offset.x = event.stageX - this.scene.x;
   	offset.y = event.stageY - this.scene.y;

};

   var drag = function (event) {
       this.scene.x = event.stageX - offset.x;
       this.scene.y = event.stageY - offset.y;
   };

dragBox.on("mousedown", ondrag.bind(this), offset); dragBox.on("pressmove", drag.bind(this), offset); this.scene.on("mousedown", ondrag.bind(this), offset); this.scene.on("pressmove", drag.bind(this), offset);

createjs.Ticker.addEventListener("tick", function (event) { this.stage.update() }.bind(this));

var preload = new createjs.LoadQueue(); preload.addEventListener("fileload", this.handleFileComplete.bind(this)); preload.loadFile(settings.data); };

// 1 make nodes/popups 2 arrange 4 check success 5 make edges DependencyGraph.prototype.handleFileComplete = function (event) { console.log(event.item, event.item.type);

  	var rawGraph = event.result;

var popups = new createjs.Container();

   var ctx = {popup: null};
   var nodes = new createjs.Container();


/*prepare nodes*/ for (var i = rawGraph.length - 1; i >= 0; i--) { var rawNode = rawGraph[i]; rawNode.id = rawNode.category+rawNode.number;

var date = rawNode.date; var title = rawNode.title; var link = this.urlDomain + rawNode.title.replace(/ /g,"_")+"_"+rawNode.id; var popup = new DependencyGraph.NodePopup(date, title, link); popups.addChild(popup);

var category = this.categoryMap ? this.categoryMap[rawNode.category] : rawNode.category;

var node = null; if (rawNode.isroot) { node = new DependencyGraph.RootNode(category, popup, ctx); this.roots.push(rawNode); } else { node = new DependencyGraph.Node(popup, ctx); } nodes.addChild(node);

rawNode.node = node;

       rawNode.popup = popup;
       rawNode.isLeaf = false;
       rawNode.success = false;

this.nodeMap[rawNode.id] = rawNode; };

   this.propagateSuccess(this.roots, this.nodeMap);

this.ArrangeNodes();

/*prepare edges*/

   var successEdges = new createjs.Container();
   var failEdges = new createjs.Container();

for (var i in this.nodeMap) { var node = this.nodeMap[i];

if (node.next == null) { continue; }

for (var j = node.next.length - 1; j >= 0; j--) { var nodeChild = this.nodeMap[node.next[j]]; var edge = new DependencyGraph.Edge(node, nodeChild, this.dx, this.dy);

           if (nodeChild.success) {
               successEdges.addChild(edge);
           } else {
               failEdges.addChild(edge);
           };

}; };

   /* prepare ends */
   var ends = new createjs.Container();
   for (var i in this.nodeMap) {
       var node = this.nodeMap[i];
       if (node.isLeaf) {
           var x = node.node.x;
           var y = node.node.y;
           var success = node.success;
           var tmp1 = {node: {x: x, y: y}};
           var tmp2 = {node: {x: x, y: y + this.dy / 2}, success: success};
           var edge = new DependencyGraph.Edge(tmp1, tmp2, this.dx, this.dy);
           var end;
           if (success) {
               end = new DependencyGraph.Checkmark();
           } else {
               end = new DependencyGraph.Cross();
           };
           end.x = x;
           end.y = y + this.dy / 2;
           ends.addChild(edge, end);
       };
   };

this.scene.addChild(failEdges, successEdges, ends, nodes, popups);

   var half = this.stage.canvas.width / 2;
   var cbounds = this.scene.getBounds();
   this.scene.x = half - Math.abs(cbounds.x + cbounds.width / 2);
   this.scene.y = -cbounds.y + 20;

};

DependencyGraph.prototype.propagateSuccess = function (roots, map) {

   for (var i = roots.length - 1; i >= 0; i--) {
       this.propagateSuccessRec(roots[i], map);
   };

}

DependencyGraph.prototype.propagateSuccessRec = function (node, map) {

   var success = false;
   if (node.isVisited) {
       return node.success;
   };
   node.isVisited = true;
   if (node.next != null) {
       if (node.next.length == 0) {
           success = true;
           node.isLeaf = true;
       } else {
           for (var i = node.next.length - 1; i >= 0; i--) {
               var child = this.nodeMap[node.next[i]]
   		    success = this.propagateSuccessRec(child, map) || success;
           };
       };
   } else {
       node.isLeaf = true;
   };
   node.success = success
   return success;

};

DependencyGraph.prototype.ArrangeNodes = function () { var xo = this.stage.canvas.width/2-260;

       for (var i in this.nodeMap) {
           var node = this.nodeMap[i];

node.isVisited = false; }

this.CountNodesHelper(this.roots);

       for (var i in this.nodeMap) {
           var node = this.nodeMap[i];

node.isVisited = false; }

this.ArrangeNodesHelper(this.roots,1,xo,4);

};

DependencyGraph.prototype.ArrangeNodesHelper = function (nodes,d,xo,fac) { var left = []; var right = [];

/*sort on success left and fail right*/ for (var i = nodes.length - 1; i >= 0; i--) { var node = nodes[i]; if (node.isVisited) { continue; } node.node.y = d*this.dy;

       node.popup.y = node.node.y;

if (node.success) { left.push(node); } else { right.push(node); } };

/* pop a left element from stack unless in a right branch. and repeat precedure on origin node*/ var origin = left.length ? left.pop() : right.pop(); if(!origin) { return; }

   var next = [];
   if (origin.next != null) {
       for (var i = origin.next.length - 1; i >= 0; i--) {
           next.push(this.nodeMap[origin.next[i]]);
       };
   };

this.ArrangeNodesHelper(next,d+1,xo,0); /*pass left and right tree count to parent call*/ this.ArrangeNodesHelper(right,d,xo+origin.fac*this.dx,origin.nodeDiv.nR); this.ArrangeNodesHelper(left,d,xo-this.dx*origin.nodeDiv.nL,0);

origin.node.x = xo;

   origin.popup.x = xo;

origin.isVisited = true; };


DependencyGraph.prototype.CountNodesHelper = function (nodes) { var sum = function(o1) { return o1.nL+o1.nM+o1.nR; } var left = []; var right = [];

/*sort on success left and fail right*/ for (var i = nodes.length - 1; i >= 0; i--) { var node = nodes[i]; if (node.isVisited) { continue; } if (node.success) { left.push(node); } else { right.push(node); } };

/* pop a left element from stack unless in a right branche. and repeat precedure on origin node*/ var origin = left.length ? left.pop() : right.pop(); if(!origin) { return { nL:0, nM:1, nR:0 }; }

   var next = [];
   if (origin.next != null) {
       for (var i = origin.next.length - 1; i >= 0; i--) {
           next.push(this.nodeMap[origin.next[i]]);
       };
   };
   var nMiddel = this.CountNodesHelper(next);

/*pass left and right tree count to parent call*/ var nRight; if (right.length != 0) { nRight = this.CountNodesHelper(right); } else { nRight = { nL:0, nM:0, nR:0 } }

var nLeft; if (left.length != 0) { nLeft = this.CountNodesHelper(left); } else { nLeft = { nL:0, nM:0, nR:0 } };


origin.isVisited = true; origin.nodeDiv = { nL:sum(nLeft)+nMiddel.nL, nM:1, nR:sum(nRight)+nMiddel.nR } origin.fac = origin.nodeDiv.nR - nRight.nR return origin.nodeDiv; };