Last active
August 29, 2015 14:02
-
-
Save hashg/ea941f0d680fbb86d5f6 to your computer and use it in GitHub Desktop.
D3 Linear calendar
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!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> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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