Hover element for line charts (still needs refactoring...)
This commit is contained in:
parent
77ee0468e6
commit
7ea84dda7f
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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...)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;}
|
||||
|
|
47
morris.js
47
morris.js
|
@ -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() {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -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!')
|
||||
|
|
Loading…
Reference in New Issue