New options added: see changelog 0.2.6

This commit is contained in:
Francesco Laurita 2012-03-17 21:15:21 +01:00
parent 3fa0ba6dff
commit 39eb308271
6 changed files with 162 additions and 53 deletions

View File

@ -25,6 +25,13 @@ Fork, hack, send a pull request :)
## Changelog
### 0.2.6 - 17th March 2012
- The X labels can be disabled (with `drawXlabels` option, default is true)
- The Y labels can be disabled (with `drawYlabels` option, default is true)
- The automatic data sort can be disabled (with `sortData` option, default is true)
- The options.data can be sorted via custom function (with `sortDataFunction` option, default is null)
### 0.2.5 - 15th March 2012
- Raw millisecond timestamp support (with `dateFormat` option)

39
examples/custom-sort.html Normal file
View File

@ -0,0 +1,39 @@
<!doctype html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://raw.github.com/DmitryBaranovskiy/raphael/300aa589f5a0ba7fce667cd62c7cdda0bd5ad904/raphael-min.js"></script>
<script src="../morris.js"></script>
<script src="lib/prettify.js"></script>
<script src="lib/example.js"></script>
<link rel="stylesheet" href="lib/example.css">
<link rel="stylesheet" href="lib/prettify.css">
</head>
<body>
<h1>Custom data sort</h1>
<div id="graph"></div>
<pre id="code" class="prettyprint linenums">
var data = [
{"elapsed": "I", "value": 34},
{"elapsed": "II", "value": 24},
{"elapsed": "III", "value": 3},
{"elapsed": "IV", "value": 12},
{"elapsed": "V", "value": 13},
{"elapsed": "VI", "value": 22},
{"elapsed": "VII", "value": 5},
{"elapsed": "VIII", "value": 26},
{"elapsed": "IX", "value": 12},
{"elapsed": "X", "value": 19},
];
Morris.Line({
element: 'graph',
data: data,
xkey: 'elapsed',
ykeys: ['value'],
labels: ['value'],
parseTime: false,
sortDataFunction: function(a,b){
return a["value"] < b["value"];
}
});
</pre>
</body>

38
examples/no-xylabels.html Normal file
View File

@ -0,0 +1,38 @@
<!doctype html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://raw.github.com/DmitryBaranovskiy/raphael/300aa589f5a0ba7fce667cd62c7cdda0bd5ad904/raphael-min.js"></script>
<script src="../morris.js"></script>
<script src="lib/prettify.js"></script>
<script src="lib/example.js"></script>
<link rel="stylesheet" href="lib/example.css">
<link rel="stylesheet" href="lib/prettify.css">
</head>
<body>
<h1>Disable X and Y labels</h1>
<div id="graph"></div>
<pre id="code" class="prettyprint linenums">
var timestamp_data = [
{"period": 1349046000000, "licensed": 3407, "sorned": 660},
{"period": 1313103600000, "licensed": 3351, "sorned": 629},
{"period": 1299110400000, "licensed": 3269, "sorned": 618},
{"period": 1281222000000, "licensed": 3246, "sorned": 661},
{"period": 1273446000000, "licensed": 3257, "sorned": 667},
{"period": 1268524800000, "licensed": 3248, "sorned": 627},
{"period": 1263081600000, "licensed": 3171, "sorned": 660},
{"period": 1260403200000, "licensed": 3171, "sorned": 676},
{"period": 1254870000000, "licensed": 3201, "sorned": 656},
{"period": 1253833200000, "licensed": 3215, "sorned": 622}
];
Morris.Line({
element: 'graph',
data: timestamp_data,
xkey: 'period',
ykeys: ['licensed', 'sorned'],
labels: ['Licensed', 'SORN'],
drawYlabel: false,
drawXlabel: false,
dateFormat: function (x) { return new Date(x).toDateString(); }
});
</pre>
</body>

View File

@ -61,12 +61,20 @@ class Morris.Line
parseTime: true
units: ''
dateFormat: (x) -> new Date(x).toString()
sortData: true
sortDataFunction: null
drawYlabel: true
drawXlabel: true
# Do any necessary pre-processing for a new dataset
#
precalc: ->
# sort data
@options.data.sort (a, b) => (a[@options.xkey] < b[@options.xkey]) - (b[@options.xkey] < a[@options.xkey])
if @options.sortData
if typeof @options.sortDataFunction isnt 'function'
@options.data.sort (a,b) => (a[@options.xkey] < b[@options.xkey]) - (b[@options.xkey] < a[@options.xkey])
else
@options.data.sort @options.sortDataFunction
# extract labels
@columnLabels = $.map @options.data, (d) => d[@options.xkey]
@seriesLabels = @options.labels
@ -144,40 +152,43 @@ class Morris.Line
for lineY in [firstY..lastY] by yInterval
v = Math.floor(lineY)
y = transY(v)
@r.text(left - @options.marginLeft/2, y, v + @options.units)
.attr('font-size', @options.gridTextSize)
.attr('fill', @options.gridTextColor)
.attr('text-anchor', 'end')
if @options.drawYlabels
@r.text(left - @options.marginLeft/2, y, v + @options.units)
.attr('font-size', @options.gridTextSize)
.attr('fill', @options.gridTextColor)
.attr('text-anchor', 'end')
@r.path("M" + left + "," + y + 'H' + (left + width))
.attr('stroke', @options.gridLineColor)
.attr('stroke-width', @options.gridStrokeWidth)
## draw x axis labels
prevLabelMargin = null
xLabelMargin = 50 # make this an option?
if @options.parseTime
x1 = new Date(@xmin).getFullYear()
x2 = new Date(@xmax).getFullYear()
else
x1 = @xmin
x2 = @xmax
for i in [x1..x2]
if @options.drawXlabel
prevLabelMargin = null
xLabelMargin = 50 # make this an option?
if @options.parseTime
xpos = new Date(i, 0, 1).getTime()
if xpos < @xmin
continue
x1 = new Date(@xmin).getFullYear()
x2 = new Date(@xmax).getFullYear()
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)
.attr('font-size', @options.gridTextSize)
.attr('fill', @options.gridTextColor)
labelBox = label.getBBox()
x1 = @xmin
x2 = @xmax
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)
.attr('font-size', @options.gridTextSize)
.attr('fill', @options.gridTextColor)
labelBox = label.getBBox()
# ensure a minimum of `xLabelMargin` pixels between labels
if prevLabelMargin is null or prevLabelMargin <= labelBox.x
prevLabelMargin = labelBox.x + labelBox.width + xLabelMargin
else
label.remove()
if prevLabelMargin is null or prevLabelMargin <= labelBox.x
prevLabelMargin = labelBox.x + labelBox.width + xLabelMargin
else
label.remove()
# draw the actual series
columns = (transX(x) for x in @xvals)

View File

@ -51,15 +51,25 @@
units: '',
dateFormat: function(x) {
return new Date(x).toString();
}
},
sortData: true,
sortDataFunction: null,
drawYlabel: true,
drawXlabel: true
};
Line.prototype.precalc = function() {
var ykey, ymax, ymin, _i, _j, _len, _ref, _ref2, _results,
_this = this;
this.options.data.sort(function(a, b) {
return (a[_this.options.xkey] < b[_this.options.xkey]) - (b[_this.options.xkey] < a[_this.options.xkey]);
});
if (this.options.sortData) {
if (typeof this.options.sortDataFunction !== 'function') {
this.options.data.sort(function(a, b) {
return (a[_this.options.xkey] < b[_this.options.xkey]) - (b[_this.options.xkey] < a[_this.options.xkey]);
});
} else {
this.options.data.sort(this.options.sortDataFunction);
}
}
this.columnLabels = $.map(this.options.data, function(d) {
return d[_this.options.xkey];
});
@ -141,32 +151,36 @@
for (lineY = firstY; firstY <= lastY ? lineY <= lastY : lineY >= lastY; lineY += yInterval) {
v = Math.floor(lineY);
y = transY(v);
this.r.text(left - this.options.marginLeft / 2, y, v + this.options.units).attr('font-size', this.options.gridTextSize).attr('fill', this.options.gridTextColor).attr('text-anchor', 'end');
if (this.options.drawYlabels) {
this.r.text(left - this.options.marginLeft / 2, y, v + this.options.units).attr('font-size', this.options.gridTextSize).attr('fill', this.options.gridTextColor).attr('text-anchor', 'end');
}
this.r.path("M" + left + "," + y + 'H' + (left + width)).attr('stroke', this.options.gridLineColor).attr('stroke-width', this.options.gridStrokeWidth);
}
prevLabelMargin = null;
xLabelMargin = 50;
if (this.options.parseTime) {
x1 = new Date(this.xmin).getFullYear();
x2 = new Date(this.xmax).getFullYear();
} else {
x1 = this.xmin;
x2 = this.xmax;
}
for (i = x1; x1 <= x2 ? i <= x2 : i >= x2; x1 <= x2 ? i++ : i--) {
if (this.options.drawXlabel) {
prevLabelMargin = null;
xLabelMargin = 50;
if (this.options.parseTime) {
xpos = new Date(i, 0, 1).getTime();
if (xpos < this.xmin) continue;
x1 = new Date(this.xmin).getFullYear();
x2 = new Date(this.xmax).getFullYear();
} else {
xpos = i;
x1 = this.xmin;
x2 = this.xmax;
}
labelText = this.options.parseTime ? i : this.columnLabels[this.columnLabels.length - i - 1];
label = this.r.text(transX(xpos), this.options.marginTop + height + this.options.marginBottom / 2, labelText).attr('font-size', this.options.gridTextSize).attr('fill', this.options.gridTextColor);
labelBox = label.getBBox();
if (prevLabelMargin === null || prevLabelMargin <= labelBox.x) {
prevLabelMargin = labelBox.x + labelBox.width + xLabelMargin;
} else {
label.remove();
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(transX(xpos), this.options.marginTop + height + this.options.marginBottom / 2, labelText).attr('font-size', this.options.gridTextSize).attr('fill', this.options.gridTextColor);
labelBox = label.getBBox();
if (prevLabelMargin === null || prevLabelMargin <= labelBox.x) {
prevLabelMargin = labelBox.x + labelBox.width + xLabelMargin;
} else {
label.remove();
}
}
}
columns = (function() {

2
morris.min.js vendored

File diff suppressed because one or more lines are too long