Add source JavaScript files for existing minimized versions
This commit is contained in:
parent
975e25f506
commit
39796a852f
|
|
@ -0,0 +1,505 @@
|
|||
(function(){
|
||||
|
||||
|
||||
var rsplit = function(string, regex) {
|
||||
var result = regex.exec(string),retArr = new Array(), first_idx, last_idx, first_bit;
|
||||
while (result != null)
|
||||
{
|
||||
first_idx = result.index; last_idx = regex.lastIndex;
|
||||
if ((first_idx) != 0)
|
||||
{
|
||||
first_bit = string.substring(0,first_idx);
|
||||
retArr.push(string.substring(0,first_idx));
|
||||
string = string.slice(first_idx);
|
||||
}
|
||||
retArr.push(result[0]);
|
||||
string = string.slice(result[0].length);
|
||||
result = regex.exec(string);
|
||||
}
|
||||
if (! string == '')
|
||||
{
|
||||
retArr.push(string);
|
||||
}
|
||||
return retArr;
|
||||
},
|
||||
chop = function(string){
|
||||
return string.substr(0, string.length - 1);
|
||||
},
|
||||
extend = function(d, s){
|
||||
for(var n in s){
|
||||
if(s.hasOwnProperty(n)) d[n] = s[n]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EJS = function( options ){
|
||||
options = typeof options == "string" ? {view: options} : options
|
||||
this.set_options(options);
|
||||
if(options.precompiled){
|
||||
this.template = {};
|
||||
this.template.process = options.precompiled;
|
||||
EJS.update(this.name, this);
|
||||
return;
|
||||
}
|
||||
if(options.element)
|
||||
{
|
||||
if(typeof options.element == 'string'){
|
||||
var name = options.element
|
||||
options.element = document.getElementById( options.element )
|
||||
if(options.element == null) throw name+'does not exist!'
|
||||
}
|
||||
if(options.element.value){
|
||||
this.text = options.element.value
|
||||
}else{
|
||||
this.text = options.element.innerHTML
|
||||
}
|
||||
this.name = options.element.id
|
||||
this.type = '['
|
||||
}else if(options.url){
|
||||
options.url = EJS.endExt(options.url, this.extMatch);
|
||||
this.name = this.name ? this.name : options.url;
|
||||
var url = options.url
|
||||
//options.view = options.absolute_url || options.view || options.;
|
||||
var template = EJS.get(this.name /*url*/, this.cache);
|
||||
if (template) return template;
|
||||
if (template == EJS.INVALID_PATH) return null;
|
||||
try{
|
||||
this.text = EJS.request( url+(this.cache ? '' : '?'+Math.random() ));
|
||||
}catch(e){}
|
||||
|
||||
if(this.text == null){
|
||||
throw( {type: 'EJS', message: 'There is no template at '+url} );
|
||||
}
|
||||
//this.name = url;
|
||||
}
|
||||
var template = new EJS.Compiler(this.text, this.type);
|
||||
|
||||
template.compile(options, this.name);
|
||||
|
||||
|
||||
EJS.update(this.name, this);
|
||||
this.template = template;
|
||||
};
|
||||
/* @Prototype*/
|
||||
EJS.prototype = {
|
||||
/**
|
||||
* Renders an object with extra view helpers attached to the view.
|
||||
* @param {Object} object data to be rendered
|
||||
* @param {Object} extra_helpers an object with additonal view helpers
|
||||
* @return {String} returns the result of the string
|
||||
*/
|
||||
render : function(object, extra_helpers){
|
||||
object = object || {};
|
||||
this._extra_helpers = extra_helpers;
|
||||
var v = new EJS.Helpers(object, extra_helpers || {});
|
||||
return this.template.process.call(object, object,v);
|
||||
},
|
||||
update : function(element, options){
|
||||
if(typeof element == 'string'){
|
||||
element = document.getElementById(element)
|
||||
}
|
||||
if(options == null){
|
||||
_template = this;
|
||||
return function(object){
|
||||
EJS.prototype.update.call(_template, element, object)
|
||||
}
|
||||
}
|
||||
if(typeof options == 'string'){
|
||||
params = {}
|
||||
params.url = options
|
||||
_template = this;
|
||||
params.onComplete = function(request){
|
||||
var object = eval( request.responseText )
|
||||
EJS.prototype.update.call(_template, element, object)
|
||||
}
|
||||
EJS.ajax_request(params)
|
||||
}else
|
||||
{
|
||||
element.innerHTML = this.render(options)
|
||||
}
|
||||
},
|
||||
out : function(){
|
||||
return this.template.out;
|
||||
},
|
||||
/**
|
||||
* Sets options on this view to be rendered with.
|
||||
* @param {Object} options
|
||||
*/
|
||||
set_options : function(options){
|
||||
this.type = options.type || EJS.type;
|
||||
this.cache = options.cache != null ? options.cache : EJS.cache;
|
||||
this.text = options.text || null;
|
||||
this.name = options.name || null;
|
||||
this.ext = options.ext || EJS.ext;
|
||||
this.extMatch = new RegExp(this.ext.replace(/\./, '\.'));
|
||||
}
|
||||
};
|
||||
EJS.endExt = function(path, match){
|
||||
if(!path) return null;
|
||||
match.lastIndex = 0
|
||||
return path+ (match.test(path) ? '' : this.ext )
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* @Static*/
|
||||
EJS.Scanner = function(source, left, right) {
|
||||
|
||||
extend(this,
|
||||
{left_delimiter: left +'%',
|
||||
right_delimiter: '%'+right,
|
||||
double_left: left+'%%',
|
||||
double_right: '%%'+right,
|
||||
left_equal: left+'%=',
|
||||
left_comment: left+'%#'})
|
||||
|
||||
this.SplitRegexp = left=='[' ? /(\[%%)|(%%\])|(\[%=)|(\[%#)|(\[%)|(%\]\n)|(%\])|(\n)/ : new RegExp('('+this.double_left+')|(%%'+this.double_right+')|('+this.left_equal+')|('+this.left_comment+')|('+this.left_delimiter+')|('+this.right_delimiter+'\n)|('+this.right_delimiter+')|(\n)') ;
|
||||
|
||||
this.source = source;
|
||||
this.stag = null;
|
||||
this.lines = 0;
|
||||
};
|
||||
|
||||
EJS.Scanner.to_text = function(input){
|
||||
if(input == null || input === undefined)
|
||||
return '';
|
||||
if(input instanceof Date)
|
||||
return input.toDateString();
|
||||
if(input.toString)
|
||||
return input.toString();
|
||||
return '';
|
||||
};
|
||||
|
||||
EJS.Scanner.prototype = {
|
||||
scan: function(block) {
|
||||
scanline = this.scanline;
|
||||
regex = this.SplitRegexp;
|
||||
if (! this.source == '')
|
||||
{
|
||||
var source_split = rsplit(this.source, /\n/);
|
||||
for(var i=0; i<source_split.length; i++) {
|
||||
var item = source_split[i];
|
||||
this.scanline(item, regex, block);
|
||||
}
|
||||
}
|
||||
},
|
||||
scanline: function(line, regex, block) {
|
||||
this.lines++;
|
||||
var line_split = rsplit(line, regex);
|
||||
for(var i=0; i<line_split.length; i++) {
|
||||
var token = line_split[i];
|
||||
if (token != null) {
|
||||
try{
|
||||
block(token, this);
|
||||
}catch(e){
|
||||
throw {type: 'EJS.Scanner', line: this.lines};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
EJS.Buffer = function(pre_cmd, post_cmd) {
|
||||
this.line = new Array();
|
||||
this.script = "";
|
||||
this.pre_cmd = pre_cmd;
|
||||
this.post_cmd = post_cmd;
|
||||
for (var i=0; i<this.pre_cmd.length; i++)
|
||||
{
|
||||
this.push(pre_cmd[i]);
|
||||
}
|
||||
};
|
||||
EJS.Buffer.prototype = {
|
||||
|
||||
push: function(cmd) {
|
||||
this.line.push(cmd);
|
||||
},
|
||||
|
||||
cr: function() {
|
||||
this.script = this.script + this.line.join('; ');
|
||||
this.line = new Array();
|
||||
this.script = this.script + "\n";
|
||||
},
|
||||
|
||||
close: function() {
|
||||
if (this.line.length > 0)
|
||||
{
|
||||
for (var i=0; i<this.post_cmd.length; i++){
|
||||
this.push(pre_cmd[i]);
|
||||
}
|
||||
this.script = this.script + this.line.join('; ');
|
||||
line = null;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
EJS.Compiler = function(source, left) {
|
||||
this.pre_cmd = ['var ___ViewO = [];'];
|
||||
this.post_cmd = new Array();
|
||||
this.source = ' ';
|
||||
if (source != null)
|
||||
{
|
||||
if (typeof source == 'string')
|
||||
{
|
||||
source = source.replace(/\r\n/g, "\n");
|
||||
source = source.replace(/\r/g, "\n");
|
||||
this.source = source;
|
||||
}else if (source.innerHTML){
|
||||
this.source = source.innerHTML;
|
||||
}
|
||||
if (typeof this.source != 'string'){
|
||||
this.source = "";
|
||||
}
|
||||
}
|
||||
left = left || '<';
|
||||
var right = '>';
|
||||
switch(left) {
|
||||
case '[':
|
||||
right = ']';
|
||||
break;
|
||||
case '<':
|
||||
break;
|
||||
default:
|
||||
throw left+' is not a supported deliminator';
|
||||
break;
|
||||
}
|
||||
this.scanner = new EJS.Scanner(this.source, left, right);
|
||||
this.out = '';
|
||||
};
|
||||
EJS.Compiler.prototype = {
|
||||
compile: function(options, name) {
|
||||
options = options || {};
|
||||
this.out = '';
|
||||
var put_cmd = "___ViewO.push(";
|
||||
var insert_cmd = put_cmd;
|
||||
var buff = new EJS.Buffer(this.pre_cmd, this.post_cmd);
|
||||
var content = '';
|
||||
var clean = function(content)
|
||||
{
|
||||
content = content.replace(/\\/g, '\\\\');
|
||||
content = content.replace(/\n/g, '\\n');
|
||||
content = content.replace(/"/g, '\\"');
|
||||
return content;
|
||||
};
|
||||
this.scanner.scan(function(token, scanner) {
|
||||
if (scanner.stag == null)
|
||||
{
|
||||
switch(token) {
|
||||
case '\n':
|
||||
content = content + "\n";
|
||||
buff.push(put_cmd + '"' + clean(content) + '");');
|
||||
buff.cr();
|
||||
content = '';
|
||||
break;
|
||||
case scanner.left_delimiter:
|
||||
case scanner.left_equal:
|
||||
case scanner.left_comment:
|
||||
scanner.stag = token;
|
||||
if (content.length > 0)
|
||||
{
|
||||
buff.push(put_cmd + '"' + clean(content) + '")');
|
||||
}
|
||||
content = '';
|
||||
break;
|
||||
case scanner.double_left:
|
||||
content = content + scanner.left_delimiter;
|
||||
break;
|
||||
default:
|
||||
content = content + token;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch(token) {
|
||||
case scanner.right_delimiter:
|
||||
switch(scanner.stag) {
|
||||
case scanner.left_delimiter:
|
||||
if (content[content.length - 1] == '\n')
|
||||
{
|
||||
content = chop(content);
|
||||
buff.push(content);
|
||||
buff.cr();
|
||||
}
|
||||
else {
|
||||
buff.push(content);
|
||||
}
|
||||
break;
|
||||
case scanner.left_equal:
|
||||
buff.push(insert_cmd + "(EJS.Scanner.to_text(" + content + ")))");
|
||||
break;
|
||||
}
|
||||
scanner.stag = null;
|
||||
content = '';
|
||||
break;
|
||||
case scanner.double_right:
|
||||
content = content + scanner.right_delimiter;
|
||||
break;
|
||||
default:
|
||||
content = content + token;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (content.length > 0)
|
||||
{
|
||||
// Chould be content.dump in Ruby
|
||||
buff.push(put_cmd + '"' + clean(content) + '")');
|
||||
}
|
||||
buff.close();
|
||||
this.out = buff.script + ";";
|
||||
var to_be_evaled = '/*'+name+'*/this.process = function(_CONTEXT,_VIEW) { try { with(_VIEW) { with (_CONTEXT) {'+this.out+" return ___ViewO.join('');}}}catch(e){e.lineNumber=null;throw e;}};";
|
||||
|
||||
try{
|
||||
eval(to_be_evaled);
|
||||
}catch(e){
|
||||
if(typeof JSLINT != 'undefined'){
|
||||
JSLINT(this.out);
|
||||
for(var i = 0; i < JSLINT.errors.length; i++){
|
||||
var error = JSLINT.errors[i];
|
||||
if(error.reason != "Unnecessary semicolon."){
|
||||
error.line++;
|
||||
var e = new Error();
|
||||
e.lineNumber = error.line;
|
||||
e.message = error.reason;
|
||||
if(options.view)
|
||||
e.fileName = options.view;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//type, cache, folder
|
||||
/**
|
||||
* Sets default options for all views
|
||||
* @param {Object} options Set view with the following options
|
||||
* <table class="options">
|
||||
<tbody><tr><th>Option</th><th>Default</th><th>Description</th></tr>
|
||||
<tr>
|
||||
<td>type</td>
|
||||
<td>'<'</td>
|
||||
<td>type of magic tags. Options are '<' or '['
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>cache</td>
|
||||
<td>true in production mode, false in other modes</td>
|
||||
<td>true to cache template.
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
*
|
||||
*/
|
||||
EJS.config = function(options){
|
||||
EJS.cache = options.cache != null ? options.cache : EJS.cache;
|
||||
EJS.type = options.type != null ? options.type : EJS.type;
|
||||
EJS.ext = options.ext != null ? options.ext : EJS.ext;
|
||||
|
||||
var templates_directory = EJS.templates_directory || {}; //nice and private container
|
||||
EJS.templates_directory = templates_directory;
|
||||
EJS.get = function(path, cache){
|
||||
if(cache == false) return null;
|
||||
if(templates_directory[path]) return templates_directory[path];
|
||||
return null;
|
||||
};
|
||||
|
||||
EJS.update = function(path, template) {
|
||||
if(path == null) return;
|
||||
templates_directory[path] = template ;
|
||||
};
|
||||
|
||||
EJS.INVALID_PATH = -1;
|
||||
};
|
||||
EJS.config( {cache: true, type: '<', ext: '.ejs' } );
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* By adding functions to EJS.Helpers.prototype, those functions will be available in the
|
||||
* views.
|
||||
* @init Creates a view helper. This function is called internally. You should never call it.
|
||||
* @param {Object} data The data passed to the view. Helpers have access to it through this._data
|
||||
*/
|
||||
EJS.Helpers = function(data, extras){
|
||||
this._data = data;
|
||||
this._extras = extras;
|
||||
extend(this, extras );
|
||||
};
|
||||
/* @prototype*/
|
||||
EJS.Helpers.prototype = {
|
||||
/**
|
||||
* Renders a new view. If data is passed in, uses that to render the view.
|
||||
* @param {Object} options standard options passed to a new view.
|
||||
* @param {optional:Object} data
|
||||
* @return {String}
|
||||
*/
|
||||
view: function(options, data, helpers){
|
||||
if(!helpers) helpers = this._extras
|
||||
if(!data) data = this._data;
|
||||
return new EJS(options).render(data, helpers);
|
||||
},
|
||||
/**
|
||||
* For a given value, tries to create a human representation.
|
||||
* @param {Object} input the value being converted.
|
||||
* @param {Object} null_text what text should be present if input == null or undefined, defaults to ''
|
||||
* @return {String}
|
||||
*/
|
||||
to_text: function(input, null_text) {
|
||||
if(input == null || input === undefined) return null_text || '';
|
||||
if(input instanceof Date) return input.toDateString();
|
||||
if(input.toString) return input.toString().replace(/\n/g, '<br />').replace(/''/g, "'");
|
||||
return '';
|
||||
}
|
||||
};
|
||||
EJS.newRequest = function(){
|
||||
var factories = [function() { return new ActiveXObject("Msxml2.XMLHTTP"); },function() { return new XMLHttpRequest(); },function() { return new ActiveXObject("Microsoft.XMLHTTP"); }];
|
||||
for(var i = 0; i < factories.length; i++) {
|
||||
try {
|
||||
var request = factories[i]();
|
||||
if (request != null) return request;
|
||||
}
|
||||
catch(e) { continue;}
|
||||
}
|
||||
}
|
||||
|
||||
EJS.request = function(path){
|
||||
var request = new EJS.newRequest()
|
||||
request.open("GET", path, false);
|
||||
|
||||
try{request.send(null);}
|
||||
catch(e){return null;}
|
||||
|
||||
if ( request.status == 404 || request.status == 2 ||(request.status == 0 && request.responseText == '') ) return null;
|
||||
|
||||
return request.responseText
|
||||
}
|
||||
EJS.ajax_request = function(params){
|
||||
params.method = ( params.method ? params.method : 'GET')
|
||||
|
||||
var request = new EJS.newRequest();
|
||||
request.onreadystatechange = function(){
|
||||
if(request.readyState == 4){
|
||||
if(request.status == 200){
|
||||
params.onComplete(request)
|
||||
}else
|
||||
{
|
||||
params.onComplete(request)
|
||||
}
|
||||
}
|
||||
}
|
||||
request.open(params.method, params.url)
|
||||
request.send(null)
|
||||
}
|
||||
|
||||
|
||||
})();
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,431 @@
|
|||
/* Pretty handling of time axes.
|
||||
|
||||
Copyright (c) 2007-2013 IOLA and Ole Laursen.
|
||||
Licensed under the MIT license.
|
||||
|
||||
Set axis.mode to "time" to enable. See the section "Time series data" in
|
||||
API.txt for details.
|
||||
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
|
||||
var options = {
|
||||
xaxis: {
|
||||
timezone: null, // "browser" for local to the client or timezone for timezone-js
|
||||
timeformat: null, // format string to use
|
||||
twelveHourClock: false, // 12 or 24 time in time mode
|
||||
monthNames: null // list of names of months
|
||||
}
|
||||
};
|
||||
|
||||
// round to nearby lower multiple of base
|
||||
|
||||
function floorInBase(n, base) {
|
||||
return base * Math.floor(n / base);
|
||||
}
|
||||
|
||||
// Returns a string with the date d formatted according to fmt.
|
||||
// A subset of the Open Group's strftime format is supported.
|
||||
|
||||
function formatDate(d, fmt, monthNames, dayNames) {
|
||||
|
||||
if (typeof d.strftime == "function") {
|
||||
return d.strftime(fmt);
|
||||
}
|
||||
|
||||
var leftPad = function(n, pad) {
|
||||
n = "" + n;
|
||||
pad = "" + (pad == null ? "0" : pad);
|
||||
return n.length == 1 ? pad + n : n;
|
||||
};
|
||||
|
||||
var r = [];
|
||||
var escape = false;
|
||||
var hours = d.getHours();
|
||||
var isAM = hours < 12;
|
||||
|
||||
if (monthNames == null) {
|
||||
monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
||||
}
|
||||
|
||||
if (dayNames == null) {
|
||||
dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
||||
}
|
||||
|
||||
var hours12;
|
||||
|
||||
if (hours > 12) {
|
||||
hours12 = hours - 12;
|
||||
} else if (hours == 0) {
|
||||
hours12 = 12;
|
||||
} else {
|
||||
hours12 = hours;
|
||||
}
|
||||
|
||||
for (var i = 0; i < fmt.length; ++i) {
|
||||
|
||||
var c = fmt.charAt(i);
|
||||
|
||||
if (escape) {
|
||||
switch (c) {
|
||||
case 'a': c = "" + dayNames[d.getDay()]; break;
|
||||
case 'b': c = "" + monthNames[d.getMonth()]; break;
|
||||
case 'd': c = leftPad(d.getDate()); break;
|
||||
case 'e': c = leftPad(d.getDate(), " "); break;
|
||||
case 'h': // For back-compat with 0.7; remove in 1.0
|
||||
case 'H': c = leftPad(hours); break;
|
||||
case 'I': c = leftPad(hours12); break;
|
||||
case 'l': c = leftPad(hours12, " "); break;
|
||||
case 'm': c = leftPad(d.getMonth() + 1); break;
|
||||
case 'M': c = leftPad(d.getMinutes()); break;
|
||||
// quarters not in Open Group's strftime specification
|
||||
case 'q':
|
||||
c = "" + (Math.floor(d.getMonth() / 3) + 1); break;
|
||||
case 'S': c = leftPad(d.getSeconds()); break;
|
||||
case 'y': c = leftPad(d.getFullYear() % 100); break;
|
||||
case 'Y': c = "" + d.getFullYear(); break;
|
||||
case 'p': c = (isAM) ? ("" + "am") : ("" + "pm"); break;
|
||||
case 'P': c = (isAM) ? ("" + "AM") : ("" + "PM"); break;
|
||||
case 'w': c = "" + d.getDay(); break;
|
||||
}
|
||||
r.push(c);
|
||||
escape = false;
|
||||
} else {
|
||||
if (c == "%") {
|
||||
escape = true;
|
||||
} else {
|
||||
r.push(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return r.join("");
|
||||
}
|
||||
|
||||
// To have a consistent view of time-based data independent of which time
|
||||
// zone the client happens to be in we need a date-like object independent
|
||||
// of time zones. This is done through a wrapper that only calls the UTC
|
||||
// versions of the accessor methods.
|
||||
|
||||
function makeUtcWrapper(d) {
|
||||
|
||||
function addProxyMethod(sourceObj, sourceMethod, targetObj, targetMethod) {
|
||||
sourceObj[sourceMethod] = function() {
|
||||
return targetObj[targetMethod].apply(targetObj, arguments);
|
||||
};
|
||||
};
|
||||
|
||||
var utc = {
|
||||
date: d
|
||||
};
|
||||
|
||||
// support strftime, if found
|
||||
|
||||
if (d.strftime != undefined) {
|
||||
addProxyMethod(utc, "strftime", d, "strftime");
|
||||
}
|
||||
|
||||
addProxyMethod(utc, "getTime", d, "getTime");
|
||||
addProxyMethod(utc, "setTime", d, "setTime");
|
||||
|
||||
var props = ["Date", "Day", "FullYear", "Hours", "Milliseconds", "Minutes", "Month", "Seconds"];
|
||||
|
||||
for (var p = 0; p < props.length; p++) {
|
||||
addProxyMethod(utc, "get" + props[p], d, "getUTC" + props[p]);
|
||||
addProxyMethod(utc, "set" + props[p], d, "setUTC" + props[p]);
|
||||
}
|
||||
|
||||
return utc;
|
||||
};
|
||||
|
||||
// select time zone strategy. This returns a date-like object tied to the
|
||||
// desired timezone
|
||||
|
||||
function dateGenerator(ts, opts) {
|
||||
if (opts.timezone == "browser") {
|
||||
return new Date(ts);
|
||||
} else if (!opts.timezone || opts.timezone == "utc") {
|
||||
return makeUtcWrapper(new Date(ts));
|
||||
} else if (typeof timezoneJS != "undefined" && typeof timezoneJS.Date != "undefined") {
|
||||
var d = new timezoneJS.Date();
|
||||
// timezone-js is fickle, so be sure to set the time zone before
|
||||
// setting the time.
|
||||
d.setTimezone(opts.timezone);
|
||||
d.setTime(ts);
|
||||
return d;
|
||||
} else {
|
||||
return makeUtcWrapper(new Date(ts));
|
||||
}
|
||||
}
|
||||
|
||||
// map of app. size of time units in milliseconds
|
||||
|
||||
var timeUnitSize = {
|
||||
"second": 1000,
|
||||
"minute": 60 * 1000,
|
||||
"hour": 60 * 60 * 1000,
|
||||
"day": 24 * 60 * 60 * 1000,
|
||||
"month": 30 * 24 * 60 * 60 * 1000,
|
||||
"quarter": 3 * 30 * 24 * 60 * 60 * 1000,
|
||||
"year": 365.2425 * 24 * 60 * 60 * 1000
|
||||
};
|
||||
|
||||
// the allowed tick sizes, after 1 year we use
|
||||
// an integer algorithm
|
||||
|
||||
var baseSpec = [
|
||||
[1, "second"], [2, "second"], [5, "second"], [10, "second"],
|
||||
[30, "second"],
|
||||
[1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"],
|
||||
[30, "minute"],
|
||||
[1, "hour"], [2, "hour"], [4, "hour"],
|
||||
[8, "hour"], [12, "hour"],
|
||||
[1, "day"], [2, "day"], [3, "day"],
|
||||
[0.25, "month"], [0.5, "month"], [1, "month"],
|
||||
[2, "month"]
|
||||
];
|
||||
|
||||
// we don't know which variant(s) we'll need yet, but generating both is
|
||||
// cheap
|
||||
|
||||
var specMonths = baseSpec.concat([[3, "month"], [6, "month"],
|
||||
[1, "year"]]);
|
||||
var specQuarters = baseSpec.concat([[1, "quarter"], [2, "quarter"],
|
||||
[1, "year"]]);
|
||||
|
||||
function init(plot) {
|
||||
plot.hooks.processOptions.push(function (plot, options) {
|
||||
$.each(plot.getAxes(), function(axisName, axis) {
|
||||
|
||||
var opts = axis.options;
|
||||
|
||||
if (opts.mode == "time") {
|
||||
axis.tickGenerator = function(axis) {
|
||||
|
||||
var ticks = [];
|
||||
var d = dateGenerator(axis.min, opts);
|
||||
var minSize = 0;
|
||||
|
||||
// make quarter use a possibility if quarters are
|
||||
// mentioned in either of these options
|
||||
|
||||
var spec = (opts.tickSize && opts.tickSize[1] ===
|
||||
"quarter") ||
|
||||
(opts.minTickSize && opts.minTickSize[1] ===
|
||||
"quarter") ? specQuarters : specMonths;
|
||||
|
||||
if (opts.minTickSize != null) {
|
||||
if (typeof opts.tickSize == "number") {
|
||||
minSize = opts.tickSize;
|
||||
} else {
|
||||
minSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]];
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < spec.length - 1; ++i) {
|
||||
if (axis.delta < (spec[i][0] * timeUnitSize[spec[i][1]]
|
||||
+ spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2
|
||||
&& spec[i][0] * timeUnitSize[spec[i][1]] >= minSize) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var size = spec[i][0];
|
||||
var unit = spec[i][1];
|
||||
|
||||
// special-case the possibility of several years
|
||||
|
||||
if (unit == "year") {
|
||||
|
||||
// if given a minTickSize in years, just use it,
|
||||
// ensuring that it's an integer
|
||||
|
||||
if (opts.minTickSize != null && opts.minTickSize[1] == "year") {
|
||||
size = Math.floor(opts.minTickSize[0]);
|
||||
} else {
|
||||
|
||||
var magn = Math.pow(10, Math.floor(Math.log(axis.delta / timeUnitSize.year) / Math.LN10));
|
||||
var norm = (axis.delta / timeUnitSize.year) / magn;
|
||||
|
||||
if (norm < 1.5) {
|
||||
size = 1;
|
||||
} else if (norm < 3) {
|
||||
size = 2;
|
||||
} else if (norm < 7.5) {
|
||||
size = 5;
|
||||
} else {
|
||||
size = 10;
|
||||
}
|
||||
|
||||
size *= magn;
|
||||
}
|
||||
|
||||
// minimum size for years is 1
|
||||
|
||||
if (size < 1) {
|
||||
size = 1;
|
||||
}
|
||||
}
|
||||
|
||||
axis.tickSize = opts.tickSize || [size, unit];
|
||||
var tickSize = axis.tickSize[0];
|
||||
unit = axis.tickSize[1];
|
||||
|
||||
var step = tickSize * timeUnitSize[unit];
|
||||
|
||||
if (unit == "second") {
|
||||
d.setSeconds(floorInBase(d.getSeconds(), tickSize));
|
||||
} else if (unit == "minute") {
|
||||
d.setMinutes(floorInBase(d.getMinutes(), tickSize));
|
||||
} else if (unit == "hour") {
|
||||
d.setHours(floorInBase(d.getHours(), tickSize));
|
||||
} else if (unit == "month") {
|
||||
d.setMonth(floorInBase(d.getMonth(), tickSize));
|
||||
} else if (unit == "quarter") {
|
||||
d.setMonth(3 * floorInBase(d.getMonth() / 3,
|
||||
tickSize));
|
||||
} else if (unit == "year") {
|
||||
d.setFullYear(floorInBase(d.getFullYear(), tickSize));
|
||||
}
|
||||
|
||||
// reset smaller components
|
||||
|
||||
d.setMilliseconds(0);
|
||||
|
||||
if (step >= timeUnitSize.minute) {
|
||||
d.setSeconds(0);
|
||||
}
|
||||
if (step >= timeUnitSize.hour) {
|
||||
d.setMinutes(0);
|
||||
}
|
||||
if (step >= timeUnitSize.day) {
|
||||
d.setHours(0);
|
||||
}
|
||||
if (step >= timeUnitSize.day * 4) {
|
||||
d.setDate(1);
|
||||
}
|
||||
if (step >= timeUnitSize.month * 2) {
|
||||
d.setMonth(floorInBase(d.getMonth(), 3));
|
||||
}
|
||||
if (step >= timeUnitSize.quarter * 2) {
|
||||
d.setMonth(floorInBase(d.getMonth(), 6));
|
||||
}
|
||||
if (step >= timeUnitSize.year) {
|
||||
d.setMonth(0);
|
||||
}
|
||||
|
||||
var carry = 0;
|
||||
var v = Number.NaN;
|
||||
var prev;
|
||||
|
||||
do {
|
||||
|
||||
prev = v;
|
||||
v = d.getTime();
|
||||
ticks.push(v);
|
||||
|
||||
if (unit == "month" || unit == "quarter") {
|
||||
if (tickSize < 1) {
|
||||
|
||||
// a bit complicated - we'll divide the
|
||||
// month/quarter up but we need to take
|
||||
// care of fractions so we don't end up in
|
||||
// the middle of a day
|
||||
|
||||
d.setDate(1);
|
||||
var start = d.getTime();
|
||||
d.setMonth(d.getMonth() +
|
||||
(unit == "quarter" ? 3 : 1));
|
||||
var end = d.getTime();
|
||||
d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize);
|
||||
carry = d.getHours();
|
||||
d.setHours(0);
|
||||
} else {
|
||||
d.setMonth(d.getMonth() +
|
||||
tickSize * (unit == "quarter" ? 3 : 1));
|
||||
}
|
||||
} else if (unit == "year") {
|
||||
d.setFullYear(d.getFullYear() + tickSize);
|
||||
} else {
|
||||
d.setTime(v + step);
|
||||
}
|
||||
} while (v < axis.max && v != prev);
|
||||
|
||||
return ticks;
|
||||
};
|
||||
|
||||
axis.tickFormatter = function (v, axis) {
|
||||
|
||||
var d = dateGenerator(v, axis.options);
|
||||
|
||||
// first check global format
|
||||
|
||||
if (opts.timeformat != null) {
|
||||
return formatDate(d, opts.timeformat, opts.monthNames, opts.dayNames);
|
||||
}
|
||||
|
||||
// possibly use quarters if quarters are mentioned in
|
||||
// any of these places
|
||||
|
||||
var useQuarters = (axis.options.tickSize &&
|
||||
axis.options.tickSize[1] == "quarter") ||
|
||||
(axis.options.minTickSize &&
|
||||
axis.options.minTickSize[1] == "quarter");
|
||||
|
||||
var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]];
|
||||
var span = axis.max - axis.min;
|
||||
var suffix = (opts.twelveHourClock) ? " %p" : "";
|
||||
var hourCode = (opts.twelveHourClock) ? "%I" : "%H";
|
||||
var fmt;
|
||||
|
||||
if (t < timeUnitSize.minute) {
|
||||
fmt = hourCode + ":%M:%S" + suffix;
|
||||
} else if (t < timeUnitSize.day) {
|
||||
if (span < 2 * timeUnitSize.day) {
|
||||
fmt = hourCode + ":%M" + suffix;
|
||||
} else {
|
||||
fmt = "%b %d " + hourCode + ":%M" + suffix;
|
||||
}
|
||||
} else if (t < timeUnitSize.month) {
|
||||
fmt = "%b %d";
|
||||
} else if ((useQuarters && t < timeUnitSize.quarter) ||
|
||||
(!useQuarters && t < timeUnitSize.year)) {
|
||||
if (span < timeUnitSize.year) {
|
||||
fmt = "%b";
|
||||
} else {
|
||||
fmt = "%b %Y";
|
||||
}
|
||||
} else if (useQuarters && t < timeUnitSize.year) {
|
||||
if (span < timeUnitSize.year) {
|
||||
fmt = "Q%q";
|
||||
} else {
|
||||
fmt = "Q%q %Y";
|
||||
}
|
||||
} else {
|
||||
fmt = "%Y";
|
||||
}
|
||||
|
||||
var rt = formatDate(d, fmt, opts.monthNames, opts.dayNames);
|
||||
|
||||
return rt;
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$.plot.plugins.push({
|
||||
init: init,
|
||||
options: options,
|
||||
name: 'time',
|
||||
version: '1.0'
|
||||
});
|
||||
|
||||
// Time-axis support used to be in Flot core, which exposed the
|
||||
// formatDate function on the plot object. Various plugins depend
|
||||
// on the function, so we need to re-expose it here.
|
||||
|
||||
$.plot.formatDate = formatDate;
|
||||
|
||||
})(jQuery);
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue