Hover in bar charts.

This commit is contained in:
Olly Smith 2012-12-17 20:08:39 +00:00
parent 5a31deda53
commit d308cb04be
5 changed files with 98 additions and 19 deletions

View File

@ -6,6 +6,11 @@ class Morris.Bar extends Morris.Grid
init: ->
@cumulative = @options.stacked
if @options.hideHover isnt 'always'
@hover = new Morris.Hover(parent: @el)
@on('hovermove', @onHoverMove)
@on('hoverout', @onHoverOut)
# Default configuration
#
defaults:
@ -26,6 +31,8 @@ class Morris.Bar extends Morris.Grid
# @private
calc: ->
@calcBars()
if @options.hideHover is false
@hover.update(@hoverContentForRow(@data.length - 1)...)
# calculate series data bars coordinates and sizes
#
@ -101,7 +108,7 @@ class Morris.Bar extends Morris.Grid
#
# @param row [Object] row data
# @param sidx [Number] series index
# @param type [String] "bar" or "hover"
# @param type [String] "bar", "hover" or "label"
colorFor: (row, sidx, type) ->
if typeof @options.barColors is 'function'
r = { x: row.x, y: row.y[sidx], label: row.label }
@ -109,3 +116,36 @@ class Morris.Bar extends Morris.Grid
@options.barColors.call(@, r, s, type)
else
@options.barColors[sidx % @options.barColors.length]
# hit test - returns the index of the row beneath the given coordinate
#
hitTest: (x, y) ->
x = Math.max(Math.min(x, @right), @left)
Math.min(@data.length - 1,
Math.floor((x - @left) / ((@right - @left) / @data.length)))
# hover event handler
#
onHoverMove: (x, y) =>
index = @hitTest(x, y)
@hover.update(@hoverContentForRow(index)...)
onHoverOut: =>
if @options.hideHover is 'auto'
@hover.hide()
# hover content for a point
#
# @private
hoverContentForRow: (index) ->
row = @data[index]
content = "<div class='morris-hover-row-label'>#{row.label}</div>"
for y, j in row.y
content += """
<div class='morris-hover-point' style='color: #{@colorFor(row, j, 'label')}'>
#{@options.labels[j]}:
#{@yLabelFormat(y)}
</div>
"""
x = @left + (index + 0.5) * (@right - @left) / @data.length
[content, x]

View File

@ -42,7 +42,7 @@ class Morris.Grid extends Morris.EventEmitter
# hover
@el.bind 'mousemove', (evt) =>
offset = @el.offset()
@fire 'hover', evt.pageX - offset.left, evt.pageY - offset.top
@fire 'hovermove', evt.pageX - offset.left, evt.pageY - offset.top
@el.bind 'mouseout', (evt) =>
@fire 'hoverout'

View File

@ -12,7 +12,7 @@ class Morris.Line extends Morris.Grid
if @options.hideHover isnt 'always'
@hover = new Morris.Hover(parent: @el)
@on('hover', @onHover)
@on('hovermove', @onHoverMove)
@on('hoverout', @onHoverOut)
# Default configuration
@ -65,11 +65,9 @@ class Morris.Line extends Morris.Grid
# hover event handler
#
onHover: (x, y) =>
onHoverMove: (x, y) =>
index = @hitTest(x, y)
if @options.hideHover isnt 'always'
@hover.update(@hoverContentForRow(index)...)
@hilight(index)
displayHoverForRow(index)
onHoverOut: =>
if @options.hideHover is 'auto'

View File

@ -98,7 +98,7 @@
this.el.bind('mousemove', function(evt) {
var offset;
offset = _this.el.offset();
return _this.fire('hover', evt.pageX - offset.left, evt.pageY - offset.top);
return _this.fire('hovermove', evt.pageX - offset.left, evt.pageY - offset.top);
});
this.el.bind('mouseout', function(evt) {
return _this.fire('hoverout');
@ -522,7 +522,7 @@
this.onHoverOut = __bind(this.onHoverOut, this);
this.onHover = __bind(this.onHover, this);
this.onHoverMove = __bind(this.onHoverMove, this);
if (!(this instanceof Morris.Line)) {
return new Morris.Line(options);
}
@ -540,7 +540,7 @@
this.hover = new Morris.Hover({
parent: this.el
});
this.on('hover', this.onHover);
this.on('hovermove', this.onHoverMove);
return this.on('hoverout', this.onHoverOut);
}
};
@ -613,13 +613,10 @@
return index;
};
Line.prototype.onHover = function(x, y) {
var index, _ref;
Line.prototype.onHoverMove = function(x, y) {
var index;
index = this.hitTest(x, y);
if (this.options.hideHover !== 'always') {
(_ref = this.hover).update.apply(_ref, this.hoverContentForRow(index));
return this.hilight(index);
}
return displayHoverForRow(index);
};
Line.prototype.onHoverOut = function() {
@ -1083,6 +1080,9 @@
__extends(Bar, _super);
function Bar(options) {
this.onHoverOut = __bind(this.onHoverOut, this);
this.onHoverMove = __bind(this.onHoverMove, this);
if (!(this instanceof Morris.Bar)) {
return new Morris.Bar(options);
}
@ -1092,7 +1092,14 @@
}
Bar.prototype.init = function() {
return this.cumulative = this.options.stacked;
this.cumulative = this.options.stacked;
if (this.options.hideHover !== 'always') {
this.hover = new Morris.Hover({
parent: this.el
});
this.on('hovermove', this.onHoverMove);
return this.on('hoverout', this.onHoverOut);
}
};
Bar.prototype.defaults = {
@ -1102,7 +1109,11 @@
};
Bar.prototype.calc = function() {
return this.calcBars();
var _ref;
this.calcBars();
if (this.options.hideHover === false) {
return (_ref = this.hover).update.apply(_ref, this.hoverContentForRow(this.data.length - 1));
}
};
Bar.prototype.calcBars = function() {
@ -1222,6 +1233,36 @@
}
};
Bar.prototype.hitTest = function(x, y) {
x = Math.max(Math.min(x, this.right), this.left);
return Math.min(this.data.length - 1, Math.floor((x - this.left) / ((this.right - this.left) / this.data.length)));
};
Bar.prototype.onHoverMove = function(x, y) {
var index, _ref;
index = this.hitTest(x, y);
return (_ref = this.hover).update.apply(_ref, this.hoverContentForRow(index));
};
Bar.prototype.onHoverOut = function() {
if (this.options.hideHover === 'auto') {
return this.hover.hide();
}
};
Bar.prototype.hoverContentForRow = function(index) {
var content, j, row, x, y, _i, _len, _ref;
row = this.data[index];
content = "<div class='morris-hover-row-label'>" + row.label + "</div>";
_ref = row.y;
for (j = _i = 0, _len = _ref.length; _i < _len; j = ++_i) {
y = _ref[j];
content += "<div class='morris-hover-point' style='color: " + (this.colorFor(row, j, 'label')) + "'>\n " + this.options.labels[j] + ":\n " + (this.yLabelFormat(y)) + "\n</div>";
}
x = this.left + (index + 0.5) * (this.right - this.left) / this.data.length;
return [content, x];
};
return Bar;
})(Morris.Grid);

2
morris.min.js vendored

File diff suppressed because one or more lines are too long