Hover element for line charts (still needs refactoring...)

This commit is contained in:
Olly Smith 2012-12-13 19:09:50 +00:00
parent 77ee0468e6
commit 7ea84dda7f
8 changed files with 104 additions and 17 deletions

View File

@ -1,9 +1,27 @@
.morris-popup {
border-radius: 10px;
.morris-hover {
position: absolute;
z-index: 1000;
padding: 6px;
color: #666;
background: rgba(255, 255, 255, 0.8);
border: solid 2px rgba(230, 230, 230, 0.8);
&.morris-default-style {
border-radius: 10px;
padding: 6px;
color: #666;
background: rgba(255, 255, 255, 0.8);
border: solid 2px rgba(230, 230, 230, 0.8);
font-family: sans-serif;
font-size: 12px;
text-align: center;
.morris-hover-row-label {
font-weight: bold;
margin: 0.25em 0;
}
.morris-hover-point {
white-space: nowrap;
margin: 0.1em 0;
}
}
}

View File

@ -12,6 +12,9 @@ class Morris.Grid extends Morris.EventEmitter
if not @el? or @el.length == 0
throw new Error("Graph container element not found")
if @el.css('position') == 'static'
@el.css('position', 'relative')
@options = $.extend {}, @gridDefaults, (@defaults || {}), options
# bail if there's no data
@ -280,7 +283,7 @@ class Morris.Grid extends Morris.EventEmitter
@el.bind 'touchstart touchmove touchend', (evt) =>
touch = evt.originalEvent.touches[0] or evt.originalEvent.changedTouches[0]
@updateHover touch.pageX, touch.pageY
return touch
touch
hitTest: (x, y) -> null
@ -288,7 +291,7 @@ class Morris.Grid extends Morris.EventEmitter
offset = @el.offset()
x -= offset.left
y -= offset.top
hit = hitTest(x, y)
hit = @hitTest(x, y)
if hit?
@hover.update(hit...)

View File

@ -2,7 +2,7 @@ class Morris.Hover
# Displays contextual information in a floating HTML div.
@defaults:
class: 'morris-popup'
class: 'morris-hover morris-default-style'
constructor: (options = {}) ->
@options = $.extend {}, Morris.Hover.defaults, options

View File

@ -66,6 +66,7 @@ class Morris.Line extends Morris.Grid
row._x = @transX(row.x)
row._y = for y in row.y
if y? then @transY(y) else y
row._ymax = Math.min.apply(null, [@bottom].concat(y for y in row._y when y?))
# calculate hilight margins
#
@ -73,6 +74,31 @@ class Morris.Line extends Morris.Grid
calcHilightMargins: ->
@hilightMargins = ((r._x + @data[i]._x) / 2 for r, i in @data.slice(1))
# hover element hit test
#
# @private
hitTest: (x, y) ->
# TODO better search algo
for r, i in @data.slice(1)
break if x < (r._x + @data[i]._x) / 2
@hoverFor(i)
# hover content for a point
#
# @private
hoverFor: (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>
"""
[content, row._x, row._ymax]
# generate paths for series lines
#
# @private

View File

@ -1 +1,2 @@
.morris-popup{border-radius:10px;position:absolute;z-index:1000;padding:6px;color:#666;background:rgba(255, 255, 255, 0.8);border:solid 2px rgba(230, 230, 230, 0.8);}
.morris-hover{position:absolute;z-index:1000;}.morris-hover.morris-default-style{border-radius:10px;padding:6px;color:#666;background:rgba(255, 255, 255, 0.8);border:solid 2px rgba(230, 230, 230, 0.8);font-family:sans-serif;font-size:12px;text-align:center;}.morris-hover.morris-default-style .morris-hover-row-label{font-weight:bold;margin:0.25em 0;}
.morris-hover.morris-default-style .morris-hover-point{white-space:nowrap;margin:0.1em 0;}

View File

@ -76,6 +76,9 @@
if (!(this.el != null) || this.el.length === 0) {
throw new Error("Graph container element not found");
}
if (this.el.css('position') === 'static') {
this.el.css('position', 'relative');
}
this.options = $.extend({}, this.gridDefaults, this.defaults || {}, options);
if (this.options.data === void 0 || this.options.data.length === 0) {
return;
@ -398,7 +401,7 @@
offset = this.el.offset();
x -= offset.left;
y -= offset.top;
hit = hitTest(x, y);
hit = this.hitTest(x, y);
if (hit != null) {
return (_ref = this.hover).update.apply(_ref, hit);
}
@ -468,7 +471,7 @@
Morris.Hover = (function() {
Hover.defaults = {
"class": 'morris-popup'
"class": 'morris-hover morris-default-style'
};
function Hover(options) {
@ -603,7 +606,7 @@
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
row = _ref[_i];
row._x = this.transX(row.x);
_results.push(row._y = (function() {
row._y = (function() {
var _j, _len1, _ref1, _results1;
_ref1 = row.y;
_results1 = [];
@ -616,7 +619,19 @@
}
}
return _results1;
}).call(this));
}).call(this);
_results.push(row._ymax = Math.min.apply(null, [this.bottom].concat((function() {
var _j, _len1, _ref1, _results1;
_ref1 = row._y;
_results1 = [];
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
y = _ref1[_j];
if (y != null) {
_results1.push(y);
}
}
return _results1;
})())));
}
return _results;
};
@ -635,6 +650,30 @@
}).call(this);
};
Line.prototype.hitTest = function(x, y) {
var i, r, _i, _len, _ref;
_ref = this.data.slice(1);
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
r = _ref[i];
if (x < (r._x + this.data[i]._x) / 2) {
break;
}
}
return this.hoverFor(i);
};
Line.prototype.hoverFor = function(index) {
var content, j, row, 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>";
}
return [content, row._x, row._ymax];
};
Line.prototype.generatePaths = function() {
var c, coords, i, r, smooth;
return this.paths = (function() {

2
morris.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -6,7 +6,7 @@ describe "Morris.Hover", ->
parent = $('<div style="width:200px;height:180px"></div>')
.appendTo($('#test'))
@hover = new Morris.Hover(parent: parent)
@element = $('#test .morris-popup')
@element = $('#test .morris-hover')
it "should initialise a hidden, empty popup", ->
@element.should.exist
@ -58,7 +58,7 @@ describe "Morris.Hover", ->
hover = new Morris.Hover(parent: $('#test'))
html = "<div style='width:84px;height:84px'>Hello, Everyone!</div>"
hover.update(html, 150, 200)
el = $('#test .morris-popup')
el = $('#test .morris-hover')
el.should.have.css('left', '100px')
el.should.have.css('top', '90px')
el.should.have.text('Hello, Everyone!')