tomgp
7/21/2016 - 9:39 AM

weekday scale

'use strict';
function scaleWeekday(){

	var domain = [0,1];
	var range = [0,1];
	var msDay = 60000 * 60 * 24; //number of ms in a day

	function scale(x){
		//TODO: check we have a date... if not NaN
		//if it's a weekend reject, returning NaN
		if(x.getDay() == 0 || x.getDay() == 6) return undefined; //sunday is 0, saturday is 6
		var domainWeekendsMs = countWeekendDays(domain[0], domain[1]) * msDay;
//		console.log(domain[0] + '->' + x, ' weekend days ' + countWeekendDays(domain[0], x) ) 


//		console.log('adjusting')
//		console.log(x.getTime(),'-',countWeekendDays(domain[0],x) * msDay)
		var adjustedValue = ( x.getTime() - (countWeekendDays(domain[0],x) * msDay) )-domain[0].getTime();

		var scaleFactor = (range[1] - range[0]) / ((domain[1] - domain[0]) - domainWeekendsMs ); //range units per ms
//		console.log('scale', scaleFactor);
		return adjustedValue * scaleFactor;
	}

	scale.invert = function(x){ //TODO, this would be useful

	}

	scale.domain = function(x){
		if(!x) return domain;
		domain = x;
		return scale;
	}

	scale.range = function(x){
		if(!x) return range;
		range = x;
		return scale;
	}

	function countWeekendDays(d1, d2){ //how many weekend days are there between d1 and d2
	    var firstday = d1.getDay();
        var daySpan = (d2.getTime() - d1.getTime() - firstday) / msDay;
        var weekSpan = (daySpan / 7) | 0;
        var weekRemainder = Math.ceil(daySpan % 7); 
        var extra = 0;
    	if (firstday + weekRemainder > 7){
    		extra = 2;
    	}else if (firstday + weekRemainder == 7 || weekRemainder > firstday){
        	extra = 1;
        }
    	return weekSpan * 2 + extra;
	}

	return scale;
}


module.exports = scaleWeekday;

//usage
// var myScale = scaleWeekday()
// 	.domain([new Date(2016,6,1), new Date(2016,6,3)])
// 	.range([0, 200])
	
// var position = myScale(new Date(2016, 6, 14));