Refactor x-axis labelling.

This commit is contained in:
Olly Smith 2012-04-01 22:29:37 +01:00
parent 18b4191093
commit fc4ff279a5
5 changed files with 517 additions and 171 deletions

View File

@ -15,15 +15,15 @@
// data stolen from http://howmanyleft.co.uk/vehicle/jaguar_'e'_type
var day_data = [
{"period": "2012-10-01", "licensed": 3407, "sorned": 660},
{"period": "2011-08-12", "licensed": 3351, "sorned": 629},
{"period": "2011-03-03", "licensed": 3269, "sorned": 618},
{"period": "2010-08-08", "licensed": 3246, "sorned": 661},
{"period": "2010-05-10", "licensed": 3257, "sorned": 667},
{"period": "2010-03-14", "licensed": 3248, "sorned": 627},
{"period": "2010-01-10", "licensed": 3171, "sorned": 660},
{"period": "2009-12-10", "licensed": 3171, "sorned": 676},
{"period": "2009-10-07", "licensed": 3201, "sorned": 656},
{"period": "2009-09-25", "licensed": 3215, "sorned": 622},
{"period": "2012-09-30", "licensed": 3351, "sorned": 629},
{"period": "2012-09-29", "licensed": 3269, "sorned": 618},
{"period": "2012-09-20", "licensed": 3246, "sorned": 661},
{"period": "2012-09-19", "licensed": 3257, "sorned": 667},
{"period": "2012-09-18", "licensed": 3248, "sorned": 627},
{"period": "2012-09-17", "licensed": 3171, "sorned": 660},
{"period": "2012-09-16", "licensed": 3171, "sorned": 676},
{"period": "2012-09-15", "licensed": 3201, "sorned": 656},
{"period": "2012-09-10", "licensed": 3215, "sorned": 622},
];
Morris.Line({
element: 'graph',

View File

@ -82,7 +82,7 @@ class Morris.Line
# translate x labels into nominal dates
# note: currently using decimal years to specify dates
if @options.parseTime
@xvals = $.map @columnLabels, (x) => @parseDate x
@xvals = $.map @columnLabels, (x) -> Morris.parseDate x
else
@xvals = [(@columnLabels.length-1)..0]
# translate column labels, if they're timestamps
@ -198,7 +198,7 @@ class Morris.Line
for lineY in [firstY..lastY] by yInterval
v = Math.floor(lineY)
y = @transY(v)
@r.text(@left - @options.marginLeft/2, y, @commas(v) + @options.units)
@r.text(@left - @options.marginLeft/2, y, Morris.commas(v) + @options.units)
.attr('font-size', @options.gridTextSize)
.attr('fill', @options.gridTextColor)
.attr('text-anchor', 'end')
@ -207,23 +207,11 @@ class Morris.Line
.attr('stroke-width', @options.gridStrokeWidth)
## draw x axis labels
prevLabelMargin = null
ypos = @options.marginTop + @height + @options.marginBottom / 2
xLabelMargin = 50 # make this an option?
if @options.parseTime
x1 = new Date(@xmin).getFullYear()
x2 = new Date(@xmax).getFullYear()
else
x1 = 0
x2 = @columnLabels.length
for i in [x1..x2]
if @options.parseTime
xpos = new Date(i, 0, 1).getTime()
if xpos < @xmin
continue
else
xpos = i
labelText = if @options.parseTime then i else @columnLabels[@columnLabels.length-i-1]
label = @r.text(@transX(xpos), @options.marginTop + @height + @options.marginBottom / 2, labelText)
prevLabelMargin = null
drawLabel = (labelText, xpos) =>
label = @r.text(@transX(xpos), ypos, labelText)
.attr('font-size', @options.gridTextSize)
.attr('fill', @options.gridTextColor)
labelBox = label.getBBox()
@ -232,6 +220,13 @@ class Morris.Line
prevLabelMargin = labelBox.x + labelBox.width + xLabelMargin
else
label.remove()
if @options.parseTime
for l in Morris.labelSeries(@xmin, @xmax, @width, xLabelMargin)
drawLabel(l[0], l[1])
else
for i in [0..@columnLabels.length]
labelText = @columnLabels[@columnLabels.length - i - 1]
drawLabel(labelText, i)
# draw the data series
#
@ -320,7 +315,7 @@ class Morris.Line
@hoverSet.show()
@xLabel.attr('text', @columnLabels[index])
for i in [0..@series.length-1]
@yLabels[i].attr('text', "#{@seriesLabels[i]}: #{@commas(@series[i][index])}#{@options.units}")
@yLabels[i].attr('text', "#{@seriesLabels[i]}: #{Morris.commas(@series[i][index])}#{@options.units}")
# recalculate hover box width
maxLabelWidth = Math.max.apply null, $.map @yLabels, (l) ->
l.getBBox().width
@ -370,75 +365,143 @@ class Morris.Line
tt.remove()
return ret
parseDate: (date) ->
if typeof date is 'number'
return date
m = date.match /^(\d+) Q(\d)$/
n = date.match /^(\d+)-(\d+)$/
o = date.match /^(\d+)-(\d+)-(\d+)$/
p = date.match /^(\d+) W(\d+)$/
q = date.match /^(\d+)-(\d+)-(\d+)[ T](\d+):(\d+)Z?$/
r = date.match /^(\d+)-(\d+)-(\d+)[ T](\d+):(\d+):(\d+(\.\d+)?)Z?$/
if m
new Date(
parseInt(m[1], 10),
parseInt(m[2], 10) * 3 - 1,
1).getTime()
else if n
new Date(
parseInt(n[1], 10),
parseInt(n[2], 10) - 1,
1).getTime()
else if o
new Date(
parseInt(o[1], 10),
parseInt(o[2], 10) - 1,
parseInt(o[3], 10)).getTime()
else if p
# calculate number of weeks in year given
ret = new Date(parseInt(p[1], 10), 0, 1);
# first thursday in year (ISO 8601 standard)
if ret.getDay() isnt 4
ret.setMonth(0, 1 + ((4 - ret.getDay()) + 7) % 7);
# add weeks
ret.getTime() + parseInt(p[2], 10) * 604800000
else if q
new Date(
parseInt(q[1], 10),
parseInt(q[2], 10) - 1,
parseInt(q[3], 10),
parseInt(q[4], 10),
parseInt(q[5], 10)).getTime()
else if r
secs = parseFloat(r[6])
isecs = Math.floor(secs)
msecs = Math.floor((secs - isecs) * 1000)
new Date(
parseInt(r[1], 10),
parseInt(r[2], 10) - 1,
parseInt(r[3], 10),
parseInt(r[4], 10),
parseInt(r[5], 10),
isecs,
msecs).getTime()
else
new Date(parseInt(date, 10), 0, 1)
# parse a date into a javascript timestamp
#
Morris.parseDate = (date) ->
if typeof date is 'number'
return date
m = date.match /^(\d+) Q(\d)$/
n = date.match /^(\d+)-(\d+)$/
o = date.match /^(\d+)-(\d+)-(\d+)$/
p = date.match /^(\d+) W(\d+)$/
q = date.match /^(\d+)-(\d+)-(\d+)[ T](\d+):(\d+)Z?$/
r = date.match /^(\d+)-(\d+)-(\d+)[ T](\d+):(\d+):(\d+(\.\d+)?)Z?$/
if m
new Date(
parseInt(m[1], 10),
parseInt(m[2], 10) * 3 - 1,
1).getTime()
else if n
new Date(
parseInt(n[1], 10),
parseInt(n[2], 10) - 1,
1).getTime()
else if o
new Date(
parseInt(o[1], 10),
parseInt(o[2], 10) - 1,
parseInt(o[3], 10)).getTime()
else if p
# calculate number of weeks in year given
ret = new Date(parseInt(p[1], 10), 0, 1);
# first thursday in year (ISO 8601 standard)
if ret.getDay() isnt 4
ret.setMonth(0, 1 + ((4 - ret.getDay()) + 7) % 7);
# add weeks
ret.getTime() + parseInt(p[2], 10) * 604800000
else if q
new Date(
parseInt(q[1], 10),
parseInt(q[2], 10) - 1,
parseInt(q[3], 10),
parseInt(q[4], 10),
parseInt(q[5], 10)).getTime()
else if r
secs = parseFloat(r[6])
isecs = Math.floor(secs)
msecs = Math.round((secs - isecs) * 1000)
new Date(
parseInt(r[1], 10),
parseInt(r[2], 10) - 1,
parseInt(r[3], 10),
parseInt(r[4], 10),
parseInt(r[5], 10),
isecs,
msecs).getTime()
else
new Date(parseInt(date, 10), 0, 1).getTime()
# make long numbers prettier by inserting commas
# eg: commas(1234567) -> '1,234,567'
#
commas: (num) ->
if num is null
"n/a"
else
ret = if num < 0 then "-" else ""
absnum = Math.abs(num)
intnum = Math.floor(absnum).toFixed(0)
ret += intnum.replace(/(?=(?:\d{3})+$)(?!^)/g, ',')
strabsnum = absnum.toString()
if strabsnum.length > intnum.length
ret += strabsnum.slice(intnum.length)
ret
# make long numbers prettier by inserting commas
# eg: commas(1234567) -> '1,234,567'
#
Morris.commas = (num) ->
if num is null
"n/a"
else
ret = if num < 0 then "-" else ""
absnum = Math.abs(num)
intnum = Math.floor(absnum).toFixed(0)
ret += intnum.replace(/(?=(?:\d{3})+$)(?!^)/g, ',')
strabsnum = absnum.toString()
if strabsnum.length > intnum.length
ret += strabsnum.slice(intnum.length)
ret
# zero-pad numbers to two characters wide
#
Morris.pad2 = (number) -> (if number < 10 then '0' else '') + number
# generate a series of label, timestamp pairs for x-axis labels
#
Morris.labelSeries = (dmin, dmax, pxwidth) ->
ddensity = 200 * (dmax - dmin) / pxwidth # seconds per `margin` pixels
d0 = new Date(dmin)
for s in Morris.LABEL_SPECS
if ddensity >= s.span or s.span == Morris.LABEL_SPECS[Morris.LABEL_SPECS.length - 1].span
d = s.start(d0)
ret = []
while (t = d.getTime()) <= dmax
if t >= dmin
ret.push [s.fmt(d), t]
s.incr(d)
return ret
minutesSpecHelper = (interval) ->
{
span: interval * 60 * 1000
start: (d) -> new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours())
fmt: (d) -> "#{Morris.pad2(d.getHours())}:#{Morris.pad2(d.getMinutes())}"
incr: (d) -> d.setMinutes(d.getMinutes() + interval)
}
secondsSpecHelper = (interval) ->
{
span: interval * 1000
start: (d) -> new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes())
fmt: (d) -> "#{Morris.pad2(d.getHours())}:#{Morris.pad2(d.getMinutes())}:#{Morris.pad2(d.getSeconds())}"
incr: (d) -> d.setSeconds(d.getSeconds() + interval)
}
Morris.LABEL_SPECS = [
{
span: 17280000000 # 365 * 24 * 60 * 60 * 1000
start: (d) -> new Date(d.getFullYear(), 0, 1)
fmt: (d) -> "#{d.getFullYear()}"
incr: (d) -> d.setFullYear(d.getFullYear() + 1)
}
{
span: 2419200000 # 28 * 24 * 60 * 60 * 1000
start: (d) -> new Date(d.getFullYear(), d.getMonth(), 1)
fmt: (d) -> "#{d.getFullYear()}-#{Morris.pad2(d.getMonth() + 1)}"
incr: (d) -> d.setMonth(d.getMonth() + 1)
}
{
span: 86400000 # 24 * 60 * 60 * 1000
start: (d) -> new Date(d.getFullYear(), d.getMonth(), d.getDate())
fmt: (d) -> "#{d.getFullYear()}-#{Morris.pad2(d.getMonth() + 1)}-#{Morris.pad2(d.getDate())}"
incr: (d) -> d.setDate(d.getDate() + 1)
}
minutesSpecHelper(60)
minutesSpecHelper(30)
minutesSpecHelper(15)
minutesSpecHelper(10)
minutesSpecHelper(5)
minutesSpecHelper(1)
secondsSpecHelper(30)
secondsSpecHelper(15)
secondsSpecHelper(10)
secondsSpecHelper(5)
secondsSpecHelper(1)
]
window.Morris = Morris
# vim: set et ts=2 sw=2 sts=2

239
morris.js
View File

@ -1,5 +1,5 @@
(function() {
var $, Morris,
var $, Morris, minutesSpecHelper, secondsSpecHelper,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
$ = jQuery;
@ -83,7 +83,7 @@
}
if (this.options.parseTime) {
this.xvals = $.map(this.columnLabels, function(x) {
return _this.parseDate(x);
return Morris.parseDate(x);
});
} else {
this.xvals = (function() {
@ -219,43 +219,46 @@
};
Line.prototype.drawGrid = function() {
var firstY, i, label, labelBox, labelText, lastY, lineY, prevLabelMargin, v, x1, x2, xLabelMargin, xpos, y, yInterval, _results;
var drawLabel, firstY, i, l, labelText, lastY, lineY, prevLabelMargin, v, xLabelMargin, y, yInterval, ypos, _i, _len, _ref, _ref2, _results, _results2,
_this = this;
yInterval = (this.options.ymax - this.options.ymin) / (this.options.numLines - 1);
firstY = Math.ceil(this.options.ymin / yInterval) * yInterval;
lastY = Math.floor(this.options.ymax / yInterval) * yInterval;
for (lineY = firstY; firstY <= lastY ? lineY <= lastY : lineY >= lastY; lineY += yInterval) {
v = Math.floor(lineY);
y = this.transY(v);
this.r.text(this.left - this.options.marginLeft / 2, y, this.commas(v) + this.options.units).attr('font-size', this.options.gridTextSize).attr('fill', this.options.gridTextColor).attr('text-anchor', 'end');
this.r.text(this.left - this.options.marginLeft / 2, y, Morris.commas(v) + this.options.units).attr('font-size', this.options.gridTextSize).attr('fill', this.options.gridTextColor).attr('text-anchor', 'end');
this.r.path("M" + this.left + "," + y + "H" + (this.left + this.width)).attr('stroke', this.options.gridLineColor).attr('stroke-width', this.options.gridStrokeWidth);
}
prevLabelMargin = null;
ypos = this.options.marginTop + this.height + this.options.marginBottom / 2;
xLabelMargin = 50;
if (this.options.parseTime) {
x1 = new Date(this.xmin).getFullYear();
x2 = new Date(this.xmax).getFullYear();
} else {
x1 = 0;
x2 = this.columnLabels.length;
}
_results = [];
for (i = x1; x1 <= x2 ? i <= x2 : i >= x2; x1 <= x2 ? i++ : i--) {
if (this.options.parseTime) {
xpos = new Date(i, 0, 1).getTime();
if (xpos < this.xmin) continue;
} else {
xpos = i;
}
labelText = this.options.parseTime ? i : this.columnLabels[this.columnLabels.length - i - 1];
label = this.r.text(this.transX(xpos), this.options.marginTop + this.height + this.options.marginBottom / 2, labelText).attr('font-size', this.options.gridTextSize).attr('fill', this.options.gridTextColor);
prevLabelMargin = null;
drawLabel = function(labelText, xpos) {
var label, labelBox;
label = _this.r.text(_this.transX(xpos), ypos, labelText).attr('font-size', _this.options.gridTextSize).attr('fill', _this.options.gridTextColor);
labelBox = label.getBBox();
if (prevLabelMargin === null || prevLabelMargin <= labelBox.x) {
_results.push(prevLabelMargin = labelBox.x + labelBox.width + xLabelMargin);
return prevLabelMargin = labelBox.x + labelBox.width + xLabelMargin;
} else {
_results.push(label.remove());
return label.remove();
}
};
if (this.options.parseTime) {
_ref = Morris.labelSeries(this.xmin, this.xmax, this.width, xLabelMargin);
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
l = _ref[_i];
_results.push(drawLabel(l[0], l[1]));
}
return _results;
} else {
_results2 = [];
for (i = 0, _ref2 = this.columnLabels.length; 0 <= _ref2 ? i <= _ref2 : i >= _ref2; 0 <= _ref2 ? i++ : i--) {
labelText = this.columnLabels[this.columnLabels.length - i - 1];
_results2.push(drawLabel(labelText, i));
}
return _results2;
}
return _results;
};
Line.prototype.drawSeries = function() {
@ -364,7 +367,7 @@
this.hoverSet.show();
this.xLabel.attr('text', this.columnLabels[index]);
for (i = 0, _ref = this.series.length - 1; 0 <= _ref ? i <= _ref : i >= _ref; 0 <= _ref ? i++ : i--) {
this.yLabels[i].attr('text', "" + this.seriesLabels[i] + ": " + (this.commas(this.series[i][index])) + this.options.units);
this.yLabels[i].attr('text', "" + this.seriesLabels[i] + ": " + (Morris.commas(this.series[i][index])) + this.options.units);
}
maxLabelWidth = Math.max.apply(null, $.map(this.yLabels, function(l) {
return l.getBBox().width;
@ -436,58 +439,146 @@
return ret;
};
Line.prototype.parseDate = function(date) {
var isecs, m, msecs, n, o, p, q, r, ret, secs;
if (typeof date === 'number') return date;
m = date.match(/^(\d+) Q(\d)$/);
n = date.match(/^(\d+)-(\d+)$/);
o = date.match(/^(\d+)-(\d+)-(\d+)$/);
p = date.match(/^(\d+) W(\d+)$/);
q = date.match(/^(\d+)-(\d+)-(\d+)[ T](\d+):(\d+)Z?$/);
r = date.match(/^(\d+)-(\d+)-(\d+)[ T](\d+):(\d+):(\d+(\.\d+)?)Z?$/);
if (m) {
return new Date(parseInt(m[1], 10), parseInt(m[2], 10) * 3 - 1, 1).getTime();
} else if (n) {
return new Date(parseInt(n[1], 10), parseInt(n[2], 10) - 1, 1).getTime();
} else if (o) {
return new Date(parseInt(o[1], 10), parseInt(o[2], 10) - 1, parseInt(o[3], 10)).getTime();
} else if (p) {
ret = new Date(parseInt(p[1], 10), 0, 1);
if (ret.getDay() !== 4) ret.setMonth(0, 1 + ((4 - ret.getDay()) + 7) % 7);
return ret.getTime() + parseInt(p[2], 10) * 604800000;
} else if (q) {
return new Date(parseInt(q[1], 10), parseInt(q[2], 10) - 1, parseInt(q[3], 10), parseInt(q[4], 10), parseInt(q[5], 10)).getTime();
} else if (r) {
secs = parseFloat(r[6]);
isecs = Math.floor(secs);
msecs = Math.floor((secs - isecs) * 1000);
return new Date(parseInt(r[1], 10), parseInt(r[2], 10) - 1, parseInt(r[3], 10), parseInt(r[4], 10), parseInt(r[5], 10), isecs, msecs).getTime();
} else {
return new Date(parseInt(date, 10), 0, 1);
}
};
Line.prototype.commas = function(num) {
var absnum, intnum, ret, strabsnum;
if (num === null) {
return "n/a";
} else {
ret = num < 0 ? "-" : "";
absnum = Math.abs(num);
intnum = Math.floor(absnum).toFixed(0);
ret += intnum.replace(/(?=(?:\d{3})+$)(?!^)/g, ',');
strabsnum = absnum.toString();
if (strabsnum.length > intnum.length) {
ret += strabsnum.slice(intnum.length);
}
return ret;
}
};
return Line;
})();
Morris.parseDate = function(date) {
var isecs, m, msecs, n, o, p, q, r, ret, secs;
if (typeof date === 'number') return date;
m = date.match(/^(\d+) Q(\d)$/);
n = date.match(/^(\d+)-(\d+)$/);
o = date.match(/^(\d+)-(\d+)-(\d+)$/);
p = date.match(/^(\d+) W(\d+)$/);
q = date.match(/^(\d+)-(\d+)-(\d+)[ T](\d+):(\d+)Z?$/);
r = date.match(/^(\d+)-(\d+)-(\d+)[ T](\d+):(\d+):(\d+(\.\d+)?)Z?$/);
if (m) {
return new Date(parseInt(m[1], 10), parseInt(m[2], 10) * 3 - 1, 1).getTime();
} else if (n) {
return new Date(parseInt(n[1], 10), parseInt(n[2], 10) - 1, 1).getTime();
} else if (o) {
return new Date(parseInt(o[1], 10), parseInt(o[2], 10) - 1, parseInt(o[3], 10)).getTime();
} else if (p) {
ret = new Date(parseInt(p[1], 10), 0, 1);
if (ret.getDay() !== 4) ret.setMonth(0, 1 + ((4 - ret.getDay()) + 7) % 7);
return ret.getTime() + parseInt(p[2], 10) * 604800000;
} else if (q) {
return new Date(parseInt(q[1], 10), parseInt(q[2], 10) - 1, parseInt(q[3], 10), parseInt(q[4], 10), parseInt(q[5], 10)).getTime();
} else if (r) {
secs = parseFloat(r[6]);
isecs = Math.floor(secs);
msecs = Math.round((secs - isecs) * 1000);
return new Date(parseInt(r[1], 10), parseInt(r[2], 10) - 1, parseInt(r[3], 10), parseInt(r[4], 10), parseInt(r[5], 10), isecs, msecs).getTime();
} else {
return new Date(parseInt(date, 10), 0, 1).getTime();
}
};
Morris.commas = function(num) {
var absnum, intnum, ret, strabsnum;
if (num === null) {
return "n/a";
} else {
ret = num < 0 ? "-" : "";
absnum = Math.abs(num);
intnum = Math.floor(absnum).toFixed(0);
ret += intnum.replace(/(?=(?:\d{3})+$)(?!^)/g, ',');
strabsnum = absnum.toString();
if (strabsnum.length > intnum.length) ret += strabsnum.slice(intnum.length);
return ret;
}
};
Morris.pad2 = function(number) {
return (number < 10 ? '0' : '') + number;
};
Morris.labelSeries = function(dmin, dmax, pxwidth) {
var d, d0, ddensity, ret, s, t, _i, _len, _ref;
ddensity = 200 * (dmax - dmin) / pxwidth;
d0 = new Date(dmin);
_ref = Morris.LABEL_SPECS;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
s = _ref[_i];
if (ddensity >= s.span || s.span === Morris.LABEL_SPECS[Morris.LABEL_SPECS.length - 1].span) {
d = s.start(d0);
ret = [];
while ((t = d.getTime()) <= dmax) {
if (t >= dmin) ret.push([s.fmt(d), t]);
s.incr(d);
}
return ret;
}
}
};
minutesSpecHelper = function(interval) {
return {
span: interval * 60 * 1000,
start: function(d) {
return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours());
},
fmt: function(d) {
return "" + (Morris.pad2(d.getHours())) + ":" + (Morris.pad2(d.getMinutes()));
},
incr: function(d) {
return d.setMinutes(d.getMinutes() + interval);
}
};
};
secondsSpecHelper = function(interval) {
return {
span: interval * 1000,
start: function(d) {
return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes());
},
fmt: function(d) {
return "" + (Morris.pad2(d.getHours())) + ":" + (Morris.pad2(d.getMinutes())) + ":" + (Morris.pad2(d.getSeconds()));
},
incr: function(d) {
return d.setSeconds(d.getSeconds() + interval);
}
};
};
Morris.LABEL_SPECS = [
{
span: 17280000000,
start: function(d) {
return new Date(d.getFullYear(), 0, 1);
},
fmt: function(d) {
return "" + (d.getFullYear());
},
incr: function(d) {
return d.setFullYear(d.getFullYear() + 1);
}
}, {
span: 2419200000,
start: function(d) {
return new Date(d.getFullYear(), d.getMonth(), 1);
},
fmt: function(d) {
return "" + (d.getFullYear()) + "-" + (Morris.pad2(d.getMonth() + 1));
},
incr: function(d) {
return d.setMonth(d.getMonth() + 1);
}
}, {
span: 86400000,
start: function(d) {
return new Date(d.getFullYear(), d.getMonth(), d.getDate());
},
fmt: function(d) {
return "" + (d.getFullYear()) + "-" + (Morris.pad2(d.getMonth() + 1)) + "-" + (Morris.pad2(d.getDate()));
},
incr: function(d) {
return d.setDate(d.getDate() + 1);
}
}, minutesSpecHelper(60), minutesSpecHelper(30), minutesSpecHelper(15), minutesSpecHelper(10), minutesSpecHelper(5), minutesSpecHelper(1), secondsSpecHelper(30), secondsSpecHelper(15), secondsSpecHelper(10), secondsSpecHelper(5), secondsSpecHelper(1)
];
window.Morris = Morris;
}).call(this);

2
morris.min.js vendored

File diff suppressed because one or more lines are too long

192
test.html Normal file
View File

@ -0,0 +1,192 @@
<!doctype html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/qunit/git/qunit.css" type="text/css" media="screen" />
<script type="text/javascript" src="http://code.jquery.com/qunit/git/qunit.js"></script>
<script type="text/javascript" src="morris.js"></script>
<script>
$(document).ready(function(){
module("Morris");
test("Morris.commas", function () {
// zero
equal(Morris.commas(0), "0", "commas(0) = 0")
// positive integers
equal(Morris.commas(1), "1", "commas(1) = 1")
equal(Morris.commas(12), "12", "commas(12) = 12")
equal(Morris.commas(123), "123", "commas(123) = 123");
equal(Morris.commas(1234), "1,234", "commas(1234) = 1,234");
equal(Morris.commas(12345), "12,345", "commas(12345) = 12,345");
equal(Morris.commas(123456), "123,456", "commas(123456) = 123,456");
equal(Morris.commas(1234567), "1,234,567", "commas(1234567) = 1,234,567");
// negative integers
equal(Morris.commas(-1), "-1", "commas(-1) = -1")
equal(Morris.commas(-12), "-12", "commas(-12) = -12")
equal(Morris.commas(-123), "-123", "commas(-123) = -123");
equal(Morris.commas(-1234), "-1,234", "commas(-1234) = -1,234");
equal(Morris.commas(-12345), "-12,345", "commas(-12345) = -12,345");
equal(Morris.commas(-123456), "-123,456", "commas(-123456) = -123,456");
equal(Morris.commas(-1234567), "-1,234,567", "commas(-1234567) = -1,234,567");
// positive decimals
equal(Morris.commas(1.2), "1.2", "commas(1.2) = 1.2")
equal(Morris.commas(12.34), "12.34", "commas(12.34) = 12.34")
equal(Morris.commas(123.456), "123.456", "commas(123.456) = 123.456")
equal(Morris.commas(1234.56), "1,234.56", "commas(1234.56) = 1,234.56")
// negative decimals
equal(Morris.commas(-1.2), "-1.2", "commas(-1.2) = -1.2")
equal(Morris.commas(-12.34), "-12.34", "commas(-12.34) = -12.34")
equal(Morris.commas(-123.456), "-123.456", "commas(-123.456) = -123.456")
equal(Morris.commas(-1234.56), "-1,234.56", "commas(-1234.56) = -1,234.56")
});
test("Morris.pad2", function () {
equal(Morris.pad2(0), "00", "pad2(0) = 0")
equal(Morris.pad2(1), "01", "pad2(1) = 1")
equal(Morris.pad2(2), "02", "pad2(2) = 2")
equal(Morris.pad2(3), "03", "pad2(3) = 3")
equal(Morris.pad2(4), "04", "pad2(4) = 4")
equal(Morris.pad2(5), "05", "pad2(5) = 5")
equal(Morris.pad2(6), "06", "pad2(6) = 6")
equal(Morris.pad2(7), "07", "pad2(7) = 7")
equal(Morris.pad2(8), "08", "pad2(8) = 8")
equal(Morris.pad2(9), "09", "pad2(9) = 9")
equal(Morris.pad2(10), "10", "pad2(10) = 10")
equal(Morris.pad2(12), "12", "pad2(12) = 12")
equal(Morris.pad2(34), "34", "pad2(34) = 34")
equal(Morris.pad2(123), "123", "pad2(123) = 123")
});
test("Morris.labelSeries", function () {
var expected = [
[
new Date(2007, 0, 1).getTime(),
new Date(2012, 0, 1).getTime(),
[["2007", new Date(2007, 0, 1).getTime()],
["2008", new Date(2008, 0, 1).getTime()],
["2009", new Date(2009, 0, 1).getTime()],
["2010", new Date(2010, 0, 1).getTime()],
["2011", new Date(2011, 0, 1).getTime()],
["2012", new Date(2012, 0, 1).getTime()]]
],
[
new Date(2007, 3, 1).getTime(),
new Date(2012, 3, 1).getTime(),
[["2008", new Date(2008, 0, 1).getTime()],
["2009", new Date(2009, 0, 1).getTime()],
["2010", new Date(2010, 0, 1).getTime()],
["2011", new Date(2011, 0, 1).getTime()],
["2012", new Date(2012, 0, 1).getTime()]]
],
[
new Date(2012, 0, 1).getTime(),
new Date(2012, 5, 1).getTime(),
[["2012-01", new Date(2012, 0, 1).getTime()],
["2012-02", new Date(2012, 1, 1).getTime()],
["2012-03", new Date(2012, 2, 1).getTime()],
["2012-04", new Date(2012, 3, 1).getTime()],
["2012-05", new Date(2012, 4, 1).getTime()],
["2012-06", new Date(2012, 5, 1).getTime()]]
],
[
new Date(2012, 0, 1).getTime(),
new Date(2012, 0, 6).getTime(),
[["2012-01-01", new Date(2012, 0, 1).getTime()],
["2012-01-02", new Date(2012, 0, 2).getTime()],
["2012-01-03", new Date(2012, 0, 3).getTime()],
["2012-01-04", new Date(2012, 0, 4).getTime()],
["2012-01-05", new Date(2012, 0, 5).getTime()],
["2012-01-06", new Date(2012, 0, 6).getTime()]]
],
[
new Date(2012, 0, 1, 0).getTime(),
new Date(2012, 0, 1, 5).getTime(),
[["00:00", new Date(2012, 0, 1, 0).getTime()],
["01:00", new Date(2012, 0, 1, 1).getTime()],
["02:00", new Date(2012, 0, 1, 2).getTime()],
["03:00", new Date(2012, 0, 1, 3).getTime()],
["04:00", new Date(2012, 0, 1, 4).getTime()],
["05:00", new Date(2012, 0, 1, 5).getTime()]]
],
[
new Date(2012, 0, 1, 0, 0).getTime(),
new Date(2012, 0, 1, 2, 30).getTime(),
[["00:00", new Date(2012, 0, 1, 0, 0).getTime()],
["00:30", new Date(2012, 0, 1, 0, 30).getTime()],
["01:00", new Date(2012, 0, 1, 1, 0).getTime()],
["01:30", new Date(2012, 0, 1, 1, 30).getTime()],
["02:00", new Date(2012, 0, 1, 2, 0).getTime()],
["02:30", new Date(2012, 0, 1, 2, 30).getTime()]]
],
[
new Date(2012, 0, 1, 0, 0).getTime(),
new Date(2012, 0, 1, 1, 15).getTime(),
[["00:00", new Date(2012, 0, 1, 0, 0).getTime()],
["00:15", new Date(2012, 0, 1, 0, 15).getTime()],
["00:30", new Date(2012, 0, 1, 0, 30).getTime()],
["00:45", new Date(2012, 0, 1, 0, 45).getTime()],
["01:00", new Date(2012, 0, 1, 1, 0).getTime()],
["01:15", new Date(2012, 0, 1, 1, 15).getTime()]]
],
[
new Date(2012, 4, 12, 0, 0).getTime(),
new Date(2012, 4, 12, 2, 30).getTime(),
[["00:00", new Date(2012, 4, 12, 0, 0).getTime()],
["00:30", new Date(2012, 4, 12, 0, 30).getTime()],
["01:00", new Date(2012, 4, 12, 1, 0).getTime()],
["01:30", new Date(2012, 4, 12, 1, 30).getTime()],
["02:00", new Date(2012, 4, 12, 2, 0).getTime()],
["02:30", new Date(2012, 4, 12, 2, 30).getTime()]]
],
[
new Date(2012, 4, 12, 0, 0).getTime(),
new Date(2012, 4, 12, 1, 15).getTime(),
[["00:00", new Date(2012, 4, 12, 0, 0).getTime()],
["00:15", new Date(2012, 4, 12, 0, 15).getTime()],
["00:30", new Date(2012, 4, 12, 0, 30).getTime()],
["00:45", new Date(2012, 4, 12, 0, 45).getTime()],
["01:00", new Date(2012, 4, 12, 1, 0).getTime()],
["01:15", new Date(2012, 4, 12, 1, 15).getTime()]]
]
];
for (var i = 0; i < expected.length; i++) {
var dmin = expected[i][0],
dmax = expected[i][1],
ret = expected[i][2];
deepEqual(Morris.labelSeries(dmin, dmax, 1000), ret);
}
});
test("Morris.parseDate", function () {
equal(Morris.parseDate("2012"), new Date(2012, 0, 1).getTime());
equal(Morris.parseDate("2012 Q1"), new Date(2012, 2, 1).getTime());
equal(Morris.parseDate("2012-09"), new Date(2012, 8, 1).getTime());
equal(Morris.parseDate("2012-10"), new Date(2012, 9, 1).getTime());
equal(Morris.parseDate("2012-09-15"), new Date(2012, 8, 15).getTime());
equal(Morris.parseDate("2012-10-15"), new Date(2012, 9, 15).getTime());
equal(Morris.parseDate("2012-10-15 12:34"), new Date(2012, 9, 15, 12, 34).getTime());
equal(Morris.parseDate("2012-10-15T12:34"), new Date(2012, 9, 15, 12, 34).getTime());
equal(Morris.parseDate("2012-10-15T12:34Z"), new Date(2012, 9, 15, 12, 34).getTime());
equal(Morris.parseDate("2012-10-15 12:34:55"), new Date(2012, 9, 15, 12, 34, 55).getTime());
equal(Morris.parseDate("2012-10-15T12:34:55"), new Date(2012, 9, 15, 12, 34, 55).getTime());
equal(Morris.parseDate("2012-10-15T12:34:55Z"), new Date(2012, 9, 15, 12, 34, 55).getTime());
equal(Morris.parseDate("2012-10-15 12:34:55.123"), new Date(2012, 9, 15, 12, 34, 55, 123).getTime());
equal(Morris.parseDate("2012-10-15T12:34:55.123"), new Date(2012, 9, 15, 12, 34, 55, 123).getTime());
equal(Morris.parseDate("2012-10-15T12:34:55.123Z"), new Date(2012, 9, 15, 12, 34, 55, 123).getTime());
equal(Morris.parseDate(new Date(2012, 9, 15, 12, 34, 55, 123).getTime()),
new Date(2012, 9, 15, 12, 34, 55, 123).getTime());
});
});
</script>
</head>
<body>
<h1 id="qunit-header">Morris.js tests</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<div id="qunit-fixture">test markup, will be hidden</div>
</body>
</html>