Add range selection to Morris.Grid

This commit is contained in:
Omar Khan 2013-06-17 18:46:40 +01:00
parent f659e94eac
commit 7d46e6e903
3 changed files with 55 additions and 9 deletions

View File

@ -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

View File

@ -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 '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.
#
@ -346,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
#
#

View File

@ -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