mirror of
https://github.com/morrisjs/morris.js.git
synced 2024-09-21 10:41:32 +02:00
Merge branch 'range-selection' of https://github.com/arachnys/morris.js into arachnys-range-selection
Conflicts: morris.min.js
This commit is contained in:
commit
e868701016
@ -127,9 +127,9 @@ class Morris.Bar extends Morris.Grid
|
||||
else
|
||||
@options.barColors[sidx % @options.barColors.length]
|
||||
|
||||
# hit test - returns the index of the row beneath the given coordinate
|
||||
# hit test - returns the index of the row at the given x-coordinate
|
||||
#
|
||||
hitTest: (x, y) ->
|
||||
hitTest: (x) ->
|
||||
return null if @data.length == 0
|
||||
x = Math.max(Math.min(x, @right), @left)
|
||||
Math.min(@data.length - 1,
|
||||
@ -139,14 +139,14 @@ class Morris.Bar extends Morris.Grid
|
||||
#
|
||||
# @private
|
||||
onGridClick: (x, y) =>
|
||||
index = @hitTest(x, y)
|
||||
index = @hitTest(x)
|
||||
@fire 'click', index, @options.data[index], x, y
|
||||
|
||||
# hover movement event handler
|
||||
#
|
||||
# @private
|
||||
onHoverMove: (x, y) =>
|
||||
index = @hitTest(x, y)
|
||||
index = @hitTest(x)
|
||||
@hover.update(@hoverContentForRow(index)...)
|
||||
|
||||
# hover out event handler
|
||||
|
@ -29,6 +29,9 @@ class Morris.Grid extends Morris.EventEmitter
|
||||
@elementHeight = null
|
||||
@dirty = false
|
||||
|
||||
# range selection
|
||||
@selectFrom = null
|
||||
|
||||
# more stuff
|
||||
@init() if @init
|
||||
|
||||
@ -38,9 +41,19 @@ class Morris.Grid extends Morris.EventEmitter
|
||||
# hover
|
||||
@el.bind 'mousemove', (evt) =>
|
||||
offset = @el.offset()
|
||||
@fire 'hovermove', evt.pageX - offset.left, evt.pageY - offset.top
|
||||
x = evt.pageX - offset.left
|
||||
if @selectFrom
|
||||
left = @data[@hitTest(Math.min(x, @selectFrom))]._x
|
||||
right = @data[@hitTest(Math.max(x, @selectFrom))]._x
|
||||
width = right - left
|
||||
@selectionRect.attr({ x: left, width: width })
|
||||
else
|
||||
@fire 'hovermove', x, evt.pageY - offset.top
|
||||
|
||||
@el.bind 'mouseout', (evt) =>
|
||||
@el.bind 'mouseleave', (evt) =>
|
||||
if @selectFrom
|
||||
@selectionRect.hide()
|
||||
@selectFrom = null
|
||||
@fire 'hoverout'
|
||||
|
||||
@el.bind 'touchstart touchmove touchend', (evt) =>
|
||||
@ -53,6 +66,21 @@ class Morris.Grid extends Morris.EventEmitter
|
||||
offset = @el.offset()
|
||||
@fire 'gridclick', evt.pageX - offset.left, evt.pageY - offset.top
|
||||
|
||||
if @options.rangeSelect
|
||||
@selectionRect = @raphael.rect(0, 0, 0, @el.innerHeight())
|
||||
.attr({ fill: @options.rangeSelectColor, stroke: false })
|
||||
.toBack()
|
||||
.hide()
|
||||
|
||||
@el.bind 'mousedown', (evt) =>
|
||||
offset = @el.offset()
|
||||
@startRange evt.pageX - offset.left
|
||||
|
||||
@el.bind 'mouseup', (evt) =>
|
||||
offset = @el.offset()
|
||||
@endRange evt.pageX - offset.left
|
||||
@fire 'hovermove', evt.pageX - offset.left, evt.pageY - offset.top
|
||||
|
||||
@postInit() if @postInit
|
||||
|
||||
# Default options
|
||||
@ -93,6 +121,8 @@ class Morris.Grid extends Morris.EventEmitter
|
||||
'#3a5f0b'
|
||||
'#005502'
|
||||
]
|
||||
rangeSelect: null
|
||||
rangeSelectColor: '#eef'
|
||||
|
||||
# Update the data series and redraw the chart.
|
||||
#
|
||||
@ -299,11 +329,6 @@ class Morris.Grid extends Morris.EventEmitter
|
||||
else
|
||||
"#{@options.preUnits}#{Morris.commas(label)}#{@options.postUnits}"
|
||||
|
||||
updateHover: (x, y) ->
|
||||
hit = @hitTest(x, y)
|
||||
if hit?
|
||||
@hover.update(hit...)
|
||||
|
||||
# draw y axis labels, horizontal lines
|
||||
#
|
||||
drawGrid: ->
|
||||
@ -351,6 +376,22 @@ class Morris.Grid extends Morris.EventEmitter
|
||||
.attr('stroke', @options.gridLineColor)
|
||||
.attr('stroke-width', @options.gridStrokeWidth)
|
||||
|
||||
# Range selection
|
||||
#
|
||||
startRange: (x) ->
|
||||
@hover.hide()
|
||||
@selectFrom = x
|
||||
@selectionRect.attr({ x: x, width: 0 }).show()
|
||||
|
||||
endRange: (x) ->
|
||||
if @selectFrom
|
||||
start = Math.min(@selectFrom, x)
|
||||
end = Math.max(@selectFrom, x)
|
||||
@options.rangeSelect.call @el,
|
||||
start: @data[@hitTest(start)].x
|
||||
end: @data[@hitTest(end)].x
|
||||
@selectFrom = null
|
||||
|
||||
# Parse a date into a javascript timestamp
|
||||
#
|
||||
#
|
||||
|
@ -57,9 +57,9 @@ class Morris.Line extends Morris.Grid
|
||||
if y? then @transY(y) else y
|
||||
row._ymax = Math.min.apply(null, [@bottom].concat(y for y in row._y when y?))
|
||||
|
||||
# hit test - returns the index of the row beneath the given coordinate
|
||||
# hit test - returns the index of the row at the given x-coordinate
|
||||
#
|
||||
hitTest: (x, y) ->
|
||||
hitTest: (x) ->
|
||||
return null if @data.length == 0
|
||||
# TODO better search algo
|
||||
for r, index in @data.slice(1)
|
||||
@ -70,14 +70,14 @@ class Morris.Line extends Morris.Grid
|
||||
#
|
||||
# @private
|
||||
onGridClick: (x, y) =>
|
||||
index = @hitTest(x, y)
|
||||
index = @hitTest(x)
|
||||
@fire 'click', index, @options.data[index], x, y
|
||||
|
||||
# hover movement event handler
|
||||
#
|
||||
# @private
|
||||
onHoverMove: (x, y) =>
|
||||
index = @hitTest(x, y)
|
||||
index = @hitTest(x)
|
||||
@displayHoverForRow(index)
|
||||
|
||||
# hover out event handler
|
||||
|
85
morris.js
85
morris.js
@ -89,16 +89,32 @@
|
||||
this.elementWidth = null;
|
||||
this.elementHeight = null;
|
||||
this.dirty = false;
|
||||
this.selectFrom = null;
|
||||
if (this.init) {
|
||||
this.init();
|
||||
}
|
||||
this.setData(this.options.data);
|
||||
this.el.bind('mousemove', function(evt) {
|
||||
var offset;
|
||||
var left, offset, right, width, x;
|
||||
offset = _this.el.offset();
|
||||
return _this.fire('hovermove', evt.pageX - offset.left, evt.pageY - offset.top);
|
||||
x = evt.pageX - offset.left;
|
||||
if (_this.selectFrom) {
|
||||
left = _this.data[_this.hitTest(Math.min(x, _this.selectFrom))]._x;
|
||||
right = _this.data[_this.hitTest(Math.max(x, _this.selectFrom))]._x;
|
||||
width = right - left;
|
||||
return _this.selectionRect.attr({
|
||||
x: left,
|
||||
width: width
|
||||
});
|
||||
} else {
|
||||
return _this.fire('hovermove', x, evt.pageY - offset.top);
|
||||
}
|
||||
});
|
||||
this.el.bind('mouseout', function(evt) {
|
||||
this.el.bind('mouseleave', function(evt) {
|
||||
if (_this.selectFrom) {
|
||||
_this.selectionRect.hide();
|
||||
_this.selectFrom = null;
|
||||
}
|
||||
return _this.fire('hoverout');
|
||||
});
|
||||
this.el.bind('touchstart touchmove touchend', function(evt) {
|
||||
@ -113,6 +129,23 @@
|
||||
offset = _this.el.offset();
|
||||
return _this.fire('gridclick', evt.pageX - offset.left, evt.pageY - offset.top);
|
||||
});
|
||||
if (this.options.rangeSelect) {
|
||||
this.selectionRect = this.raphael.rect(0, 0, 0, this.el.innerHeight()).attr({
|
||||
fill: this.options.rangeSelectColor,
|
||||
stroke: false
|
||||
}).toBack().hide();
|
||||
this.el.bind('mousedown', function(evt) {
|
||||
var offset;
|
||||
offset = _this.el.offset();
|
||||
return _this.startRange(evt.pageX - offset.left);
|
||||
});
|
||||
this.el.bind('mouseup', function(evt) {
|
||||
var offset;
|
||||
offset = _this.el.offset();
|
||||
_this.endRange(evt.pageX - offset.left);
|
||||
return _this.fire('hovermove', evt.pageX - offset.left, evt.pageY - offset.top);
|
||||
});
|
||||
}
|
||||
if (this.postInit) {
|
||||
this.postInit();
|
||||
}
|
||||
@ -143,7 +176,9 @@
|
||||
goalLineColors: ['#666633', '#999966', '#cc6666', '#663333'],
|
||||
events: [],
|
||||
eventStrokeWidth: 1.0,
|
||||
eventLineColors: ['#005a04', '#ccffbb', '#3a5f0b', '#005502']
|
||||
eventLineColors: ['#005a04', '#ccffbb', '#3a5f0b', '#005502'],
|
||||
rangeSelect: null,
|
||||
rangeSelectColor: '#eef'
|
||||
};
|
||||
|
||||
Grid.prototype.setData = function(data, redraw) {
|
||||
@ -438,14 +473,6 @@
|
||||
}
|
||||
};
|
||||
|
||||
Grid.prototype.updateHover = function(x, y) {
|
||||
var hit, _ref;
|
||||
hit = this.hitTest(x, y);
|
||||
if (hit != null) {
|
||||
return (_ref = this.hover).update.apply(_ref, hit);
|
||||
}
|
||||
};
|
||||
|
||||
Grid.prototype.drawGrid = function() {
|
||||
var lineY, y, _i, _len, _ref, _results;
|
||||
if (this.options.grid === false && this.options.axes === false) {
|
||||
@ -508,6 +535,28 @@
|
||||
return this.raphael.path(path).attr('stroke', this.options.gridLineColor).attr('stroke-width', this.options.gridStrokeWidth);
|
||||
};
|
||||
|
||||
Grid.prototype.startRange = function(x) {
|
||||
this.hover.hide();
|
||||
this.selectFrom = x;
|
||||
return this.selectionRect.attr({
|
||||
x: x,
|
||||
width: 0
|
||||
}).show();
|
||||
};
|
||||
|
||||
Grid.prototype.endRange = function(x) {
|
||||
var end, start;
|
||||
if (this.selectFrom) {
|
||||
start = Math.min(this.selectFrom, x);
|
||||
end = Math.max(this.selectFrom, x);
|
||||
this.options.rangeSelect.call(this.el, {
|
||||
start: this.data[this.hitTest(start)].x,
|
||||
end: this.data[this.hitTest(end)].x
|
||||
});
|
||||
return this.selectFrom = null;
|
||||
}
|
||||
};
|
||||
|
||||
return Grid;
|
||||
|
||||
})(Morris.EventEmitter);
|
||||
@ -723,7 +772,7 @@
|
||||
return _results;
|
||||
};
|
||||
|
||||
Line.prototype.hitTest = function(x, y) {
|
||||
Line.prototype.hitTest = function(x) {
|
||||
var index, r, _i, _len, _ref;
|
||||
if (this.data.length === 0) {
|
||||
return null;
|
||||
@ -740,13 +789,13 @@
|
||||
|
||||
Line.prototype.onGridClick = function(x, y) {
|
||||
var index;
|
||||
index = this.hitTest(x, y);
|
||||
index = this.hitTest(x);
|
||||
return this.fire('click', index, this.options.data[index], x, y);
|
||||
};
|
||||
|
||||
Line.prototype.onHoverMove = function(x, y) {
|
||||
var index;
|
||||
index = this.hitTest(x, y);
|
||||
index = this.hitTest(x);
|
||||
return this.displayHoverForRow(index);
|
||||
};
|
||||
|
||||
@ -1465,7 +1514,7 @@
|
||||
}
|
||||
};
|
||||
|
||||
Bar.prototype.hitTest = function(x, y) {
|
||||
Bar.prototype.hitTest = function(x) {
|
||||
if (this.data.length === 0) {
|
||||
return null;
|
||||
}
|
||||
@ -1475,13 +1524,13 @@
|
||||
|
||||
Bar.prototype.onGridClick = function(x, y) {
|
||||
var index;
|
||||
index = this.hitTest(x, y);
|
||||
index = this.hitTest(x);
|
||||
return this.fire('click', index, this.options.data[index], x, y);
|
||||
};
|
||||
|
||||
Bar.prototype.onHoverMove = function(x, y) {
|
||||
var index, _ref;
|
||||
index = this.hitTest(x, y);
|
||||
index = this.hitTest(x);
|
||||
return (_ref = this.hover).update.apply(_ref, this.hoverContentForRow(index));
|
||||
};
|
||||
|
||||
|
2
morris.min.js
vendored
2
morris.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user