ovaltimeline
Version:
298 lines (228 loc) • 9.92 kB
JavaScript
(function ($) {
var dateHelper = function () {
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
return {
addYear: function (date, amount) {
if (amount < 0)
{
return date;
}
return new Date(date.getFullYear() + amount, date.getMonth(), date.getDay());
},
getMonthOfYear: function (monthNum) {
return months[ monthNum + 1 ];
},
getMonthArray: months,
getDateObj: function( dateString ){
return new Date(dateString.substring(0, 4), dateString.substring(5, 7), dateString.substring(8, 10));
},
formatDate: function( date ){
var day = date.getDate();
var monthIndex = date.getMonth();
var year = date.getFullYear();
return day + "." + monthIndex + "." + year;
}
}
}();
//Main worker object
var timelineGraph = function (options) {
var diffObj;
var containerWidth;
var spaceBetweenYear;
var skippedYears = false;
function getDiffObj(date1, date2)
{
var diff = Math.floor(date1.getTime() - date2.getTime());
var day = 1000 * 60 * 60 * 24;
var days = Math.floor(diff / day);
var months = Math.floor(days / 31);
var years = Math.floor(months / 12);
return {
days: days,
months: months,
years: years
}
}
function setBaseHTML() {
var html = "";
html += "<div id='" + options.elementId + "'>";
html += "<div class=\"timeline-wrap\">";
html += "<div class=\"timeline-events\">";
html += "<div class=\"timeline-large-item timeline-large-scale\"></div>";
html += "<div class=\"timeline-small-item timeline-small-scale\"></div>";
html += "</div>";
html += "</div>";
html += "</div>";
$(options.containerElement).html(html);
}
function calculateYearLeftValue(totalYears, currentYear) {
totalYears = totalYears - 1;
if (currentYear == 0)
{
return 0;
}
if (totalYears == currentYear)
{
return containerWidth;
}
spaceBetweenYear = (containerWidth / totalYears);
return (containerWidth / totalYears) * currentYear;
}
function setYearLine() {
var startYear = options.startDate;
var totalYearsToDisplay = diffObj.years + 2;
//Check if need to ouput all years or on nth year
var nthYear = 0;
var sizeBetweenPoints = (containerWidth / totalYearsToDisplay);
if (sizeBetweenPoints < 85)
{
//y = a * (b)x + c
//Exponential graph formula
nthYear = Math.round(90 * Math.pow(0.7, sizeBetweenPoints) + 1.7);
}
skippedYears = (nthYear > 0) ? true : false;
//Build HTML
var yearHTML = "";
for (var a = 0; a < totalYearsToDisplay; a++)
{
if (nthYear === 0 ||
(a % nthYear) === 0)
{
var yearValue = dateHelper.addYear(startYear, a).getFullYear();
var yearLeftValue = calculateYearLeftValue(totalYearsToDisplay, a);
yearHTML += "<div class=\"timeline-large-item timeline-dateblock\" id=\"timeline-large-item-" + a + "\" style=\"left: " + yearLeftValue + "px;\"><div class=\"rotate\">" + yearValue + "</div></div>";
}
}
$('.timeline-large-scale', options.containerElement).html(yearHTML);
}
function calculateMonthLeftValue(currentYear, currentMonth, totalMonths) {
var monthPosition = ((currentYear) * 12) + currentMonth;
return (containerWidth / totalMonths) * monthPosition;
}
function setMonthLines() {
//Build HTML
var monthHTML = "";
var totalMonthsToDisplay = (Math.floor(diffObj.months / 12) + 1) * 12;
var totalYearsToDisplay = diffObj.years + 1;
//Check if need to ouput all years or on nth year
var nthYear = 0;
var sizeBetweenPoints = spaceBetweenYear;
var monthsToShow = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
if( sizeBetweenPoints < 300 )
{
var monthsToShow = [3, 6, 9];
}
$('#someval').text(sizeBetweenPoints);
for (var a = 0; a < totalYearsToDisplay; a++)
{
for (var b = 0; b < dateHelper.getMonthArray.length; b++)
{
if (b !== 0 && monthsToShow.indexOf(b) !== -1)
{
var monthValue = dateHelper.getMonthArray[b];
var monthLeftValue = calculateMonthLeftValue(a, b, totalMonthsToDisplay);
monthHTML += "<div class=\"timeline-small-item timeline-dateblock\" id=\"timeline-small-item-" + b + "\" style=\"left: " + monthLeftValue + "px;\"><div class=\"rotate\">" + monthValue + "</div></div>";
}
}
}
$('.timeline-small-scale', options.containerElement).html(monthHTML);
}
function getPointLeftValue( date ) {
var diff = getDiffObj( date, options.startDate );
var dayDiff = diff.days;
var totalDays = diffObj.days;
var percent = (dayDiff / totalDays) * 100;
return percent;
}
function setData(){
var data = options.data;
var html = "";
var c =0;
for( var a in data )
{
var date = dateHelper.getDateObj( data[a].date );
var leftValue = getPointLeftValue( date );
var dateFormated = dateHelper.formatDate( date );
html += '<div class="timeline-event timeline-bottom" id="timeline-event-1" style="left: '+leftValue+'%; z-index: 1;">';
html += '<div class="timeline-event-node" id="timeline-event-node-1"></div>';
html += '<div class="timeline-event-arrow" style="display: none;"></div>';
html += '<div class="timeline-event-contents" style="display: none; margin-left: -20px; width: 234px;">';
if( options.tooltipTemplate ){
var result = options.tooltipTemplate( data[a] );
if( typeof result === "string" )
html += options.tooltipTemplate( data[a] );
}else
{
html += '<div class="timeline-event-title"><span>'+dateFormated+'</span>'+data[a].title+'</div>';
html += '<div class="timeline-event-content">';
html += data[a].description;
html += '</div>';
if( data[a].link )
{
html += '<div class="timeline-event-link"><a href="'+data[a].link+'">Read More</a></div>';
}
}
html += '</div>';
html += '</div>';
c++;
}
$('.timeline-wrap', options.containerElement ).append( html );
$( '.timeline-event',options.containerElement ).click(function(){
$('.timeline-event-arrow').hide();
$('.timeline-event-contents').hide();
var obj = $(this);
$('.timeline-event-arrow', obj).show();
$('.timeline-event-contents', obj).show();
});
}
function setHTML(_diffObj) {
setBaseHTML();
if (diffObj.years > 1)
{
setYearLine();
}
if (skippedYears === false)
{
setMonthLines();
}
setData();
}
this.buildGraph = function () {
containerWidth = $(options.containerElement).width();
var _diffObj = diffObj = getDiffObj(options.endDate, options.startDate);
setHTML(_diffObj);
};
};
//Instantiates plugin and adds jquery support
$.fn.timeline = function (options) {
//Plugin options
var defaultOptions = {
startDate: "1800-01-01",
endDate: "2016-06-01",
elementId: "ovaltimeline",
data: []
};
var options = $.extend(defaultOptions, options);
//Properties
var containerElement = this;
//Methods
function SortOptions() {
var startDate = options.startDate;
options.startDate = dateHelper.getDateObj(startDate);
var endDate = options.endDate;
options.endDate = dateHelper.getDateObj(endDate);
options.containerElement = containerElement;
}
function Construct() {
SortOptions();
var timeline = new timelineGraph(options);
$(window).resize(function () {
timeline.buildGraph();
});
timeline.buildGraph();
}
//Init
Construct();
return containerElement;
};
}(jQuery));