adding first Ox.Calendar demo

This commit is contained in:
rlx 2011-04-20 11:29:34 +00:00
parent cc87bc3c3f
commit 1c05a7945f
6 changed files with 620 additions and 15 deletions

View file

@ -102,6 +102,68 @@ Bars
margin: 4px 0 0 4px; margin: 4px 0 0 4px;
} }
/*
================================================================================
Calendar
================================================================================
*/
.OxCalendar {
position: absolute;
}
.OxCalendar > .OxCalendarContainer {
position: absolute;
left: 0;
right: 0;
overflow: hidden;
}
.OxCalendar .OxLine {
position: absolute;
}
.OxCalendar .OxDate {
position: absolute;
height: 16px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
cursor: pointer;
}
.OxCalendar .OxLine:nth-child(even) .OxDate {
background-color: rgb(255, 0, 0);
}
.OxCalendar .OxLine:nth-child(odd) .OxDate {
background-color: rgb(255, 64, 64);
}
.OxCalendar .OxTimeline {
position: absolute;
height: 16px;
//overflow: hidden;
}
.OxCalendar .OxTimeline .OxDate {
position: absolute;
border-radius: 0;
cursor: ew-resize;
}
.OxCalendar .OxOverlay {
position: absolute;
left: 0;
right: 0;
height: 16px;
}
.OxCalendar .OxOverlay div {
position: absolute;
height: 16px;
cursor: ew-resize;
}
.OxCalendar .OxOverlay div:nth-child(odd) {
background-color: rgba(0, 0, 0, 0.333);
}
/* /*
================================================================================ ================================================================================
Dialog Dialog

View file

@ -31,6 +31,22 @@ Bars
background-color: rgb(48, 48, 48); background-color: rgb(48, 48, 48);
} }
/*
================================================================================
Calendar
================================================================================
*/
.OxThemeModern .OxCalendar .OxTimeline > div.even {
background: -moz-linear-gradient(top, rgb(64, 64, 64), rgb(32, 32, 32));
background: -webkit-gradient(linear, left top, left bottom, from(rgb(64, 64, 64)), to(rgb(32, 32, 32)));
}
.OxThemeModern .OxCalendar .OxTimeline > div.odd {
background: -moz-linear-gradient(top, rgb(56, 56, 56), rgb(24, 24, 24));
background: -webkit-gradient(linear, left top, left bottom, from(rgb(56, 56, 56)), to(rgb(24, 24, 24)));
}
/* /*
================================================================================ ================================================================================
Dialog Dialog

View file

@ -43,6 +43,9 @@ Ox.MONTHS = [
'January', 'February', 'March', 'April', 'May', 'June', 'January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December' 'July', 'August', 'September', 'October', 'November', 'December'
]; ];
Ox.SHORT_MONTHS = Ox.MONTHS.map(function(val) {
return val.substr(0, 3);
});
Ox.PREFIXES = ['K', 'M', 'G', 'T', 'P']; Ox.PREFIXES = ['K', 'M', 'G', 'T', 'P'];
Ox.SYMBOLS = { Ox.SYMBOLS = {
DOLLAR: '\u0024', DOLLAR: '\u0024',
@ -77,6 +80,9 @@ Ox.VERSION = '0.1.2';
Ox.WEEKDAYS = [ Ox.WEEKDAYS = [
'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday' 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'
]; ];
Ox.SHORT_WEEKDAYS = Ox.WEEKDAYS.map(function(val) {
return val.substr(0, 3);
});
/* /*
================================================================================ ================================================================================
@ -491,9 +497,14 @@ Ox.len = function(obj) {
return Ox.isObject(obj) ? Ox.values(obj).length : obj.length; return Ox.isObject(obj) ? Ox.values(obj).length : obj.length;
}; };
Ox.loop = function(num, fn) { Ox.loop = function() {
var i; var length = arguments.length,
for (i = 0; i < num; i++) { fn = arguments[length - 1],
step = length == 4 ? arguments[2] : 1,
stop = arguments[length > 2 ? 1 : 0],
start = length > 2 ? arguments[0] : 0,
i;
for (i = start; i < stop; i += step) {
fn(i); fn(i);
} }
}; };
@ -957,6 +968,10 @@ Ox.getDaysInMonth = function(year, month) {
//return Ox.DAYS[month - 1] + (month == 2 && Ox.isLeapYear(year)); //return Ox.DAYS[month - 1] + (month == 2 && Ox.isLeapYear(year));
} }
Ox.getDaysInYear = function(year) {
return 365 + Ox.isLeapYear(year);
};
Ox.getFirstDayOfTheYear = function(date) { Ox.getFirstDayOfTheYear = function(date) {
/* /*
Decimal weekday of January 1 (0-6, Sunday as first day) Decimal weekday of January 1 (0-6, Sunday as first day)
@ -1610,10 +1625,10 @@ Ox.formatDate = function() {
["v", function() {return "%e-%b-%Y";}], ["v", function() {return "%e-%b-%Y";}],
["\\+", function() {return "%a %b %e %H:%M:%S %Z %Y";}], ["\\+", function() {return "%a %b %e %H:%M:%S %Z %Y";}],
["A", function(d) {return Ox.WEEKDAYS[(d.getDay() + 6) % 7];}], ["A", function(d) {return Ox.WEEKDAYS[(d.getDay() + 6) % 7];}],
["a", function(d) {return Ox.WEEKDAYS[(d.getDay() + 6) % 7].toString().substr(0, 3);}], ["a", function(d) {return Ox.SHORT_WEEKDAYS[(d.getDay() + 6) % 7];}],
["B", function(d) {return Ox.MONTHS[d.getMonth()];}], ["B", function(d) {return Ox.MONTHS[d.getMonth()];}],
["b", function(d) {return Ox.MONTHS[d.getMonth()].toString().substr(0, 3);}], ["b", function(d) {return Ox.SHORT_MONTHS[d.getMonth()];}],
["C", function(d) {return d.getFullYear().toString().substr(0, 2);}], ["C", function(d) {return (d.getFullYear() / 100).toString();}],
["d", function(d) {return Ox.pad(d.getDate(), 2);}], ["d", function(d) {return Ox.pad(d.getDate(), 2);}],
["e", function(d) {return Ox.pad(d.getDate(), 2, " ");}], ["e", function(d) {return Ox.pad(d.getDate(), 2, " ");}],
["G", function(d) {return Ox.getISOYear(d);}], ["G", function(d) {return Ox.getISOYear(d);}],
@ -1737,6 +1752,38 @@ Ox.formatNumber = function(num, dec) {
return (num < 0 ? '-' : '') + spl.join('.'); return (num < 0 ? '-' : '') + spl.join('.');
}; };
Ox.formatOrdinal = function(num) {
/*
>>> Ox.formatOrdinal(1)
"1st"
>>> Ox.formatOrdinal(2)
"2nd"
>>> Ox.formatOrdinal(3)
"3rd"
>>> Ox.formatOrdinal(4)
"4th"
>>> Ox.formatOrdinal(11)
"11th"
>>> Ox.formatOrdinal(12)
"12th"
>>> Ox.formatOrdinal(13)
"13th"
*/
var str = num.toString(),
end = str[str.length - 1],
ten = str.length > 1 && str[str.length - 2] == '1';
if (end == '1' && !ten) {
str += 'st';
} else if (end == '2' && !ten) {
str += 'nd';
} else if (end == '3' && !ten) {
str += 'rd';
} else {
str += 'th';
}
return str;
};
Ox.formatPercent = function(num, total, dec) { Ox.formatPercent = function(num, total, dec) {
/* /*
>>> Ox.formatPercent(1, 1000, 2) >>> Ox.formatPercent(1, 1000, 2)
@ -2245,6 +2292,17 @@ Ox.log = function(num, base) {
return Math.log(num) / Math.log(base || Math.E); return Math.log(num) / Math.log(base || Math.E);
}; };
Ox.mod = function(num, by) {
/*
>>> Ox.mod(11, 10)
1
>>> Ox.mod(-11, 10)
9
*/
var mod = num % by;
return mod >= 0 ? mod : mod + by;
};
Ox.rad = function(deg) { Ox.rad = function(deg) {
/* /*
>>> Ox.rad(360) >>> Ox.rad(360)

View file

@ -9858,7 +9858,7 @@ requires
function initMap() { function initMap() {
var mapBounds; var mapBounds;
updateFormElements() updateFormElements();
self.elevationService = new google.maps.ElevationService(); self.elevationService = new google.maps.ElevationService();
self.geocoder = new google.maps.Geocoder(); self.geocoder = new google.maps.Geocoder();
@ -10760,16 +10760,17 @@ requires
}; };
/**
options
height image height (px)
places array of either names (''), points ([0, 0]),
or objects ({name, point, highlight})
type map type ('hybrid', 'roadmap', 'satellite', 'terrain')
width image width (px)
*/
Ox.MapImage = function(options, self) { Ox.MapImage = function(options, self) {
/**
options
height image height (px)
places array of either names (''), points ([0, 0]),
or objects ({name, point, highlight})
type map type ('hybrid', 'roadmap', 'satellite', 'terrain')
width image width (px)
*/
var self = self || {}, var self = self || {},
that = new Ox.Element('img', self) that = new Ox.Element('img', self)
.defaults({ .defaults({
@ -10827,6 +10828,426 @@ requires
}; };
Ox.Calendar = function(options, self) {
self = self || {};
var that = new Ox.Element({}, self)
.defaults({
date: new Date(),
dates: [],
height: 512,
range: [100, 5101],
width: 512,
zoom: 5
})
.options(options || {})
.addClass('OxCalendar')
.css({
width: self.options.width + 'px',
height: self.options.height + 'px'
});
self.overlayWidths = [Math.round(self.options.width / 16)];
self.overlayWidths = [
Math.floor((self.options.width - self.overlayWidths[0]) / 2),
self.overlayWidths[0],
Math.ceil((self.options.width - self.overlayWidths[0]) / 2),
];
self.units = [
{
id: 'century',
seconds: 36524 * 86400,
date: function(i) {
return new Date((i + 19) + '00');
},
name: function(i) {
return Ox.formatOrdinal(i + 20) + ' century';
},
value: function(date) {
return Math.floor(date.getFullYear() / 100) - 19;
}
},
{
id: 'decade',
seconds: 3652 * 86400,
date: function(i) {
return (i + 197) + '0'
},
name: function(i) {
return (i + 197) + '0s'
},
value: function(date) {
return Math.floor(date.getFullYear() / 10) - 197;
}
},
{
id: 'year',
seconds: 365 * 86400,
date: function(i) {
return (i + 1970) + '';
},
name: function(i) {
return (i + 1970) + '';
},
value: function(date) {
return date.getFullYear() - 1970;
}
},
{
id: 'month',
seconds: 28 * 86000,
date: function(i) {
return (Math.floor(i / 12) + 1970) + '-' + (Ox.mod(i, 12) + 1);
},
name: function(i) {
return Ox.SHORT_MONTHS[Ox.mod(i, 12)] + ' ' + Math.floor(i / 12 + 1970)
},
value: function(date) {
return (date.getFullYear() - 1970) * 12 + date.getMonth();
}
},
{
id: 'day',
seconds: 86400,
date: function(i) {
return i * 86400000;
},
name: function(i) {
return Ox.formatDate(new Date(i * 86400000), '%a, %b %e, %Y');
},
value: function(date) {
return Math.floor(date / 86400000);
}
},
{
id: 'hour',
seconds: 3600,
date: function(i) {
return i * 3600000;
},
name: function(i) {
return Ox.formatDate(new Date(i * 3600000), '%b %e, %H:00');
},
value: function(date) {
return Math.floor(date / 3600000);
}
},
{
id: 'minute',
seconds: 60,
date: function(i) {
return i * 60000;
},
name: function(i) {
return Ox.formatDate(new Date(i * 60000), '%b %e, %H:%M');
},
value: function(date) {
return Math.floor(date / 60000);
}
},
{
id: 'second',
seconds: 1,
date: function(i) {
return i * 1000;
},
name: function(i) {
return Ox.formatDate(new Date(i * 1000), '%H:%M:%S');
},
value: function(date) {
return Math.floor(date / 1000);
}
}
];
self.$container = new Ox.Element()
.addClass('OxCalendarContainer')
.css({
top: '24px',
bottom: '40px'
})
.bindEvent({
dragstart: dragstart,
drag: drag,
dragend: dragend
})
.appendTo(that);
self.$content = new Ox.Element()
.addClass('OxCalendarContent')
.appendTo(self.$container)
self.$scalebar = new Ox.Element()
.addClass('OxTimeline')
.css({
posision: 'absolute',
})
.appendTo(self.$content);
self.$scrollbar = new Ox.Element()
.addClass('OxTimeline')
.css({
posision: 'absolute',
bottom: '40px'
})
.appendTo(that);
self.$overlay = new Ox.Element()
.addClass('OxOverlay')
.css({
bottom: '40px'
})
.append(
$('<div>').css({
width: self.overlayWidths[0] + 'px'
})
)
.append(
$('<div>').css({
left: self.overlayWidths[0] + 'px',
width: self.overlayWidths[1] + 'px'
})
)
.append(
$('<div>').css({
left: (self.overlayWidths[0] + self.overlayWidths[1]) + 'px',
width: self.overlayWidths[2] + 'px'
})
)
.bindEvent({
dragstart: dragstartScrollbar,
drag: dragScrollbar,
dragend: dragendScrollbar
})
.appendTo(that);
self.$zoombar = new Ox.Bar({
size: 16
})
.css({
position: 'absolute',
bottom: 24 + 'px'
})
.appendTo(that);
self.$zoomInput = new Ox.Range({
arrows: true,
max: 28,
min: 0,
size: self.options.width,
thumbSize: 32,
thumbValue: true,
value: self.options.zoom
})
.bindEvent({
change: changeZoom
})
.appendTo(self.$zoombar);
sortDates();
renderTimelines();
renderDates();
function changeDate() {
}
function changeZoom(event, data) {
self.options.zoom = data.value;
$('.OxDate').remove();
renderTimelines();
renderDates();
}
function dragstart(event, e) {
if ($(e.target).is(':not(.OxLine > .OxDate)')) {
self.drag = {x: e.clientX};
}
}
function drag(event, e) {
if (self.drag) {
self.$content.css({
marginLeft: (e.clientX - self.drag.x) + 'px'
});
self.$scrollbar.css({
marginLeft: Math.round((e.clientX - self.drag.x) / 16) + 'px'
});
}
}
function dragend(event, e) {
if (self.drag) {
self.options.date = new Date(
+self.options.date + (self.drag.x - e.clientX) * getSecondsPerPixel() * 1000
);
dragafter();
}
}
function dragstartScrollbar(event, e) {
self.drag = {x: e.clientX};
}
function dragScrollbar(event, e) {
self.$content.css({
marginLeft: ((e.clientX - self.drag.x) * 16) + 'px'
});
self.$scrollbar.css({
marginLeft: (e.clientX - self.drag.x) + 'px'
});
}
function dragendScrollbar(event, e) {
self.options.date = new Date(
+self.options.date + (self.drag.x - e.clientX) * getSecondsPerPixel() * 1000 * 16
);
dragafter();
}
function dragafter() {
self.drag = null;
self.$content.css({
marginLeft: 0
});
self.$scrollbar.css({
marginLeft: 0
});
$('.OxDate').remove();
renderTimelines();
renderDates();
}
function getDateElement(date, zoom) {
var left = getPosition(date.start, zoom),
width = Math.max(getPosition(date.stop, zoom) - left, 1);
return new Ox.Element()
.addClass('OxDate')
.attr({
title: date.name
})
.css({
left: left + 'px',
width: width + 'px'
})
.html('&nbsp;' + date.name);
}
function getPixelsPerSecond(zoom) {
return Math.pow(2, (zoom || self.options.zoom) - 24);
}
function getSecondsPerPixel(zoom) {
return 1 / getPixelsPerSecond(zoom);
}
function getPosition(date, zoom) {
zoom = zoom || self.options.zoom
return Math.round(
self.options.width / 2 +
(date - self.options.date) / 1000 * getPixelsPerSecond(zoom)
);
}
function getTimelineElements(zoom) {
var $elements = [],
pixelsPerSecond = getPixelsPerSecond(zoom),
n, unit, value, width;
self.units = self.units.reverse();
Ox.forEach(self.units, function(v) {
width = v.seconds * pixelsPerSecond;
if (width >= 64) {
unit = Ox.getObjectById(self.units, v.id);
return false;
}
});
self.units = self.units.reverse();
n = Math.ceil(self.options.width * 1.5/* * 16*/ / width);
value = unit.value(self.options.date);
Ox.loop(-n, n + 1, function(i) {
$elements.push(
getDateElement({
name: unit.name(value + i)/* + unit.date(value + i) + '-' + unit.date(value + i + 1)*/,
start: new Date(unit.date(value + i)),
stop: new Date(unit.date(value + i + 1))
}, zoom)
.addClass(Ox.mod(value + i, 2) == 0 ? 'even' : 'odd')
);
});
return $elements;
}
function overlaps(date0, date1) {
return (
date0.start >= date1.start && date0.start < date1.stop
) || (
date1.start >= date0.start && date1.start < date0.stop
);
}
function renderDates() {
self.lineDates = [];
self.$lines = [];
self.options.dates.forEach(function(date, i) {
var line = self.$lines.length;
Ox.forEach(self.lineDates, function(dates, line_) {
var fits = true;
Ox.forEach(dates, function(date_) {
if (overlaps(date, date_)) {
Ox.print('over', date.name, date_.name)
fits = false;
return false;
}
});
if (fits) {
Ox.print(date.name, 'fits', line_)
line = line_;
return false;
}
});
Ox.print(date.name, line)
if (line == self.$lines.length) {
self.lineDates[line] = [];
self.$lines[line] = new Ox.Element()
.addClass('OxLine')
.css({
top: ((line + 1) * 16) + 'px'
});
}
self.lineDates[line].push(date);
self.$lines[line].append(getDateElement(date));
});
$('.OxLine').remove();
self.$lines.forEach(function($line) {
$line.appendTo(self.$content);
});
}
function renderTimelines() {
getTimelineElements(self.options.zoom).forEach(function($element) {
$element.appendTo(self.$scalebar.$element);
});
getTimelineElements(Math.max(self.options.zoom - 4, 0)).forEach(function($element) {
$element.appendTo(self.$scrollbar.$element);
});
}
function sortDates() {
self.options.dates.sort(function(a, b) {
return (b.stop - b.start) - (a.stop - a.start);
});
}
self.onChange = function(key, val) {
if (key == 'date') {
} else if (key == 'zoom') {
}
};
return that;
};
/* /*
============================================================================ ============================================================================
Menus Menus
@ -10836,6 +11257,7 @@ requires
/** /**
*/ */
Ox.MainMenu = function(options, self) { Ox.MainMenu = function(options, self) {
var self = self || {}, var self = self || {},
that = new Ox.Bar({}, self) that = new Ox.Bar({}, self)
.defaults({ .defaults({

13
demos/calendar/index.html Normal file
View file

@ -0,0 +1,13 @@
<!DOCTYPE HTML>
<html>
<head>
<title>ox.js calendar demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link rel="stylesheet" type="text/css" href="../../build/css/ox.ui.css"/>
<script type="text/javascript" src="../../build/js/jquery-1.5.js"></script>
<script type="text/javascript" src="../../build/js/ox.js"></script>
<script type="text/javascript" src="../../build/js/ox.ui.js"></script>
<script type="text/javascript" src="js/calendar.js"></script>
</head>
<body></body>
</html>

View file

@ -0,0 +1,34 @@
$(function() {
Ox.theme('modern');
new Ox.Calendar({
date: new Date(0),
dates: [
{name: 'December 1969', start: new Date('1969-12-01'), stop: new Date('1970-01-01')},
{name: '20th century', start: new Date('1900-01-01'), stop: new Date('2000-01-01')},
{name: 'World War One', start: new Date('1914-01-01'), stop: new Date('1919-01-01')},
{name: 'The Third Reich', start: new Date('1933-01-30'), stop: new Date('1945-05-09')},
{name: 'World War Two', start: new Date('1939-01-01'), stop: new Date('1946-01-01')},
{name: '1960s', start: new Date('1960-01-01'), stop: new Date('1970-01-01')},
{name: 'Assassination of John F. Kennedy', start: new Date('1963-11-22'), stop: new Date('1963-11-23')},
{name: 'Assassination of Benno Ohnesorg', start: new Date('1967-06-02'), stop: new Date('1967-06-03')},
{name: '1968', start: new Date('1968-01-01'), stop: new Date('1969-01-01')},
{name: 'Assassination of Martin Luther King', start: new Date('1968-04-04'), stop: new Date('1968-04-05')},
{name: 'Assassination of Rudi Dutschke', start: new Date('1968-04-11'), stop: new Date('1968-04-12')},
{name: 'May 1968', start: new Date('1968-05-01'), stop: new Date('1968-06-01')},
{name: '1968 Cannes Film Festival', start: new Date('1968-05-10'), stop: new Date('1968-05-20')},
{name: 'Assassination of Robert F. Kennedy', start: new Date('1968-06-05'), stop: new Date('1968-06-06')},
{name: 'Apollo 11', start: new Date('1969-07-16'), stop: new Date('1969-07-25')},
{name: 'Moon Landing', start: new Date('1969-07-20'), stop: new Date('1969-07-21')},
{name: 'The Epoch', start: new Date('1970-01-01 00:00:00'), stop: new Date('1970-01-01 00:00:01')},
{name: 'Apollo 17', start: new Date('1972-12-07'), stop: new Date('1972-12-20')},
{name: 'Tschernobyl', start: new Date('1986-04-26'), stop: new Date('1986-04-27')},
{name: '9-11', start: new Date('2001-09-11'), stop: new Date('2001-09-12')}
],
height: window.innerHeight,
width: window.innerWidth,
zoom: 5
}).appendTo(Ox.UI.$body);
});