forked from 0x2620/oxjs
much better formatting of date ranges and their duration
This commit is contained in:
parent
13669aec63
commit
f0052d3e3c
4 changed files with 247 additions and 97 deletions
|
|
@ -74,12 +74,26 @@ Ox.Calendar = function(options, self) {
|
|||
|
||||
self.options.events.forEach(function(event) {
|
||||
event.id = Ox.isUndefined(event.id) ? Ox.uid() : event.id;
|
||||
event.start = Ox.parseDate(event.start, true);
|
||||
event.end = Ox.parseDate(event.end, true);
|
||||
event.startTime = Ox.parseDate(event.start, true);
|
||||
event.endTime = Ox.parseDate(event.end, true);
|
||||
event.rangeText = Ox.formatDateRange(event.start, event.end, true);
|
||||
event.durationText = Ox.formatDateRangeDuration(event.start, event.end, true);
|
||||
});
|
||||
|
||||
self.maxZoom = 32;
|
||||
self.minLabelWidth = 80;
|
||||
|
||||
/*
|
||||
We need to iterate over irregular intervals, like months or years.
|
||||
The idea is to put this logic into a data structure, the units.
|
||||
Just like the 0-th second is 1970-01-01 00:00:00, the 0th month
|
||||
is 1970-01, or the 0-th century is the 20th century.
|
||||
A month unit, for example, has the following properties:
|
||||
- seconds: average number of seconds
|
||||
- date: returns the start date of the index-th month
|
||||
- name: returns a string representation of the index-th month
|
||||
- value: returns the month index for a given date
|
||||
*/
|
||||
self.units = [
|
||||
{
|
||||
id: 'millennium',
|
||||
|
|
@ -93,8 +107,8 @@ Ox.Calendar = function(options, self) {
|
|||
},
|
||||
name: function(i) {
|
||||
return i > -2
|
||||
? Ox.formatOrdinal(i + 2) + ' millennium'
|
||||
: Ox.formatOrdinal(-i - 1) + ' millennium BC'
|
||||
? Ox.formatOrdinal(i + 2) + ' Millennium'
|
||||
: Ox.formatOrdinal(-i - 1) + ' Millennium BC'
|
||||
},
|
||||
value: function(date) {
|
||||
return Math.floor(date.getUTCFullYear() / 1000) - 1;
|
||||
|
|
@ -112,8 +126,8 @@ Ox.Calendar = function(options, self) {
|
|||
},
|
||||
name: function(i) {
|
||||
return i > -20
|
||||
? Ox.formatOrdinal(i + 20) + ' century'
|
||||
: Ox.formatOrdinal(-i - 19) + ' century BC'
|
||||
? Ox.formatOrdinal(i + 20) + ' Century'
|
||||
: Ox.formatOrdinal(-i - 19) + ' Century BC'
|
||||
},
|
||||
value: function(date) {
|
||||
return Math.floor(date.getUTCFullYear() / 100) - 19;
|
||||
|
|
@ -506,55 +520,11 @@ Ox.Calendar = function(options, self) {
|
|||
renderCalendar();
|
||||
}
|
||||
|
||||
function formatEvent(event) {
|
||||
return formatEventRange(event) + '<br/>' + formatEventDuration(event);
|
||||
}
|
||||
|
||||
function formatEventDuration(event) {
|
||||
// fixme: still wrong because of different number of leap days
|
||||
var date = new Date(getEventDuration(event)),
|
||||
strings = [],
|
||||
values = {
|
||||
years: date.getUTCFullYear() - 1970,
|
||||
days: Ox.getDayOfTheYear(date, true) - 1,
|
||||
hours: date.getUTCHours(),
|
||||
minutes: date.getUTCMinutes(),
|
||||
seconds: date.getUTCMilliseconds()
|
||||
};
|
||||
//Ox.print('****', values);
|
||||
['year', 'day', 'hour', 'minute', 'second'].forEach(function(key) {
|
||||
var value = values[key + 's'];
|
||||
value && strings.push(value + ' ' + key + (value > 1 ? 's' : ''));
|
||||
});
|
||||
return strings.join(' ');
|
||||
}
|
||||
|
||||
function formatEventRange(event) {
|
||||
var isFullDays = Ox.formatDate(event.start, '%H:%M:%S', true) == '00:00:00' &&
|
||||
Ox.formatDate(event.end, '%H:%M:%S', true) == '00:00:00',
|
||||
isOneDay = isFullDays && getEventDuration(event) == 86400000, // fixme: wrong, DST
|
||||
isSameDay = Ox.formatDate(event.start, '%Y-%m-%d', true) ==
|
||||
Ox.formatDate(event.end, '%Y-%m-%d', true),
|
||||
isSameYear = event.start.getUTCFullYear() == event.end.getUTCFullYear(),
|
||||
timeFormat = isFullDays ? '' : ', %H:%M:%S',
|
||||
string = Ox.formatDate(event.start, '%a, %b %e', true);
|
||||
if (isOneDay || isSameDay || !isSameYear) {
|
||||
string += Ox.formatDate(event.start, ', %Y' + timeFormat, true);
|
||||
}
|
||||
if (!isOneDay && !isSameDay) {
|
||||
string += Ox.formatDate(event.end, ' - %a, %b %e, %Y' + timeFormat, true);
|
||||
}
|
||||
if (isSameDay) {
|
||||
string += Ox.formatDate(event.end, ' - ' + timeFormat.replace(', ', ''), true);
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
function getCalendarEvent(zoom) {
|
||||
var ms = self.options.width * getSecondsPerPixel(zoom) * 1000;
|
||||
return {
|
||||
start: new Date(+self.options.date - ms / 2),
|
||||
end: new Date(+self.options.date + ms / 2)
|
||||
startTime: new Date(+self.options.date - ms / 2),
|
||||
endTime: new Date(+self.options.date + ms / 2)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -570,17 +540,17 @@ Ox.Calendar = function(options, self) {
|
|||
}
|
||||
|
||||
function getEventCenter(event) {
|
||||
return new Date(+event.start + getEventDuration(event) / 2);
|
||||
return new Date(+event.startTime + getEventDuration(event) / 2);
|
||||
}
|
||||
|
||||
function getEventDuration(event) {
|
||||
return event.end - event.start;
|
||||
return event.endTime - event.startTime;
|
||||
}
|
||||
|
||||
function getEventElement(event, zoom) {
|
||||
var left = Math.max(getPosition(event.start, zoom), -10000),
|
||||
var left = Math.max(getPosition(event.startTime, zoom), -10000),
|
||||
paddingLeft = (event.type && left < 0 ? -left : 0),
|
||||
width = Ox.limit(getPosition(event.end, zoom) - left, 1, 20000) - paddingLeft;
|
||||
width = Ox.limit(getPosition(event.endTime, zoom) - left, 1, 20000) - paddingLeft;
|
||||
return new Ox.Element()
|
||||
.addClass('OxEvent' +
|
||||
(event.type ? ' Ox' + Ox.toTitleCase(event.type) : '' ) +
|
||||
|
|
@ -692,8 +662,8 @@ Ox.Calendar = function(options, self) {
|
|||
$elements.push(
|
||||
getEventElement({
|
||||
name: unit.name(value + i),
|
||||
start: unit.date(value + i),
|
||||
end: unit.date(value + i + 1)
|
||||
startTime: unit.date(value + i),
|
||||
endTime: unit.date(value + i + 1)
|
||||
}, zoom)
|
||||
.addClass(Ox.mod(value + i, 2) == 0 ? 'even' : 'odd')
|
||||
);
|
||||
|
|
@ -729,7 +699,7 @@ Ox.Calendar = function(options, self) {
|
|||
if ($target.is('.OxLine > .OxEvent')) {
|
||||
event = getEventById($target.data('id'));
|
||||
title = '<span class="OxBright">' + event.name + '</span><br/>' +
|
||||
formatEvent(event);
|
||||
event.rangeText + '<br>' + event.durationText;
|
||||
} else {
|
||||
title = Ox.formatDate(getMouseDate(e), '%a, %b %e, %Y, %H:%M:%S', true);
|
||||
}
|
||||
|
|
@ -763,9 +733,9 @@ Ox.Calendar = function(options, self) {
|
|||
|
||||
function overlaps(eventA, eventB) {
|
||||
return (
|
||||
eventA.start >= eventB.start && eventA.start < eventB.end
|
||||
eventA.startTime >= eventB.startTime && eventA.startTime < eventB.endTime
|
||||
) || (
|
||||
eventB.start >= eventA.start && eventB.start < eventA.end
|
||||
eventB.startTime >= eventA.startTime && eventB.startTime < eventA.endTime
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -827,10 +797,10 @@ Ox.Calendar = function(options, self) {
|
|||
return -1;
|
||||
} else if (a.type != 'date' && b.type == 'date') {
|
||||
return 1;
|
||||
} else if (a.start < b.start || a.start > b.start) {
|
||||
return a.start - b.start;
|
||||
} else if (a.startTime < b.startTime || a.startTime > b.startTime) {
|
||||
return a.startTime - b.startTime;
|
||||
} else {
|
||||
return (b.end - b.start) - (a.end - a.start);
|
||||
return (b.endTime - b.startTime) - (a.endTime - a.startTime);
|
||||
}
|
||||
}).forEach(function(event, i) {
|
||||
var line = lineEvents.length;
|
||||
|
|
@ -865,7 +835,7 @@ Ox.Calendar = function(options, self) {
|
|||
.appendTo(self.$content);
|
||||
events.sort(function(a, b) {
|
||||
// sort events by start, ascending
|
||||
return a.start - b.start;
|
||||
return a.startTime - b.startTime;
|
||||
}).forEach(function(event) {
|
||||
overlaps(event, calendarEvent) &&
|
||||
getEventElement(event).appendTo($line);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue