Skip to content

Instantly share code, notes, and snippets.

@hashg
Last active August 29, 2015 14:02
Show Gist options
  • Select an option

  • Save hashg/ea941f0d680fbb86d5f6 to your computer and use it in GitHub Desktop.

Select an option

Save hashg/ea941f0d680fbb86d5f6 to your computer and use it in GitHub Desktop.
D3 Linear calendar
<!doctype html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<!-- Place favicon.ico and apple-touch-icon.png in the root directory -->
<!-- build:js scripts/vendor/modernizr.js -->
<!-- <script src="bower_components/modernizr/modernizr.js"></script> -->
<!-- endbuild -->
</head>
<style>
.cell {
fill: lightgrey; //wheat;
/*stroke: black;*/
}
.weekend {
opacity: 0.5;
}
.today {
stroke: magenta; //black;
}
.cell.holiday {
fill: turquoise; //darksalmon;// tomato;
}
.cell.vacation {
fill: gold; //cadetblue; //yellow
}
.vacation.holiday, .holiday.vacation {
fill: url(#grad);
}
.text {
font-family: consolas, sans-serif;
font-size: 11px;
color: white;
fill: black;
}
</style>
<style type="text/css">
.axis text {
font: 10px calibri,cambria,sans-serif;
font-size: 13px;
fill: brown;
text-transform: capitalize;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.yline path {
stroke: none;
}
</style>
<body>
<div id="chart"></svg>
<script src="bower_components/utils/moment.js"></script>
<script src="bower_components/d3/d3.js"></script>
<script src="scripts/matrix.js"></script>
</body>
</html>
var width = 1600,
height = 500,
margin = {t: 15, r:10, b: 20, l:75}
cell = {w: 18, h:18, pad: 2},
start = new Date(),
weeks = 4;
var vacations = [
['6/05/2014','6/12/2014','6/25/2014','6/28/2014', '7/7/2014', '7/17/2014'],
['6/07/2014','6/15/2014','6/23/2014','6/30/2014', '7/2/2014', '7/7/2014'],
['7/7/2014','7/8/2014', '7/9/2014'],
['6/05/2014','6/12/2014','6/25/2014','6/28/2014', '7/7/2014', '7/17/2014'],
['6/07/2014','6/15/2014','6/23/2014','6/30/2014', '7/2/2014', '7/7/2014'],
['7/7/2014','7/8/2014', '7/9/2014']
];
var holidays = [
['6/15/2014','6/16/2014','6/25/2014','6/29/2014', '7/1/2014', '7/13/2014'],
['6/01/2014','6/10/2014','6/25/2014','6/30/2014','6/31/2014', '7/5/2014', '7/11/2014']
];
var names = ['harish', 'gowda', 'hashg', 'tenali', 'birbal', 'sherlock'];
var div = d3.select('#chart');
var right_now = start;
var drag = d3.behavior.drag()
.on("drag", function(d,i) {
// console.log(d3.event.dx +":"+ d3.event.dx);
if(d3.event.dx > 0 )
right_now = moment(right_now).add( 'd', 1 );
else
right_now = moment(right_now).subtract( 'd', 1 );
render(vacations, holidays, 10, right_now);
});
var svg = div.append('svg')
.attr('class', 'container')
.attr('width', width)
.attr('height', height)
.call(drag);
/*0 split eg: 2 * half rectangle* /
var gradient = svg.append("defs")
.append("linearGradient")
.attr("id", "grad")
.attr("x1", "0%")
.attr("x2", "100%")
.attr("y1", "50%")
.attr("y2", "50%")
.attr("spreadMehod", "repeat");*/
/*1 split*/
/*0 diagonal*/
var gradient = svg.append("defs")
.append("linearGradient")
.attr("id", "grad")
.attr("x1", "0%")
.attr("x2", "100%")
.attr("y1", "100%")
.attr("y2", "0%")
.attr("spreadMehod", "repeat");
/*1 diagonal*/
gradient.append("stop")
.attr("offset", "0%")
.attr("stop-color", "gold")
.attr("stop-opacity", 1);
gradient.append("stop")
.attr("offset", "50%")
.attr("stop-color", "gold")
.attr("stop-opacity", 1);
gradient.append("stop")
.attr("offset", "40%")
.attr("stop-color", "turquoise")
.attr("stop-opacity", 1);
gradient.append("stop")
.attr("offset", "100%")
.attr("stop-color", "turquoise")
.attr("stop-opacity", 1);
var xline = svg.append('g').attr('class', 'xline axis');
var yline = svg.append('g').attr('class', 'yline axis');
function render(vacations, holidays, weeks, start)
{
var today = moment().format("MM-DD-YYYY");
var data = [];
for (var k = 0; k < vacations.length; k += 1) {
data.push( d3.time.days( start, moment(start).add( 'w', weeks ) ) );
}
var thisWidth = (data[0].length * (cell.w + cell.pad)) - cell.pad ;
var thisHeight = (data.length * (cell.h + cell.pad)) - (cell.h + cell.pad);
var day_fmt = d3.time.format("%d");
var week_fmt = d3.time.format("%a");
var x = d3.time.scale()
.domain([start, moment(start).add( 'w', weeks )])
.range([0, thisWidth]);
var y = d3.time.scale()
.domain([0,thisHeight])
.range([0, thisHeight]);
//Define Y axis
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(data.length)
.tickSize(0,0)
.tickFormat(function(d,i) { return names[i];});
//Define X axis
var xAxis = d3.svg.axis()
.scale(x)
.orient("top")
.ticks(d3.time.months)
.tickSize(15, 0)
.tickFormat(function(d) { return d3.time.format("%B")(d).substr(0,3); });
/* //Define X axis
var xAxis = d3.svg.axis()
.scale(x)
.orient("top")
.ticks(d3.time.days)
.tickSize(15, 0)
.tickFormat(function(d) { return week_fmt(d)[0]; });
*/
var dCompare = function(arr, d) {
var ret = false;
arr.forEach( function(v,i) {
var dt = new Date(v);
if(d.getTime() == dt.getTime())
{
ret = true;
return true;
}
});
return ret;
}
// Create a group for each row in the data matrix and
// translate the group vertically
var grp = svg.selectAll('.row')
.data(data);
grp.attr('transform', function(d, i) {
return 'translate('+ margin.l +' , ' + (margin.t + (cell.h + cell.pad) * i) + ')';
});
grp.enter()
.append('g')
.attr('class', 'row')
.attr('transform', function(d, i) {
return 'translate('+ margin.l +' , ' + (margin.t + (cell.h + cell.pad) * i) + ')';
});
grp.exit()
.remove();
var rect = grp.selectAll('rect')
.data(function(d) { return d; });
var text = grp.selectAll('text')
.data(function(d) { return d; });
//UPDATE
rect.attr('x', function(d, i) { return (cell.w + cell.pad) * i; })
.attr('width', cell.w)
.attr('height', cell.h)
.classed('weekend', function(d){
if( week_fmt(d)[0] === 'S')
return true;
return false;
})
.classed('vacation', function(d,i,j) {
return dCompare(vacations[j], d);
})
.classed('holiday', function(d,i,j) {
return holidays[j] && dCompare(holidays[j], d);
})
.classed('today', function(d,i,j) {
var current = moment(d).format("MM-DD-YYYY");
// console.log(current +":"+ today);
return current === today;
});
text.attr('class', 'text')
.transition()
.duration(750)
.attr('x', function(d, i) {
return ((cell.w + cell.pad) * i) + cell.w/7;
})
.attr('y', function(d, i, j) { return cell.h/2 + 3; })
.text(function(d,i) { return day_fmt(d); });
//ENTER
// For each group, create a set of rectangles and bind
// them to the inner array (the inner array is already
// binded to the group)
rect.enter()
.append('rect')
.attr('class', 'cell')
.attr('x', function(d, i) { return 20 * i; })
.attr('width', cell.w)
.attr('height', cell.h)
.classed('weekend', function(d){
if( week_fmt(d)[0] === 'S')
return true;
return false;
})
.classed('vacation', function(d,i,j) {
return dCompare(vacations[j], d);
})
.classed('holiday', function(d,i,j) {
return holidays[j] && dCompare(holidays[j], d);
})
.classed('today', function(d,i,j) {
var current = moment(d).format("MM-DD-YYYY");
// console.log(current +":"+ today);
return current === today;
});
text.enter()
.append('text')
.attr('class', 'text')
.attr('x', function(d, i) {
return ((cell.w + cell.pad) * i) + cell.w/7;
})
.attr('y', function(d, i, j) { return cell.h/2 + 3; })
.text(function(d,i) { return day_fmt(d); });
//EXIT
rect.exit()
.remove();
text.exit()
.transition()
.duration(750)
.attr("y", 60)
.style("fill-opacity", 1e-6)
.remove();
xline
.attr('transform', 'translate(' + (margin.l) +', ' + ( margin.t - cell.pad ) + ')')
.call(xAxis)
.selectAll('.tick text')
.style('text-anchor', 'start')
.attr('x', 4)
.attr('y', -4);
yline
.attr('transform', 'translate(' + margin.l +', ' + cell.h + ')')
.call(yAxis)
.selectAll('.tick text')
.attr('x', -5)
.attr('y', 8);
}
render(vacations, holidays, weeks, start);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment