Non-year X labels. This is controlled by new options numXLabels, xLabelFormat, and xLabelMargin.

This commit is contained in:
Jon Thornton 2012-03-26 17:08:08 -04:00
parent 18b4191093
commit a2d25c5f56
4 changed files with 43 additions and 24 deletions

View File

@ -46,7 +46,11 @@ Morris.Line({
data: week_data, data: week_data,
xkey: 'period', xkey: 'period',
ykeys: ['licensed', 'sorned'], ykeys: ['licensed', 'sorned'],
labels: ['Licensed', 'SORN'] labels: ['Licensed', 'SORN'],
numXLabels: 7,
xLabelFormat: function(x) {
var d = new Date(x); return (d.getMonth()+1)+'-'+d.getFullYear()
}
}); });
</pre> </pre>
</body> </body>

View File

@ -43,6 +43,9 @@ class Morris.Line
marginBottom: 30 marginBottom: 30
marginLeft: 25 marginLeft: 25
numLines: 5 numLines: 5
numXLabels: 5
xLabelMargin: 50
xLabelFormat: (x) -> new Date(x).getFullYear()
gridLineColor: '#aaa' gridLineColor: '#aaa'
gridTextColor: '#888' gridTextColor: '#888'
gridTextSize: 12 gridTextSize: 12
@ -208,28 +211,32 @@ class Morris.Line
## draw x axis labels ## draw x axis labels
prevLabelMargin = null prevLabelMargin = null
xLabelMargin = 50 # make this an option? prevLabelText = null
if @options.parseTime if @options.parseTime
x1 = new Date(@xmin).getFullYear() step = (@xmax - @xmin)/(@options.numXLabels-1)
x2 = new Date(@xmax).getFullYear() x1 = @xmin/step
x2 = @xmax/step
else else
x1 = 0 x1 = 0
x2 = @columnLabels.length x2 = @columnLabels.length
for i in [x1..x2] for i in [x1..x2]
if @options.parseTime if @options.parseTime
xpos = new Date(i, 0, 1).getTime() xpos = i*step
if xpos < @xmin if xpos < @xmin
continue continue
else else
xpos = i xpos = i
labelText = if @options.parseTime then i else @columnLabels[@columnLabels.length-i-1] labelText = if @options.parseTime then @options.xLabelFormat(xpos) else @columnLabels[@columnLabels.length-i-1]
if labelText == prevLabelText
continue
prevLabelText = labelText
label = @r.text(@transX(xpos), @options.marginTop + @height + @options.marginBottom / 2, labelText) label = @r.text(@transX(xpos), @options.marginTop + @height + @options.marginBottom / 2, labelText)
.attr('font-size', @options.gridTextSize) .attr('font-size', @options.gridTextSize)
.attr('fill', @options.gridTextColor) .attr('fill', @options.gridTextColor)
labelBox = label.getBBox() labelBox = label.getBBox()
# ensure a minimum of `xLabelMargin` pixels between labels # ensure a minimum of `xLabelMargin` pixels between labels
if prevLabelMargin is null or prevLabelMargin <= labelBox.x if prevLabelMargin is null or prevLabelMargin <= labelBox.x
prevLabelMargin = labelBox.x + labelBox.width + xLabelMargin prevLabelMargin = labelBox.x + labelBox.width + @options.xLabelMargin
else else
label.remove() label.remove()

View File

@ -37,6 +37,11 @@
marginBottom: 30, marginBottom: 30,
marginLeft: 25, marginLeft: 25,
numLines: 5, numLines: 5,
numXLabels: 5,
xLabelMargin: 50,
xLabelFormat: function(x) {
return new Date(x).getFullYear();
},
gridLineColor: '#aaa', gridLineColor: '#aaa',
gridTextColor: '#888', gridTextColor: '#888',
gridTextSize: 12, gridTextSize: 12,
@ -219,7 +224,7 @@
}; };
Line.prototype.drawGrid = function() { Line.prototype.drawGrid = function() {
var firstY, i, label, labelBox, labelText, lastY, lineY, prevLabelMargin, v, x1, x2, xLabelMargin, xpos, y, yInterval, _results; var firstY, i, label, labelBox, labelText, lastY, lineY, prevLabelMargin, prevLabelText, step, v, x1, x2, xpos, y, yInterval, _results;
yInterval = (this.options.ymax - this.options.ymin) / (this.options.numLines - 1); yInterval = (this.options.ymax - this.options.ymin) / (this.options.numLines - 1);
firstY = Math.ceil(this.options.ymin / yInterval) * yInterval; firstY = Math.ceil(this.options.ymin / yInterval) * yInterval;
lastY = Math.floor(this.options.ymax / yInterval) * yInterval; lastY = Math.floor(this.options.ymax / yInterval) * yInterval;
@ -230,10 +235,11 @@
this.r.path("M" + this.left + "," + y + "H" + (this.left + this.width)).attr('stroke', this.options.gridLineColor).attr('stroke-width', this.options.gridStrokeWidth); 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; prevLabelMargin = null;
xLabelMargin = 50; prevLabelText = null;
if (this.options.parseTime) { if (this.options.parseTime) {
x1 = new Date(this.xmin).getFullYear(); step = (this.xmax - this.xmin) / (this.options.numXLabels - 1);
x2 = new Date(this.xmax).getFullYear(); x1 = this.xmin / step;
x2 = this.xmax / step;
} else { } else {
x1 = 0; x1 = 0;
x2 = this.columnLabels.length; x2 = this.columnLabels.length;
@ -241,16 +247,18 @@
_results = []; _results = [];
for (i = x1; x1 <= x2 ? i <= x2 : i >= x2; x1 <= x2 ? i++ : i--) { for (i = x1; x1 <= x2 ? i <= x2 : i >= x2; x1 <= x2 ? i++ : i--) {
if (this.options.parseTime) { if (this.options.parseTime) {
xpos = new Date(i, 0, 1).getTime(); xpos = i * step;
if (xpos < this.xmin) continue; if (xpos < this.xmin) continue;
} else { } else {
xpos = i; xpos = i;
} }
labelText = this.options.parseTime ? i : this.columnLabels[this.columnLabels.length - i - 1]; labelText = this.options.parseTime ? this.options.xLabelFormat(xpos) : this.columnLabels[this.columnLabels.length - i - 1];
if (labelText === prevLabelText) continue;
prevLabelText = labelText;
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); 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);
labelBox = label.getBBox(); labelBox = label.getBBox();
if (prevLabelMargin === null || prevLabelMargin <= labelBox.x) { if (prevLabelMargin === null || prevLabelMargin <= labelBox.x) {
_results.push(prevLabelMargin = labelBox.x + labelBox.width + xLabelMargin); _results.push(prevLabelMargin = labelBox.x + labelBox.width + this.options.xLabelMargin);
} else { } else {
_results.push(label.remove()); _results.push(label.remove());
} }

2
morris.min.js vendored

File diff suppressed because one or more lines are too long