mirror of
https://github.com/morrisjs/morris.js.git
synced 2024-09-21 10:41:32 +02:00
Merge branch 'wrap_raphael_add_classes' of https://github.com/chriserin/morris.js into chriserin-wrap_raphael_add_classes
Conflicts: lib/morris.donut.coffee
This commit is contained in:
commit
cd5129c489
1
grunt.js
1
grunt.js
@ -15,6 +15,7 @@ module.exports = function (grunt) {
|
||||
concat: {
|
||||
'build/morris.coffee': [
|
||||
'lib/morris.coffee',
|
||||
'lib/morris.svg.coffee',
|
||||
'lib/morris.grid.coffee',
|
||||
'lib/morris.hover.coffee',
|
||||
'lib/morris.line.coffee',
|
||||
|
@ -26,9 +26,7 @@ class Morris.Area extends Morris.Line
|
||||
path = @paths[i]
|
||||
if path isnt null
|
||||
path = path + "L#{@transX(@xmax)},#{@bottom}L#{@transX(@xmin)},#{@bottom}Z"
|
||||
@r.path(path)
|
||||
.attr('fill', @fillForSeries(i))
|
||||
.attr('stroke-width', 0)
|
||||
@drawFilledPath(path, @fillForSeries(i))
|
||||
super()
|
||||
|
||||
fillForSeries: (i) ->
|
||||
@ -37,3 +35,8 @@ class Morris.Area extends Morris.Line
|
||||
color.h,
|
||||
Math.min(255, color.s * 0.75),
|
||||
Math.min(255, color.l * 1.25))
|
||||
|
||||
drawFilledPath: (path, fill) ->
|
||||
@raphael.path(path)
|
||||
.attr('fill', fill)
|
||||
.attr('stroke-width', 0)
|
||||
|
@ -59,9 +59,7 @@ class Morris.Bar extends Morris.Grid
|
||||
prevLabelMargin = null
|
||||
for i in [0...@data.length]
|
||||
row = @data[@data.length - 1 - i]
|
||||
label = @r.text(row._x, ypos, row.label)
|
||||
.attr('font-size', @options.gridTextSize)
|
||||
.attr('fill', @options.gridTextColor)
|
||||
label = @drawXAxisLabel(row._x, ypos, row.label)
|
||||
labelBox = label.getBBox()
|
||||
# ensure a minimum of `xLabelMargin` pixels between labels, and ensure
|
||||
# labels don't overflow the container
|
||||
@ -96,9 +94,7 @@ class Morris.Bar extends Morris.Grid
|
||||
size = bottom - top
|
||||
|
||||
top -= lastTop if @options.stacked
|
||||
@r.rect(left, top, barWidth, size)
|
||||
.attr('fill', @colorFor(row, sidx, 'bar'))
|
||||
.attr('stroke-width', 0)
|
||||
@drawBar(left, top, barWidth, size, @colorFor(row, sidx, 'bar'))
|
||||
|
||||
lastTop += size
|
||||
else
|
||||
@ -156,3 +152,13 @@ class Morris.Bar extends Morris.Grid
|
||||
"""
|
||||
x = @left + (index + 0.5) * @width / @data.length
|
||||
[content, x]
|
||||
|
||||
drawXAxisLabel: (xPos, yPos, text) ->
|
||||
label = @raphael.text(xPos, yPos, text)
|
||||
.attr('font-size', @options.gridTextSize)
|
||||
.attr('fill', @options.gridTextColor)
|
||||
|
||||
drawBar: (xPos, yPos, width, height, barColor) ->
|
||||
@raphael.rect(xPos, yPos, width, height)
|
||||
.attr('fill', barColor)
|
||||
.attr('stroke-width', 0)
|
||||
|
@ -55,7 +55,7 @@ class Morris.Donut
|
||||
redraw: ->
|
||||
@el.empty()
|
||||
|
||||
@r = new Raphael(@el[0])
|
||||
@raphael = new Raphael(@el[0])
|
||||
|
||||
cx = @el.width() / 2
|
||||
cy = @el.height() / 2
|
||||
@ -72,14 +72,14 @@ class Morris.Donut
|
||||
@segments = []
|
||||
for d in @data
|
||||
next = last + min + C * (d.value / total)
|
||||
seg = new Morris.DonutSegment(cx, cy, w*2, w, last, next, @options.colors[idx % @options.colors.length], @options.backgroundColor, d)
|
||||
seg.render @r
|
||||
seg = new Morris.DonutSegment(cx, cy, w*2, w, last, next, @options.colors[idx % @options.colors.length], @options.backgroundColor, d, @raphael)
|
||||
seg.render()
|
||||
@segments.push seg
|
||||
seg.on 'hover', @select
|
||||
last = next
|
||||
idx += 1
|
||||
@text1 = @r.text(cx, cy - 10, '').attr('font-size': 15, 'font-weight': 800)
|
||||
@text2 = @r.text(cx, cy + 10, '').attr('font-size': 14)
|
||||
@text1 = @drawEmptyDonutLabel(cx, cy - 10, 15, 800)
|
||||
@text2 = @drawEmptyDonutLabel(cx, cy + 10, 14)
|
||||
max_value = Math.max.apply(null, d.value for d in @data)
|
||||
idx = 0
|
||||
for d in @data
|
||||
@ -110,12 +110,17 @@ class Morris.Donut
|
||||
text2scale = Math.min(maxWidth / text2bbox.width, maxHeightBottom / text2bbox.height)
|
||||
@text2.attr(transform: "S#{text2scale},#{text2scale},#{text2bbox.x + text2bbox.width / 2},#{text2bbox.y}")
|
||||
|
||||
drawEmptyDonutLabel: (xPos, yPos, fontSize, fontWeight) ->
|
||||
text = @raphael.text(xPos, yPos, '').attr('font-size', fontSize)
|
||||
text.attr('font-weight', fontWeight) if fontWeight?
|
||||
return text
|
||||
|
||||
|
||||
# A segment within a donut chart.
|
||||
#
|
||||
# @private
|
||||
class Morris.DonutSegment extends Morris.EventEmitter
|
||||
constructor: (@cx, @cy, @inner, @outer, p0, p1, @color, @backgroundColor, @data) ->
|
||||
constructor: (@cx, @cy, @inner, @outer, p0, p1, @color, @backgroundColor, @data, @raphael) ->
|
||||
@sin_p0 = Math.sin(p0)
|
||||
@cos_p0 = Math.cos(p0)
|
||||
@sin_p1 = Math.sin(p1)
|
||||
@ -148,11 +153,18 @@ class Morris.DonutSegment extends Morris.EventEmitter
|
||||
"M#{ix0},#{iy0}" +
|
||||
"A#{r},#{r},0,#{@is_long},0,#{ix1},#{iy1}")
|
||||
|
||||
render: (r) ->
|
||||
@arc = r.path(@hilight).attr(stroke: @color, 'stroke-width': 2, opacity: 0)
|
||||
@seg = r.path(@path)
|
||||
.attr(fill: @color, stroke: @backgroundColor, 'stroke-width': 3)
|
||||
.hover(=> @fire('hover', @))
|
||||
render: ->
|
||||
@arc = @drawDonutArc(@hilight, @color)
|
||||
@seg = @drawDonutSegment(@path, @color, @backgroundColor, => @fire('hover', @))
|
||||
|
||||
drawDonutArc: (path, color) ->
|
||||
@raphael.path(path)
|
||||
.attr(stroke: color, 'stroke-width': 2, opacity: 0)
|
||||
|
||||
drawDonutSegment: (path, fillColor, strokeColor, hoverFunction) ->
|
||||
@raphael.path(path)
|
||||
.attr(fill: fillColor, stroke: strokeColor, 'stroke-width': 3)
|
||||
.hover(hoverFunction)
|
||||
|
||||
select: =>
|
||||
unless @selected
|
||||
|
@ -26,7 +26,7 @@ class Morris.Grid extends Morris.EventEmitter
|
||||
@options.postUnits = options.units
|
||||
|
||||
# the raphael drawing instance
|
||||
@r = new Raphael(@el[0])
|
||||
@raphael = new Raphael(@el[0])
|
||||
|
||||
# some redraw stuff
|
||||
@elementWidth = null
|
||||
@ -227,7 +227,7 @@ class Morris.Grid extends Morris.EventEmitter
|
||||
# If you need to re-size your charts, call this method after changing the
|
||||
# size of the container element.
|
||||
redraw: ->
|
||||
@r.clear()
|
||||
@raphael.clear()
|
||||
@_calc()
|
||||
@drawGrid()
|
||||
@drawGoals()
|
||||
@ -238,16 +238,12 @@ class Morris.Grid extends Morris.EventEmitter
|
||||
#
|
||||
drawGoals: ->
|
||||
for goal, i in @options.goals
|
||||
@r.path("M#{@left},#{@transY(goal)}H#{@left + @width}")
|
||||
.attr('stroke', @options.goalLineColors[i % @options.goalLineColors.length])
|
||||
.attr('stroke-width', @options.goalStrokeWidth)
|
||||
@drawGoal("M#{@left},#{@transY(goal)}H#{@left + @width}")
|
||||
|
||||
# draw events vertical lines
|
||||
drawEvents: ->
|
||||
for event, i in @events
|
||||
@r.path("M#{@transX(event)},#{@bottom}V#{@top}")
|
||||
.attr('stroke', @options.eventLineColors[i % @options.eventLineColors.length])
|
||||
.attr('stroke-width', @options.eventStrokeWidth)
|
||||
@drawEvent("M#{@transX(event)},#{@bottom}V#{@top}")
|
||||
|
||||
# draw y axis labels, horizontal lines
|
||||
#
|
||||
@ -259,19 +255,14 @@ class Morris.Grid extends Morris.EventEmitter
|
||||
v = parseFloat(lineY.toFixed(@precision))
|
||||
y = @transY(v)
|
||||
if @options.axes
|
||||
@r.text(@left - @options.padding / 2, y, @yAxisFormat(v))
|
||||
.attr('font-size', @options.gridTextSize)
|
||||
.attr('fill', @options.gridTextColor)
|
||||
.attr('text-anchor', 'end')
|
||||
@drawYAxisLabel(@left - @options.padding / 2, y, @yAxisFormat(v))
|
||||
if @options.grid
|
||||
@r.path("M#{@left},#{y}H#{@left + @width}")
|
||||
.attr('stroke', @options.gridLineColor)
|
||||
.attr('stroke-width', @options.gridStrokeWidth)
|
||||
@drawGridLine("M#{@left},#{y}H#{@left + @width}")
|
||||
|
||||
# @private
|
||||
#
|
||||
measureText: (text, fontSize = 12) ->
|
||||
tt = @r.text(100, 100, text).attr('font-size', fontSize)
|
||||
tt = @raphael.text(100, 100, text).attr('font-size', fontSize)
|
||||
ret = tt.getBBox()
|
||||
tt.remove()
|
||||
ret
|
||||
@ -293,6 +284,27 @@ class Morris.Grid extends Morris.EventEmitter
|
||||
if hit?
|
||||
@hover.update(hit...)
|
||||
|
||||
drawGoal: (path) ->
|
||||
@raphael.path(path)
|
||||
.attr('stroke', @options.goalLineColors[i % @options.goalLineColors.length])
|
||||
.attr('stroke-width', @options.goalStrokeWidth)
|
||||
|
||||
drawEvent: (path) ->
|
||||
@raphael.path(path)
|
||||
.attr('stroke', @options.eventLineColors[i % @options.eventLineColors.length])
|
||||
.attr('stroke-width', @options.eventStrokeWidth)
|
||||
|
||||
drawYAxisLabel: (xPos, yPos, text) ->
|
||||
@raphael.text(xPos, yPos, text)
|
||||
.attr('font-size', @options.gridTextSize)
|
||||
.attr('fill', @options.gridTextColor)
|
||||
.attr('text-anchor', 'end')
|
||||
|
||||
drawGridLine: (path) ->
|
||||
@raphael.path(path)
|
||||
.attr('stroke', @options.gridLineColor)
|
||||
.attr('stroke-width', @options.gridStrokeWidth)
|
||||
|
||||
# Parse a date into a javascript timestamp
|
||||
#
|
||||
#
|
||||
|
@ -138,9 +138,7 @@ class Morris.Line extends Morris.Grid
|
||||
ypos = @bottom + @options.gridTextSize * 1.25
|
||||
prevLabelMargin = null
|
||||
drawLabel = (labelText, xpos) =>
|
||||
label = @r.text(@transX(xpos), ypos, labelText)
|
||||
.attr('font-size', @options.gridTextSize)
|
||||
.attr('fill', @options.gridTextColor)
|
||||
label = @drawXAxisLabel(@transX(xpos), ypos, labelText)
|
||||
labelBox = label.getBBox()
|
||||
# ensure a minimum of `xLabelMargin` pixels between labels, and ensure
|
||||
# labels don't overflow the container
|
||||
@ -170,17 +168,12 @@ class Morris.Line extends Morris.Grid
|
||||
for i in [@options.ykeys.length-1..0]
|
||||
path = @paths[i]
|
||||
if path isnt null
|
||||
@r.path(path)
|
||||
.attr('stroke', @colorFor(row, i, 'line'))
|
||||
.attr('stroke-width', @options.lineWidth)
|
||||
@drawLinePath(path, @colorFor(row, i, 'line')) #row isn't available here?
|
||||
@seriesPoints = ([] for i in [0...@options.ykeys.length])
|
||||
for i in [@options.ykeys.length-1..0]
|
||||
for row in @data
|
||||
if row._y[i]?
|
||||
circle = @r.circle(row._x, row._y[i], @options.pointSize)
|
||||
.attr('fill', @colorFor(row, i, 'point'))
|
||||
.attr('stroke-width', @strokeWidthForSeries(i))
|
||||
.attr('stroke', @strokeForSeries(i))
|
||||
circle = @drawLinePoint(row._x, row._y[i], @options.pointSize, @colorFor(row, i, 'point'), i)
|
||||
else
|
||||
circle = null
|
||||
@seriesPoints[i].push(circle)
|
||||
@ -245,14 +238,6 @@ class Morris.Line extends Morris.Grid
|
||||
@seriesPoints[i][index].animate @pointGrow
|
||||
@prevHilight = index
|
||||
|
||||
# @private
|
||||
strokeWidthForSeries: (index) ->
|
||||
@options.pointWidths[index % @options.pointWidths.length]
|
||||
|
||||
# @private
|
||||
strokeForSeries: (index) ->
|
||||
@options.pointStrokeColors[index % @options.pointStrokeColors.length]
|
||||
|
||||
colorFor: (row, sidx, type) ->
|
||||
if typeof @options.lineColors is 'function'
|
||||
@options.lineColors.call(@, row, sidx, type)
|
||||
@ -261,6 +246,29 @@ class Morris.Line extends Morris.Grid
|
||||
else
|
||||
@options.lineColors[sidx % @options.lineColors.length]
|
||||
|
||||
drawXAxisLabel: (xPos, yPos, text) ->
|
||||
@raphael.text(xPos, yPos, text)
|
||||
.attr('font-size', @options.gridTextSize)
|
||||
.attr('fill', @options.gridTextColor)
|
||||
|
||||
drawLinePath: (path, lineColor) ->
|
||||
@raphael.path(path)
|
||||
.attr('stroke', lineColor)
|
||||
.attr('stroke-width', @options.lineWidth)
|
||||
|
||||
drawLinePoint: (xPos, yPos, size, pointColor, lineIndex) ->
|
||||
@raphael.circle(xPos, yPos, size)
|
||||
.attr('fill', pointColor)
|
||||
.attr('stroke-width', @strokeWidthForSeries(lineIndex))
|
||||
.attr('stroke', @strokeForSeries(lineIndex))
|
||||
|
||||
# @private
|
||||
strokeWidthForSeries: (index) ->
|
||||
@options.pointWidths[index % @options.pointWidths.length]
|
||||
|
||||
# @private
|
||||
strokeForSeries: (index) ->
|
||||
@options.pointStrokeColors[index % @options.pointStrokeColors.length]
|
||||
|
||||
# generate a series of label, timestamp pairs for x-axis labels
|
||||
#
|
||||
|
136
morris.js
136
morris.js
@ -87,7 +87,7 @@
|
||||
if (typeof this.options.units === 'string') {
|
||||
this.options.postUnits = options.units;
|
||||
}
|
||||
this.r = new Raphael(this.el[0]);
|
||||
this.raphael = new Raphael(this.el[0]);
|
||||
this.elementWidth = null;
|
||||
this.elementHeight = null;
|
||||
this.dirty = false;
|
||||
@ -324,7 +324,7 @@
|
||||
};
|
||||
|
||||
Grid.prototype.redraw = function() {
|
||||
this.r.clear();
|
||||
this.raphael.clear();
|
||||
this._calc();
|
||||
this.drawGrid();
|
||||
this.drawGoals();
|
||||
@ -340,7 +340,7 @@
|
||||
_results = [];
|
||||
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
|
||||
goal = _ref[i];
|
||||
_results.push(this.r.path("M" + this.left + "," + (this.transY(goal)) + "H" + (this.left + this.width)).attr('stroke', this.options.goalLineColors[i % this.options.goalLineColors.length]).attr('stroke-width', this.options.goalStrokeWidth));
|
||||
_results.push(this.drawGoal("M" + this.left + "," + (this.transY(goal)) + "H" + (this.left + this.width)));
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
@ -351,7 +351,7 @@
|
||||
_results = [];
|
||||
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
|
||||
event = _ref[i];
|
||||
_results.push(this.r.path("M" + (this.transX(event)) + "," + this.bottom + "V" + this.top).attr('stroke', this.options.eventLineColors[i % this.options.eventLineColors.length]).attr('stroke-width', this.options.eventStrokeWidth));
|
||||
_results.push(this.drawEvent("M" + (this.transX(event)) + "," + this.bottom + "V" + this.top));
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
@ -368,10 +368,10 @@
|
||||
v = parseFloat(lineY.toFixed(this.precision));
|
||||
y = this.transY(v);
|
||||
if (this.options.axes) {
|
||||
this.r.text(this.left - this.options.padding / 2, y, this.yAxisFormat(v)).attr('font-size', this.options.gridTextSize).attr('fill', this.options.gridTextColor).attr('text-anchor', 'end');
|
||||
this.drawYAxisLabel(this.left - this.options.padding / 2, y, this.yAxisFormat(v));
|
||||
}
|
||||
if (this.options.grid) {
|
||||
_results.push(this.r.path("M" + this.left + "," + y + "H" + (this.left + this.width)).attr('stroke', this.options.gridLineColor).attr('stroke-width', this.options.gridStrokeWidth));
|
||||
_results.push(this.drawGridLine("M" + this.left + "," + y + "H" + (this.left + this.width)));
|
||||
} else {
|
||||
_results.push(void 0);
|
||||
}
|
||||
@ -384,7 +384,7 @@
|
||||
if (fontSize == null) {
|
||||
fontSize = 12;
|
||||
}
|
||||
tt = this.r.text(100, 100, text).attr('font-size', fontSize);
|
||||
tt = this.raphael.text(100, 100, text).attr('font-size', fontSize);
|
||||
ret = tt.getBBox();
|
||||
tt.remove();
|
||||
return ret;
|
||||
@ -410,6 +410,22 @@
|
||||
}
|
||||
};
|
||||
|
||||
Grid.prototype.drawGoal = function(path) {
|
||||
return this.raphael.path(path).attr('stroke', this.options.goalLineColors[i % this.options.goalLineColors.length]).attr('stroke-width', this.options.goalStrokeWidth);
|
||||
};
|
||||
|
||||
Grid.prototype.drawEvent = function(path) {
|
||||
return this.raphael.path(path).attr('stroke', this.options.eventLineColors[i % this.options.eventLineColors.length]).attr('stroke-width', this.options.eventStrokeWidth);
|
||||
};
|
||||
|
||||
Grid.prototype.drawYAxisLabel = function(xPos, yPos, text) {
|
||||
return this.raphael.text(xPos, yPos, text).attr('font-size', this.options.gridTextSize).attr('fill', this.options.gridTextColor).attr('text-anchor', 'end');
|
||||
};
|
||||
|
||||
Grid.prototype.drawGridLine = function(path) {
|
||||
return this.raphael.path(path).attr('stroke', this.options.gridLineColor).attr('stroke-width', this.options.gridStrokeWidth);
|
||||
};
|
||||
|
||||
return Grid;
|
||||
|
||||
})(Morris.EventEmitter);
|
||||
@ -735,7 +751,7 @@
|
||||
prevLabelMargin = null;
|
||||
drawLabel = function(labelText, xpos) {
|
||||
var label, labelBox;
|
||||
label = _this.r.text(_this.transX(xpos), ypos, labelText).attr('font-size', _this.options.gridTextSize).attr('fill', _this.options.gridTextColor);
|
||||
label = _this.drawXAxisLabel(_this.transX(xpos), ypos, labelText);
|
||||
labelBox = label.getBBox();
|
||||
if ((!(prevLabelMargin != null) || prevLabelMargin >= labelBox.x + labelBox.width) && labelBox.x >= 0 && (labelBox.x + labelBox.width) < _this.el.width()) {
|
||||
return prevLabelMargin = labelBox.x - _this.options.xLabelMargin;
|
||||
@ -775,7 +791,7 @@
|
||||
for (i = _i = _ref = this.options.ykeys.length - 1; _ref <= 0 ? _i <= 0 : _i >= 0; i = _ref <= 0 ? ++_i : --_i) {
|
||||
path = this.paths[i];
|
||||
if (path !== null) {
|
||||
this.r.path(path).attr('stroke', this.colorFor(row, i, 'line')).attr('stroke-width', this.options.lineWidth);
|
||||
this.drawLinePath(path, this.colorFor(row, i, 'line'));
|
||||
}
|
||||
}
|
||||
this.seriesPoints = (function() {
|
||||
@ -795,7 +811,7 @@
|
||||
for (_k = 0, _len = _ref2.length; _k < _len; _k++) {
|
||||
row = _ref2[_k];
|
||||
if (row._y[i] != null) {
|
||||
circle = this.r.circle(row._x, row._y[i], this.options.pointSize).attr('fill', this.colorFor(row, i, 'point')).attr('stroke-width', this.strokeWidthForSeries(i)).attr('stroke', this.strokeForSeries(i));
|
||||
circle = this.drawLinePoint(row._x, row._y[i], this.options.pointSize, this.colorFor(row, i, 'point'), i);
|
||||
} else {
|
||||
circle = null;
|
||||
}
|
||||
@ -893,14 +909,6 @@
|
||||
return this.prevHilight = index;
|
||||
};
|
||||
|
||||
Line.prototype.strokeWidthForSeries = function(index) {
|
||||
return this.options.pointWidths[index % this.options.pointWidths.length];
|
||||
};
|
||||
|
||||
Line.prototype.strokeForSeries = function(index) {
|
||||
return this.options.pointStrokeColors[index % this.options.pointStrokeColors.length];
|
||||
};
|
||||
|
||||
Line.prototype.colorFor = function(row, sidx, type) {
|
||||
if (typeof this.options.lineColors === 'function') {
|
||||
return this.options.lineColors.call(this, row, sidx, type);
|
||||
@ -911,6 +919,26 @@
|
||||
}
|
||||
};
|
||||
|
||||
Line.prototype.drawXAxisLabel = function(xPos, yPos, text) {
|
||||
return this.raphael.text(xPos, yPos, text).attr('font-size', this.options.gridTextSize).attr('fill', this.options.gridTextColor);
|
||||
};
|
||||
|
||||
Line.prototype.drawLinePath = function(path, lineColor) {
|
||||
return this.raphael.path(path).attr('stroke', lineColor).attr('stroke-width', this.options.lineWidth);
|
||||
};
|
||||
|
||||
Line.prototype.drawLinePoint = function(xPos, yPos, size, pointColor, lineIndex) {
|
||||
return this.raphael.circle(xPos, yPos, size).attr('fill', pointColor).attr('stroke-width', this.strokeWidthForSeries(lineIndex)).attr('stroke', this.strokeForSeries(lineIndex));
|
||||
};
|
||||
|
||||
Line.prototype.strokeWidthForSeries = function(index) {
|
||||
return this.options.pointWidths[index % this.options.pointWidths.length];
|
||||
};
|
||||
|
||||
Line.prototype.strokeForSeries = function(index) {
|
||||
return this.options.pointStrokeColors[index % this.options.pointStrokeColors.length];
|
||||
};
|
||||
|
||||
return Line;
|
||||
|
||||
})(Morris.Grid);
|
||||
@ -1086,7 +1114,7 @@
|
||||
path = this.paths[i];
|
||||
if (path !== null) {
|
||||
path = path + ("L" + (this.transX(this.xmax)) + "," + this.bottom + "L" + (this.transX(this.xmin)) + "," + this.bottom + "Z");
|
||||
this.r.path(path).attr('fill', this.fillForSeries(i)).attr('stroke-width', 0);
|
||||
this.drawFilledPath(path, this.fillForSeries(i));
|
||||
}
|
||||
}
|
||||
return Area.__super__.drawSeries.call(this);
|
||||
@ -1098,6 +1126,10 @@
|
||||
return Raphael.hsl(color.h, Math.min(255, color.s * 0.75), Math.min(255, color.l * 1.25));
|
||||
};
|
||||
|
||||
Area.prototype.drawFilledPath = function(path, fill) {
|
||||
return this.raphael.path(path).attr('fill', fill).attr('stroke-width', 0);
|
||||
};
|
||||
|
||||
return Area;
|
||||
|
||||
})(Morris.Line);
|
||||
@ -1183,7 +1215,7 @@
|
||||
_results = [];
|
||||
for (i = _i = 0, _ref = this.data.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
|
||||
row = this.data[this.data.length - 1 - i];
|
||||
label = this.r.text(row._x, ypos, row.label).attr('font-size', this.options.gridTextSize).attr('fill', this.options.gridTextColor);
|
||||
label = this.drawXAxisLabel(row._x, ypos, row.label);
|
||||
labelBox = label.getBBox();
|
||||
if ((!(prevLabelMargin != null) || prevLabelMargin >= labelBox.x + labelBox.width) && labelBox.x >= 0 && (labelBox.x + labelBox.width) < this.el.width()) {
|
||||
_results.push(prevLabelMargin = labelBox.x - this.options.xLabelMargin);
|
||||
@ -1230,7 +1262,7 @@
|
||||
if (this.options.stacked) {
|
||||
top -= lastTop;
|
||||
}
|
||||
this.r.rect(left, top, barWidth, size).attr('fill', this.colorFor(row, sidx, 'bar')).attr('stroke-width', 0);
|
||||
this.drawBar(left, top, barWidth, size, this.colorFor(row, sidx, 'bar'));
|
||||
_results1.push(lastTop += size);
|
||||
} else {
|
||||
_results1.push(null);
|
||||
@ -1296,6 +1328,15 @@
|
||||
return [content, x];
|
||||
};
|
||||
|
||||
Bar.prototype.drawXAxisLabel = function(xPos, yPos, text) {
|
||||
var label;
|
||||
return label = this.raphael.text(xPos, yPos, text).attr('font-size', this.options.gridTextSize).attr('fill', this.options.gridTextColor);
|
||||
};
|
||||
|
||||
Bar.prototype.drawBar = function(xPos, yPos, width, height, barColor) {
|
||||
return this.raphael.rect(xPos, yPos, width, height).attr('fill', barColor).attr('stroke-width', 0);
|
||||
};
|
||||
|
||||
return Bar;
|
||||
|
||||
})(Morris.Grid);
|
||||
@ -1332,7 +1373,7 @@
|
||||
Donut.prototype.redraw = function() {
|
||||
var C, cx, cy, d, idx, last, max_value, min, next, seg, total, w, x, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _results;
|
||||
this.el.empty();
|
||||
this.r = new Raphael(this.el[0]);
|
||||
this.raphael = new Raphael(this.el[0]);
|
||||
cx = this.el.width() / 2;
|
||||
cy = this.el.height() / 2;
|
||||
w = (Math.min(cx, cy) - 10) / 3;
|
||||
@ -1351,20 +1392,15 @@
|
||||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
||||
d = _ref1[_j];
|
||||
next = last + min + C * (d.value / total);
|
||||
seg = new Morris.DonutSegment(cx, cy, w * 2, w, last, next, this.options.colors[idx % this.options.colors.length], this.options.backgroundColor, d);
|
||||
seg.render(this.r);
|
||||
seg = new Morris.DonutSegment(cx, cy, w * 2, w, last, next, this.options.colors[idx % this.options.colors.length], this.options.backgroundColor, d, this.raphael);
|
||||
seg.render();
|
||||
this.segments.push(seg);
|
||||
seg.on('hover', this.select);
|
||||
last = next;
|
||||
idx += 1;
|
||||
}
|
||||
this.text1 = this.r.text(cx, cy - 10, '').attr({
|
||||
'font-size': 15,
|
||||
'font-weight': 800
|
||||
});
|
||||
this.text2 = this.r.text(cx, cy + 10, '').attr({
|
||||
'font-size': 14
|
||||
});
|
||||
this.text1 = this.drawEmptyDonutLabel(cx, cy - 10, 15, 800);
|
||||
this.text2 = this.drawEmptyDonutLabel(cx, cy + 10, 14);
|
||||
max_value = Math.max.apply(null, (function() {
|
||||
var _k, _len2, _ref2, _results;
|
||||
_ref2 = this.data;
|
||||
@ -1431,6 +1467,15 @@
|
||||
});
|
||||
};
|
||||
|
||||
Donut.prototype.drawEmptyDonutLabel = function(xPos, yPos, fontSize, fontWeight) {
|
||||
var text;
|
||||
text = this.raphael.text(xPos, yPos, '').attr('font-size', fontSize);
|
||||
if (fontWeight != null) {
|
||||
text.attr('font-weight', fontWeight);
|
||||
}
|
||||
return text;
|
||||
};
|
||||
|
||||
return Donut;
|
||||
|
||||
})();
|
||||
@ -1439,7 +1484,7 @@
|
||||
|
||||
__extends(DonutSegment, _super);
|
||||
|
||||
function DonutSegment(cx, cy, inner, outer, p0, p1, color, backgroundColor, data) {
|
||||
function DonutSegment(cx, cy, inner, outer, p0, p1, color, backgroundColor, data, raphael) {
|
||||
this.cx = cx;
|
||||
this.cy = cy;
|
||||
this.inner = inner;
|
||||
@ -1447,6 +1492,7 @@
|
||||
this.color = color;
|
||||
this.backgroundColor = backgroundColor;
|
||||
this.data = data;
|
||||
this.raphael = raphael;
|
||||
this.deselect = __bind(this.deselect, this);
|
||||
|
||||
this.select = __bind(this.select, this);
|
||||
@ -1478,20 +1524,28 @@
|
||||
return ("M" + ix0 + "," + iy0) + ("A" + r + "," + r + ",0," + this.is_long + ",0," + ix1 + "," + iy1);
|
||||
};
|
||||
|
||||
DonutSegment.prototype.render = function(r) {
|
||||
DonutSegment.prototype.render = function() {
|
||||
var _this = this;
|
||||
this.arc = r.path(this.hilight).attr({
|
||||
stroke: this.color,
|
||||
this.arc = this.drawDonutArc(this.hilight, this.color);
|
||||
return this.seg = this.drawDonutSegment(this.path, this.color, this.backgroundColor, function() {
|
||||
return _this.fire('hover', _this);
|
||||
});
|
||||
};
|
||||
|
||||
DonutSegment.prototype.drawDonutArc = function(path, color) {
|
||||
return this.raphael.path(path).attr({
|
||||
stroke: color,
|
||||
'stroke-width': 2,
|
||||
opacity: 0
|
||||
});
|
||||
return this.seg = r.path(this.path).attr({
|
||||
fill: this.color,
|
||||
stroke: this.backgroundColor,
|
||||
};
|
||||
|
||||
DonutSegment.prototype.drawDonutSegment = function(path, fillColor, strokeColor, hoverFunction) {
|
||||
return this.raphael.path(path).attr({
|
||||
fill: fillColor,
|
||||
stroke: strokeColor,
|
||||
'stroke-width': 3
|
||||
}).hover(function() {
|
||||
return _this.fire('hover', _this);
|
||||
});
|
||||
}).hover(hoverFunction);
|
||||
};
|
||||
|
||||
DonutSegment.prototype.select = function() {
|
||||
|
2
morris.min.js
vendored
2
morris.min.js
vendored
File diff suppressed because one or more lines are too long
47
spec/lib/area/area_spec.coffee
Normal file
47
spec/lib/area/area_spec.coffee
Normal file
@ -0,0 +1,47 @@
|
||||
describe 'Morris.Area', ->
|
||||
|
||||
describe 'svg structure', ->
|
||||
defaults =
|
||||
element: 'graph'
|
||||
data: [{x: '2012 Q1', y: 1}, {x: '2012 Q2', y: 1}]
|
||||
lineColors: [ '#0b62a4', '#7a92a3']
|
||||
gridLineColor: '#aaa'
|
||||
xkey: 'x'
|
||||
ykeys: ['y']
|
||||
labels: ['Y']
|
||||
|
||||
it 'should contain a line path for each line', ->
|
||||
chart = Morris.Area $.extend {}, defaults
|
||||
$('#graph').find("path[stroke='#0b62a4']").size().should.equal 1
|
||||
|
||||
it 'should contain a path with stroke-width 0 for each line', ->
|
||||
chart = Morris.Area $.extend {}, defaults
|
||||
$('#graph').find("path[stroke='#0b62a4']").size().should.equal 1
|
||||
|
||||
it 'should contain 5 grid lines', ->
|
||||
chart = Morris.Area $.extend {}, defaults
|
||||
$('#graph').find("path[stroke='#aaaaaa']").size().should.equal 5
|
||||
|
||||
it 'should contain 9 text elements', ->
|
||||
chart = Morris.Area $.extend {}, defaults
|
||||
$('#graph').find("text").size().should.equal 9
|
||||
|
||||
describe 'svg attributes', ->
|
||||
defaults =
|
||||
element: 'graph'
|
||||
data: [{x: '2012 Q1', y: 1}, {x: '2012 Q2', y: 1}]
|
||||
xkey: 'x'
|
||||
ykeys: ['y']
|
||||
labels: ['Y']
|
||||
lineColors: [ '#0b62a4', '#7a92a3']
|
||||
lineWidth: 3
|
||||
pointWidths: [5]
|
||||
pointStrokeColors: ['#ffffff']
|
||||
gridLineColor: '#aaa'
|
||||
gridStrokeWidth: 0.5
|
||||
gridTextColor: '#888'
|
||||
gridTextSize: 12
|
||||
|
||||
it 'should have a line with the fill of a modified line color', ->
|
||||
chart = Morris.Area $.extend {}, defaults
|
||||
$('#graph').find("path[fill='#2577b5']").size().should.equal 1
|
50
spec/lib/bar/bar_spec.coffee
Normal file
50
spec/lib/bar/bar_spec.coffee
Normal file
@ -0,0 +1,50 @@
|
||||
describe 'Morris.Bar', ->
|
||||
|
||||
describe 'svg structure', ->
|
||||
defaults =
|
||||
element: 'graph'
|
||||
data: [{x: 'foo', y: 2, z: 3}, {x: 'bar', y: 4, z: 6}]
|
||||
xkey: 'x'
|
||||
ykeys: ['y', 'z']
|
||||
labels: ['Y', 'Z']
|
||||
|
||||
it 'should contain a rect for each bar', ->
|
||||
chart = Morris.Bar $.extend {}, defaults
|
||||
$('#graph').find("rect").size().should.equal 4
|
||||
|
||||
it 'should contain 5 grid lines', ->
|
||||
chart = Morris.Bar $.extend {}, defaults
|
||||
$('#graph').find("path").size().should.equal 5
|
||||
|
||||
it 'should contain 7 text elements', ->
|
||||
chart = Morris.Bar $.extend {}, defaults
|
||||
$('#graph').find("text").size().should.equal 7
|
||||
|
||||
describe 'svg attributes', ->
|
||||
defaults =
|
||||
element: 'graph'
|
||||
data: [{x: 'foo', y: 2, z: 3}, {x: 'bar', y: 4, z: 6}]
|
||||
xkey: 'x'
|
||||
ykeys: ['y', 'z']
|
||||
labels: ['Y', 'Z']
|
||||
barColors: [ '#0b62a4', '#7a92a3']
|
||||
gridLineColor: '#aaa'
|
||||
gridStrokeWidth: 0.5
|
||||
gridTextColor: '#888'
|
||||
gridTextSize: 12
|
||||
|
||||
it 'should have a bar with the first default color', ->
|
||||
chart = Morris.Bar $.extend {}, defaults
|
||||
$('#graph').find("rect[fill='#0b62a4']").size().should.equal 2
|
||||
|
||||
it 'should have a bar with stroke width 0', ->
|
||||
chart = Morris.Bar $.extend {}, defaults
|
||||
$('#graph').find("rect[stroke-width='0']").size().should.equal 4
|
||||
|
||||
it 'should have text with configured fill color', ->
|
||||
chart = Morris.Bar $.extend {}, defaults
|
||||
$('#graph').find("text[fill='#888888']").size().should.equal 7
|
||||
|
||||
it 'should have text with configured font size', ->
|
||||
chart = Morris.Bar $.extend {}, defaults
|
||||
$('#graph').find("text[font-size='12px']").size().should.equal 7
|
@ -33,4 +33,4 @@ describe 'Morris.Bar#colorFor', ->
|
||||
stub.should.have.been.calledWith(
|
||||
{x:0, y:3, label:'foo'},
|
||||
{index:1, key:'z', label:'Z'},
|
||||
'hover')
|
||||
'hover')
|
||||
|
61
spec/lib/donut/donut_spec.coffee
Normal file
61
spec/lib/donut/donut_spec.coffee
Normal file
@ -0,0 +1,61 @@
|
||||
describe 'Morris.Donut', ->
|
||||
|
||||
describe 'svg structure', ->
|
||||
defaults =
|
||||
element: 'graph'
|
||||
data: [ {label: 'Jam', value: 25 },
|
||||
{label: 'Frosted', value: 40 },
|
||||
{label: 'Custard', value: 25 },
|
||||
{label: 'Sugar', value: 10 } ]
|
||||
formatter: (y) -> "#{y}%"
|
||||
|
||||
it 'should contain 2 paths for each segment', ->
|
||||
chart = Morris.Donut $.extend {}, defaults
|
||||
$('#graph').find("path").size().should.equal 8
|
||||
|
||||
it 'should contain 2 text elements for the label', ->
|
||||
chart = Morris.Donut $.extend {}, defaults
|
||||
$('#graph').find("text").size().should.equal 2
|
||||
|
||||
describe 'svg attributes', ->
|
||||
defaults =
|
||||
defaults =
|
||||
element: 'graph'
|
||||
data: [ {label: 'Jam', value: 25 },
|
||||
{label: 'Frosted', value: 40 },
|
||||
{label: 'Custard', value: 25 },
|
||||
{label: 'Sugar', value: 10 } ]
|
||||
formatter: (y) -> "#{y}%"
|
||||
colors: [ '#0B62A4', '#3980B5', '#679DC6', '#95BBD7']
|
||||
|
||||
it 'should have a label with font size 15', ->
|
||||
chart = Morris.Donut $.extend {}, defaults
|
||||
$('#graph').find("text[font-size='15px']").size().should.equal 1
|
||||
|
||||
it 'should have a label with font size 14', ->
|
||||
chart = Morris.Donut $.extend {}, defaults
|
||||
$('#graph').find("text[font-size='14px']").size().should.equal 1
|
||||
|
||||
it 'should have a label with font-weight 800', ->
|
||||
chart = Morris.Donut $.extend {}, defaults
|
||||
$('#graph').find("text[font-weight='800']").size().should.equal 1
|
||||
|
||||
it 'should have 1 paths with fill of first color', ->
|
||||
chart = Morris.Donut $.extend {}, defaults
|
||||
$('#graph').find("path[fill='#0b62a4']").size().should.equal 1
|
||||
|
||||
it 'should have 1 paths with stroke of first color', ->
|
||||
chart = Morris.Donut $.extend {}, defaults
|
||||
$('#graph').find("path[stroke='#0b62a4']").size().should.equal 1
|
||||
|
||||
it 'should have a path with white stroke', ->
|
||||
chart = Morris.Donut $.extend {}, defaults
|
||||
$('#graph').find("path[stroke='#ffffff']").size().should.equal 4
|
||||
|
||||
it 'should have a path with stroke-width 3', ->
|
||||
chart = Morris.Donut $.extend {}, defaults
|
||||
$('#graph').find("path[stroke-width='3']").size().should.equal 4
|
||||
|
||||
it 'should have a path with stroke-width 2', ->
|
||||
chart = Morris.Donut $.extend {}, defaults
|
||||
$('#graph').find("path[stroke-width='2']").size().should.equal 4
|
@ -140,3 +140,68 @@ describe 'Morris.Line', ->
|
||||
testData = [{x: 0, y: null}, {x: 10, y: 10}, {x: 20, y: 0}, {x: 30, y: 10}, {x: 40, y: null}]
|
||||
path = Morris.Line.createPath(testData, true, 20)
|
||||
path.should.equal 'M10,10C12.5,7.5,17.5,0,20,0C22.5,0,27.5,7.5,30,10'
|
||||
|
||||
describe 'svg structure', ->
|
||||
defaults =
|
||||
element: 'graph'
|
||||
data: [{x: '2012 Q1', y: 1}, {x: '2012 Q2', y: 1}]
|
||||
lineColors: [ '#0b62a4', '#7a92a3']
|
||||
xkey: 'x'
|
||||
ykeys: ['y']
|
||||
labels: ['dontcare']
|
||||
|
||||
it 'should contain a path that represents the line', ->
|
||||
chart = Morris.Line $.extend {}, defaults
|
||||
$('#graph').find("path[stroke='#0b62a4']").size().should.equal 1
|
||||
|
||||
it 'should contain a circle for each data point', ->
|
||||
chart = Morris.Line $.extend {}, defaults
|
||||
$('#graph').find("circle").size().should.equal 2
|
||||
|
||||
it 'should contain 5 grid lines', ->
|
||||
chart = Morris.Line $.extend {}, defaults
|
||||
$('#graph').find("path[stroke='#aaaaaa']").size().should.equal 5
|
||||
|
||||
it 'should contain 9 text elements', ->
|
||||
chart = Morris.Line $.extend {}, defaults
|
||||
$('#graph').find("text").size().should.equal 9
|
||||
|
||||
describe 'svg attributes', ->
|
||||
defaults =
|
||||
element: 'graph'
|
||||
data: [{x: '2012 Q1', y: 1}, {x: '2012 Q2', y: 1}]
|
||||
xkey: 'x'
|
||||
ykeys: ['y', 'z']
|
||||
labels: ['Y', 'Z']
|
||||
lineColors: [ '#0b62a4', '#7a92a3']
|
||||
lineWidth: 3
|
||||
pointWidths: [5]
|
||||
pointStrokeColors: ['#ffffff']
|
||||
gridLineColor: '#aaa'
|
||||
gridStrokeWidth: 0.5
|
||||
gridTextColor: '#888'
|
||||
gridTextSize: 12
|
||||
|
||||
it 'should have circles with configured fill color', ->
|
||||
chart = Morris.Line $.extend {}, defaults
|
||||
$('#graph').find("circle[fill='#0b62a4']").size().should.equal 2
|
||||
|
||||
it 'should have circles with configured stroke width', ->
|
||||
chart = Morris.Line $.extend {}, defaults
|
||||
$('#graph').find("circle[stroke-width='5']").size().should.equal 2
|
||||
|
||||
it 'should have circles with configured stroke color', ->
|
||||
chart = Morris.Line $.extend {}, defaults
|
||||
$('#graph').find("circle[stroke='#ffffff']").size().should.equal 2
|
||||
|
||||
it 'should have line with configured line width', ->
|
||||
chart = Morris.Line $.extend {}, defaults
|
||||
$('#graph').find("path[stroke-width='3']").size().should.equal 1
|
||||
|
||||
it 'should have text with configured font size', ->
|
||||
chart = Morris.Line $.extend {}, defaults
|
||||
$('#graph').find("text[font-size='12px']").size().should.equal 9
|
||||
|
||||
it 'should have text with configured font size', ->
|
||||
chart = Morris.Line $.extend {}, defaults
|
||||
$('#graph').find("text[fill='#888888']").size().should.equal 9
|
||||
|
Loading…
Reference in New Issue
Block a user