mirror of
https://github.com/morrisjs/morris.js.git
synced 2024-11-10 21:36:34 +01:00
MUCH simpler internal code.
This commit is contained in:
parent
f6b1cfe7a0
commit
1aca098694
@ -34,7 +34,7 @@ class Morris.Grid extends Morris.EventEmitter
|
||||
@init() if @init
|
||||
|
||||
# load data
|
||||
@setData(@options.data)
|
||||
@setData @options.data
|
||||
|
||||
# Default options
|
||||
#
|
||||
@ -55,62 +55,55 @@ class Morris.Grid extends Morris.EventEmitter
|
||||
# Update the data series and redraw the chart.
|
||||
#
|
||||
setData: (data, redraw = true) ->
|
||||
# shallow copy data
|
||||
@options.data = $.map data, (row) =>
|
||||
ymax = null
|
||||
ymin = null
|
||||
@data = $.map data, (row, index) =>
|
||||
ret = {}
|
||||
ret.label = row[@options.xkey]
|
||||
if @options.parseTime
|
||||
$.extend {'__T': Morris.parseDate(row[@options.xkey])}, row
|
||||
ret.x = Morris.parseDate(ret.label)
|
||||
if @options.dateFormat
|
||||
ret.label = @options.dateFormat ret.x
|
||||
else if typeof ret.label is 'number'
|
||||
ret.label = new Date(ret.label).toString()
|
||||
else
|
||||
$.extend {}, row
|
||||
if @options.parseTime
|
||||
@options.data = @options.data.sort (a, b) =>
|
||||
(a['__T'] > b['__T']) - (b['__T'] > a['__T'])
|
||||
ret.x = index
|
||||
ret.y = for ykey in @options.ykeys
|
||||
yval = row[ykey]
|
||||
yval = parseFloat(yval) if typeof yval is 'string'
|
||||
yval = null unless typeof yval is 'number'
|
||||
unless yval is null
|
||||
if ymax is null
|
||||
ymax = ymin = yval
|
||||
else
|
||||
ymax = Math.max(yval, ymax)
|
||||
ymin = Math.min(yval, ymin)
|
||||
yval
|
||||
ret
|
||||
|
||||
# extract series data
|
||||
@series = []
|
||||
for ykey in @options.ykeys
|
||||
seriesData = []
|
||||
for d in @options.data
|
||||
y = d[ykey]
|
||||
seriesData.push switch typeof y
|
||||
when 'number' then y
|
||||
when 'string' then parseFloat y
|
||||
else null
|
||||
@series.push seriesData
|
||||
|
||||
# extract labels / x values
|
||||
@columnLabels = $.map @options.data, (row) => row[@options.xkey]
|
||||
if @options.parseTime
|
||||
@xvals = $.map @options.data, (row) -> row['__T']
|
||||
if @options.dateFormat
|
||||
@columnLabels = $.map @xvals, (d) => @options.dateFormat d
|
||||
else
|
||||
@columnLabels = $.map @columnLabels, (d) =>
|
||||
# default formatter for numeric timestamp labels
|
||||
if typeof d is 'number' then new Date(d).toString() else d
|
||||
else
|
||||
@xvals = [0...@columnLabels.length]
|
||||
@data = @data.sort (a, b) -> (a.x > b.x) - (b.x > a.x)
|
||||
|
||||
# calculate horizontal range of the graph
|
||||
@xmin = Math.min.apply null, @xvals
|
||||
@xmax = Math.max.apply null, @xvals
|
||||
@xmin = @data[0].x
|
||||
@xmax = @data[@data.length - 1].x
|
||||
if @xmin is @xmax
|
||||
@xmin -= 1
|
||||
@xmax += 1
|
||||
|
||||
# Compute the vertical range of the graph if desired
|
||||
if typeof @options.ymax is 'string' and @options.ymax[0..3] is 'auto'
|
||||
# use Array.concat to flatten arrays and find the max y value
|
||||
ymax = Math.max.apply null, Array.prototype.concat.apply([], @series)
|
||||
if @options.ymax.length > 5
|
||||
@ymax = Math.max parseInt(@options.ymax[5..], 10), ymax
|
||||
if typeof @options.ymax is 'string'
|
||||
if @options.ymax[0..3] is 'auto'
|
||||
# use Array.concat to flatten arrays and find the max y value
|
||||
if @options.ymax.length > 5
|
||||
@ymax = Math.max parseInt(@options.ymax[5..], 10), ymax
|
||||
else
|
||||
@ymax = ymax
|
||||
else
|
||||
@ymax = ymax
|
||||
else if typeof @options.ymax is 'string'
|
||||
@ymax = parseInt(@options.ymax, 10)
|
||||
@ymax = parseInt(@options.ymax, 10)
|
||||
else
|
||||
@ymax = @options.ymax
|
||||
if typeof @options.ymin is 'string' and @options.ymin[0..3] is 'auto'
|
||||
ymin = Math.min.apply null, Array.prototype.concat.apply([], @series)
|
||||
if @options.ymin.length > 5
|
||||
@ymin = Math.min parseInt(@options.ymin[5..], 10), ymin
|
||||
else
|
||||
@ -120,7 +113,7 @@ class Morris.Grid extends Morris.EventEmitter
|
||||
else
|
||||
@ymin = @options.ymin
|
||||
if @ymin is @ymax
|
||||
if @ymin is not 0 then @ymin -= 1
|
||||
if @ymin isnt 0 then @ymin -= 1
|
||||
@ymax += 1
|
||||
|
||||
@yInterval = (@ymax - @ymin) / (@options.numLines - 1)
|
||||
@ -158,7 +151,7 @@ class Morris.Grid extends Morris.EventEmitter
|
||||
#
|
||||
transY: (y) -> @bottom - (y - @ymin) * @dy
|
||||
transX: (x) ->
|
||||
if @xvals.length == 1
|
||||
if @data.length == 1
|
||||
(@left + @right) / 2
|
||||
else
|
||||
@left + (x - @xmin) * @dx
|
||||
|
@ -60,18 +60,15 @@ class Morris.Line extends Morris.Grid
|
||||
# @private
|
||||
calc: ->
|
||||
# calculate series data point coordinates
|
||||
@columns = (@transX(x) for x in @xvals)
|
||||
@seriesCoords = []
|
||||
for s in @series
|
||||
scoords = []
|
||||
$.each s, (i, y) =>
|
||||
if y == null
|
||||
scoords.push(null)
|
||||
else
|
||||
scoords.push(x: @columns[i], y: @transY(y))
|
||||
@seriesCoords.push(scoords)
|
||||
for row in @data
|
||||
row._x = @transX(row.x)
|
||||
row._y = for y in row.y
|
||||
if y is null
|
||||
null
|
||||
else
|
||||
@transY(y)
|
||||
# calculate hover margins
|
||||
@hoverMargins = $.map @columns.slice(1), (x, i) => (x + @columns[i]) / 2
|
||||
@hoverMargins = $.map @data.slice(1), (r, i) => (r._x + @data[i]._x) / 2
|
||||
|
||||
# Draws the line chart.
|
||||
#
|
||||
@ -79,7 +76,7 @@ class Morris.Line extends Morris.Grid
|
||||
@drawXAxis()
|
||||
@drawSeries()
|
||||
@drawHover()
|
||||
@hilight(if @options.hideHover then null else @options.data.length - 1)
|
||||
@hilight(if @options.hideHover then null else @data.length - 1)
|
||||
|
||||
# draw the x-axis labels
|
||||
#
|
||||
@ -102,25 +99,24 @@ class Morris.Line extends Morris.Grid
|
||||
else
|
||||
label.remove()
|
||||
if @options.parseTime
|
||||
if @columnLabels.length == 1 and @options.xLabels == 'auto'
|
||||
if @data.length == 1 and @options.xLabels == 'auto'
|
||||
# where there's only one value in the series, we can't make a
|
||||
# sensible guess for an x labelling scheme, so just use the original
|
||||
# column label
|
||||
drawLabel(@columnLabels[0], @xvals[0])
|
||||
drawLabel(@data[0].label, @data[0].x)
|
||||
else
|
||||
for l in Morris.labelSeries(@xmin, @xmax, @width, @options.xLabels, @options.xLabelFormat)
|
||||
drawLabel(l[0], l[1])
|
||||
else
|
||||
for i in [0...@columnLabels.length]
|
||||
labelText = @columnLabels[i]
|
||||
drawLabel(labelText, i)
|
||||
for row in @data
|
||||
drawLabel(row.label, row.x)
|
||||
|
||||
# draw the data series
|
||||
#
|
||||
# @private
|
||||
drawSeries: ->
|
||||
for i in [@seriesCoords.length-1..0]
|
||||
coords = $.map @seriesCoords[i], (c) -> c
|
||||
for i in [@options.ykeys.length-1..0]
|
||||
coords = ({x: r._x, y: r._y[i]} for r in @data when r._y[i] isnt null)
|
||||
smooth = @options.smooth is true or
|
||||
$.inArray(@options.ykeys[i], @options.smooth) > -1
|
||||
if coords.length > 1
|
||||
@ -128,13 +124,13 @@ class Morris.Line extends Morris.Grid
|
||||
@r.path(path)
|
||||
.attr('stroke', @colorForSeries(i))
|
||||
.attr('stroke-width', @options.lineWidth)
|
||||
@seriesPoints = ([] for i in [0..@seriesCoords.length-1])
|
||||
for i in [@seriesCoords.length-1..0]
|
||||
for c in @seriesCoords[i]
|
||||
if c == null
|
||||
@seriesPoints = ([] for i in [0...@options.ykeys.length])
|
||||
for i in [@options.ykeys.length-1..0]
|
||||
for row in @data
|
||||
if row._y[i] == null
|
||||
circle = null
|
||||
else
|
||||
circle = @r.circle(c.x, c.y, @options.pointSize)
|
||||
circle = @r.circle(row._x, row._y[i], @options.pointSize)
|
||||
.attr('fill', @pointFillColorForSeries(i) || @colorForSeries(i))
|
||||
.attr('stroke-width', @strokeWidthForSeries(i))
|
||||
.attr('stroke', @strokeForSeries(i))
|
||||
@ -182,7 +178,7 @@ class Morris.Line extends Morris.Grid
|
||||
# @private
|
||||
drawHover: ->
|
||||
# hover labels
|
||||
@hoverHeight = @options.hoverFontSize * 1.5 * (@series.length + 1)
|
||||
@hoverHeight = @options.hoverFontSize * 1.5 * (@options.ykeys.length + 1)
|
||||
@hover = @r.rect(-10, -@hoverHeight / 2 - @options.hoverPaddingY, 20, @hoverHeight + @options.hoverPaddingY * 2, 10)
|
||||
.attr('fill', @options.hoverFillColor)
|
||||
.attr('stroke', @options.hoverBorderColor)
|
||||
@ -196,7 +192,7 @@ class Morris.Line extends Morris.Grid
|
||||
@hoverSet.push(@hover)
|
||||
@hoverSet.push(@xLabel)
|
||||
@yLabels = []
|
||||
for i in [0..@series.length-1]
|
||||
for i in [0...@data.length]
|
||||
yLabel = @r.text(0, @options.hoverFontSize * 1.5 * (i + 1.5) - @hoverHeight / 2, '')
|
||||
.attr('fill', @colorForSeries(i))
|
||||
.attr('font-size', @options.hoverFontSize)
|
||||
@ -206,9 +202,10 @@ class Morris.Line extends Morris.Grid
|
||||
# @private
|
||||
updateHover: (index) =>
|
||||
@hoverSet.show()
|
||||
@xLabel.attr('text', @columnLabels[index])
|
||||
for i in [0..@series.length-1]
|
||||
@yLabels[i].attr('text', "#{@options.labels[i]}: #{@yLabelFormat(@series[i][index])}")
|
||||
row = @data[index]
|
||||
@xLabel.attr('text', row.label)
|
||||
for y, i in row.y
|
||||
@yLabels[i].attr('text', "#{@options.labels[i]}: #{@yLabelFormat(y)}")
|
||||
# recalculate hover box width
|
||||
maxLabelWidth = Math.max.apply null, $.map @yLabels, (l) ->
|
||||
l.getBBox().width
|
||||
@ -216,15 +213,14 @@ class Morris.Line extends Morris.Grid
|
||||
@hover.attr 'width', maxLabelWidth + @options.hoverPaddingX * 2
|
||||
@hover.attr 'x', -@options.hoverPaddingX - maxLabelWidth / 2
|
||||
# move to y pos
|
||||
yloc = Math.min.apply null, $.map @series, (s) =>
|
||||
@transY s[index]
|
||||
yloc = Math.min.apply null, row.y
|
||||
if yloc > @hoverHeight + @options.hoverPaddingY * 2 + @options.hoverMargin + @top
|
||||
yloc = yloc - @hoverHeight / 2 - @options.hoverPaddingY - @options.hoverMargin
|
||||
else
|
||||
yloc = yloc + @hoverHeight / 2 + @options.hoverPaddingY + @options.hoverMargin
|
||||
yloc = Math.max @top + @hoverHeight / 2 + @options.hoverPaddingY, yloc
|
||||
yloc = Math.min @bottom - @hoverHeight / 2 - @options.hoverPaddingY, yloc
|
||||
xloc = Math.min @right - maxLabelWidth / 2 - @options.hoverPaddingX, @columns[index]
|
||||
xloc = Math.min @right - maxLabelWidth / 2 - @options.hoverPaddingX, @data[index]._x
|
||||
xloc = Math.max @left + maxLabelWidth / 2 + @options.hoverPaddingX, xloc
|
||||
@hoverSet.attr 'transform', "t#{xloc},#{yloc}"
|
||||
|
||||
|
252
morris.js
252
morris.js
@ -62,6 +62,16 @@
|
||||
return (number < 10 ? '0' : '') + number;
|
||||
};
|
||||
|
||||
Morris.Data = (function() {
|
||||
|
||||
function Data() {}
|
||||
|
||||
Data.prototype.initialize = function(options) {};
|
||||
|
||||
return Data;
|
||||
|
||||
})();
|
||||
|
||||
Morris.Donut = (function() {
|
||||
|
||||
Donut.prototype.defaults = {
|
||||
@ -329,94 +339,79 @@
|
||||
};
|
||||
|
||||
Grid.prototype.setData = function(data, redraw) {
|
||||
var d, seriesData, y, ykey, ymax, ymin, _i, _j, _k, _len, _len1, _ref, _ref1, _ref2, _results,
|
||||
var ymax, ymin,
|
||||
_this = this;
|
||||
if (redraw == null) {
|
||||
redraw = true;
|
||||
}
|
||||
this.options.data = $.map(data, function(row) {
|
||||
ymax = null;
|
||||
ymin = null;
|
||||
this.data = $.map(data, function(row, index) {
|
||||
var ret, ykey, yval;
|
||||
ret = {};
|
||||
ret.label = row[_this.options.xkey];
|
||||
if (_this.options.parseTime) {
|
||||
return $.extend({
|
||||
'__T': Morris.parseDate(row[_this.options.xkey])
|
||||
}, row);
|
||||
ret.x = Morris.parseDate(ret.label);
|
||||
if (_this.options.dateFormat) {
|
||||
ret.label = _this.options.dateFormat(ret.x);
|
||||
} else if (typeof ret.label === 'number') {
|
||||
ret.label = new Date(ret.label).toString();
|
||||
}
|
||||
} else {
|
||||
return $.extend({}, row);
|
||||
ret.x = index;
|
||||
}
|
||||
});
|
||||
if (this.options.parseTime) {
|
||||
this.options.data = this.options.data.sort(function(a, b) {
|
||||
return (a['__T'] > b['__T']) - (b['__T'] > a['__T']);
|
||||
});
|
||||
}
|
||||
this.series = [];
|
||||
_ref = this.options.ykeys;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
ykey = _ref[_i];
|
||||
seriesData = [];
|
||||
_ref1 = this.options.data;
|
||||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
||||
d = _ref1[_j];
|
||||
y = d[ykey];
|
||||
seriesData.push((function() {
|
||||
switch (typeof y) {
|
||||
case 'number':
|
||||
return y;
|
||||
case 'string':
|
||||
return parseFloat(y);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
})());
|
||||
}
|
||||
this.series.push(seriesData);
|
||||
}
|
||||
this.columnLabels = $.map(this.options.data, function(row) {
|
||||
return row[_this.options.xkey];
|
||||
});
|
||||
if (this.options.parseTime) {
|
||||
this.xvals = $.map(this.options.data, function(row) {
|
||||
return row['__T'];
|
||||
});
|
||||
if (this.options.dateFormat) {
|
||||
this.columnLabels = $.map(this.xvals, function(d) {
|
||||
return _this.options.dateFormat(d);
|
||||
});
|
||||
} else {
|
||||
this.columnLabels = $.map(this.columnLabels, function(d) {
|
||||
if (typeof d === 'number') {
|
||||
return new Date(d).toString();
|
||||
} else {
|
||||
return d;
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.xvals = (function() {
|
||||
ret.y = (function() {
|
||||
var _i, _len, _ref, _results;
|
||||
_ref = this.options.ykeys;
|
||||
_results = [];
|
||||
for (var _k = 0, _ref2 = this.columnLabels.length; 0 <= _ref2 ? _k < _ref2 : _k > _ref2; 0 <= _ref2 ? _k++ : _k--){ _results.push(_k); }
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
ykey = _ref[_i];
|
||||
yval = row[ykey];
|
||||
if (typeof yval === 'string') {
|
||||
yval = parseFloat(yval);
|
||||
}
|
||||
if (typeof yval !== 'number') {
|
||||
yval = null;
|
||||
}
|
||||
if (yval !== null) {
|
||||
if (ymax === null) {
|
||||
ymax = ymin = yval;
|
||||
} else {
|
||||
ymax = Math.max(yval, ymax);
|
||||
ymin = Math.min(yval, ymin);
|
||||
}
|
||||
}
|
||||
_results.push(yval);
|
||||
}
|
||||
return _results;
|
||||
}).apply(this);
|
||||
}).call(_this);
|
||||
return ret;
|
||||
});
|
||||
if (this.options.parseTime) {
|
||||
this.data = this.data.sort(function(a, b) {
|
||||
return (a.x > b.x) - (b.x > a.x);
|
||||
});
|
||||
}
|
||||
this.xmin = Math.min.apply(null, this.xvals);
|
||||
this.xmax = Math.max.apply(null, this.xvals);
|
||||
this.xmin = this.data[0].x;
|
||||
this.xmax = this.data[this.data.length - 1].x;
|
||||
if (this.xmin === this.xmax) {
|
||||
this.xmin -= 1;
|
||||
this.xmax += 1;
|
||||
}
|
||||
if (typeof this.options.ymax === 'string' && this.options.ymax.slice(0, 4) === 'auto') {
|
||||
ymax = Math.max.apply(null, Array.prototype.concat.apply([], this.series));
|
||||
if (this.options.ymax.length > 5) {
|
||||
this.ymax = Math.max(parseInt(this.options.ymax.slice(5), 10), ymax);
|
||||
if (typeof this.options.ymax === 'string') {
|
||||
if (this.options.ymax.slice(0, 4) === 'auto') {
|
||||
if (this.options.ymax.length > 5) {
|
||||
this.ymax = Math.max(parseInt(this.options.ymax.slice(5), 10), ymax);
|
||||
} else {
|
||||
this.ymax = ymax;
|
||||
}
|
||||
} else {
|
||||
this.ymax = ymax;
|
||||
this.ymax = parseInt(this.options.ymax, 10);
|
||||
}
|
||||
} else if (typeof this.options.ymax === 'string') {
|
||||
this.ymax = parseInt(this.options.ymax, 10);
|
||||
} else {
|
||||
this.ymax = this.options.ymax;
|
||||
}
|
||||
if (typeof this.options.ymin === 'string' && this.options.ymin.slice(0, 4) === 'auto') {
|
||||
ymin = Math.min.apply(null, Array.prototype.concat.apply([], this.series));
|
||||
if (this.options.ymin.length > 5) {
|
||||
this.ymin = Math.min(parseInt(this.options.ymin.slice(5), 10), ymin);
|
||||
} else {
|
||||
@ -428,7 +423,7 @@
|
||||
this.ymin = this.options.ymin;
|
||||
}
|
||||
if (this.ymin === this.ymax) {
|
||||
if (this.ymin === !0) {
|
||||
if (this.ymin !== 0) {
|
||||
this.ymin -= 1;
|
||||
}
|
||||
this.ymax += 1;
|
||||
@ -473,7 +468,7 @@
|
||||
};
|
||||
|
||||
Grid.prototype.transX = function(x) {
|
||||
if (this.xvals.length === 1) {
|
||||
if (this.data.length === 1) {
|
||||
return (this.left + this.right) / 2;
|
||||
} else {
|
||||
return this.left + (x - this.xmin) * this.dx;
|
||||
@ -651,37 +646,29 @@
|
||||
};
|
||||
|
||||
Line.prototype.calc = function() {
|
||||
var s, scoords, x, _i, _len, _ref,
|
||||
var row, y, _i, _len, _ref,
|
||||
_this = this;
|
||||
this.columns = (function() {
|
||||
var _i, _len, _ref, _results;
|
||||
_ref = this.xvals;
|
||||
_results = [];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
x = _ref[_i];
|
||||
_results.push(this.transX(x));
|
||||
}
|
||||
return _results;
|
||||
}).call(this);
|
||||
this.seriesCoords = [];
|
||||
_ref = this.series;
|
||||
_ref = this.data;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
s = _ref[_i];
|
||||
scoords = [];
|
||||
$.each(s, function(i, y) {
|
||||
if (y === null) {
|
||||
return scoords.push(null);
|
||||
} else {
|
||||
return scoords.push({
|
||||
x: _this.columns[i],
|
||||
y: _this.transY(y)
|
||||
});
|
||||
row = _ref[_i];
|
||||
row._x = this.transX(row.x);
|
||||
row._y = (function() {
|
||||
var _j, _len1, _ref1, _results;
|
||||
_ref1 = row.y;
|
||||
_results = [];
|
||||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
||||
y = _ref1[_j];
|
||||
if (y === null) {
|
||||
_results.push(null);
|
||||
} else {
|
||||
_results.push(this.transY(y));
|
||||
}
|
||||
}
|
||||
});
|
||||
this.seriesCoords.push(scoords);
|
||||
return _results;
|
||||
}).call(this);
|
||||
}
|
||||
return this.hoverMargins = $.map(this.columns.slice(1), function(x, i) {
|
||||
return (x + _this.columns[i]) / 2;
|
||||
return this.hoverMargins = $.map(this.data.slice(1), function(r, i) {
|
||||
return (r._x + _this.data[i]._x) / 2;
|
||||
});
|
||||
};
|
||||
|
||||
@ -689,11 +676,11 @@
|
||||
this.drawXAxis();
|
||||
this.drawSeries();
|
||||
this.drawHover();
|
||||
return this.hilight(this.options.hideHover ? null : this.options.data.length - 1);
|
||||
return this.hilight(this.options.hideHover ? null : this.data.length - 1);
|
||||
};
|
||||
|
||||
Line.prototype.drawXAxis = function() {
|
||||
var drawLabel, i, l, labelText, prevLabelMargin, xLabelMargin, ypos, _i, _j, _len, _ref, _ref1, _results, _results1,
|
||||
var drawLabel, l, prevLabelMargin, row, xLabelMargin, ypos, _i, _j, _len, _len1, _ref, _ref1, _results, _results1,
|
||||
_this = this;
|
||||
ypos = this.bottom + this.options.gridTextSize * 1.25;
|
||||
xLabelMargin = 50;
|
||||
@ -709,8 +696,8 @@
|
||||
}
|
||||
};
|
||||
if (this.options.parseTime) {
|
||||
if (this.columnLabels.length === 1 && this.options.xLabels === 'auto') {
|
||||
return drawLabel(this.columnLabels[0], this.xvals[0]);
|
||||
if (this.data.length === 1 && this.options.xLabels === 'auto') {
|
||||
return drawLabel(this.data[0].label, this.data[0].x);
|
||||
} else {
|
||||
_ref = Morris.labelSeries(this.xmin, this.xmax, this.width, this.options.xLabels, this.options.xLabelFormat);
|
||||
_results = [];
|
||||
@ -721,21 +708,34 @@
|
||||
return _results;
|
||||
}
|
||||
} else {
|
||||
_ref1 = this.data;
|
||||
_results1 = [];
|
||||
for (i = _j = 0, _ref1 = this.columnLabels.length; 0 <= _ref1 ? _j < _ref1 : _j > _ref1; i = 0 <= _ref1 ? ++_j : --_j) {
|
||||
labelText = this.columnLabels[i];
|
||||
_results1.push(drawLabel(labelText, i));
|
||||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
||||
row = _ref1[_j];
|
||||
_results1.push(drawLabel(row.label, row.x));
|
||||
}
|
||||
return _results1;
|
||||
}
|
||||
};
|
||||
|
||||
Line.prototype.drawSeries = function() {
|
||||
var c, circle, coords, i, path, smooth, _i, _j, _ref, _ref1, _results;
|
||||
for (i = _i = _ref = this.seriesCoords.length - 1; _ref <= 0 ? _i <= 0 : _i >= 0; i = _ref <= 0 ? ++_i : --_i) {
|
||||
coords = $.map(this.seriesCoords[i], function(c) {
|
||||
return c;
|
||||
});
|
||||
var circle, coords, i, path, r, row, smooth, _i, _j, _ref, _ref1, _results;
|
||||
for (i = _i = _ref = this.options.ykeys.length - 1; _ref <= 0 ? _i <= 0 : _i >= 0; i = _ref <= 0 ? ++_i : --_i) {
|
||||
coords = (function() {
|
||||
var _j, _len, _ref1, _results;
|
||||
_ref1 = this.data;
|
||||
_results = [];
|
||||
for (_j = 0, _len = _ref1.length; _j < _len; _j++) {
|
||||
r = _ref1[_j];
|
||||
if (r._y[i] !== null) {
|
||||
_results.push({
|
||||
x: r._x,
|
||||
y: r._y[i]
|
||||
});
|
||||
}
|
||||
}
|
||||
return _results;
|
||||
}).call(this);
|
||||
smooth = this.options.smooth === true || $.inArray(this.options.ykeys[i], this.options.smooth) > -1;
|
||||
if (coords.length > 1) {
|
||||
path = this.createPath(coords, this.bottom, smooth);
|
||||
@ -745,23 +745,23 @@
|
||||
this.seriesPoints = (function() {
|
||||
var _j, _ref1, _results;
|
||||
_results = [];
|
||||
for (i = _j = 0, _ref1 = this.seriesCoords.length - 1; 0 <= _ref1 ? _j <= _ref1 : _j >= _ref1; i = 0 <= _ref1 ? ++_j : --_j) {
|
||||
for (i = _j = 0, _ref1 = this.options.ykeys.length; 0 <= _ref1 ? _j < _ref1 : _j > _ref1; i = 0 <= _ref1 ? ++_j : --_j) {
|
||||
_results.push([]);
|
||||
}
|
||||
return _results;
|
||||
}).call(this);
|
||||
_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.options.ykeys.length - 1; _ref1 <= 0 ? _j <= 0 : _j >= 0; i = _ref1 <= 0 ? ++_j : --_j) {
|
||||
_results.push((function() {
|
||||
var _k, _len, _ref2, _results1;
|
||||
_ref2 = this.seriesCoords[i];
|
||||
_ref2 = this.data;
|
||||
_results1 = [];
|
||||
for (_k = 0, _len = _ref2.length; _k < _len; _k++) {
|
||||
c = _ref2[_k];
|
||||
if (c === null) {
|
||||
row = _ref2[_k];
|
||||
if (row._y[i] === null) {
|
||||
circle = null;
|
||||
} else {
|
||||
circle = this.r.circle(c.x, c.y, this.options.pointSize).attr('fill', this.pointFillColorForSeries(i) || this.colorForSeries(i)).attr('stroke-width', this.strokeWidthForSeries(i)).attr('stroke', this.strokeForSeries(i));
|
||||
circle = this.r.circle(row._x, row._y[i], this.options.pointSize).attr('fill', this.pointFillColorForSeries(i) || this.colorForSeries(i)).attr('stroke-width', this.strokeWidthForSeries(i)).attr('stroke', this.strokeForSeries(i));
|
||||
}
|
||||
_results1.push(this.seriesPoints[i].push(circle));
|
||||
}
|
||||
@ -814,7 +814,7 @@
|
||||
|
||||
Line.prototype.drawHover = function() {
|
||||
var i, yLabel, _i, _ref, _results;
|
||||
this.hoverHeight = this.options.hoverFontSize * 1.5 * (this.series.length + 1);
|
||||
this.hoverHeight = this.options.hoverFontSize * 1.5 * (this.options.ykeys.length + 1);
|
||||
this.hover = this.r.rect(-10, -this.hoverHeight / 2 - this.options.hoverPaddingY, 20, this.hoverHeight + this.options.hoverPaddingY * 2, 10).attr('fill', this.options.hoverFillColor).attr('stroke', this.options.hoverBorderColor).attr('stroke-width', this.options.hoverBorderWidth).attr('opacity', this.options.hoverOpacity);
|
||||
this.xLabel = this.r.text(0, (this.options.hoverFontSize * 0.75) - this.hoverHeight / 2, '').attr('fill', this.options.hoverLabelColor).attr('font-weight', 'bold').attr('font-size', this.options.hoverFontSize);
|
||||
this.hoverSet = this.r.set();
|
||||
@ -822,7 +822,7 @@
|
||||
this.hoverSet.push(this.xLabel);
|
||||
this.yLabels = [];
|
||||
_results = [];
|
||||
for (i = _i = 0, _ref = this.series.length - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
|
||||
for (i = _i = 0, _ref = this.data.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
|
||||
yLabel = this.r.text(0, this.options.hoverFontSize * 1.5 * (i + 1.5) - this.hoverHeight / 2, '').attr('fill', this.colorForSeries(i)).attr('font-size', this.options.hoverFontSize);
|
||||
this.yLabels.push(yLabel);
|
||||
_results.push(this.hoverSet.push(yLabel));
|
||||
@ -831,12 +831,14 @@
|
||||
};
|
||||
|
||||
Line.prototype.updateHover = function(index) {
|
||||
var i, maxLabelWidth, xloc, yloc, _i, _ref,
|
||||
_this = this;
|
||||
var i, maxLabelWidth, row, xloc, y, yloc, _i, _len, _ref;
|
||||
this.hoverSet.show();
|
||||
this.xLabel.attr('text', this.columnLabels[index]);
|
||||
for (i = _i = 0, _ref = this.series.length - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
|
||||
this.yLabels[i].attr('text', "" + this.options.labels[i] + ": " + (this.yLabelFormat(this.series[i][index])));
|
||||
row = this.data[index];
|
||||
this.xLabel.attr('text', row.label);
|
||||
_ref = row.y;
|
||||
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
|
||||
y = _ref[i];
|
||||
this.yLabels[i].attr('text', "" + this.options.labels[i] + ": " + (this.yLabelFormat(y)));
|
||||
}
|
||||
maxLabelWidth = Math.max.apply(null, $.map(this.yLabels, function(l) {
|
||||
return l.getBBox().width;
|
||||
@ -844,9 +846,7 @@
|
||||
maxLabelWidth = Math.max(maxLabelWidth, this.xLabel.getBBox().width);
|
||||
this.hover.attr('width', maxLabelWidth + this.options.hoverPaddingX * 2);
|
||||
this.hover.attr('x', -this.options.hoverPaddingX - maxLabelWidth / 2);
|
||||
yloc = Math.min.apply(null, $.map(this.series, function(s) {
|
||||
return _this.transY(s[index]);
|
||||
}));
|
||||
yloc = Math.min.apply(null, row.y);
|
||||
if (yloc > this.hoverHeight + this.options.hoverPaddingY * 2 + this.options.hoverMargin + this.top) {
|
||||
yloc = yloc - this.hoverHeight / 2 - this.options.hoverPaddingY - this.options.hoverMargin;
|
||||
} else {
|
||||
@ -854,7 +854,7 @@
|
||||
}
|
||||
yloc = Math.max(this.top + this.hoverHeight / 2 + this.options.hoverPaddingY, yloc);
|
||||
yloc = Math.min(this.bottom - this.hoverHeight / 2 - this.options.hoverPaddingY, yloc);
|
||||
xloc = Math.min(this.right - maxLabelWidth / 2 - this.options.hoverPaddingX, this.columns[index]);
|
||||
xloc = Math.min(this.right - maxLabelWidth / 2 - this.options.hoverPaddingX, this.data[index]._x);
|
||||
xloc = Math.max(this.left + maxLabelWidth / 2 + this.options.hoverPaddingX, xloc);
|
||||
return this.hoverSet.attr('transform', "t" + xloc + "," + yloc);
|
||||
};
|
||||
|
2
morris.min.js
vendored
2
morris.min.js
vendored
File diff suppressed because one or more lines are too long
@ -60,7 +60,7 @@ describe 'Morris.Line', ->
|
||||
xkey: 'x'
|
||||
ykeys: ['y']
|
||||
labels: ['dontcare']
|
||||
chart.columnLabels.should == ['2012 Q1', '2012 Q2']
|
||||
chart.data.map((x) -> x.label).should == ['2012 Q1', '2012 Q2']
|
||||
|
||||
it 'should use a default format for timestamp x-values', ->
|
||||
d1 = new Date(2012, 0, 1)
|
||||
@ -71,7 +71,7 @@ describe 'Morris.Line', ->
|
||||
xkey: 'x'
|
||||
ykeys: ['y']
|
||||
labels: ['dontcare']
|
||||
chart.columnLabels.should == [d2.toString(), d1.toString()]
|
||||
chart.data.map((x) -> x.label).should == [d2.toString(), d1.toString()]
|
||||
|
||||
it 'should use user-defined formatters', ->
|
||||
d = new Date(2012, 0, 1)
|
||||
@ -84,4 +84,4 @@ describe 'Morris.Line', ->
|
||||
dateFormat: (d) ->
|
||||
x = new Date(d)
|
||||
"#{x.getYear()}/#{x.getMonth()+1}/#{x.getDay()}"
|
||||
chart.columnLabels.should == ['2012/1/1', '2012/1/2']
|
||||
chart.data.map((x) -> x.label).should == ['2012/1/1', '2012/1/2']
|
||||
|
Loading…
Reference in New Issue
Block a user