Custom dateFormat for string x-values. #90

This commit is contained in:
Olly Smith 2012-10-19 10:17:38 +01:00
parent 42099ea26b
commit 1d4c7f0d65
4 changed files with 68 additions and 25 deletions

View File

@ -90,22 +90,20 @@ class Morris.Line
parseTime: true parseTime: true
preUnits: '' preUnits: ''
postUnits: '' postUnits: ''
dateFormat: (x) -> new Date(x).toString() dateFormat: null
xLabels: 'auto' xLabels: 'auto'
xLabelFormat: null xLabelFormat: null
# Update the data series and redraw the chart. # Update the data series and redraw the chart.
# #
setData: (data, redraw = true) -> setData: (data, redraw = true) ->
# shallow copy & sort data # shallow copy & sort data (if required)
@options.data = data.slice(0) @options.data = data.slice(0)
if @options.parseTime if @options.parseTime
@options.data.sort (a, b) => @options.data.sort (a, b) =>
(a[@options.xkey] < b[@options.xkey]) - (b[@options.xkey] < a[@options.xkey]) (a[@options.xkey] < b[@options.xkey]) - (b[@options.xkey] < a[@options.xkey])
else else
@options.data.reverse() @options.data.reverse()
# extract labels
@columnLabels = $.map @options.data, (d) => d[@options.xkey]
# extract series data # extract series data
@series = [] @series = []
@ -118,19 +116,25 @@ class Morris.Line
else null else null
@series.push(series_data) @series.push(series_data)
# extract labels
@columnLabels = $.map @options.data, (d) => d[@options.xkey]
# translate x labels into nominal dates # translate x labels into nominal dates
# note: currently using decimal years to specify dates
if @options.parseTime if @options.parseTime
@xvals = $.map @columnLabels, (x) -> Morris.parseDate x @xvals = $.map @columnLabels, (x) -> Morris.parseDate x
else else
@xvals = [(@columnLabels.length-1)..0] @xvals = [(@columnLabels.length-1)..0]
# translate column labels, if they're timestamps
# format column labels
if @options.parseTime if @options.parseTime
@columnLabels = $.map @columnLabels, (d) => if @options.dateFormat
if typeof d is 'number' @columnLabels = $.map @xvals, (d) => @options.dateFormat(d)
@options.dateFormat(d) else
else @columnLabels = $.map @columnLabels, (d) =>
d # default formatter for numeric timestamp labels
if typeof d is 'number' then new Date(d).toString() else d
# calculate horizontal range of the graph
@xmin = Math.min.apply null, @xvals @xmin = Math.min.apply null, @xvals
@xmax = Math.max.apply null, @xvals @xmax = Math.max.apply null, @xvals
if @xmin is @xmax if @xmin is @xmax

View File

@ -381,9 +381,7 @@
parseTime: true, parseTime: true,
preUnits: '', preUnits: '',
postUnits: '', postUnits: '',
dateFormat: function(x) { dateFormat: null,
return new Date(x).toString();
},
xLabels: 'auto', xLabels: 'auto',
xLabelFormat: null xLabelFormat: null
}; };
@ -402,9 +400,6 @@
} else { } else {
this.options.data.reverse(); this.options.data.reverse();
} }
this.columnLabels = $.map(this.options.data, function(d) {
return d[_this.options.xkey];
});
this.series = []; this.series = [];
_ref = this.options.ykeys; _ref = this.options.ykeys;
for (_i = 0, _len = _ref.length; _i < _len; _i++) { for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@ -426,6 +421,9 @@
} }
this.series.push(series_data); this.series.push(series_data);
} }
this.columnLabels = $.map(this.options.data, function(d) {
return d[_this.options.xkey];
});
if (this.options.parseTime) { if (this.options.parseTime) {
this.xvals = $.map(this.columnLabels, function(x) { this.xvals = $.map(this.columnLabels, function(x) {
return Morris.parseDate(x); return Morris.parseDate(x);
@ -438,13 +436,19 @@
}).apply(this); }).apply(this);
} }
if (this.options.parseTime) { if (this.options.parseTime) {
this.columnLabels = $.map(this.columnLabels, function(d) { if (this.options.dateFormat) {
if (typeof d === 'number') { this.columnLabels = $.map(this.xvals, function(d) {
return _this.options.dateFormat(d); return _this.options.dateFormat(d);
} else { });
return d; } else {
} this.columnLabels = $.map(this.columnLabels, function(d) {
}); if (typeof d === 'number') {
return new Date(d).toString();
} else {
return d;
}
});
}
} }
this.xmin = Math.min.apply(null, this.xvals); this.xmin = Math.min.apply(null, this.xvals);
this.xmax = Math.max.apply(null, this.xvals); this.xmax = Math.max.apply(null, this.xvals);

2
morris.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -49,4 +49,39 @@ describe 'Morris.Line', ->
chart.strokeForSeries(1).should.equal blue chart.strokeForSeries(1).should.equal blue
(null == chart.pointFillColorForSeries(0)).should.be (null == chart.pointFillColorForSeries(0)).should.be
(chart.pointFillColorForSeries(0) || chart.colorForSeries(0)).should.equal chart.colorForSeries(0) (chart.pointFillColorForSeries(0) || chart.colorForSeries(0)).should.equal chart.colorForSeries(0)
chart.pointFillColorForSeries(1).should.equal red chart.pointFillColorForSeries(1).should.equal red
describe 'generating column labels', ->
it 'should use user-supplied x value strings by default', ->
chart = Morris.Line
element: 'graph'
data: [{x: '2012 Q1', y: 1}, {x: '2012 Q2', y: 1}]
xkey: 'x'
ykeys: ['y']
labels: ['dontcare']
chart.columnLabels.should == ['2012 Q1', '2012 Q2']
it 'should use a default format for timestamp x-values', ->
d1 = new Date(2012, 0, 1)
d2 = new Date(2012, 0, 2)
chart = Morris.Line
element: 'graph'
data: [{x: d1.getTime(), y: 1}, {x: d2.getTime(), y: 1}]
xkey: 'x'
ykeys: ['y']
labels: ['dontcare']
chart.columnLabels.should == [d2.toString(), d1.toString()]
it 'should use user-defined formatters', ->
d = new Date(2012, 0, 1)
chart = Morris.Line
element: 'graph'
data: [{x: d.getTime(), y: 1}, {x: '2012-01-02', y: 1}]
xkey: 'x'
ykeys: ['y']
labels: ['dontcare']
dateFormat: (d) ->
x = new Date(d)
"#{x.getYear()}/#{x.getMonth()+1}/#{x.getDay()}"
chart.columnLabels.should == ['2012/1/1', '2012/1/2']