Added code and options to animate the initial drawing of the graph

Options added:
 - animate (boolean) - flag on whether to animate or not
 - duration (number) - duration of the animation
 - easing (string) - one of Raphael's supported easing options

 Methods changed:
 - drawSeries - added animation code

Method added:
 - seriesAverage - caculates the average y value for a set of coords

 NB minified js not modified
This commit is contained in:
Dave Tonge 2012-05-25 09:04:11 +01:00
parent aa67b1a305
commit a1218b68bb
2 changed files with 1319 additions and 1244 deletions

View File

@ -71,6 +71,9 @@ class Morris.Line
dateFormat: (x) -> new Date(x).toString() dateFormat: (x) -> new Date(x).toString()
xLabels: 'auto' xLabels: 'auto'
xLabelFormat: null xLabelFormat: null
animate: true
easing: "bounce"
duration: 1500
# Do any necessary pre-processing for a new dataset # Do any necessary pre-processing for a new dataset
# #
@ -248,10 +251,21 @@ class Morris.Line
# draw the data series # draw the data series
# #
drawSeries: -> drawSeries: ->
averages = []
for i in [@seriesCoords.length-1..0] for i in [@seriesCoords.length-1..0]
coords = @seriesCoords[i] coords = @seriesCoords[i]
if coords.length > 1 if coords.length > 1
path = @createPath coords, @options.marginTop, @left, @options.marginTop + @height, @left + @width path = @createPath coords, @options.marginTop, @left, @options.marginTop + @height, @left + @width
if @options.animate
averages[i] = average = Morris.seriesAverage(coords)
straightCoords = ({x:c.x, y:average} for c in coords)
straightPath = @createPath straightCoords, @options.marginTop, @left, @options.marginTop + @height, @left + @width
rPath = @r.path(straightPath)
.attr('stroke', @options.lineColors[i])
.attr('stroke-width', @options.lineWidth)
do (rPath, path) =>
rPath.animate {path}, @options.duration, @options.easing
else
@r.path(path) @r.path(path)
.attr('stroke', @options.lineColors[i]) .attr('stroke', @options.lineColors[i])
.attr('stroke-width', @options.lineWidth) .attr('stroke-width', @options.lineWidth)
@ -261,10 +275,15 @@ class Morris.Line
if c == null if c == null
circle = null circle = null
else else
circle = @r.circle(c.x, c.y, @options.pointSize) y = if @options.animate then averages[i] else c.y
circle = @r.circle(c.x, y, @options.pointSize)
.attr('fill', @options.lineColors[i]) .attr('fill', @options.lineColors[i])
.attr('stroke-width', 1) .attr('stroke-width', 1)
.attr('stroke', '#ffffff') .attr('stroke', '#ffffff')
if @options.animate
do (circle, c) =>
circle.animate {cy:c.y}, @options.duration, @options.easing
@seriesPoints[i].push(circle) @seriesPoints[i].push(circle)
# create a path for a data series # create a path for a data series
@ -565,5 +584,12 @@ Morris.AUTO_LABEL_ORDER = [
"30sec", "15sec", "10sec", "5sec", "second" "30sec", "15sec", "10sec", "5sec", "second"
] ]
Morris.seriesAverage = (series) ->
total = 0
for point in series
total += point.y ? 0
(total / series.length) / 2
window.Morris = Morris window.Morris = Morris
# vim: set et ts=2 sw=2 sts=2 # vim: set et ts=2 sw=2 sts=2

View File

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.3.3 // Generated by CoffeeScript 1.3.1
(function() { (function() {
var $, Morris, minutesSpecHelper, secondsSpecHelper, var $, Morris, minutesSpecHelper, secondsSpecHelper,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
@ -9,6 +9,8 @@
Morris.Line = (function() { Morris.Line = (function() {
Line.name = 'Line';
function Line(options) { function Line(options) {
this.updateHilight = __bind(this.updateHilight, this); this.updateHilight = __bind(this.updateHilight, this);
@ -75,7 +77,10 @@
return new Date(x).toString(); return new Date(x).toString();
}, },
xLabels: 'auto', xLabels: 'auto',
xLabelFormat: null xLabelFormat: null,
animate: true,
easing: "bounce",
duration: 1500
}; };
Line.prototype.precalc = function() { Line.prototype.precalc = function() {
@ -286,14 +291,39 @@
}; };
Line.prototype.drawSeries = function() { Line.prototype.drawSeries = function() {
var c, circle, coords, i, path, _i, _j, _ref, _ref1, _results; var average, averages, c, circle, coords, i, path, rPath, straightCoords, straightPath, y, _i, _j, _ref, _ref1, _results,
_this = this;
averages = [];
for (i = _i = _ref = this.seriesCoords.length - 1; _ref <= 0 ? _i <= 0 : _i >= 0; i = _ref <= 0 ? ++_i : --_i) { for (i = _i = _ref = this.seriesCoords.length - 1; _ref <= 0 ? _i <= 0 : _i >= 0; i = _ref <= 0 ? ++_i : --_i) {
coords = this.seriesCoords[i]; coords = this.seriesCoords[i];
if (coords.length > 1) { if (coords.length > 1) {
path = this.createPath(coords, this.options.marginTop, this.left, this.options.marginTop + this.height, this.left + this.width); path = this.createPath(coords, this.options.marginTop, this.left, this.options.marginTop + this.height, this.left + this.width);
if (this.options.animate) {
averages[i] = average = Morris.seriesAverage(coords);
straightCoords = (function() {
var _j, _len, _results;
_results = [];
for (_j = 0, _len = coords.length; _j < _len; _j++) {
c = coords[_j];
_results.push({
x: c.x,
y: average
});
}
return _results;
})();
straightPath = this.createPath(straightCoords, this.options.marginTop, this.left, this.options.marginTop + this.height, this.left + this.width);
rPath = this.r.path(straightPath).attr('stroke', this.options.lineColors[i]).attr('stroke-width', this.options.lineWidth);
(function(rPath, path) {
return rPath.animate({
path: path
}, _this.options.duration, _this.options.easing);
})(rPath, path);
} else {
this.r.path(path).attr('stroke', this.options.lineColors[i]).attr('stroke-width', this.options.lineWidth); this.r.path(path).attr('stroke', this.options.lineColors[i]).attr('stroke-width', this.options.lineWidth);
} }
} }
}
this.seriesPoints = (function() { this.seriesPoints = (function() {
var _j, _ref1, _results; var _j, _ref1, _results;
_results = []; _results = [];
@ -305,7 +335,8 @@
_results = []; _results = [];
for (i = _j = _ref1 = this.seriesCoords.length - 1; _ref1 <= 0 ? _j <= 0 : _j >= 0; i = _ref1 <= 0 ? ++_j : --_j) { for (i = _j = _ref1 = this.seriesCoords.length - 1; _ref1 <= 0 ? _j <= 0 : _j >= 0; i = _ref1 <= 0 ? ++_j : --_j) {
_results.push((function() { _results.push((function() {
var _k, _len, _ref2, _results1; var _k, _len, _ref2, _results1,
_this = this;
_ref2 = this.seriesCoords[i]; _ref2 = this.seriesCoords[i];
_results1 = []; _results1 = [];
for (_k = 0, _len = _ref2.length; _k < _len; _k++) { for (_k = 0, _len = _ref2.length; _k < _len; _k++) {
@ -313,7 +344,15 @@
if (c === null) { if (c === null) {
circle = null; circle = null;
} else { } else {
circle = this.r.circle(c.x, c.y, this.options.pointSize).attr('fill', this.options.lineColors[i]).attr('stroke-width', 1).attr('stroke', '#ffffff'); y = this.options.animate ? averages[i] : c.y;
circle = this.r.circle(c.x, y, this.options.pointSize).attr('fill', this.options.lineColors[i]).attr('stroke-width', 1).attr('stroke', '#ffffff');
if (this.options.animate) {
(function(circle, c) {
return circle.animate({
cy: c.y
}, _this.options.duration, _this.options.easing);
})(circle, c);
}
} }
_results1.push(this.seriesPoints[i].push(circle)); _results1.push(this.seriesPoints[i].push(circle));
} }
@ -670,6 +709,16 @@
Morris.AUTO_LABEL_ORDER = ["year", "month", "day", "hour", "30min", "15min", "10min", "5min", "minute", "30sec", "15sec", "10sec", "5sec", "second"]; Morris.AUTO_LABEL_ORDER = ["year", "month", "day", "hour", "30min", "15min", "10min", "5min", "minute", "30sec", "15sec", "10sec", "5sec", "second"];
Morris.seriesAverage = function(series) {
var point, total, _i, _len, _ref;
total = 0;
for (_i = 0, _len = series.length; _i < _len; _i++) {
point = series[_i];
total += (_ref = point.y) != null ? _ref : 0;
}
return (total / series.length) / 2;
};
window.Morris = Morris; window.Morris = Morris;
}).call(this); }).call(this);