<commit_before>/**
 *
 * check of bank and card
 *
 *
 *
 * 20150617
 */

function Log(msg){
	msg = msg || 'empty';
	if(envirment=="production"){

	} else {
		console.log(msg);
	}

}

(function($, undefined){
	//生产类
	var Pub = function(el, op){
		this.$el = $(el);

		this.boxFlag = 0;//标志卡号合法之后，下面层出现与否
		this.iFlag = 1;//标志所有数据合法时，提交按钮提交次数
		this.nameInput = this.$el.find('[node-type="LoanNameInput"]');
		this.cardInput = this.$el.find('[node-type="LoanCardInput"]');
		this.submitBtn = this.$el.find('[node-type="LoanSubmitBtn"]');
		this.bankCardIcon = this.$el.find('[node-type="LoanBankCardIcon"]');
		this.idCardInput = this.$el.find('[node-type="LoanIdCardInput"]');
		this.mobileIcon = this.$el.find('[node-type="LoanMobileIcon"]');
		this.mobileInput = this.$el.find('[node-type="LoanMobileInput"]');
		this.agreement = $("#agreement-btn");
		this.agreeClose = $("#close10");
		this.agree= $("#agreement");
		this.imbox = $("#imbox");
		this.bankName = $("#bank_name");
		this.mask = $("#masker");
		this.iconOption = $(".icon-option");
		this._addEvents();
	}

	Pub.prototype = {
		//所有事件绑定
		_addEvents : function(){
			var sthis=this;
			/*协议弹框高度初始化*/
			var wheight = $(window).height();
					wwidth = $(window).width();
					agreeList = $("#agree_list");

				/*sthis.agree.css("left",-wwidth);*/
				agreeList.height(wheight/6*4);
				sthis.agree.css("top",wheight/8);

			/*判断信息完整*/
			this.$el.find("input").on("input", function(){
				var _this = this;
				/*Log('AAA');*/
				setTimeout(function(){
					sthis._fnComplete();
					var Id = $(_this).attr("id");
					if(Id=="ID_card"){
						var idCard_val = $(_this).val();
						_this.value = sthis._fnIdentity(idCard_val);
					}
				},500)
			})

			/*卡号输入判断*/
			this.cardInput.on("keyup", function(){
				var card_id=this.value;
				this.value=sthis._fnCard(card_id);
			})
			/*身份证号输入判断*/
			this.idCardInput.on("keyup", function(){
				var idCard_val = this.value;
				this.value = sthis._fnIdentity(idCard_val);
				if(this.value==0){
					$(this).siblings().hide();
				}else{
					$(this).siblings().show();
				}
			})
			/*icon单机操作*/
			this.$el.find(".icon-option").on("click", function(){
				var icon_this=this;
				sthis._fnIcon(icon_this);
			})

			/*失去焦点隐藏icon*/
			this.$el.find("input").on("focus", function(){
				sthis.iconOption.hide();
				if(this.id=="ID_card"){
					if(this.value.length > 1){
						$(this).siblings().show();
					}
				}else{
					$(this).siblings().show();
				}
			})
			/*手机号输入判断*/
			this.mobileInput.on("keyup",function(){
				var mobile_val = this.value;
				this.value = sthis._fnModile(mobile_val);
			})

			/*提交按钮*/
			this.submitBtn.on("click",function(){

				var zCard = $("#bank_card").val();
				var zIdCard = $("#ID_card").val();
				var zMobile = $("#mobile").val();
				var zName = $("#name").val();
				sthis._fnSubmit(zCard,zIdCard,zMobile,zName);

			})
			/*协议*/
			this.agreement.on("click",function(){

				sthis._fnGetAgree();
				sthis.mask.show();
				sthis.agree.show();
				sthis.agree.css("left",0);
			})

			this.agreeClose.on("click",function(){
				sthis.mask.hide();
				sthis.agree.hide();
			})

		},
		//卡号处理
		_fnCard : function(card_id){
			card_id = card_id.replace(/\D/g,'').replace(/....(?!$)/g,'$& ');
			var b_len = card_id.length,
				bRIcon = $("#bRIcon");
			if(b_len==0){
				bRIcon.addClass("active").show().siblings().hide();
				this.imbox.hide();
				this.bankName.hide();
			}else if(b_len==1){
				bRIcon.removeClass("active").hide().siblings().show().removeClass("active");
			}else if(b_len==18){

			}else if(b_len==19){
				var bank_type=TOOLS.isBank(card_id.replace(/\s+/g,""));
				if(bank_type){
					this.boxFlag=1;
					this.imbox.show();
				}
			}else if(b_len<12){
				this.imbox.hide();
				this.boxFlag=0;
				this.bankName.hide();
			}else if(b_len>=12){
				var bank_type=TOOLS.isBank(card_id.replace(/\s+/g,""));
				if(bank_type){
					this.bankName.find("span").removeClass();
					this.bankName.find("span").addClass("bankName "+bank_type);
					this.bankName.show();

				}
			}
			return card_id;
		},
		//身份证处理
		_fnIdentity : function(idCard_val){
			idCard_val=idCard_val.replace(/[^\d|xX]/g,"");
			return idCard_val;
		},
		//手机号验证
		_fnModile : function(mobile_val){
			mobile_val = mobile_val.replace(/\D/g,'');
			var m_len = mobile_val.length;
				mRIcon = $("#mRIcon");

			if(m_len==0){
				mRIcon.addClass("active").show().siblings().hide();
			}else if(m_len==1){
				mRIcon.removeClass("active").hide().siblings().show().removeClass("active");
			}

			return mobile_val;
		},
		//表单处理
		_fnComplete : function(){
			var ipt=this.$el.find("input"),
				next=$("#next2"),
				ipt_flag=1,
				ipt_len=4;

			if(this.boxFlag==0){
				ipt_len=2;
			}
			for(var i=0; i<ipt_len; i++){
				if(ipt[i].value.length == 0){
					ipt_flag=0;
				}
			}
			if(ipt_flag==1){
				next.removeAttr("disabled");
			}else{
				next.attr("disabled","disabled");
			}
		},
		//icon处理
		_fnIcon : function(icon_this){
			var intype = $(icon_this).attr("node-type");
			var inIs = $(icon_this).find("i");
			var inIsD = $(inIs[0]).css("display");
			var next=$("#next2");
			if(inIs.hasClass("icons-infoNew active")){
				if(inIs.is(".icons-infoNew") && intype=="bank_card"){
					MessageBox.alert({type:"message",txt:CS.ERRORMSG["EFFECTIVEBANK"]});
				}else{
					MessageBox.alert({type:"message",txt:CS.ERRORMSG["AVAILABLEPHONENUMBER"]});
				}
			}else{
				if(inIs.is(".icons-infoNew")){
					$('#'+intype).val("");
					$(inIs[0]).addClass("active").show();
					$(inIs[1]).hide();
					if(intype=="bank_card"){
						this.imbox.hide();
						this.bankName.hide();
						this.idCardInput.val("");
						this.mobileInput.val("");
					}
					next.attr("disabled","disabled");
				}else{
					$('#'+intype).val("");
					$(inIs[0]).parent().hide();
					next.attr("disabled","disabled");
				}
			}
		},

		/*获取协议*/
		_fnGetAgree : function(){
			var now = new Date();
				year = now.getFullYear();
				month = now.getMonth()+1;
				day = now.getDate();
				name = $("#name").val();
				id_card = $("#ID_card").val();
				bank_card = $("#bank_card").val();
			$("#year").html(year);
			$("#year1").html(year);
			$("#month").html(month);
			$("#month1").html(month);
			$("#day").html(day);
			$("#day1").html(day);
			$("#c_id").html(id_card);
			$("#c_bid").html(bank_card);
			$("#c_name").html(name);
		},

		//提交按钮处理
		_fnSubmit : function(zCard,zIdCard,zMobile,zName){
			var zCard_len = zCard.length,
				age = TOOLS.isIdentity(zIdCard),
				phone = TOOLS.isMobile(zMobile),
				bcflag = TOOLS.isCard(zCard.replace(/\s+/g,"")),
				bcflag2 = TOOLS.isBank(zCard.replace(/\s+/g,"")),
				zzCard = zCard.replace(/\s+/g,""),
				smBtn = $("#next2"),
				cbank_name,
				bank_index = -1,
				bankListE = ["IBCB","ABC","CCB","CMB","BOC","PSBC","COMM","CITIC","CMBC","CEB","CIB","SPDB","GDB","HXBANK","SPABANK","BJBANK","BJRCB","SHBANK","JSBANK"],
				bankListC = ["中国工商银行","中国农业银行","中国建设银行","招商银行","中国银行","中国邮政储蓄银行","交通银行","中信银行","中国民生银行","中国光大银行","兴业银行","浦发银行","广发银行","华夏银行","平安银行","北京银行","北京农商银行","上海银行","江苏银行"];

				if(bcflag2){
					for(var i=0;i<bankListE.length;i++){
						if(bcflag2 == bankListE[i]){bank_index = i;}
					}
					cbank_name = bankListC[bank_index];
				}

			if(this.boxFlag){
				if(zCard_len != 19 && zCard_len == 23 || zCard_len != 23 && zCard_len == 19){
					if(bcflag){
						if(age){
							if(age>30 || age<16){
								MessageBox.alert({type:"common",txt:CS.ERRORMSG["AGENOTRANGEERROR"]});
							}else{
								if(phone){
									/*提交*/
									if(smBtn.hasClass("disabled")) return false;
									smBtn.addClass('disabled');
									TOOLS.ajax({
										url:"./index.php?r=loan/verify",
										data:{name:zName,bank_card:zzCard,id_card:zIdCard,mobile:zMobile,bank_name:cbank_name},
										dataType:"json",
										type:"post",
										fnSuccess:function(data){
											if(data.stat == "1"){
												window.location.href= "./index.php?r=loan/sms&mobile="+data.mobile;
											}else if(data.stat == "2"){
												if(data.verify_times == "2"){
													MessageBox.alert({type:"message",txt:CS.ERRORMSG["TWOCHANCE"],cls:true});
													smBtn.removeClass("disabled");
												}else if(data.verify_times == "1"){
													MessageBox.alert({type:"message",txt:CS.ERRORMSG["ONECHANCE"],cls:true});
													smBtn.removeClass("disabled");
												}else if(data.verify_times <= "0"){
													window.location.href= "./index.php?r=loan/failed";
												}
											}else{
												MessageBox.alert({type:"message","系统错误，请稍后重试！"});
												smBtn.removeClass("disabled");
											}

										},
										fnError:function(){}
									});

								}else{
									MessageBox.alert({type:"common",txt:CS.ERRORMSG["MOBILEERROR"]});
								}
							}
						}else{
							MessageBox.alert({type:"common",txt:CS.ERRORMSG["IDENTITYERROR"]});
						}
					}else{
						MessageBox.alert({type:"common",txt:CS.ERRORMSG["BANKCARDERROR"]});
					}

				}else{
					MessageBox.alert({type:"common",txt:CS.ERRORMSG["BANKCARDERROR"]});
				}
			}else{
				if(zCard_len != 19 && zCard_len == 23 || zCard_len != 23 && zCard_len == 19){
					if(bcflag){
						if(bcflag2){
						}else{
							MessageBox.alert({type:"common",txt:CS.ERRORMSG["NOBANKERROR"]});
						}
					}else{
						MessageBox.alert({type:"common",txt:CS.ERRORMSG["BANKCARDERROR"]});
					}
				}else{
					MessageBox.alert({type:"common",txt:CS.ERRORMSG["BANKCARDERROR"]});
				}
			}

		}
	}

	$.fn.PUB = function(options){
		return this.each(function(){
			var $this = $(this) ,
				data = $this.data('PUB');

	          if (!data) {
	        	  $this.data('PUB', (data = new Pub(this, options)))
	          }

	          if (typeof options == 'string') data[options](setData);
		});
	}
})(window.jQuery||window.Zepto)
<commit_msg>update<commit_after>/**
 *
 * check of bank and card
 *
 *
 *
 * 20150617
 */

function Log(msg){
	msg = msg || 'empty';
	if(envirment=="production"){

	} else {
		console.log(msg);
	}

}

(function($, undefined){
	//生产类
	var Pub = function(el, op){
		this.$el = $(el);

		this.boxFlag = 0;//标志卡号合法之后，下面层出现与否
		this.iFlag = 1;//标志所有数据合法时，提交按钮提交次数
		this.nameInput = this.$el.find('[node-type="LoanNameInput"]');
		this.cardInput = this.$el.find('[node-type="LoanCardInput"]');
		this.submitBtn = this.$el.find('[node-type="LoanSubmitBtn"]');
		this.bankCardIcon = this.$el.find('[node-type="LoanBankCardIcon"]');
		this.idCardInput = this.$el.find('[node-type="LoanIdCardInput"]');
		this.mobileIcon = this.$el.find('[node-type="LoanMobileIcon"]');
		this.mobileInput = this.$el.find('[node-type="LoanMobileInput"]');
		this.agreement = $("#agreement-btn");
		this.agreeClose = $("#close10");
		this.agree= $("#agreement");
		this.imbox = $("#imbox");
		this.bankName = $("#bank_name");
		this.mask = $("#masker");
		this.iconOption = $(".icon-option");
		this._addEvents();
	}

	Pub.prototype = {
		//所有事件绑定
		_addEvents : function(){
			var sthis=this;
			/*协议弹框高度初始化*/
			var wheight = $(window).height();
					wwidth = $(window).width();
					agreeList = $("#agree_list");

				/*sthis.agree.css("left",-wwidth);*/
				agreeList.height(wheight/6*4);
				sthis.agree.css("top",wheight/8);

			/*判断信息完整*/
			this.$el.find("input").on("input", function(){
				var _this = this;
				/*Log('AAA');*/
				setTimeout(function(){
					sthis._fnComplete();
					var Id = $(_this).attr("id");
					if(Id=="ID_card"){
						var idCard_val = $(_this).val();
						_this.value = sthis._fnIdentity(idCard_val);
					}
				},500)
			})

			/*卡号输入判断*/
			this.cardInput.on("keyup", function(){
				var card_id=this.value;
				this.value=sthis._fnCard(card_id);
			})
			/*身份证号输入判断*/
			this.idCardInput.on("keyup", function(){
				var idCard_val = this.value;
				this.value = sthis._fnIdentity(idCard_val);
				if(this.value==0){
					$(this).siblings().hide();
				}else{
					$(this).siblings().show();
				}
			})
			/*icon单机操作*/
			this.$el.find(".icon-option").on("click", function(){
				var icon_this=this;
				sthis._fnIcon(icon_this);
			})

			/*失去焦点隐藏icon*/
			this.$el.find("input").on("focus", function(){
				sthis.iconOption.hide();
				if(this.id=="ID_card"){
					if(this.value.length > 1){
						$(this).siblings().show();
					}
				}else{
					$(this).siblings().show();
				}
			})
			/*手机号输入判断*/
			this.mobileInput.on("keyup",function(){
				var mobile_val = this.value;
				this.value = sthis._fnModile(mobile_val);
			})

			/*提交按钮*/
			this.submitBtn.on("click",function(){

				var zCard = $("#bank_card").val();
				var zIdCard = $("#ID_card").val();
				var zMobile = $("#mobile").val();
				var zName = $("#name").val();
				sthis._fnSubmit(zCard,zIdCard,zMobile,zName);

			})
			/*协议*/
			this.agreement.on("click",function(){

				sthis._fnGetAgree();
				sthis.mask.show();
				sthis.agree.show();
				sthis.agree.css("left",0);
			})

			this.agreeClose.on("click",function(){
				sthis.mask.hide();
				sthis.agree.hide();
			})

		},
		//卡号处理
		_fnCard : function(card_id){
			card_id = card_id.replace(/\D/g,'').replace(/....(?!$)/g,'$& ');
			var b_len = card_id.length,
				bRIcon = $("#bRIcon");
			if(b_len==0){
				bRIcon.addClass("active").show().siblings().hide();
				this.imbox.hide();
				this.bankName.hide();
			}else if(b_len==1){
				bRIcon.removeClass("active").hide().siblings().show().removeClass("active");
			}else if(b_len==18){

			}else if(b_len==19){
				var bank_type=TOOLS.isBank(card_id.replace(/\s+/g,""));
				if(bank_type){
					this.boxFlag=1;
					this.imbox.show();
				}
			}else if(b_len<12){
				this.imbox.hide();
				this.boxFlag=0;
				this.bankName.hide();
			}else if(b_len>=12){
				var bank_type=TOOLS.isBank(card_id.replace(/\s+/g,""));
				if(bank_type){
					this.bankName.find("span").removeClass();
					this.bankName.find("span").addClass("bankName "+bank_type);
					this.bankName.show();

				}
			}
			return card_id;
		},
		//身份证处理
		_fnIdentity : function(idCard_val){
			idCard_val=idCard_val.replace(/[^\d|xX]/g,"");
			return idCard_val;
		},
		//手机号验证
		_fnModile : function(mobile_val){
			mobile_val = mobile_val.replace(/\D/g,'');
			var m_len = mobile_val.length;
				mRIcon = $("#mRIcon");

			if(m_len==0){
				mRIcon.addClass("active").show().siblings().hide();
			}else if(m_len==1){
				mRIcon.removeClass("active").hide().siblings().show().removeClass("active");
			}

			return mobile_val;
		},
		//表单处理
		_fnComplete : function(){
			var ipt=this.$el.find("input"),
				next=$("#next2"),
				ipt_flag=1,
				ipt_len=4;

			if(this.boxFlag==0){
				ipt_len=2;
			}
			for(var i=0; i<ipt_len; i++){
				if(ipt[i].value.length == 0){
					ipt_flag=0;
				}
			}
			if(ipt_flag==1){
				next.removeAttr("disabled");
			}else{
				next.attr("disabled","disabled");
			}
		},
		//icon处理
		_fnIcon : function(icon_this){
			var intype = $(icon_this).attr("node-type");
			var inIs = $(icon_this).find("i");
			var inIsD = $(inIs[0]).css("display");
			var next=$("#next2");
			if(inIs.hasClass("icons-infoNew active")){
				if(inIs.is(".icons-infoNew") && intype=="bank_card"){
					MessageBox.alert({type:"message",txt:CS.ERRORMSG["EFFECTIVEBANK"]});
				}else{
					MessageBox.alert({type:"message",txt:CS.ERRORMSG["AVAILABLEPHONENUMBER"]});
				}
			}else{
				if(inIs.is(".icons-infoNew")){
					$('#'+intype).val("");
					$(inIs[0]).addClass("active").show();
					$(inIs[1]).hide();
					if(intype=="bank_card"){
						this.imbox.hide();
						this.bankName.hide();
						this.idCardInput.val("");
						this.mobileInput.val("");
					}
					next.attr("disabled","disabled");
				}else{
					$('#'+intype).val("");
					$(inIs[0]).parent().hide();
					next.attr("disabled","disabled");
				}
			}
		},

		/*获取协议*/
		_fnGetAgree : function(){
			var now = new Date();
				year = now.getFullYear();
				month = now.getMonth()+1;
				day = now.getDate();
				name = $("#name").val();
				id_card = $("#ID_card").val();
				bank_card = $("#bank_card").val();
			$("#year").html(year);
			$("#year1").html(year);
			$("#month").html(month);
			$("#month1").html(month);
			$("#day").html(day);
			$("#day1").html(day);
			$("#c_id").html(id_card);
			$("#c_bid").html(bank_card);
			$("#c_name").html(name);
		},

		//提交按钮处理
		_fnSubmit : function(zCard,zIdCard,zMobile,zName){
			var zCard_len = zCard.length,
				age = TOOLS.isIdentity(zIdCard),
				phone = TOOLS.isMobile(zMobile),
				bcflag = TOOLS.isCard(zCard.replace(/\s+/g,"")),
				bcflag2 = TOOLS.isBank(zCard.replace(/\s+/g,"")),
				zzCard = zCard.replace(/\s+/g,""),
				smBtn = $("#next2"),
				cbank_name,
				bank_index = -1,
				bankListE = ["IBCB","ABC","CCB","CMB","BOC","PSBC","COMM","CITIC","CMBC","CEB","CIB","SPDB","GDB","HXBANK","SPABANK","BJBANK","BJRCB","SHBANK","JSBANK"],
				bankListC = ["中国工商银行","中国农业银行","中国建设银行","招商银行","中国银行","中国邮政储蓄银行","交通银行","中信银行","中国民生银行","中国光大银行","兴业银行","浦发银行","广发银行","华夏银行","平安银行","北京银行","北京农商银行","上海银行","江苏银行"];

				if(bcflag2){
					for(var i=0;i<bankListE.length;i++){
						if(bcflag2 == bankListE[i]){bank_index = i;}
					}
					cbank_name = bankListC[bank_index];
				}

			if(this.boxFlag){
				if(zCard_len != 19 && zCard_len == 23 || zCard_len != 23 && zCard_len == 19){
					if(bcflag){
						if(age){
							if(age>30 || age<16){
								MessageBox.alert({type:"common",txt:CS.ERRORMSG["AGENOTRANGEERROR"]});
							}else{
								if(phone){
									/*提交*/
									if(smBtn.hasClass("disabled")) return false;
									smBtn.addClass('disabled');
									TOOLS.ajax({
										url:"./index.php?r=loan/verify",
										data:{name:zName,bank_card:zzCard,id_card:zIdCard,mobile:zMobile,bank_name:cbank_name},
										dataType:"json",
										type:"post",
										fnSuccess:function(data){
											if(data.stat == "1"){
												window.location.href= "./index.php?r=loan/sms&mobile="+data.mobile;
											}else if(data.stat == "2"){
												if(data.verify_times == "2"){
													MessageBox.alert({type:"message",txt:CS.ERRORMSG["TWOCHANCE"],cls:true});
													smBtn.removeClass("disabled");
												}else if(data.verify_times == "1"){
													MessageBox.alert({type:"message",txt:CS.ERRORMSG["ONECHANCE"],cls:true});
													smBtn.removeClass("disabled");
												}else if(data.verify_times <= "0"){
													window.location.href= "./index.php?r=loan/failed";
												}
											}else{
												MessageBox.alert({type:"message",txt:"系统错误，请稍后重试！"});
												smBtn.removeClass("disabled");
											}

										},
										fnError:function(){}
									});

								}else{
									MessageBox.alert({type:"common",txt:CS.ERRORMSG["MOBILEERROR"]});
								}
							}
						}else{
							MessageBox.alert({type:"common",txt:CS.ERRORMSG["IDENTITYERROR"]});
						}
					}else{
						MessageBox.alert({type:"common",txt:CS.ERRORMSG["BANKCARDERROR"]});
					}

				}else{
					MessageBox.alert({type:"common",txt:CS.ERRORMSG["BANKCARDERROR"]});
				}
			}else{
				if(zCard_len != 19 && zCard_len == 23 || zCard_len != 23 && zCard_len == 19){
					if(bcflag){
						if(bcflag2){
						}else{
							MessageBox.alert({type:"common",txt:CS.ERRORMSG["NOBANKERROR"]});
						}
					}else{
						MessageBox.alert({type:"common",txt:CS.ERRORMSG["BANKCARDERROR"]});
					}
				}else{
					MessageBox.alert({type:"common",txt:CS.ERRORMSG["BANKCARDERROR"]});
				}
			}

		}
	}

	$.fn.PUB = function(options){
		return this.each(function(){
			var $this = $(this) ,
				data = $this.data('PUB');

	          if (!data) {
	        	  $this.data('PUB', (data = new Pub(this, options)))
	          }

	          if (typeof options == 'string') data[options](setData);
		});
	}
})(window.jQuery||window.Zepto)
<|endoftext|>


<commit_before>;(function($$){ 'use strict';

  var CanvasRenderer = $$('renderer', 'canvas');
  var CRp = CanvasRenderer.prototype;

  // Draw node
  CRp.drawNode = function(context, node, drawOverlayInstead) {

    var r = this;
    var nodeWidth, nodeHeight;
    var style = node._private.style;
    var rs = node._private.rscratch;
    var _p = node._private;

    var usePaths = CanvasRenderer.usePaths();
    var canvasContext = context;
    var path;
    var pathCacheHit = false;

    var overlayPadding = style['overlay-padding'].pxValue;
    var overlayOpacity = style['overlay-opacity'].value;
    var overlayColor = style['overlay-color'].value;

    if( drawOverlayInstead && overlayOpacity === 0 ){ // exit early if drawing overlay but none to draw
      return;
    }

    var parentOpacity = node.effectiveOpacity();
    if( parentOpacity === 0 ){ return; }

    nodeWidth = this.getNodeWidth(node);
    nodeHeight = this.getNodeHeight(node);

    context.lineWidth = style['border-width'].pxValue;

    if( drawOverlayInstead === undefined || !drawOverlayInstead ){

      var url = style['background-image'].value[2] ||
        style['background-image'].value[1];
      var image;

      if (url !== undefined) {

        // get image, and if not loaded then ask to redraw when later loaded
        image = this.getCachedImage(url, function(){
          r.data.canvasNeedsRedraw[CanvasRenderer.NODE] = true;
          r.data.canvasNeedsRedraw[CanvasRenderer.DRAG] = true;

          r.drawingImage = true;

          r.redraw();
        });

        var prevBging = _p.backgrounding;
        _p.backgrounding = !image.complete;

        if( prevBging !== _p.backgrounding ){ // update style b/c :backgrounding state changed
          node.updateStyle( false );
        }
      }

      // Node color & opacity

      var bgColor = style['background-color'].value;
      var borderColor = style['border-color'].value;
      var borderStyle = style['border-style'].value;

      this.fillStyle(context, bgColor[0], bgColor[1], bgColor[2], style['background-opacity'].value * style['opacity'].value * parentOpacity);

      this.strokeStyle(context, borderColor[0], borderColor[1], borderColor[2], style['border-opacity'].value * style['opacity'].value * parentOpacity);

      var shadowBlur = style['shadow-blur'].pxValue;
      var shadowOpacity = style['shadow-opacity'].value;
      var shadowColor = style['shadow-color'].value;
      var shadowOffsetX = style['shadow-offset-x'].pxValue;
      var shadowOffsetY = style['shadow-offset-y'].pxValue;

      this.shadowStyle(context, shadowColor, shadowOpacity, shadowBlur, shadowOffsetX, shadowOffsetY);

      context.lineJoin = 'miter'; // so borders are square with the node shape

      if( context.setLineDash ){ // for very outofdate browsers
        switch( borderStyle ){
          case 'dotted':
            context.setLineDash([ 1, 1 ]);
            break;

          case 'dashed':
            context.setLineDash([ 4, 2 ]);
            break;

          case 'solid':
          case 'double':
            context.setLineDash([ ]);
            break;
        }
      }

      var styleShape = style['shape'].strValue;

      var pos = node._private.position;

      if( usePaths ){
        var pathCacheKey = styleShape + '$' + nodeWidth +'$' + nodeHeight;

        context.translate( pos.x, pos.y );

        if( rs.pathCacheKey === pathCacheKey ){
          path = context = rs.pathCache;
          pathCacheHit = true;
        } else {
          path = context = new Path2D();
          rs.pathCacheKey = pathCacheKey;
          rs.pathCache = path;
        }
      }

      if( !pathCacheHit ){

        var npos = pos;

        if( usePaths ){
          npos = {
            x: 0,
            y: 0
          };
        }

        CanvasRenderer.nodeShapes[this.getNodeShape(node)].drawPath(
              context,
              npos.x,
              npos.y,
              nodeWidth,
              nodeHeight);
      }

      context = canvasContext;

      if( usePaths ){
        context.fill( path );
      } else {
        context.fill();
      }

      this.shadowStyle(context, 'transparent', 0); // reset for next guy

      if (url !== undefined) {
        if( image.complete ){
          this.drawInscribedImage(context, image, node);
        }
      }

      var darkness = style['background-blacken'].value;
      var borderWidth = style['border-width'].pxValue;

      if( this.hasPie(node) ){
        this.drawPie(context, node);

        // redraw path for blacken and border
        if( darkness !== 0 || borderWidth !== 0 ){

          if( !usePaths ){
            CanvasRenderer.nodeShapes[this.getNodeShape(node)].drawPath(
                context,
                pos.x,
                pos.y,
                nodeWidth,
                nodeHeight);
          }
        }
      }

      if( darkness > 0 ){
        this.fillStyle(context, 0, 0, 0, darkness);

        if( usePaths ){
          context.fill( path );
        } else {
          context.fill();
        }

      } else if( darkness < 0 ){
        this.fillStyle(context, 255, 255, 255, -darkness);

        if( usePaths ){
          context.fill( path );
        } else {
          context.fill();
        }
      }

      // Border width, draw border
      if (borderWidth > 0) {

        if( usePaths ){
          context.stroke( path );
        } else {
          context.stroke();
        }

        if( borderStyle === 'double' ){
          context.lineWidth = style['border-width'].pxValue/3;

          var gco = context.globalCompositeOperation;
          context.globalCompositeOperation = 'destination-out';

          if( usePaths ){
            context.stroke( path );
          } else {
            context.stroke();
          }

          context.globalCompositeOperation = gco;
        }

      }

      if( usePaths ){
        context.translate( -pos.x, -pos.y );
      }

      // reset in case we changed the border style
      if( context.setLineDash ){ // for very outofdate browsers
        context.setLineDash([ ]);
      }

    // draw the overlay
    } else {

      if( overlayOpacity > 0 ){
        this.fillStyle(context, overlayColor[0], overlayColor[1], overlayColor[2], overlayOpacity);

        CanvasRenderer.nodeShapes['roundrectangle'].drawPath(
          context,
          node._private.position.x,
          node._private.position.y,
          nodeWidth + overlayPadding * 2,
          nodeHeight + overlayPadding * 2
        );

        context.fill();
      }
    }

  };

  // does the node have at least one pie piece?
  CRp.hasPie = function(node){
    node = node[0]; // ensure ele ref

    return node._private.hasPie;
  };

  CRp.drawPie = function(context, node){
    node = node[0]; // ensure ele ref

    var pieSize = node._private.style['pie-size'];
    var nodeW = this.getNodeWidth( node );
    var nodeH = this.getNodeHeight( node );
    var x = node._private.position.x;
    var y = node._private.position.y;
    var radius = Math.min( nodeW, nodeH ) / 2; // must fit in node
    var lastPercent = 0; // what % to continue drawing pie slices from on [0, 1]
    var usePaths = CanvasRenderer.usePaths();

    if( usePaths ){
      x = 0;
      y = 0;
    }

    if( pieSize.units === '%' ){
      radius = radius * pieSize.value / 100;
    } else if( pieSize.pxValue !== undefined ){
      radius = pieSize.pxValue / 2;
    }

    for( var i = 1; i <= $$.style.pieBackgroundN; i++ ){ // 1..N
      var size = node._private.style['pie-' + i + '-background-size'].value;
      var color = node._private.style['pie-' + i + '-background-color'].value;
      var opacity = node._private.style['pie-' + i + '-background-opacity'].value;
      var percent = size / 100; // map integer range [0, 100] to [0, 1]
      var angleStart = 1.5 * Math.PI + 2 * Math.PI * lastPercent; // start at 12 o'clock and go clockwise
      var angleDelta = 2 * Math.PI * percent;
      var angleEnd = angleStart + angleDelta;

      // ignore if
      // - zero size
      // - we're already beyond the full circle
      // - adding the current slice would go beyond the full circle
      if( size === 0 || lastPercent >= 1 || lastPercent + percent > 1 ){
        continue;
      }

      context.beginPath();
      context.moveTo(x, y);
      context.arc( x, y, radius, angleStart, angleEnd );
      context.closePath();

      this.fillStyle(context, color[0], color[1], color[2], opacity);

      context.fill();

      lastPercent += percent;
    }

  };

})( cytoscape );
<commit_msg> Pie doesn't take into consideration node opacity #1010<commit_after>;(function($$){ 'use strict';

  var CanvasRenderer = $$('renderer', 'canvas');
  var CRp = CanvasRenderer.prototype;

  // Draw node
  CRp.drawNode = function(context, node, drawOverlayInstead) {

    var r = this;
    var nodeWidth, nodeHeight;
    var style = node._private.style;
    var rs = node._private.rscratch;
    var _p = node._private;

    var usePaths = CanvasRenderer.usePaths();
    var canvasContext = context;
    var path;
    var pathCacheHit = false;

    var overlayPadding = style['overlay-padding'].pxValue;
    var overlayOpacity = style['overlay-opacity'].value;
    var overlayColor = style['overlay-color'].value;

    if( drawOverlayInstead && overlayOpacity === 0 ){ // exit early if drawing overlay but none to draw
      return;
    }

    var parentOpacity = node.effectiveOpacity();
    if( parentOpacity === 0 ){ return; }

    nodeWidth = this.getNodeWidth(node);
    nodeHeight = this.getNodeHeight(node);

    context.lineWidth = style['border-width'].pxValue;

    if( drawOverlayInstead === undefined || !drawOverlayInstead ){

      var url = style['background-image'].value[2] ||
        style['background-image'].value[1];
      var image;

      if (url !== undefined) {

        // get image, and if not loaded then ask to redraw when later loaded
        image = this.getCachedImage(url, function(){
          r.data.canvasNeedsRedraw[CanvasRenderer.NODE] = true;
          r.data.canvasNeedsRedraw[CanvasRenderer.DRAG] = true;

          r.drawingImage = true;

          r.redraw();
        });

        var prevBging = _p.backgrounding;
        _p.backgrounding = !image.complete;

        if( prevBging !== _p.backgrounding ){ // update style b/c :backgrounding state changed
          node.updateStyle( false );
        }
      }

      // Node color & opacity

      var bgColor = style['background-color'].value;
      var borderColor = style['border-color'].value;
      var borderStyle = style['border-style'].value;

      this.fillStyle(context, bgColor[0], bgColor[1], bgColor[2], style['background-opacity'].value * parentOpacity);

      this.strokeStyle(context, borderColor[0], borderColor[1], borderColor[2], style['border-opacity'].value * parentOpacity);

      var shadowBlur = style['shadow-blur'].pxValue;
      var shadowOpacity = style['shadow-opacity'].value;
      var shadowColor = style['shadow-color'].value;
      var shadowOffsetX = style['shadow-offset-x'].pxValue;
      var shadowOffsetY = style['shadow-offset-y'].pxValue;

      this.shadowStyle(context, shadowColor, shadowOpacity, shadowBlur, shadowOffsetX, shadowOffsetY);

      context.lineJoin = 'miter'; // so borders are square with the node shape

      if( context.setLineDash ){ // for very outofdate browsers
        switch( borderStyle ){
          case 'dotted':
            context.setLineDash([ 1, 1 ]);
            break;

          case 'dashed':
            context.setLineDash([ 4, 2 ]);
            break;

          case 'solid':
          case 'double':
            context.setLineDash([ ]);
            break;
        }
      }

      var styleShape = style['shape'].strValue;

      var pos = node._private.position;

      if( usePaths ){
        var pathCacheKey = styleShape + '$' + nodeWidth +'$' + nodeHeight;

        context.translate( pos.x, pos.y );

        if( rs.pathCacheKey === pathCacheKey ){
          path = context = rs.pathCache;
          pathCacheHit = true;
        } else {
          path = context = new Path2D();
          rs.pathCacheKey = pathCacheKey;
          rs.pathCache = path;
        }
      }

      if( !pathCacheHit ){

        var npos = pos;

        if( usePaths ){
          npos = {
            x: 0,
            y: 0
          };
        }

        CanvasRenderer.nodeShapes[this.getNodeShape(node)].drawPath(
              context,
              npos.x,
              npos.y,
              nodeWidth,
              nodeHeight);
      }

      context = canvasContext;

      if( usePaths ){
        context.fill( path );
      } else {
        context.fill();
      }

      this.shadowStyle(context, 'transparent', 0); // reset for next guy

      if (url !== undefined) {
        if( image.complete ){
          this.drawInscribedImage(context, image, node);
        }
      }

      var darkness = style['background-blacken'].value;
      var borderWidth = style['border-width'].pxValue;

      if( this.hasPie(node) ){
        this.drawPie( context, node, parentOpacity );

        // redraw path for blacken and border
        if( darkness !== 0 || borderWidth !== 0 ){

          if( !usePaths ){
            CanvasRenderer.nodeShapes[this.getNodeShape(node)].drawPath(
                context,
                pos.x,
                pos.y,
                nodeWidth,
                nodeHeight);
          }
        }
      }

      if( darkness > 0 ){
        this.fillStyle(context, 0, 0, 0, darkness);

        if( usePaths ){
          context.fill( path );
        } else {
          context.fill();
        }

      } else if( darkness < 0 ){
        this.fillStyle(context, 255, 255, 255, -darkness);

        if( usePaths ){
          context.fill( path );
        } else {
          context.fill();
        }
      }

      // Border width, draw border
      if (borderWidth > 0) {

        if( usePaths ){
          context.stroke( path );
        } else {
          context.stroke();
        }

        if( borderStyle === 'double' ){
          context.lineWidth = style['border-width'].pxValue/3;

          var gco = context.globalCompositeOperation;
          context.globalCompositeOperation = 'destination-out';

          if( usePaths ){
            context.stroke( path );
          } else {
            context.stroke();
          }

          context.globalCompositeOperation = gco;
        }

      }

      if( usePaths ){
        context.translate( -pos.x, -pos.y );
      }

      // reset in case we changed the border style
      if( context.setLineDash ){ // for very outofdate browsers
        context.setLineDash([ ]);
      }

    // draw the overlay
    } else {

      if( overlayOpacity > 0 ){
        this.fillStyle(context, overlayColor[0], overlayColor[1], overlayColor[2], overlayOpacity);

        CanvasRenderer.nodeShapes['roundrectangle'].drawPath(
          context,
          node._private.position.x,
          node._private.position.y,
          nodeWidth + overlayPadding * 2,
          nodeHeight + overlayPadding * 2
        );

        context.fill();
      }
    }

  };

  // does the node have at least one pie piece?
  CRp.hasPie = function(node){
    node = node[0]; // ensure ele ref

    return node._private.hasPie;
  };

  CRp.drawPie = function( context, node, nodeOpacity ){
    node = node[0]; // ensure ele ref

    var _p = node._private;
    var style = _p.style;
    var pieSize = style['pie-size'];
    var nodeW = this.getNodeWidth( node );
    var nodeH = this.getNodeHeight( node );
    var x = _p.position.x;
    var y = _p.position.y;
    var radius = Math.min( nodeW, nodeH ) / 2; // must fit in node
    var lastPercent = 0; // what % to continue drawing pie slices from on [0, 1]
    var usePaths = CanvasRenderer.usePaths();

    if( usePaths ){
      x = 0;
      y = 0;
    }

    if( pieSize.units === '%' ){
      radius = radius * pieSize.value / 100;
    } else if( pieSize.pxValue !== undefined ){
      radius = pieSize.pxValue / 2;
    }

    for( var i = 1; i <= $$.style.pieBackgroundN; i++ ){ // 1..N
      var size = style['pie-' + i + '-background-size'].value;
      var color = style['pie-' + i + '-background-color'].value;
      var opacity = style['pie-' + i + '-background-opacity'].value * nodeOpacity;
      var percent = size / 100; // map integer range [0, 100] to [0, 1]
      var angleStart = 1.5 * Math.PI + 2 * Math.PI * lastPercent; // start at 12 o'clock and go clockwise
      var angleDelta = 2 * Math.PI * percent;
      var angleEnd = angleStart + angleDelta;

      // ignore if
      // - zero size
      // - we're already beyond the full circle
      // - adding the current slice would go beyond the full circle
      if( size === 0 || lastPercent >= 1 || lastPercent + percent > 1 ){
        continue;
      }

      context.beginPath();
      context.moveTo(x, y);
      context.arc( x, y, radius, angleStart, angleEnd );
      context.closePath();

      this.fillStyle(context, color[0], color[1], color[2], opacity);

      context.fill();

      lastPercent += percent;
    }

  };

})( cytoscape );
<|endoftext|>


<commit_before>angular.module('S36QuickInboxDirectives', [])
.directive('feedbackout', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind('click', function(e) {
                $('.widget-list input[type=checkbox][name=feedid]:checked').parents('div.widget-item').fadeOut();
            });
        }
    }
})
.directive('punch', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind('click', function(e) {
                console.log("PUNCH");
            })
        }
    }
})
.directive('social', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            attrs.$observe('login', function(at) {
                if(at == 'fb') {
                    scope.socialsrc = " Facebook Verified";
                }
            })
        }
      , template: ''
    }
})
.directive('feedbackdate', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            attrs.$observe('date', function(at) {
                var d = Date.parse(at);
                scope.time = '
' + d.toString('MMMM d, yyyy') + '
' + '
' + d.toString('h:mm:ss tt') + '
';
            })
        }
      , template: ''
    }
})
.directive('infoblock', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            attrs.$observe('load', function(at) {
                var data = angular.fromJson(at);
                if(data.attachments || data.metadata) {
                    $(element).addClass("additional-info");
                }
            })
        }
    }
})
.directive('metadata', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            attrs.$observe('load', function(at) {
                if(at) {
                    var data = angular.fromJson(at);
                    //console.log(data);
                    scope.template = '
';
                    for(var prop in data) {
                        var meta = data[prop];
                        scope.template += '
';
                        for(var pr in meta)  {
                            scope.template += '
';
                            var submeta = meta[pr];
                            //console.log(ucwords(pr.replace(/_/g, " ")));
                            scope.template += ucwords(pr.replace(/_/g, " ")) + ": ";
                            var prefix = "";
                            for(var i=0; i<submeta.length; i++) {
                                //console.log(" -" + submeta[i].value);
                                scope.template += '' + prefix + submeta[i].value + '';
                                prefix = ", ";
                            }
                            scope.template += '
';
                        }
                        scope.template += '
';
                    }
                    scope.template += '
';
                }
            });
        }
      , template: ''
    }
})
.directive('attachments', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            attrs.$observe('load', function(at) {
                if(at) {
                    var data = angular.fromJson(at);
                    //console.log(data);
                    scope.mtemplate = '
';
                    for(var prop in data) {
                        var links = data[prop];

                        //videos
                        if(links.hasOwnProperty('video') && links.video == 'yes') {
                            scope.mtemplate += '
';
                            scope.mtemplate += '

';
                            scope.mtemplate += '

';
                            scope.mtemplate += '
';
                        }

                        //links
                        if(links.hasOwnProperty('video') && links.video == 'no') {
                            scope.mtemplate += '
';
                            scope.mtemplate += '
linky
';
                            scope.mtemplate += '
';
                        }

                        //pics
                        for(var i=0; i<links.length; i++) {
                            /*
                            scope.mtemplate += '
x
';
                            */
                            scope.mtemplate += '
';
                            scope.mtemplate += '
';
                            scope.mtemplate += '
';
                            scope.mtemplate += '
';
                        }

                    }
                    scope.mtemplate += '
';
                }
            });
        }
      , template: ''
    }
})
.directive('openVideo', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind('click', function() {

                var scroll_offset = $(document).scrollTop();
                var top_offset = scroll_offset + 100;
                var embed_url = $(this).attr('link-url').replace('www.youtube.com/watch?v=','www.youtube.com/embed/');
                var html  = '';

                $('.lightbox').fadeIn().css('top', top_offset);
                $('.uploaded-images-content').html(html);
            })
        }
    }
})
.directive('openPic', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            attrs.$observe('load', function(at) {
                $(element).bind('click', function() {
                    var scroll_offset = $(document).scrollTop();
                    var top_offset = scroll_offset + 100;
                    $('.lightbox').fadeIn().css('top', top_offset);
                    var html = '';
                    $('.uploaded-images-content').html(html);
                })
            })
        }
    }
})
.directive('checkfeed', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind('click', function() {
                $("#quickInboxActions").show();
            })
        }
    }
});

//helper functions
function ucwords(str) {
    return (str + '').replace(/^([a-z])|\s+([a-z])/g, function ($1) {
        return $1.toUpperCase();
    });
}
<commit_msg>I saw the internet<commit_after>angular.module('S36QuickInboxDirectives', [])
.directive('feedbackout', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind('click', function(e) {
                $('.widget-list input[type=checkbox][name=feedid]:checked').parents('div.widget-item').fadeOut();
            });
        }
    }
})
.directive('punch', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind('click', function(e) {
                console.log("PUNCH");
            })
        }
    }
})
.directive('social', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            attrs.$observe('login', function(at) {
                if(at == 'fb') {
                    scope.socialsrc = " Facebook Verified";
                }
            })
        }
      , template: ''
    }
})
.directive('feedbackdate', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            attrs.$observe('date', function(at) {
                var d = Date.parse(at);
                scope.time = '
' + d.toString('MMMM d, yyyy') + '
' + '
' + d.toString('h:mm:ss tt') + '
';
            })
        }
      , template: ''
    }
})
.directive('infoblock', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            attrs.$observe('load', function(at) {
                var data = angular.fromJson(at);
                if(data.attachments || data.metadata) {
                    $(element).addClass("additional-info");
                }
            })
        }
    }
})
.directive('metadata', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            attrs.$observe('load', function(at) {
                if(at) {
                    var data = angular.fromJson(at);
                    //console.log(data);
                    scope.template = '
';
                    for(var prop in data) {
                        var meta = data[prop];
                        scope.template += '
';
                        for(var pr in meta)  {
                            scope.template += '
';
                            var submeta = meta[pr];
                            //console.log(ucwords(pr.replace(/_/g, " ")));
                            scope.template += ucwords(pr.replace(/_/g, " ")) + ": ";
                            var prefix = "";
                            for(var i=0; i<submeta.length; i++) {
                                //console.log(" -" + submeta[i].value);
                                scope.template += '' + prefix + submeta[i].value + '';
                                prefix = ", ";
                            }
                            scope.template += '
';
                        }
                        scope.template += '
';
                    }
                    scope.template += '
';
                }
            });
        }
      , template: ''
    }
})
.directive('attachments', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            attrs.$observe('load', function(at) {
                if(at) {
                    var data = angular.fromJson(at);

                    console.log(data);

                    scope.mtemplate = '
';
                    for(var prop in data) {
                        var links = data[prop];

                        //videos
                        if(links.hasOwnProperty('video') && links.video == 'yes') {
                            scope.mtemplate += '
';
                            scope.mtemplate += '

';
                            scope.mtemplate += '

';
                            scope.mtemplate += '
';
                        }

                        //links
                        if(links.hasOwnProperty('video') && links.video == 'no') {
                            scope.mtemplate += '
';
                            scope.mtemplate += '
linky
';
                            scope.mtemplate += '
';
                        }

                        //pics
                        for(var i=0; i<links.length; i++) {
                            /*
                            scope.mtemplate += '
x
';
                            */
                            scope.mtemplate += '
';
                            scope.mtemplate += '
';
                            scope.mtemplate += '
';
                            scope.mtemplate += '
';
                        }

                    }
                    scope.mtemplate += '
';
                }
            });
        }
      , template: ''
    }
})
.directive('openVideo', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind('click', function() {

                var scroll_offset = $(document).scrollTop();
                var top_offset = scroll_offset + 100;
                var embed_url = $(this).attr('link-url').replace('www.youtube.com/watch?v=','www.youtube.com/embed/');
                var html  = '';

                $('.lightbox').fadeIn().css('top', top_offset);
                $('.uploaded-images-content').html(html);
            })
        }
    }
})
.directive('openPic', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            attrs.$observe('load', function(at) {
                $(element).bind('click', function() {
                    var scroll_offset = $(document).scrollTop();
                    var top_offset = scroll_offset + 100;
                    $('.lightbox').fadeIn().css('top', top_offset);
                    var html = '';
                    $('.uploaded-images-content').html(html);
                })
            })
        }
    }
})
.directive('checkfeed', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind('click', function() {
                $("#quickInboxActions").show();
            })
        }
    }
});

//helper functions
function ucwords(str) {
    return (str + '').replace(/^([a-z])|\s+([a-z])/g, function ($1) {
        return $1.toUpperCase();
    });
}
<|endoftext|>


<commit_before>(function() {
    var env = angular.module("env", []);

    env.constant("version",'1.0.1-RC1');
    env.constant("env",'1.0');
    env.constant("color",'success');

})();
<commit_msg>change prod env<commit_after>(function() {
    var env = angular.module("env", []);

    env.constant("version",'1.0.1-RC3');
    env.constant("env",'1.0.1');
    env.constant("color",'success');

})();
<|endoftext|>


<commit_before>/*
 * Copyright 2012 Brett Slatkin
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var GROUP_TYPE_COLUMN = 0;
var GROUP_VALUE_COLUMN = 1;
var DAY_COLUMN = 2;

function getSelectedGroupType() {
  return $('input:radio[name=\'chart1\']:checked').val();
}

function getSelectedGroupValues() {
  return $.makeArray(
    $('.group-value-checkbox:checked').map(function(index, el) {
      return $(el).val();
    }));
}

function getIsNormalized() {
  return $('input:checkbox[name=\'normalize\']:checked').val();
}

function getIsWeekly() {
  return $('input:checkbox[name=\'weekly\']:checked').val();
}

function createGroupTypeRadios(groupTypes) {
  var vizDiv = $('#viz_group_type1');
  vizDiv.empty();

  // Guess that whichever group type has only one value and that value is
  // empty will be the topline data.
  var checkedType = null;
  $.each(groupTypes, function(key, value) {
    if (value.length == 1 && value[0] === '') {
      checkedType = key;
    }
  });

  var i = 0;
  $.each(groupTypes, function(key, value) {
    var radioId = 'group_type_radio1_' + (i++);
    var useRadio = $('<input type="radio">')
        .addClass('group-type-radio')
        .attr('id', radioId)
        .attr('name', 'chart1')
        .attr('value', key);

    // Select the default group type.
    if (!!checkedType && checkedType === key) {
      useRadio.attr('checked', 'checked');
    }

    var container = $('
');
    container.append(useRadio);
    container.append($('').attr('for', radioId).text(key));

    vizDiv.append(container);
  });

  // Register event handlers
  $('.group-type-radio').click(function() {
    createGroupValueCheckboxes(groupTypes);
    $(document).trigger('cohorts.viz');
  });
}

function createGroupValueCheckboxes(groupTypes) {
  var type = getSelectedGroupType();
  var values = groupTypes[type];
  if (!values) {
    $.error('Bad group type: ' + type);
  }

  var valuesDiv = $('#viz_group_value1');
  valuesDiv.empty();

  // Special case for group types that only have a single, empty value.
  if (values.length == 1 && values[0] === '') {
    return;
  }

  valuesDiv.append(
      $('
')
          .text('Included group values'));

  var i = 0;
  $.each(values, function(key, value) {
    var checkboxId = 'group_value_checkbox1_' + (i++);
    var container = $('
');
    container.append(
        $('<input type="checkbox" class="group-value-checkbox" checked>')
        .attr('value', value)
        .attr('id', checkboxId));
    container.append(
        $('').attr('for', checkboxId).text(value));
    valuesDiv.append(container);
  });

  // Register event handlers
  $('.group-value-checkbox').click(function() {
    $(document).trigger('cohorts.viz');
  });
}

function createLegend(rowsWithHeader) {
  var columnNames = rowsWithHeader[0].slice(3);
  var container = $('#viz_legend');
  container.empty();

  var color = d3.scale.category20();
  $.each(columnNames, function(index, value) {
    var item = $('
');
    $('
')
        .attr('style', 'background-color: ' + color(index))
        .appendTo(item);
    $('
')
        .text(value)
        .appendTo(item);
    // Reverse order to match graph stacking.
    container.prepend(item);
  });
}

function getCohort(cohortDay, cohortsInOrder, weekly) {
  if (weekly) {
    var index = cohortsInOrder.indexOf(cohortDay);
    var indexRounded = 6 * Math.floor(index / 7);
    result = cohortsInOrder[indexRounded];
    return result;
  } else {
    return cohortDay;
  }
};

function filterData(rows, groupType, groupValues, weekly) {
  // Helper function for only pulling the row data that matches.
  function shouldSkip(index, value) {
    // Skip the header row.
    if (index == 0) {
      return true;
    }
    // Skip rows of the wrong group type.
    if (groupType !== value[GROUP_TYPE_COLUMN]) {
      return true;
    }
    // Skip rows with unmatched group values. Match everything if no values
    // were supplied.
    if (groupValues.length > 0 &&
        groupValues.indexOf(value[GROUP_VALUE_COLUMN]) == -1) {
      return true;
    }
  }

  // Extract the cohort days so we can do arbitrary time regroupings.
  function compareCohorts(a, b) {
    return d3.ascending(format.parse(a), format.parse(b));
  }

  var cohortsInOrder = [];
  $.each(rows, function(index, value) {
    if (shouldSkip(index, value)) {
      return;
    }
    cohortsInOrder.push(value[DAY_COLUMN]);
  });
  var format = d3.time.format("%m/%d/%y");
  cohortsInOrder.sort(compareCohorts);

  // Maps cohort key to the combined data row for the key. The data rows in
  // the values of this map have all cohort columns removed.
  var cohorts = {};

  // Filter matching group type and group values.
  $.each(rows, function(index, value) {
    if (shouldSkip(index, value)) {
      return;
    }

    var cohort = getCohort(value[DAY_COLUMN], cohortsInOrder, weekly);
    var cohortRows = cohorts[cohort];
    if (!cohortRows) {
      // First row for a cohort. Truncate the group type, group name, and date
      // columns, leaving just numeric data.
      var firstRow = [];
      for (var i = 3, n = value.length; i < n; ++i) {
        firstRow.push(parseInt(value[i]));
      }
      cohorts[cohort] = firstRow;
    } else {
      for (var i = 0, n = cohortRows.length; i < n; ++i) {
        cohortRows[i] += parseInt(value[i + 3]);
      }
    }
  });

  // Save some metadata about the cohorts.
  var rowData = [];
  $.each(cohortsInOrder, function(index, value) {
    var valueList = cohorts[value];
    var total = d3.sum(valueList || []);
    rowData.push({
      cohort: value,
      x: index,
      total: total,
      show: !!valueList
    });
  });

  // Now regroup the data as sets of points grouped by column (for D3).
  var columns = {};
  var headers = rows[0].slice(3);
  $.each(cohortsInOrder, function(index, key) {
    var columnValues = cohorts[key];
    $.each(headers, function(columnIndex, header) {
      var data = columns[header];
      if (!data) {
        data = []
        columns[header] = data;
      }

      if (!columnValues) {
        data.push({
          cohort: key,
          x: cohortsInOrder.indexOf(key),
          y: 0,
          show: false
        });
      } else {
        data.push({
          cohort: key,
          x: cohortsInOrder.indexOf(key),
          y: columnValues[columnIndex],
          show: true
        });
      }
    });
  });

  var columnData = [];
  $.each(columns, function(key, value) {
    columnData.push({name: key, values: value});
  });

  return [rowData, columnData];
}

function extractGroupTypes(csvData) {
  // Maps cohort group types to lists of cohort group values
  var cohortGroupTypes = {};

  // Skip the header row
  for (var i = 1; i < csvData.length; ++i) {
    var row = csvData[i];
    var groupType = row[GROUP_TYPE_COLUMN];
    var groupValue = row[GROUP_VALUE_COLUMN];
    var valueList = cohortGroupTypes[groupType];
    if (!valueList) {
      valueList = [];
      cohortGroupTypes[groupType] = valueList;
    }
    if (valueList.indexOf(groupValue) == -1) {
      valueList.push(groupValue);
    }
  }

  return cohortGroupTypes;
}

function clearViz() {
  d3.select('#viz_graph1')
      .select('svg.stacked').select('g').selectAll('g.layer').remove();
}

function updateViz(rows) {
  var groupType = getSelectedGroupType();
  var groupValues = getSelectedGroupValues();
  var normalized = getIsNormalized();
  var weekly = getIsWeekly();

  view = filterData(rows, groupType, groupValues, weekly);
  var viewCohorts = view[0];
  var viewBarGroups = view[1];

  var realRows = viewCohorts.filter(function(value, index) {
    return value.show;
  });

  console.log('Filtered to: type="' + groupType +
              '", values="' + (groupValues.join('|')) +
              '"; ' + realRows.length + ' rows found');

  // Scale graph to whole window area, with minimum
  var height = 500;
  var width = $(window).width() - 100;
  if (width < 500) {
    width = 500;
  }
  $('#viz_container').width(width);

  // Put margins around the graphs so the axes render without clipping
  var marginX = 50;
  var marginY = 20;
  height -= 2 * marginY;
  width -= 2 * marginX;

  var scaleX = d3.scale.linear()
      .domain([0, viewCohorts.length])
      .range([0, width]);
  var barWidth = width / realRows.length;
  var maxY = d3.max(viewCohorts, function(d) { return d.total; });
  if (normalized) {
    maxY = 1;
  }

  var scaleY = d3.scale.linear()
      .domain([0, maxY])
      .range([marginY, height - (2 * marginY)]);
  var scaleColor = d3.scale.category20();

  var getColor = function(d, i) {
    return scaleColor(i);
  };
  var getX = function(d) {
    return scaleX(d.x);
  };
  var getY = function(d) {
    if (d.show) {
      return scaleY(maxY - d.y0 - d.y);
    } else {
      return height - marginY;  // TODO: Clean this up
    }
  };
  var getHeight = function(d) {
    if (d.show) {
      return scaleY(d.y);
    } else {
      return 0;
    }
  };
  var getWidth = function(d, i) {
    if (d.show) {
      return barWidth;
    } else {
      return 0;
    }
  };

  var getValues = function(d) { return d.values; };

  var chart = d3.select('#viz_graph1')
      .select('svg.stacked')
        .attr('width', width + 2 * marginX)
        .attr('height', height + 2 * marginY)
      .select('g')
        .attr("transform", "translate(" + marginX + "," + marginY + ")");

  var stack = d3.layout.stack();
  if (normalized) {
    stack = stack.offset('expand');
  }
  stack = stack.values(getValues)(viewBarGroups);

  var layers = chart.selectAll('g.layer').data(stack);
  layers.enter().append('svg:g')
      .attr('class', 'layer')
      .style('fill', getColor)
      .style('stroke', d3.rgb('#333'));

  layers.exit().remove();

  var bars = layers.selectAll('rect.bar').data(getValues);
  bars.enter().append('svg:rect')
      .attr('class', 'bar')
      .attr('x', getX)
      .attr('y', height - marginY) // TODO: Clean this up
      .attr('width', getWidth)
      .attr('height', 0)
    .transition()
      .duration(500)
      .attr('width', getWidth)
      .attr('height', getHeight)
      .attr('x', getX)
      .attr('y', getY);

  bars.transition()
      .duration(500)
      .attr('x', getX)
      .attr('y', getY)
      .attr('height', getHeight)
    .transition()
      .delay(500)
      .attr('width', getWidth);

  bars.exit().remove();

  // Cohort date axis
  // TODO: Always include the last one!
  function filterTicks(value, index) {
    // With very few ticks, show them all
    if (viewCohorts.length <= 5) {
      return true;
    }
    if (index % 7 == 0) {
      return true;
    }
    return false;
  };

  var domain = viewCohorts.map(function(d) { return d.cohort; });
  var range = viewCohorts.map(function(d, i) {
    return scaleX(i);
  });
  domain = domain.filter(filterTicks);
  range = range.filter(filterTicks);

  var xAxisScale = d3.scale.ordinal()
    .domain(domain)
    .range(range);

  var xAxis = d3.svg.axis()
      .scale(xAxisScale)
      .tickSize(5, 2, 0);

  chart.selectAll('g.bottom.axis').remove();

  chart.append("g")
      .attr("class", "bottom axis")
      .attr("transform", "translate(0," + (height-marginY) + ")")
      .call(xAxis.orient("bottom"));

  // Vertical axis
  var yAxisScale = d3.time.scale()
    .domain([0, maxY])
    .range([height-marginY, marginY]);

  var yAxis = d3.svg.axis().scale(yAxisScale);

  if (normalized) {
    yAxis = yAxis.tickFormat(d3.format("%"))
        .tickSize(5, 0, 0)
        .tickValues([1]);
  } else {
    yAxis = yAxis.tickFormat(d3.format(",.0f"))
        .tickSize(5, 0, 0)
        .tickValues([maxY]);
  }

  chart.selectAll('g.left.axis').remove();

  chart.append("g")
      .attr("class", "left axis")
      .call(yAxis.orient("left"));
}

function handleClickVisualize() {
  // Parse the CSV data
  var rowsWithHeader = $.csv.toArrays($('#data').val());
  var groupTypes = extractGroupTypes(rowsWithHeader);

  // Setup UI
  createGroupTypeRadios(groupTypes);
  createGroupValueCheckboxes(groupTypes);
  createLegend(rowsWithHeader);

  // Register event handlers
  $(document).unbind('cohorts.viz');
  $(document).bind('cohorts.viz', function() {
    updateViz(rowsWithHeader);
  });

  // Clear any existing chart
  clearViz();

  // Build chart
  $(document).trigger('cohorts.viz');
}

function init() {
  $('#visualize_my_data').click(handleClickVisualize);

  var trigger = function() {
    $(document).trigger('cohorts.viz');
  };

  $('#normalize-check').click(trigger);
  $('#weekly-check').click(trigger)

  $(window).resize(trigger);

  // Start off with the dummy data that's in the textarea on page load.
  handleClickVisualize();
}

$(document).ready(init);
<commit_msg>Backed out the broke regrouping; trying again<commit_after>/*
 * Copyright 2012 Brett Slatkin
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var GROUP_TYPE_COLUMN = 0;
var GROUP_VALUE_COLUMN = 1;
var DAY_COLUMN = 2;

function getSelectedGroupType() {
  return $('input:radio[name=\'chart1\']:checked').val();
}

function getSelectedGroupValues() {
  return $.makeArray(
    $('.group-value-checkbox:checked').map(function(index, el) {
      return $(el).val();
    }));
}

function getIsNormalized() {
  return $('input:checkbox[name=\'normalize\']:checked').val();
}

function getIsWeekly() {
  return $('input:checkbox[name=\'weekly\']:checked').val();
}

function createGroupTypeRadios(groupTypes) {
  var vizDiv = $('#viz_group_type1');
  vizDiv.empty();

  // Guess that whichever group type has only one value and that value is
  // empty will be the topline data.
  var checkedType = null;
  $.each(groupTypes, function(key, value) {
    if (value.length == 1 && value[0] === '') {
      checkedType = key;
    }
  });

  var i = 0;
  $.each(groupTypes, function(key, value) {
    var radioId = 'group_type_radio1_' + (i++);
    var useRadio = $('<input type="radio">')
        .addClass('group-type-radio')
        .attr('id', radioId)
        .attr('name', 'chart1')
        .attr('value', key);

    // Select the default group type.
    if (!!checkedType && checkedType === key) {
      useRadio.attr('checked', 'checked');
    }

    var container = $('
');
    container.append(useRadio);
    container.append($('').attr('for', radioId).text(key));

    vizDiv.append(container);
  });

  // Register event handlers
  $('.group-type-radio').click(function() {
    createGroupValueCheckboxes(groupTypes);
    $(document).trigger('cohorts.viz');
  });
}

function createGroupValueCheckboxes(groupTypes) {
  var type = getSelectedGroupType();
  var values = groupTypes[type];
  if (!values) {
    $.error('Bad group type: ' + type);
  }

  var valuesDiv = $('#viz_group_value1');
  valuesDiv.empty();

  // Special case for group types that only have a single, empty value.
  if (values.length == 1 && values[0] === '') {
    return;
  }

  valuesDiv.append(
      $('
')
          .text('Included group values'));

  var i = 0;
  $.each(values, function(key, value) {
    var checkboxId = 'group_value_checkbox1_' + (i++);
    var container = $('
');
    container.append(
        $('<input type="checkbox" class="group-value-checkbox" checked>')
        .attr('value', value)
        .attr('id', checkboxId));
    container.append(
        $('').attr('for', checkboxId).text(value));
    valuesDiv.append(container);
  });

  // Register event handlers
  $('.group-value-checkbox').click(function() {
    $(document).trigger('cohorts.viz');
  });
}

function createLegend(rowsWithHeader) {
  var columnNames = rowsWithHeader[0].slice(3);
  var container = $('#viz_legend');
  container.empty();

  var color = d3.scale.category20();
  $.each(columnNames, function(index, value) {
    var item = $('
');
    $('
')
        .attr('style', 'background-color: ' + color(index))
        .appendTo(item);
    $('
')
        .text(value)
        .appendTo(item);
    // Reverse order to match graph stacking.
    container.prepend(item);
  });
}

function getCohort(cohortDay, cohortsInOrder, weekly) {
  if (weekly) {
    var index = cohortsInOrder.indexOf(cohortDay);
    var indexRounded = 6 * Math.floor(index / 7);
    result = cohortsInOrder[indexRounded];
    return result;
  } else {
    return cohortDay;
  }
};

function filterData(rows, groupType, groupValues, weekly) {
  // Helper function for only pulling the row data that matches.
  function shouldSkip(index, value) {
    // Skip the header row.
    if (index == 0) {
      return true;
    }
    // Skip rows of the wrong group type.
    if (groupType !== value[GROUP_TYPE_COLUMN]) {
      return true;
    }
    // Skip rows with unmatched group values. Match everything if no values
    // were supplied.
    if (groupValues.length > 0 &&
        groupValues.indexOf(value[GROUP_VALUE_COLUMN]) == -1) {
      return true;
    }
  }

  // Extract the cohort days so we can do arbitrary time regroupings.
  function compareCohorts(a, b) {
    return d3.ascending(format.parse(a), format.parse(b));
  }
  var cohortsInOrder = [];
  $.each(rows, function(index, value) {
    if (shouldSkip(index, value)) {
      return;
    }
    var cohortDay = value[DAY_COLUMN];
    if (cohortsInOrder.indexOf(cohortDay) == -1) {
      cohortsInOrder.push(cohortDay);
    }
  });
  var format = d3.time.format("%m/%d/%y");
  cohortsInOrder.sort(compareCohorts);

  // Maps cohort key to the combined data row for the key. The data rows in
  // the values of this map have all cohort columns removed.
  var cohorts = {};

  // Filter matching group type and group values.
  $.each(rows, function(index, value) {
    if (shouldSkip(index, value)) {
      return;
    }

    var cohort = getCohort(value[DAY_COLUMN], cohortsInOrder, weekly);
    var cohortRows = cohorts[cohort];
    if (!cohortRows) {
      // First row for a cohort. Truncate the group type, group name, and date
      // columns, leaving just numeric data.
      var firstRow = [];
      for (var i = 3, n = value.length; i < n; ++i) {
        firstRow.push(parseInt(value[i]));
      }
      cohorts[cohort] = firstRow;
    } else {
      for (var i = 0, n = cohortRows.length; i < n; ++i) {
        cohortRows[i] += parseInt(value[i + 3]);
      }
    }
  });

  // Save some metadata about the cohorts.
  var rowData = [];
  $.each(cohortsInOrder, function(index, key) {
    var valueList = cohorts[key];
    var total = d3.sum(valueList || []);
    rowData.push({
      cohort: key,
      x: index,
      total: total
    });
  });

  // Now regroup the data as sets of points grouped by column (for D3).
  var columns = {};
  var headers = rows[0].slice(3);
  $.each(cohorts, function(key, columnValues) {
    $.each(headers, function(columnIndex, header) {
      var data = columns[header];
      if (!data) {
        data = []
        columns[header] = data;
      }
      data.push({
        cohort: key,
        x: cohortsInOrder.indexOf(key),
        y: columnValues[columnIndex]
      });
    });
  });

  var columnData = [];
  $.each(columns, function(key, value) {
    columnData.push({name: key, values: value});
  });

  return [rowData, columnData];
}

function extractGroupTypes(csvData) {
  // Maps cohort group types to lists of cohort group values
  var cohortGroupTypes = {};

  // Skip the header row
  for (var i = 1; i < csvData.length; ++i) {
    var row = csvData[i];
    var groupType = row[GROUP_TYPE_COLUMN];
    var groupValue = row[GROUP_VALUE_COLUMN];
    var valueList = cohortGroupTypes[groupType];
    if (!valueList) {
      valueList = [];
      cohortGroupTypes[groupType] = valueList;
    }
    if (valueList.indexOf(groupValue) == -1) {
      valueList.push(groupValue);
    }
  }

  return cohortGroupTypes;
}

function clearViz() {
  d3.select('#viz_graph1')
      .select('svg.stacked').select('g').selectAll('g.layer').remove();
}

function updateViz(rows) {
  var groupType = getSelectedGroupType();
  var groupValues = getSelectedGroupValues();
  var normalized = getIsNormalized();
  var weekly = getIsWeekly();

  view = filterData(rows, groupType, groupValues, weekly);
  var viewCohorts = view[0];
  var viewBarGroups = view[1];

  console.log('Filtered to: type="' + groupType +
              '", values="' + (groupValues.join('|')) +
              '"; ' + viewCohorts.length + ' rows found');

  // Scale graph to whole window area, with minimum
  var height = 500;
  var width = $(window).width() - 100;
  if (width < 500) {
    width = 500;
  }
  $('#viz_container').width(width);

  // Put margins around the graphs so the axes render without clipping
  var marginX = 50;
  var marginY = 20;
  height -= 2 * marginY;
  width -= 2 * marginX;

  var scaleX = d3.scale.linear()
      .domain([0, viewCohorts.length])
      .range([0, width]);
  var barWidth = width / viewCohorts.length;
  var maxY = d3.max(viewCohorts, function(d) { return d.total; });
  if (normalized) {
    maxY = 1;
  }

  var scaleY = d3.scale.linear()
      .domain([0, maxY])
      .range([marginY, height - (2 * marginY)]);
  var scaleColor = d3.scale.category20();

  var getColor = function(d, i) {
    return scaleColor(i);
  };
  var getX = function(d) {
    return scaleX(d.x);
  };
  var getY = function(d) {
    return scaleY(maxY - d.y0 - d.y);
  };
  var getHeight = function(d) {
    return scaleY(d.y);
  };
  var getWidth = function(d, i) {
    return barWidth;
  };

  var getValues = function(d) { return d.values; };

  var chart = d3.select('#viz_graph1')
      .select('svg.stacked')
        .attr('width', width + 2 * marginX)
        .attr('height', height + 2 * marginY)
      .select('g')
        .attr("transform", "translate(" + marginX + "," + marginY + ")");

  var stack = d3.layout.stack();
  if (normalized) {
    stack = stack.offset('expand');
  }
  stack = stack.values(getValues)(viewBarGroups);

  var layers = chart.selectAll('g.layer').data(stack);
  layers.enter().append('svg:g')
      .attr('class', 'layer')
      .style('fill', getColor)
      .style('stroke', d3.rgb('#333'));

  layers.exit().remove();

  var bars = layers.selectAll('rect.bar').data(getValues);
  bars.enter().append('svg:rect')
      .attr('class', 'bar')
      .attr('x', getX)
      .attr('y', height - marginY) // TODO: Clean this up
      .attr('width', getWidth)
      .attr('height', 0)
    .transition()
      .duration(500)
      .attr('width', getWidth)
      .attr('height', getHeight)
      .attr('x', getX)
      .attr('y', getY);

  bars.transition()
      .duration(500)
      .attr('x', getX)
      .attr('y', getY)
      .attr('height', getHeight)
    .transition()
      .delay(500)
      .attr('width', getWidth);

  bars.exit().remove();

  // Cohort date axis
  // TODO: Always include the last one!
  function filterTicks(value, index) {
    // With very few ticks, show them all
    if (viewCohorts.length <= 5) {
      return true;
    }
    if (index % 7 == 0) {
      return true;
    }
    return false;
  };

  var domain = viewCohorts.map(function(d) { return d.cohort; });
  var range = viewCohorts.map(function(d, i) {
    return scaleX(i);
  });
  domain = domain.filter(filterTicks);
  range = range.filter(filterTicks);

  var xAxisScale = d3.scale.ordinal()
    .domain(domain)
    .range(range);

  var xAxis = d3.svg.axis()
      .scale(xAxisScale)
      .tickSize(5, 2, 0);

  chart.selectAll('g.bottom.axis').remove();

  chart.append("g")
      .attr("class", "bottom axis")
      .attr("transform", "translate(0," + (height-marginY) + ")")
      .call(xAxis.orient("bottom"));

  // Vertical axis
  var yAxisScale = d3.time.scale()
    .domain([0, maxY])
    .range([height-marginY, marginY]);

  var yAxis = d3.svg.axis().scale(yAxisScale);

  if (normalized) {
    yAxis = yAxis.tickFormat(d3.format("%"))
        .tickSize(5, 0, 0)
        .tickValues([1]);
  } else {
    yAxis = yAxis.tickFormat(d3.format(",.0f"))
        .tickSize(5, 0, 0)
        .tickValues([maxY]);
  }

  chart.selectAll('g.left.axis').remove();

  chart.append("g")
      .attr("class", "left axis")
      .call(yAxis.orient("left"));
}

function handleClickVisualize() {
  // Parse the CSV data
  var rowsWithHeader = $.csv.toArrays($('#data').val());
  var groupTypes = extractGroupTypes(rowsWithHeader);

  // Setup UI
  createGroupTypeRadios(groupTypes);
  createGroupValueCheckboxes(groupTypes);
  createLegend(rowsWithHeader);

  // Register event handlers
  $(document).unbind('cohorts.viz');
  $(document).bind('cohorts.viz', function() {
    updateViz(rowsWithHeader);
  });

  // Clear any existing chart
  clearViz();

  // Build chart
  $(document).trigger('cohorts.viz');
}

function init() {
  $('#visualize_my_data').click(handleClickVisualize);

  var trigger = function() {
    $(document).trigger('cohorts.viz');
  };

  $('#normalize-check').click(trigger);
  $('#weekly-check').click(trigger)

  $(window).resize(trigger);

  // Start off with the dummy data that's in the textarea on page load.
  handleClickVisualize();
}

$(document).ready(init);
<|endoftext|>


<commit_before>import fs from 'fs';
import Promise from 'bluebird';

var readFile = Promise.promisify(fs.readFile);
var readdir = Promise.promisify(fs.readdir);

	readFile('configuration.JSON', 'utf8')
	.then(data => JSON.parse(data))
	.each(
		task => {
		readdir(task.path)
		.then(files => files.every(file =>
			{
				if(testFile(task.path, task.matchAll, task.rules,file)) {
					events[task.event.type](task.path, file, task.event.path);
				}
			}));
		}
	).each(function(files) {
		//console.log("files:");
		//console.log(files);
	}).catch(function(err) {
		throw new Error(err);
	});

function testFile(dir, matchAll, rules, file) {

	let nrOfMatches,
			matches = 0;

	if(matchAll) {
		nrOfMatches = rules.length;
	} else {
		nrOfMatches = 1;
	}

	for(let i = 0; i < rules.length; i++) {
		if(verifiers[rules[i].verifier](file, rules[i].type, rules[i].reference)) {
			console.log("%s passed test '%s' with type: %s, reference: %s", file, rules[i].verifier, rules[i].type, rules[i].reference);
			matches++;
		} else {
			console.log("%s did not pass test '%s' with type: %s, reference: %s", file, rules[i].verifier, rules[i].type, rules[i].reference);
		}
	}

	if(matches === nrOfMatches) {
		return true;
	} else {
		return false;
	}
}

const verifiers = {
	match: (file, type, reference) => {
		let parts = file.split('.');
		if(type === 'extension') {
			return parts[1] === reference
		}
		if(type === 'name') {
			return parts[0] === reference
		}
	},
	contains: (file, type, reference) => {
		let parts = file.split('.');
		if(type === 'extension') {
			return (parts[1].indexOf(reference) >= 0)
		}
		if(type === 'name') {
			return (parts[0].indexOf(reference) >= 0)
		}
	}
}

const events = {
	move: (originalFolder, file, folder) => {
		console.log('moved file "%s" from %s to %s', file, originalFolder, folder);
		/*let source = fs.createReadStream(originalFolder+file),
				dest = fs.createWriteStream(folder+file);
		source.pipe(dest);
		source.on*/
	}
}
<commit_msg>add working move event<commit_after>import fs from 'fs';
import Promise from 'bluebird';
import path from 'path';

var readFile = Promise.promisify(fs.readFile);
var readdir = Promise.promisify(fs.readdir);
var rename = Promise.promisify(fs.rename);

	readFile('configuration.JSON', 'utf8')
	.then(data => JSON.parse(data))
	.each(
		task => {
		setInterval(() => {

		console.log("Getting path from %s to %s", task.path, __dirname);
		console.log(path.relative(__dirname, task.path));

		readdir(path.relative(__dirname, task.path))
		.then(files => files.forEach(file =>
			{
				if(testFile(task.path, task.matchAll, task.rules,file)) {
					events[task.event.type](task.path, file, task.event.path);
				}
			}))}, task.interval);
		}
	).each(function(files) {
		//console.log("files:");
		//console.log(files);
	}).catch(err => {
		throw new Error(err);
	});

function testFile(dir, matchAll, rules, file) {

	let nrOfMatches = matchAll ? rules.length : 1,
			matches = 0;

	for(let i = 0; i < rules.length; i++) {
		if(file.indexOf('.') >= 0 && verifiers[rules[i].verifier](file, rules[i].type, rules[i].reference)) {
			console.log("%s passed test '%s' with type: %s, reference: %s", file, rules[i].verifier, rules[i].type, rules[i].reference);
			matches++;
		} else {
			console.log("%s did not pass test '%s' with type: %s, reference: %s", file, rules[i].verifier, rules[i].type, rules[i].reference);
		}
	}

	let pass = (matches === nrOfMatches) ? true : false;

	return pass;
}

const verifiers = {
	match: (file, type, reference) => {
		let parts = file.split('.');
		if(type === 'extension') {
			return parts[1] === reference
		}
		if(type === 'name') {
			return parts[0] === reference
		}
	},
	contains: (file, type, reference) => {
		let parts = file.split('.');
		if(type === 'extension') {
			return (parts[1].indexOf(reference) >= 0)
		}
		if(type === 'name') {
			return (parts[0].indexOf(reference) >= 0)
		}
	}
}

const events = {
	move: (originalFolder, file, folder) => {

		let pathToOldFolder = path.relative(__dirname, originalFolder)+'/'+file;
		let pathToNewFolderFromOld = path.relative(__dirname, folder)+'/'+file;

		rename(path.relative(__dirname, originalFolder)+'/'+file, path.relative(__dirname, folder)+'/'+file)
		.then(() => {
			console.log('moved file "%s" from %s to %s', file, pathToOldFolder, pathToNewFolderFromOld);
		})
		.catch((err) => {
			console.log('Could not move file "%s" from %s to %s', file, pathToOldFolder, pathToNewFolderFromOld);
			throw new Error(err);
		});
		/*let source = fs.createReadStream(originalFolder+file),
				dest = fs.createWriteStream(folder+file);
		source.pipe(dest);
		source.on*/
	}
}
<|endoftext|>