mirror of
https://github.com/morrisjs/morris.js.git
synced 2024-11-14 07:41:11 +01:00
A deep copy is overkill here.
The only destructive change to the supplied data array is to change its ordering, so a shallow copy is enough to avoid clobbering it.
This commit is contained in:
parent
2108baaf4e
commit
942e121caa
4 changed files with 25 additions and 85 deletions
|
@ -25,10 +25,6 @@ class Morris.Line
|
||||||
# bail if there's no data
|
# bail if there's no data
|
||||||
if @options.data is undefined or @options.data.length is 0
|
if @options.data is undefined or @options.data.length is 0
|
||||||
return
|
return
|
||||||
else
|
|
||||||
# otherwise create a deep copy of the input data: we'll perform
|
|
||||||
# operations on it later so better not taint the user's data.
|
|
||||||
@options.data = clone(@options.data)
|
|
||||||
@el.addClass 'graph-initialised'
|
@el.addClass 'graph-initialised'
|
||||||
@precalc()
|
@precalc()
|
||||||
@redraw()
|
@redraw()
|
||||||
|
@ -79,7 +75,8 @@ class Morris.Line
|
||||||
# Do any necessary pre-processing for a new dataset
|
# Do any necessary pre-processing for a new dataset
|
||||||
#
|
#
|
||||||
precalc: ->
|
precalc: ->
|
||||||
# sort data
|
# shallow copy & sort data
|
||||||
|
@options.data = @options.data.slice(0)
|
||||||
@options.data.sort (a, b) => (a[@options.xkey] < b[@options.xkey]) - (b[@options.xkey] < a[@options.xkey])
|
@options.data.sort (a, b) => (a[@options.xkey] < b[@options.xkey]) - (b[@options.xkey] < a[@options.xkey])
|
||||||
# extract labels
|
# extract labels
|
||||||
@columnLabels = $.map @options.data, (d) => d[@options.xkey]
|
@columnLabels = $.map @options.data, (d) => d[@options.xkey]
|
||||||
|
@ -522,31 +519,6 @@ Morris.labelSeries = (dmin, dmax, pxwidth, specName, xLabelFormat) ->
|
||||||
spec.incr(d)
|
spec.incr(d)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
# Perform a deep copy of the given object.
|
|
||||||
# Source: http://coffeescriptcookbook.com/chapters/classes_and_objects/cloning
|
|
||||||
clone = (obj) ->
|
|
||||||
if not obj? or typeof obj isnt 'object'
|
|
||||||
return obj
|
|
||||||
|
|
||||||
if obj instanceof Date
|
|
||||||
return new Date(obj.getTime())
|
|
||||||
|
|
||||||
if obj instanceof RegExp
|
|
||||||
flags = ''
|
|
||||||
flags += 'g' if obj.global?
|
|
||||||
flags += 'i' if obj.ignoreCase?
|
|
||||||
flags += 'm' if obj.multiline?
|
|
||||||
flags += 'y' if obj.sticky?
|
|
||||||
return new RegExp(obj.source, flags)
|
|
||||||
|
|
||||||
newInstance = new obj.constructor()
|
|
||||||
|
|
||||||
for key of obj
|
|
||||||
newInstance[key] = clone obj[key]
|
|
||||||
|
|
||||||
return newInstance
|
|
||||||
|
|
||||||
|
|
||||||
minutesSpecHelper = (interval) ->
|
minutesSpecHelper = (interval) ->
|
||||||
span: interval * 60 * 1000
|
span: interval * 60 * 1000
|
||||||
start: (d) -> new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours())
|
start: (d) -> new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours())
|
||||||
|
|
36
morris.js
36
morris.js
|
@ -1,6 +1,6 @@
|
||||||
// Generated by CoffeeScript 1.3.1
|
// Generated by CoffeeScript 1.3.1
|
||||||
(function() {
|
(function() {
|
||||||
var $, Morris, clone, 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); }; };
|
||||||
|
|
||||||
$ = jQuery;
|
$ = jQuery;
|
||||||
|
@ -38,8 +38,6 @@
|
||||||
}
|
}
|
||||||
if (this.options.data === void 0 || this.options.data.length === 0) {
|
if (this.options.data === void 0 || this.options.data.length === 0) {
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
this.options.data = clone(this.options.data);
|
|
||||||
}
|
}
|
||||||
this.el.addClass('graph-initialised');
|
this.el.addClass('graph-initialised');
|
||||||
this.precalc();
|
this.precalc();
|
||||||
|
@ -85,6 +83,7 @@
|
||||||
Line.prototype.precalc = function() {
|
Line.prototype.precalc = function() {
|
||||||
var d, series_data, touchHandler, ykey, ymax, ymin, _i, _j, _k, _len, _len1, _ref, _ref1, _ref2, _results,
|
var d, series_data, touchHandler, ykey, ymax, ymin, _i, _j, _k, _len, _len1, _ref, _ref1, _ref2, _results,
|
||||||
_this = this;
|
_this = this;
|
||||||
|
this.options.data = this.options.data.slice(0);
|
||||||
this.options.data.sort(function(a, b) {
|
this.options.data.sort(function(a, b) {
|
||||||
return (a[_this.options.xkey] < b[_this.options.xkey]) - (b[_this.options.xkey] < a[_this.options.xkey]);
|
return (a[_this.options.xkey] < b[_this.options.xkey]) - (b[_this.options.xkey] < a[_this.options.xkey]);
|
||||||
});
|
});
|
||||||
|
@ -591,37 +590,6 @@
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
clone = function(obj) {
|
|
||||||
var flags, key, newInstance;
|
|
||||||
if (!(obj != null) || typeof obj !== 'object') {
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
if (obj instanceof Date) {
|
|
||||||
return new Date(obj.getTime());
|
|
||||||
}
|
|
||||||
if (obj instanceof RegExp) {
|
|
||||||
flags = '';
|
|
||||||
if (obj.global != null) {
|
|
||||||
flags += 'g';
|
|
||||||
}
|
|
||||||
if (obj.ignoreCase != null) {
|
|
||||||
flags += 'i';
|
|
||||||
}
|
|
||||||
if (obj.multiline != null) {
|
|
||||||
flags += 'm';
|
|
||||||
}
|
|
||||||
if (obj.sticky != null) {
|
|
||||||
flags += 'y';
|
|
||||||
}
|
|
||||||
return new RegExp(obj.source, flags);
|
|
||||||
}
|
|
||||||
newInstance = new obj.constructor();
|
|
||||||
for (key in obj) {
|
|
||||||
newInstance[key] = clone(obj[key]);
|
|
||||||
}
|
|
||||||
return newInstance;
|
|
||||||
};
|
|
||||||
|
|
||||||
minutesSpecHelper = function(interval) {
|
minutesSpecHelper = function(interval) {
|
||||||
return {
|
return {
|
||||||
span: interval * 60 * 1000,
|
span: interval * 60 * 1000,
|
||||||
|
|
2
morris.min.js
vendored
2
morris.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -12,28 +12,28 @@
|
||||||
module("Morris");
|
module("Morris");
|
||||||
|
|
||||||
test("Input data remains untouched", function () {
|
test("Input data remains untouched", function () {
|
||||||
var my_data = [{x: 1, y: 1}, {x: 2, y: 2}];
|
var my_data = [{x: 1, y: 1}, {x: 2, y: 2}];
|
||||||
var expected_data = [{x: 1, y: 1}, {x: 2, y: 2}];
|
var expected_data = [{x: 1, y: 1}, {x: 2, y: 2}];
|
||||||
Morris.Line({
|
Morris.Line({
|
||||||
element: "graph-placeholder",
|
element: "graph-placeholder",
|
||||||
data: my_data,
|
data: my_data,
|
||||||
xkey: 'x',
|
xkey: 'x',
|
||||||
ykeys: ['y'],
|
ykeys: ['y'],
|
||||||
labels: ['dontcare']
|
labels: ['dontcare']
|
||||||
});
|
});
|
||||||
deepEqual(my_data, expected_data);
|
deepEqual(my_data, expected_data);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Nicer error when the placeholder was not found.", function () {
|
test("Raise an error when the placeholder element is not found.", function () {
|
||||||
var my_data = [{x: 1, y: 1}, {x: 2, y: 2}];
|
var my_data = [{x: 1, y: 1}, {x: 2, y: 2}];
|
||||||
raises(function() {
|
raises(function() {
|
||||||
Morris.Line({
|
Morris.Line({
|
||||||
element: "thisplacedoesnotexist",
|
element: "thisplacedoesnotexist",
|
||||||
data: my_data,
|
data: my_data,
|
||||||
xkey: 'x',
|
xkey: 'x',
|
||||||
ykeys: ['y'],
|
ykeys: ['y'],
|
||||||
labels: ['dontcare']})
|
labels: ['dontcare']})
|
||||||
}, "Graph placeholder not found.");
|
}, "Graph placeholder not found.");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Morris.commas", function () {
|
test("Morris.commas", function () {
|
||||||
|
|
Loading…
Reference in a new issue