HeatMapCalendar 라는 이름은 그냥 내 마음대로 붙여봤음...
2012 년 예제
1년치 달력을 가로축을 월(month), 세로축을 주(week)로 배열하여 한 눈에 볼 수 있게 해주는 달력.
각 날짜마다 데이터가 있고, 해당 데이터를 색값으로 계산하여 여러 형태로 보여줄 수 있음.
원래라면 좀 더 예쁘게 나왔어야 하는건데,
예를 들면 여름은 빨갛고 겨울은 파랗다거나...-_-;
참조: http://mbostock.github.com/d3/ex/calendar.html
참조링크의 원본은 그림을 그리는 스타일이나, 간단하게 테이블로 가능할 것 같아서 만들어 봤음.
핵심은 아래와 같음.
- 1년치 날짜정보를 배열로 가져와 pivot 처리.
- 날짜정보를 인덱스로 가지는 배열과 맵핑하여 색값 계산.
색값은 참조링크처럼 말 그대로 HeatMap 처럼 나타낼 수도 있고, 데이터의 성격에 따라서 여러가지 응용이 가능할 것으로 보여짐.
<!DOCTYPE HTML>
<html><head><style>.tbl_cal { border: 0px; border-collapse: collapse; border-spacing: 0px; }.tbl_cal td { width: 10px; height: 10px; border: 1px solid #CDCDCD; }.tbl_cal .no_date { border: 0px; }.tbl_cal .sunday { border-top: 2px solid black; }.tbl_cal .saturday { border-bottom: 2px solid black; }.tbl_cal .first_day_of_month { border-top: 2px solid black; }.tbl_cal .first_week_of_month { border-left: 2px solid black; }.tbl_cal .last_week { border-right: 2px solid black; }.tbl_cal .last_day_of_year { border-bottom: 2px solid black; }</style><script>$(document).ready(function(){ // 년도 지정 var year = new Date().getFullYear(); // 시작일, 종료일 var iStart = new Date(year, 0, 1, 0, 0, 0).getTime(); var iEnd = new Date(year, 11, 31, 0, 0, 0).getTime(); // 날짜 데이터를 저장할 배열 var aDate = [[]]; // 시작 빈칸 채우기 var iStartPos = new Date(year,0,1,0,0,0).getDay(); for (var i=0; i<iStartPos; i++) { aDate[0][i] = null; } // 날짜 데이터 채우기 (+임시 데이터 만들기) var aTmpData = {}; i = iStart; var iWeek = 0; var j = iStartPos; while (i <= iEnd) { var iPos = (new Date(i)).getDay(); if (!aDate[iWeek]) aDate.push([]); var oDate = getDate(i); aDate[iWeek][iPos] = { date: oDate }; // 임시 데이터 만들기 aTmpData[oDate.year+oDate.month+oDate.day] = Math.floor(Math.random() * 255) + 1; i += 86400000; ++j; if (j > 6) { j = 0; ++iWeek; } } // 마지막 빈칸 채우기 iEndPos = new Date(i).getDay(); if (iEndPos > 0) { for (i=iEndPos; i<7; i++) { aDate[iWeek][i] = null; } } // pivot var aDatePivot = [[], [], [], [], [], [], []]; for (i=0; i<aDate.length; i++) { for (j=0; j<aDate[i].length; j++) { aDatePivot[j].push(aDate[i][j]); } } // 테이블 만들기 var sMonth = ''; var iTotalWeeks = aDatePivot[0].length; var sCalendarTable = ''; sCalendarTable += '<table id="tbl_cal" class="tbl_cal">'; for (i=0; i<aDatePivot.length; i++) { sCalendarTable += '<tr>'; for (j=0; j<iTotalWeeks; j++) { var aClass = []; var bgColor = ''; var sId = ''; if (aDatePivot[i][j] == null) aClass.push('no_date'); else { var d = aDatePivot[i][j].date; sId = ' id="tbl_cal_'+d.year+d.month+d.day+'"'; // 테이블 상단,하단 if (i == 0) aClass.push('sunday'); else if (i == 6) aClass.push('saturday'); // 월의 첫날, 마지막 날 if (d.day == '01') { aClass.push('first_day_of_month'); } // 월간 분리 if (d.month != sMonth) { sMonth = d.month; aClass.push('first_week_of_month'); } // 테이블 마지막 if (j == iTotalWeeks-1) { aClass.push('last_week'); if (d.month==12 && d.day==31 && i<6) aClass.push('last_day_of_year'); } else if (j == iTotalWeeks-2) { if (aDatePivot[i][j+1] == null) aClass.push('last_week'); } // 색상 지정 (with 임시데이터) var RGB = ''; RGB = (255 - aTmpData[d.year+d.month+d.day]).toString(16); if (RGB.length < 2) RGB = '0'+RGB; RGB = '#FF'+RGB+RGB; bgColor = ' style="background-color:'+RGB+';"'; } sCalendarTable += '<td'+sId+' class="'+aClass.join(' ')+'"'+bgColor+'></td>'; } sCalendarTable += '</tr>'; } sCalendarTable += '</table>'; var sInfoLayer = '<div id="info" style="display:none;"></div>'; // 붙이기 + 이벤트 걸기 $('body').append(sCalendarTable+sInfoLayer) .find('[id="tbl_cal"] td') .mouseover(function(){ if (!$(this).attr('id')) return; $('#info').show(); }) .mousemove(function(e){ if (!$(this).attr('id')) return; var d = $(this).attr('id').replace(/tbl_cal_/, ''); var info = d+'<br />'+aTmpData[d]; $('#info').html(info); console.log(); $('#info') .css('border', '1px solid black').css('background-color', 'yellow') .css('left', e.pageX - (parseInt($('#info').css('width'))/2)) .css('top', e.pageY - (parseInt($('#info').css('height'))) - 5) .css('z-index', 999).css('position', 'absolute').css('display', ''); }) .mouseout(function(){ if (!$(this).attr('id')) return; $('#info').hide(); }); // 타임스탬프를 받아서 Ymd 값 반환 function getDate(timestamp) { var zeroPad = function(digit, len){ var i = digit.toString().length; while (i < len) { digit = '0'+digit; ++i; } return digit; }; var aResult = { 'year': null, 'month': null, 'day': null }; var d = new Date(timestamp); aResult.year = d.getFullYear()+''; aResult.month = zeroPad(d.getMonth()+1, 2)+''; aResult.day = zeroPad(d.getDate(), 2)+''; return aResult; }});</script></head><body></body></html>'JavaScript' 카테고리의 다른 글
| [JavaScript] object 키로 정렬 (object sort by key name) (0) | 2013.01.21 |
|---|---|
| [JavaScript] 표현가능한 최고 숫자 (Number.MAX_VALUE) (0) | 2012.11.22 |
| [JavaScript] 한줄짜리 thousand separate (number_format) (0) | 2012.05.04 |
| [jQuery] iframe의 body select (마우스 드래그로 움직이기) (0) | 2011.10.11 |
| [JavaScript] HTML Element의 위치, 크기 절대값 (0) | 2011.01.26 |

