mirror of
https://github.com/morrisjs/morris.js.git
synced 2024-09-21 10:41:32 +02:00
WIP: re-organising.
This commit is contained in:
parent
cf9d10b9dc
commit
e8c6ba89c8
@ -1,11 +1,4 @@
|
|||||||
class Morris.Bar extends Morris.Grid
|
class Morris.Bar extends Morris.Grid
|
||||||
@include Morris.Hover
|
|
||||||
|
|
||||||
# override hoverCalculatePosition
|
|
||||||
hoverGetPosition: (index) ->
|
|
||||||
[x, y] = Morris.Hover.hoverGetPosition.call(this, index)
|
|
||||||
[x, (@top + @bottom)/2 - @hoverHeight/2]
|
|
||||||
|
|
||||||
constructor: (options) ->
|
constructor: (options) ->
|
||||||
return new Morris.Bar(options) unless (@ instanceof Morris.Bar)
|
return new Morris.Bar(options) unless (@ instanceof Morris.Bar)
|
||||||
super($.extend {}, options, parseTime: false)
|
super($.extend {}, options, parseTime: false)
|
||||||
@ -121,3 +114,8 @@ class Morris.Bar extends Morris.Grid
|
|||||||
@options.barColors.call(@, r, s, type)
|
@options.barColors.call(@, r, s, type)
|
||||||
else
|
else
|
||||||
@options.barColors[sidx % @options.barColors.length]
|
@options.barColors[sidx % @options.barColors.length]
|
||||||
|
|
||||||
|
hoverGetPosition: (index) ->
|
||||||
|
[x, y] = super(index)
|
||||||
|
[x, (@top + @bottom)/2 - @hoverHeight/2]
|
||||||
|
|
||||||
|
@ -2,27 +2,10 @@ Morris = window.Morris = {}
|
|||||||
|
|
||||||
$ = jQuery
|
$ = jQuery
|
||||||
|
|
||||||
# Very simple multiple-inheritance implementation.
|
|
||||||
#
|
|
||||||
# @private
|
|
||||||
class Morris.Module
|
|
||||||
@extend: (obj) ->
|
|
||||||
for key, value of obj when key not in ['extended', 'included']
|
|
||||||
@[key] = value
|
|
||||||
|
|
||||||
obj.extended?.apply(@)
|
|
||||||
this
|
|
||||||
|
|
||||||
@include: (obj) ->
|
|
||||||
for key, value of obj when key not in ['extended', 'included']
|
|
||||||
@::[key] = value
|
|
||||||
|
|
||||||
obj.included?.apply(@)
|
|
||||||
|
|
||||||
# Very simple event-emitter class.
|
# Very simple event-emitter class.
|
||||||
#
|
#
|
||||||
# @private
|
# @private
|
||||||
class Morris.EventEmitter extends Morris.Module
|
class Morris.EventEmitter
|
||||||
on: (name, handler) ->
|
on: (name, handler) ->
|
||||||
unless @handlers?
|
unless @handlers?
|
||||||
@handlers = {}
|
@handlers = {}
|
||||||
@ -57,85 +40,3 @@ Morris.commas = (num) ->
|
|||||||
# @example
|
# @example
|
||||||
# Morris.pad2(1) -> '01'
|
# Morris.pad2(1) -> '01'
|
||||||
Morris.pad2 = (number) -> (if number < 10 then '0' else '') + number
|
Morris.pad2 = (number) -> (if number < 10 then '0' else '') + number
|
||||||
|
|
||||||
# generate a series of label, timestamp pairs for x-axis labels
|
|
||||||
#
|
|
||||||
# @private
|
|
||||||
Morris.labelSeries = (dmin, dmax, pxwidth, specName, xLabelFormat) ->
|
|
||||||
ddensity = 200 * (dmax - dmin) / pxwidth # seconds per `margin` pixels
|
|
||||||
d0 = new Date(dmin)
|
|
||||||
spec = Morris.LABEL_SPECS[specName]
|
|
||||||
# if the spec doesn't exist, search for the closest one in the list
|
|
||||||
if spec is undefined
|
|
||||||
for name in Morris.AUTO_LABEL_ORDER
|
|
||||||
s = Morris.LABEL_SPECS[name]
|
|
||||||
if ddensity >= s.span
|
|
||||||
spec = s
|
|
||||||
break
|
|
||||||
# if we run out of options, use second-intervals
|
|
||||||
if spec is undefined
|
|
||||||
spec = Morris.LABEL_SPECS["second"]
|
|
||||||
# check if there's a user-defined formatting function
|
|
||||||
if xLabelFormat
|
|
||||||
spec = $.extend({}, spec, {fmt: xLabelFormat})
|
|
||||||
# calculate labels
|
|
||||||
d = spec.start(d0)
|
|
||||||
ret = []
|
|
||||||
while (t = d.getTime()) <= dmax
|
|
||||||
if t >= dmin
|
|
||||||
ret.push [spec.fmt(d), t]
|
|
||||||
spec.incr(d)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
# @private
|
|
||||||
minutesSpecHelper = (interval) ->
|
|
||||||
span: interval * 60 * 1000
|
|
||||||
start: (d) -> new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours())
|
|
||||||
fmt: (d) -> "#{Morris.pad2(d.getHours())}:#{Morris.pad2(d.getMinutes())}"
|
|
||||||
incr: (d) -> d.setMinutes(d.getMinutes() + interval)
|
|
||||||
|
|
||||||
# @private
|
|
||||||
secondsSpecHelper = (interval) ->
|
|
||||||
span: interval * 1000
|
|
||||||
start: (d) -> new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes())
|
|
||||||
fmt: (d) -> "#{Morris.pad2(d.getHours())}:#{Morris.pad2(d.getMinutes())}:#{Morris.pad2(d.getSeconds())}"
|
|
||||||
incr: (d) -> d.setSeconds(d.getSeconds() + interval)
|
|
||||||
|
|
||||||
Morris.LABEL_SPECS =
|
|
||||||
"decade":
|
|
||||||
span: 172800000000 # 10 * 365 * 24 * 60 * 60 * 1000
|
|
||||||
start: (d) -> new Date(d.getFullYear() - d.getFullYear() % 10, 0, 1)
|
|
||||||
fmt: (d) -> "#{d.getFullYear()}"
|
|
||||||
incr: (d) -> d.setFullYear(d.getFullYear() + 10)
|
|
||||||
"year":
|
|
||||||
span: 17280000000 # 365 * 24 * 60 * 60 * 1000
|
|
||||||
start: (d) -> new Date(d.getFullYear(), 0, 1)
|
|
||||||
fmt: (d) -> "#{d.getFullYear()}"
|
|
||||||
incr: (d) -> d.setFullYear(d.getFullYear() + 1)
|
|
||||||
"month":
|
|
||||||
span: 2419200000 # 28 * 24 * 60 * 60 * 1000
|
|
||||||
start: (d) -> new Date(d.getFullYear(), d.getMonth(), 1)
|
|
||||||
fmt: (d) -> "#{d.getFullYear()}-#{Morris.pad2(d.getMonth() + 1)}"
|
|
||||||
incr: (d) -> d.setMonth(d.getMonth() + 1)
|
|
||||||
"day":
|
|
||||||
span: 86400000 # 24 * 60 * 60 * 1000
|
|
||||||
start: (d) -> new Date(d.getFullYear(), d.getMonth(), d.getDate())
|
|
||||||
fmt: (d) -> "#{d.getFullYear()}-#{Morris.pad2(d.getMonth() + 1)}-#{Morris.pad2(d.getDate())}"
|
|
||||||
incr: (d) -> d.setDate(d.getDate() + 1)
|
|
||||||
"hour": minutesSpecHelper(60)
|
|
||||||
"30min": minutesSpecHelper(30)
|
|
||||||
"15min": minutesSpecHelper(15)
|
|
||||||
"10min": minutesSpecHelper(10)
|
|
||||||
"5min": minutesSpecHelper(5)
|
|
||||||
"minute": minutesSpecHelper(1)
|
|
||||||
"30sec": secondsSpecHelper(30)
|
|
||||||
"15sec": secondsSpecHelper(15)
|
|
||||||
"10sec": secondsSpecHelper(10)
|
|
||||||
"5sec": secondsSpecHelper(5)
|
|
||||||
"second": secondsSpecHelper(1)
|
|
||||||
|
|
||||||
Morris.AUTO_LABEL_ORDER = [
|
|
||||||
"decade", "year", "month", "day", "hour",
|
|
||||||
"30min", "15min", "10min", "5min", "minute",
|
|
||||||
"30sec", "15sec", "10sec", "5sec", "second"
|
|
||||||
]
|
|
@ -35,7 +35,7 @@ class Morris.Grid extends Morris.EventEmitter
|
|||||||
|
|
||||||
# load data
|
# load data
|
||||||
@setData @options.data
|
@setData @options.data
|
||||||
|
|
||||||
@postInit() if @postInit
|
@postInit() if @postInit
|
||||||
|
|
||||||
# Default options
|
# Default options
|
||||||
@ -258,6 +258,122 @@ class Morris.Grid extends Morris.EventEmitter
|
|||||||
yLabelFormat: (label) ->
|
yLabelFormat: (label) ->
|
||||||
"#{@options.preUnits}#{Morris.commas(label)}#{@options.postUnits}"
|
"#{@options.preUnits}#{Morris.commas(label)}#{@options.postUnits}"
|
||||||
|
|
||||||
|
# Hover stuff
|
||||||
|
#
|
||||||
|
#
|
||||||
|
hoverConfigure: (options) ->
|
||||||
|
@hoverOptions = $.extend {}, @hoverDefaults, options ? {}
|
||||||
|
|
||||||
|
hoverInit: ->
|
||||||
|
if @hoverOptions.enableHover
|
||||||
|
@hover = @hoverBuild()
|
||||||
|
@hoverBindEvents()
|
||||||
|
@hoverShow(if @hoverOptions.hideHover then null else @data.length - 1)
|
||||||
|
|
||||||
|
hoverDefaults:
|
||||||
|
enableHover: true
|
||||||
|
popupClass: "morris-popup"
|
||||||
|
hideHover: false
|
||||||
|
allowOverflow: false
|
||||||
|
pointMargin: 10
|
||||||
|
hoverFill: (index, row) -> @hoverFill(index, row)
|
||||||
|
|
||||||
|
hoverBindEvents: ->
|
||||||
|
@el.mousemove (evt) =>
|
||||||
|
@hoverUpdate evt.pageX
|
||||||
|
if @hoverOptions.hideHover
|
||||||
|
@el.mouseout (evt) =>
|
||||||
|
@hoverShow null
|
||||||
|
touchHandler = (evt) =>
|
||||||
|
touch = evt.originalEvent.touches[0] or evt.originalEvent.changedTouches[0]
|
||||||
|
@hoverUpdate touch.pageX
|
||||||
|
return touch
|
||||||
|
@el.bind 'touchstart', touchHandler
|
||||||
|
@el.bind 'touchmove', touchHandler
|
||||||
|
@el.bind 'touchend', touchHandler
|
||||||
|
|
||||||
|
@hover.mousemove (evt) -> evt.stopPropagation()
|
||||||
|
@hover.mouseout (evt) -> evt.stopPropagation()
|
||||||
|
@hover.bind 'touchstart', (evt) -> evt.stopPropagation()
|
||||||
|
@hover.bind 'touchmove', (evt) -> evt.stopPropagation()
|
||||||
|
@hover.bind 'touchend', (evt) -> evt.stopPropagation()
|
||||||
|
|
||||||
|
hoverCalculateMargins: ->
|
||||||
|
@hoverMargins = for i in [1...@data.length]
|
||||||
|
@left + i * @width / @data.length
|
||||||
|
|
||||||
|
hoverBuild: ->
|
||||||
|
hover = $ "<div/>"
|
||||||
|
hover.addClass "#{@hoverOptions.popupClass} js-morris-popup"
|
||||||
|
hover.appendTo @el
|
||||||
|
hover.hide()
|
||||||
|
hover
|
||||||
|
|
||||||
|
hoverUpdate: (x) ->
|
||||||
|
x -= @el.offset().left
|
||||||
|
for hoverIndex in [0...@hoverMargins.length]
|
||||||
|
break if @hoverMargins[hoverIndex] > x
|
||||||
|
@hoverShow hoverIndex
|
||||||
|
|
||||||
|
hoverShow: (index) ->
|
||||||
|
if index isnt null
|
||||||
|
@hover.html("")
|
||||||
|
@hoverOptions.hoverFill.call(@, index, @data[index])
|
||||||
|
@hoverPosition(index)
|
||||||
|
@fire "hover.show", index
|
||||||
|
@hover.show()
|
||||||
|
if not index?
|
||||||
|
@hoverHide()
|
||||||
|
|
||||||
|
hoverHide: ->
|
||||||
|
@hover.hide()
|
||||||
|
|
||||||
|
colorFor: (row, i, type) -> "inherit"
|
||||||
|
yLabelFormat: (label) -> Morris.commas(label)
|
||||||
|
|
||||||
|
hoverPosition: (index) ->
|
||||||
|
[x, y] = @hoverGetPosition index
|
||||||
|
|
||||||
|
@hover.css
|
||||||
|
top: "#{@el.offset().top + y}px"
|
||||||
|
left: "#{@el.offset().left + x}px"
|
||||||
|
|
||||||
|
hoverGetPosition: (index) ->
|
||||||
|
row = @data[index]
|
||||||
|
|
||||||
|
@hoverWidth = @hover.outerWidth(true)
|
||||||
|
@hoverHeight = @hover.outerHeight(true)
|
||||||
|
|
||||||
|
miny = y = Math.min.apply(null, (y for y in row._y when y isnt null).concat(@bottom))
|
||||||
|
|
||||||
|
x = row._x - @hoverWidth/2
|
||||||
|
y = miny
|
||||||
|
y = y - @hoverHeight - @hoverOptions.pointMargin
|
||||||
|
|
||||||
|
unless @hoverOptions.allowOverflow
|
||||||
|
if x < @left
|
||||||
|
x = row._x + @hoverOptions.pointMargin
|
||||||
|
else if x > @right - @hoverWidth
|
||||||
|
x = row._x - @hoverWidth - @hoverOptions.pointMargin
|
||||||
|
|
||||||
|
y = Math.max y, @top
|
||||||
|
y = Math.min y, (@bottom - @hoverHeight - @hoverOptions.pointMargin)
|
||||||
|
|
||||||
|
if y - miny < @hoverWidth + @hoverOptions.pointMargin
|
||||||
|
y = miny + @hoverOptions.pointMargin
|
||||||
|
|
||||||
|
[x, y]
|
||||||
|
|
||||||
|
hoverFill: (index, row) ->
|
||||||
|
xLabel = $ "<h4/>"
|
||||||
|
xLabel.text row.label
|
||||||
|
xLabel.appendTo @hover
|
||||||
|
for y, i in row.y
|
||||||
|
yLabel = $ "<p/>"
|
||||||
|
yLabel.css "color", @colorFor(row, i, "hover")
|
||||||
|
yLabel.text "#{@options.labels[i]}: #{@yLabelFormat(y)}"
|
||||||
|
yLabel.appendTo @hover
|
||||||
|
|
||||||
|
|
||||||
# Parse a date into a javascript timestamp
|
# Parse a date into a javascript timestamp
|
||||||
#
|
#
|
||||||
|
@ -1,113 +1,22 @@
|
|||||||
Morris.Hover =
|
class Morris.Hover
|
||||||
hoverConfigure: (options) ->
|
# Displays contextual information in a floating HTML div.
|
||||||
@hoverOptions = $.extend {}, @hoverDefaults, options ? {}
|
#
|
||||||
|
constructor: (options = {}) ->
|
||||||
|
@options = $.extend {}, Morris.Hover.defaults, options
|
||||||
|
@el = $ "<div class='#{@options.class}'></div>"
|
||||||
|
@el.hide()
|
||||||
|
|
||||||
hoverInit: ->
|
@defaults:
|
||||||
if @hoverOptions.enableHover
|
class: 'morris-popup'
|
||||||
@hover = @hoverBuild()
|
|
||||||
@hoverBindEvents()
|
|
||||||
@hoverShow(if @hoverOptions.hideHover then null else @data.length - 1)
|
|
||||||
|
|
||||||
hoverDefaults:
|
|
||||||
enableHover: true
|
|
||||||
popupClass: "morris-popup"
|
|
||||||
hideHover: false
|
|
||||||
allowOverflow: false
|
allowOverflow: false
|
||||||
pointMargin: 10
|
|
||||||
hoverFill: (index, row) -> @hoverFill(index, row)
|
|
||||||
|
|
||||||
hoverBindEvents: ->
|
|
||||||
@el.mousemove (evt) =>
|
|
||||||
@hoverUpdate evt.pageX
|
|
||||||
if @hoverOptions.hideHover
|
|
||||||
@el.mouseout (evt) =>
|
|
||||||
@hoverShow null
|
|
||||||
touchHandler = (evt) =>
|
|
||||||
touch = evt.originalEvent.touches[0] or evt.originalEvent.changedTouches[0]
|
|
||||||
@hoverUpdate touch.pageX
|
|
||||||
return touch
|
|
||||||
@el.bind 'touchstart', touchHandler
|
|
||||||
@el.bind 'touchmove', touchHandler
|
|
||||||
@el.bind 'touchend', touchHandler
|
|
||||||
|
|
||||||
@hover.mousemove (evt) -> evt.stopPropagation()
|
|
||||||
@hover.mouseout (evt) -> evt.stopPropagation()
|
|
||||||
@hover.bind 'touchstart', (evt) -> evt.stopPropagation()
|
|
||||||
@hover.bind 'touchmove', (evt) -> evt.stopPropagation()
|
|
||||||
@hover.bind 'touchend', (evt) -> evt.stopPropagation()
|
|
||||||
|
|
||||||
hoverCalculateMargins: ->
|
show: (x, y, data) ->
|
||||||
@hoverMargins = for i in [1...@data.length]
|
if typeof @options.content is 'function'
|
||||||
@left + i * @width / @data.length
|
@el.html @options.content(data)
|
||||||
|
else
|
||||||
|
@el.html @options.content
|
||||||
|
@el.show()
|
||||||
|
|
||||||
hoverBuild: ->
|
hide: ->
|
||||||
hover = $ "<div/>"
|
@el.hide()
|
||||||
hover.addClass "#{@hoverOptions.popupClass} js-morris-popup"
|
|
||||||
hover.appendTo @el
|
|
||||||
hover.hide()
|
|
||||||
hover
|
|
||||||
|
|
||||||
hoverUpdate: (x) ->
|
|
||||||
x -= @el.offset().left
|
|
||||||
for hoverIndex in [0...@hoverMargins.length]
|
|
||||||
break if @hoverMargins[hoverIndex] > x
|
|
||||||
@hoverShow hoverIndex
|
|
||||||
|
|
||||||
hoverShow: (index) ->
|
|
||||||
if index isnt null
|
|
||||||
@hover.html("")
|
|
||||||
@hoverOptions.hoverFill.call(@, index, @data[index])
|
|
||||||
@hoverPosition(index)
|
|
||||||
@fire "hover.show", index
|
|
||||||
@hover.show()
|
|
||||||
if not index?
|
|
||||||
@hoverHide()
|
|
||||||
|
|
||||||
hoverHide: ->
|
|
||||||
@hover.hide()
|
|
||||||
|
|
||||||
colorFor: (row, i, type) -> "inherit"
|
|
||||||
yLabelFormat: (label) -> Morris.commas(label)
|
|
||||||
|
|
||||||
hoverPosition: (index) ->
|
|
||||||
[x, y] = @hoverGetPosition index
|
|
||||||
|
|
||||||
@hover.css
|
|
||||||
top: "#{@el.offset().top + y}px"
|
|
||||||
left: "#{@el.offset().left + x}px"
|
|
||||||
|
|
||||||
hoverGetPosition: (index) ->
|
|
||||||
row = @data[index]
|
|
||||||
|
|
||||||
@hoverWidth = @hover.outerWidth(true)
|
|
||||||
@hoverHeight = @hover.outerHeight(true)
|
|
||||||
|
|
||||||
miny = y = Math.min.apply(null, (y for y in row._y when y isnt null).concat(@bottom))
|
|
||||||
|
|
||||||
x = row._x - @hoverWidth/2
|
|
||||||
y = miny
|
|
||||||
y = y - @hoverHeight - @hoverOptions.pointMargin
|
|
||||||
|
|
||||||
unless @hoverOptions.allowOverflow
|
|
||||||
if x < @left
|
|
||||||
x = row._x + @hoverOptions.pointMargin
|
|
||||||
else if x > @right - @hoverWidth
|
|
||||||
x = row._x - @hoverWidth - @hoverOptions.pointMargin
|
|
||||||
|
|
||||||
y = Math.max y, @top
|
|
||||||
y = Math.min y, (@bottom - @hoverHeight - @hoverOptions.pointMargin)
|
|
||||||
|
|
||||||
if y - miny < @hoverWidth + @hoverOptions.pointMargin
|
|
||||||
y = miny + @hoverOptions.pointMargin
|
|
||||||
|
|
||||||
[x, y]
|
|
||||||
|
|
||||||
hoverFill: (index, row) ->
|
|
||||||
xLabel = $ "<h4/>"
|
|
||||||
xLabel.text row.label
|
|
||||||
xLabel.appendTo @hover
|
|
||||||
for y, i in row.y
|
|
||||||
yLabel = $ "<p/>"
|
|
||||||
yLabel.css "color", @colorFor(row, i, "hover")
|
|
||||||
yLabel.text "#{@options.labels[i]}: #{@yLabelFormat(y)}"
|
|
||||||
yLabel.appendTo @hover
|
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
class Morris.Line extends Morris.Grid
|
class Morris.Line extends Morris.Grid
|
||||||
@include Morris.Hover
|
|
||||||
|
|
||||||
# Initialise the graph.
|
# Initialise the graph.
|
||||||
#
|
#
|
||||||
constructor: (options) ->
|
constructor: (options) ->
|
||||||
@ -11,9 +9,9 @@ class Morris.Line extends Morris.Grid
|
|||||||
# Some instance variables for later
|
# Some instance variables for later
|
||||||
@pointGrow = Raphael.animation r: @options.pointSize + 3, 25, 'linear'
|
@pointGrow = Raphael.animation r: @options.pointSize + 3, 25, 'linear'
|
||||||
@pointShrink = Raphael.animation r: @options.pointSize, 25, 'linear'
|
@pointShrink = Raphael.animation r: @options.pointSize, 25, 'linear'
|
||||||
|
|
||||||
@hoverConfigure @options.hoverOptions
|
@hoverConfigure @options.hoverOptions
|
||||||
|
|
||||||
# column hilight events
|
# column hilight events
|
||||||
if @options.hilight
|
if @options.hilight
|
||||||
@prevHilight = null
|
@prevHilight = null
|
||||||
@ -243,3 +241,86 @@ class Morris.Line extends Morris.Grid
|
|||||||
@options.pointFillColors[sidx % @options.pointFillColors.length] || @options.lineColors[sidx % @options.lineColors.length]
|
@options.pointFillColors[sidx % @options.pointFillColors.length] || @options.lineColors[sidx % @options.lineColors.length]
|
||||||
else
|
else
|
||||||
@options.lineColors[sidx % @options.lineColors.length]
|
@options.lineColors[sidx % @options.lineColors.length]
|
||||||
|
|
||||||
|
|
||||||
|
# generate a series of label, timestamp pairs for x-axis labels
|
||||||
|
#
|
||||||
|
# @private
|
||||||
|
Morris.labelSeries = (dmin, dmax, pxwidth, specName, xLabelFormat) ->
|
||||||
|
ddensity = 200 * (dmax - dmin) / pxwidth # seconds per `margin` pixels
|
||||||
|
d0 = new Date(dmin)
|
||||||
|
spec = Morris.LABEL_SPECS[specName]
|
||||||
|
# if the spec doesn't exist, search for the closest one in the list
|
||||||
|
if spec is undefined
|
||||||
|
for name in Morris.AUTO_LABEL_ORDER
|
||||||
|
s = Morris.LABEL_SPECS[name]
|
||||||
|
if ddensity >= s.span
|
||||||
|
spec = s
|
||||||
|
break
|
||||||
|
# if we run out of options, use second-intervals
|
||||||
|
if spec is undefined
|
||||||
|
spec = Morris.LABEL_SPECS["second"]
|
||||||
|
# check if there's a user-defined formatting function
|
||||||
|
if xLabelFormat
|
||||||
|
spec = $.extend({}, spec, {fmt: xLabelFormat})
|
||||||
|
# calculate labels
|
||||||
|
d = spec.start(d0)
|
||||||
|
ret = []
|
||||||
|
while (t = d.getTime()) <= dmax
|
||||||
|
if t >= dmin
|
||||||
|
ret.push [spec.fmt(d), t]
|
||||||
|
spec.incr(d)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
# @private
|
||||||
|
minutesSpecHelper = (interval) ->
|
||||||
|
span: interval * 60 * 1000
|
||||||
|
start: (d) -> new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours())
|
||||||
|
fmt: (d) -> "#{Morris.pad2(d.getHours())}:#{Morris.pad2(d.getMinutes())}"
|
||||||
|
incr: (d) -> d.setMinutes(d.getMinutes() + interval)
|
||||||
|
|
||||||
|
# @private
|
||||||
|
secondsSpecHelper = (interval) ->
|
||||||
|
span: interval * 1000
|
||||||
|
start: (d) -> new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes())
|
||||||
|
fmt: (d) -> "#{Morris.pad2(d.getHours())}:#{Morris.pad2(d.getMinutes())}:#{Morris.pad2(d.getSeconds())}"
|
||||||
|
incr: (d) -> d.setSeconds(d.getSeconds() + interval)
|
||||||
|
|
||||||
|
Morris.LABEL_SPECS =
|
||||||
|
"decade":
|
||||||
|
span: 172800000000 # 10 * 365 * 24 * 60 * 60 * 1000
|
||||||
|
start: (d) -> new Date(d.getFullYear() - d.getFullYear() % 10, 0, 1)
|
||||||
|
fmt: (d) -> "#{d.getFullYear()}"
|
||||||
|
incr: (d) -> d.setFullYear(d.getFullYear() + 10)
|
||||||
|
"year":
|
||||||
|
span: 17280000000 # 365 * 24 * 60 * 60 * 1000
|
||||||
|
start: (d) -> new Date(d.getFullYear(), 0, 1)
|
||||||
|
fmt: (d) -> "#{d.getFullYear()}"
|
||||||
|
incr: (d) -> d.setFullYear(d.getFullYear() + 1)
|
||||||
|
"month":
|
||||||
|
span: 2419200000 # 28 * 24 * 60 * 60 * 1000
|
||||||
|
start: (d) -> new Date(d.getFullYear(), d.getMonth(), 1)
|
||||||
|
fmt: (d) -> "#{d.getFullYear()}-#{Morris.pad2(d.getMonth() + 1)}"
|
||||||
|
incr: (d) -> d.setMonth(d.getMonth() + 1)
|
||||||
|
"day":
|
||||||
|
span: 86400000 # 24 * 60 * 60 * 1000
|
||||||
|
start: (d) -> new Date(d.getFullYear(), d.getMonth(), d.getDate())
|
||||||
|
fmt: (d) -> "#{d.getFullYear()}-#{Morris.pad2(d.getMonth() + 1)}-#{Morris.pad2(d.getDate())}"
|
||||||
|
incr: (d) -> d.setDate(d.getDate() + 1)
|
||||||
|
"hour": minutesSpecHelper(60)
|
||||||
|
"30min": minutesSpecHelper(30)
|
||||||
|
"15min": minutesSpecHelper(15)
|
||||||
|
"10min": minutesSpecHelper(10)
|
||||||
|
"5min": minutesSpecHelper(5)
|
||||||
|
"minute": minutesSpecHelper(1)
|
||||||
|
"30sec": secondsSpecHelper(30)
|
||||||
|
"15sec": secondsSpecHelper(15)
|
||||||
|
"10sec": secondsSpecHelper(10)
|
||||||
|
"5sec": secondsSpecHelper(5)
|
||||||
|
"second": secondsSpecHelper(1)
|
||||||
|
|
||||||
|
Morris.AUTO_LABEL_ORDER = [
|
||||||
|
"decade", "year", "month", "day", "hour",
|
||||||
|
"30min", "15min", "10min", "5min", "minute",
|
||||||
|
"30sec", "15sec", "10sec", "5sec", "second"
|
||||||
|
]
|
||||||
|
691
morris.js
691
morris.js
@ -1,8 +1,8 @@
|
|||||||
(function() {
|
(function() {
|
||||||
var $, Morris, minutesSpecHelper, secondsSpecHelper,
|
var $, Morris, minutesSpecHelper, secondsSpecHelper,
|
||||||
|
__slice = [].slice,
|
||||||
__hasProp = {}.hasOwnProperty,
|
__hasProp = {}.hasOwnProperty,
|
||||||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
||||||
__slice = [].slice,
|
|
||||||
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
|
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
|
||||||
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
||||||
|
|
||||||
@ -10,46 +10,9 @@
|
|||||||
|
|
||||||
$ = jQuery;
|
$ = jQuery;
|
||||||
|
|
||||||
Morris.Module = (function() {
|
Morris.EventEmitter = (function() {
|
||||||
|
|
||||||
function Module() {}
|
function EventEmitter() {}
|
||||||
|
|
||||||
Module.extend = function(obj) {
|
|
||||||
var key, value, _ref;
|
|
||||||
for (key in obj) {
|
|
||||||
value = obj[key];
|
|
||||||
if (key !== 'extended' && key !== 'included') {
|
|
||||||
this[key] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((_ref = obj.extended) != null) {
|
|
||||||
_ref.apply(this);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
Module.include = function(obj) {
|
|
||||||
var key, value, _ref;
|
|
||||||
for (key in obj) {
|
|
||||||
value = obj[key];
|
|
||||||
if (key !== 'extended' && key !== 'included') {
|
|
||||||
this.prototype[key] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (_ref = obj.included) != null ? _ref.apply(this) : void 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
return Module;
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
||||||
Morris.EventEmitter = (function(_super) {
|
|
||||||
|
|
||||||
__extends(EventEmitter, _super);
|
|
||||||
|
|
||||||
function EventEmitter() {
|
|
||||||
return EventEmitter.__super__.constructor.apply(this, arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
EventEmitter.prototype.on = function(name, handler) {
|
EventEmitter.prototype.on = function(name, handler) {
|
||||||
if (this.handlers == null) {
|
if (this.handlers == null) {
|
||||||
@ -77,7 +40,7 @@
|
|||||||
|
|
||||||
return EventEmitter;
|
return EventEmitter;
|
||||||
|
|
||||||
})(Morris.Module);
|
})();
|
||||||
|
|
||||||
Morris.commas = function(num) {
|
Morris.commas = function(num) {
|
||||||
var absnum, intnum, ret, strabsnum;
|
var absnum, intnum, ret, strabsnum;
|
||||||
@ -100,135 +63,6 @@
|
|||||||
return (number < 10 ? '0' : '') + number;
|
return (number < 10 ? '0' : '') + number;
|
||||||
};
|
};
|
||||||
|
|
||||||
Morris.labelSeries = function(dmin, dmax, pxwidth, specName, xLabelFormat) {
|
|
||||||
var d, d0, ddensity, name, ret, s, spec, t, _i, _len, _ref;
|
|
||||||
ddensity = 200 * (dmax - dmin) / pxwidth;
|
|
||||||
d0 = new Date(dmin);
|
|
||||||
spec = Morris.LABEL_SPECS[specName];
|
|
||||||
if (spec === void 0) {
|
|
||||||
_ref = Morris.AUTO_LABEL_ORDER;
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
name = _ref[_i];
|
|
||||||
s = Morris.LABEL_SPECS[name];
|
|
||||||
if (ddensity >= s.span) {
|
|
||||||
spec = s;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (spec === void 0) {
|
|
||||||
spec = Morris.LABEL_SPECS["second"];
|
|
||||||
}
|
|
||||||
if (xLabelFormat) {
|
|
||||||
spec = $.extend({}, spec, {
|
|
||||||
fmt: xLabelFormat
|
|
||||||
});
|
|
||||||
}
|
|
||||||
d = spec.start(d0);
|
|
||||||
ret = [];
|
|
||||||
while ((t = d.getTime()) <= dmax) {
|
|
||||||
if (t >= dmin) {
|
|
||||||
ret.push([spec.fmt(d), t]);
|
|
||||||
}
|
|
||||||
spec.incr(d);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
minutesSpecHelper = function(interval) {
|
|
||||||
return {
|
|
||||||
span: interval * 60 * 1000,
|
|
||||||
start: function(d) {
|
|
||||||
return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours());
|
|
||||||
},
|
|
||||||
fmt: function(d) {
|
|
||||||
return "" + (Morris.pad2(d.getHours())) + ":" + (Morris.pad2(d.getMinutes()));
|
|
||||||
},
|
|
||||||
incr: function(d) {
|
|
||||||
return d.setMinutes(d.getMinutes() + interval);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
secondsSpecHelper = function(interval) {
|
|
||||||
return {
|
|
||||||
span: interval * 1000,
|
|
||||||
start: function(d) {
|
|
||||||
return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes());
|
|
||||||
},
|
|
||||||
fmt: function(d) {
|
|
||||||
return "" + (Morris.pad2(d.getHours())) + ":" + (Morris.pad2(d.getMinutes())) + ":" + (Morris.pad2(d.getSeconds()));
|
|
||||||
},
|
|
||||||
incr: function(d) {
|
|
||||||
return d.setSeconds(d.getSeconds() + interval);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
Morris.LABEL_SPECS = {
|
|
||||||
"decade": {
|
|
||||||
span: 172800000000,
|
|
||||||
start: function(d) {
|
|
||||||
return new Date(d.getFullYear() - d.getFullYear() % 10, 0, 1);
|
|
||||||
},
|
|
||||||
fmt: function(d) {
|
|
||||||
return "" + (d.getFullYear());
|
|
||||||
},
|
|
||||||
incr: function(d) {
|
|
||||||
return d.setFullYear(d.getFullYear() + 10);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"year": {
|
|
||||||
span: 17280000000,
|
|
||||||
start: function(d) {
|
|
||||||
return new Date(d.getFullYear(), 0, 1);
|
|
||||||
},
|
|
||||||
fmt: function(d) {
|
|
||||||
return "" + (d.getFullYear());
|
|
||||||
},
|
|
||||||
incr: function(d) {
|
|
||||||
return d.setFullYear(d.getFullYear() + 1);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"month": {
|
|
||||||
span: 2419200000,
|
|
||||||
start: function(d) {
|
|
||||||
return new Date(d.getFullYear(), d.getMonth(), 1);
|
|
||||||
},
|
|
||||||
fmt: function(d) {
|
|
||||||
return "" + (d.getFullYear()) + "-" + (Morris.pad2(d.getMonth() + 1));
|
|
||||||
},
|
|
||||||
incr: function(d) {
|
|
||||||
return d.setMonth(d.getMonth() + 1);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"day": {
|
|
||||||
span: 86400000,
|
|
||||||
start: function(d) {
|
|
||||||
return new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
||||||
},
|
|
||||||
fmt: function(d) {
|
|
||||||
return "" + (d.getFullYear()) + "-" + (Morris.pad2(d.getMonth() + 1)) + "-" + (Morris.pad2(d.getDate()));
|
|
||||||
},
|
|
||||||
incr: function(d) {
|
|
||||||
return d.setDate(d.getDate() + 1);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"hour": minutesSpecHelper(60),
|
|
||||||
"30min": minutesSpecHelper(30),
|
|
||||||
"15min": minutesSpecHelper(15),
|
|
||||||
"10min": minutesSpecHelper(10),
|
|
||||||
"5min": minutesSpecHelper(5),
|
|
||||||
"minute": minutesSpecHelper(1),
|
|
||||||
"30sec": secondsSpecHelper(30),
|
|
||||||
"15sec": secondsSpecHelper(15),
|
|
||||||
"10sec": secondsSpecHelper(10),
|
|
||||||
"5sec": secondsSpecHelper(5),
|
|
||||||
"second": secondsSpecHelper(1)
|
|
||||||
};
|
|
||||||
|
|
||||||
Morris.AUTO_LABEL_ORDER = ["decade", "year", "month", "day", "hour", "30min", "15min", "10min", "5min", "minute", "30sec", "15sec", "10sec", "5sec", "second"];
|
|
||||||
|
|
||||||
Morris.Grid = (function(_super) {
|
Morris.Grid = (function(_super) {
|
||||||
|
|
||||||
__extends(Grid, _super);
|
__extends(Grid, _super);
|
||||||
@ -528,6 +362,184 @@
|
|||||||
return "" + this.options.preUnits + (Morris.commas(label)) + this.options.postUnits;
|
return "" + this.options.preUnits + (Morris.commas(label)) + this.options.postUnits;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Grid.prototype.hoverConfigure = function(options) {
|
||||||
|
return this.hoverOptions = $.extend({}, this.hoverDefaults, options != null ? options : {});
|
||||||
|
};
|
||||||
|
|
||||||
|
Grid.prototype.hoverInit = function() {
|
||||||
|
if (this.hoverOptions.enableHover) {
|
||||||
|
this.hover = this.hoverBuild();
|
||||||
|
this.hoverBindEvents();
|
||||||
|
return this.hoverShow(this.hoverOptions.hideHover ? null : this.data.length - 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Grid.prototype.hoverDefaults = {
|
||||||
|
enableHover: true,
|
||||||
|
popupClass: "morris-popup",
|
||||||
|
hideHover: false,
|
||||||
|
allowOverflow: false,
|
||||||
|
pointMargin: 10,
|
||||||
|
hoverFill: function(index, row) {
|
||||||
|
return this.hoverFill(index, row);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Grid.prototype.hoverBindEvents = function() {
|
||||||
|
var touchHandler,
|
||||||
|
_this = this;
|
||||||
|
this.el.mousemove(function(evt) {
|
||||||
|
return _this.hoverUpdate(evt.pageX);
|
||||||
|
});
|
||||||
|
if (this.hoverOptions.hideHover) {
|
||||||
|
this.el.mouseout(function(evt) {
|
||||||
|
return _this.hoverShow(null);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
touchHandler = function(evt) {
|
||||||
|
var touch;
|
||||||
|
touch = evt.originalEvent.touches[0] || evt.originalEvent.changedTouches[0];
|
||||||
|
_this.hoverUpdate(touch.pageX);
|
||||||
|
return touch;
|
||||||
|
};
|
||||||
|
this.el.bind('touchstart', touchHandler);
|
||||||
|
this.el.bind('touchmove', touchHandler);
|
||||||
|
this.el.bind('touchend', touchHandler);
|
||||||
|
this.hover.mousemove(function(evt) {
|
||||||
|
return evt.stopPropagation();
|
||||||
|
});
|
||||||
|
this.hover.mouseout(function(evt) {
|
||||||
|
return evt.stopPropagation();
|
||||||
|
});
|
||||||
|
this.hover.bind('touchstart', function(evt) {
|
||||||
|
return evt.stopPropagation();
|
||||||
|
});
|
||||||
|
this.hover.bind('touchmove', function(evt) {
|
||||||
|
return evt.stopPropagation();
|
||||||
|
});
|
||||||
|
return this.hover.bind('touchend', function(evt) {
|
||||||
|
return evt.stopPropagation();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Grid.prototype.hoverCalculateMargins = function() {
|
||||||
|
var i;
|
||||||
|
return this.hoverMargins = (function() {
|
||||||
|
var _i, _ref, _results;
|
||||||
|
_results = [];
|
||||||
|
for (i = _i = 1, _ref = this.data.length; 1 <= _ref ? _i < _ref : _i > _ref; i = 1 <= _ref ? ++_i : --_i) {
|
||||||
|
_results.push(this.left + i * this.width / this.data.length);
|
||||||
|
}
|
||||||
|
return _results;
|
||||||
|
}).call(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
Grid.prototype.hoverBuild = function() {
|
||||||
|
var hover;
|
||||||
|
hover = $("<div/>");
|
||||||
|
hover.addClass("" + this.hoverOptions.popupClass + " js-morris-popup");
|
||||||
|
hover.appendTo(this.el);
|
||||||
|
hover.hide();
|
||||||
|
return hover;
|
||||||
|
};
|
||||||
|
|
||||||
|
Grid.prototype.hoverUpdate = function(x) {
|
||||||
|
var hoverIndex, _i, _ref;
|
||||||
|
x -= this.el.offset().left;
|
||||||
|
for (hoverIndex = _i = 0, _ref = this.hoverMargins.length; 0 <= _ref ? _i < _ref : _i > _ref; hoverIndex = 0 <= _ref ? ++_i : --_i) {
|
||||||
|
if (this.hoverMargins[hoverIndex] > x) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.hoverShow(hoverIndex);
|
||||||
|
};
|
||||||
|
|
||||||
|
Grid.prototype.hoverShow = function(index) {
|
||||||
|
if (index !== null) {
|
||||||
|
this.hover.html("");
|
||||||
|
this.hoverOptions.hoverFill.call(this, index, this.data[index]);
|
||||||
|
this.hoverPosition(index);
|
||||||
|
this.fire("hover.show", index);
|
||||||
|
this.hover.show();
|
||||||
|
}
|
||||||
|
if (!(index != null)) {
|
||||||
|
return this.hoverHide();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Grid.prototype.hoverHide = function() {
|
||||||
|
return this.hover.hide();
|
||||||
|
};
|
||||||
|
|
||||||
|
Grid.prototype.colorFor = function(row, i, type) {
|
||||||
|
return "inherit";
|
||||||
|
};
|
||||||
|
|
||||||
|
Grid.prototype.yLabelFormat = function(label) {
|
||||||
|
return Morris.commas(label);
|
||||||
|
};
|
||||||
|
|
||||||
|
Grid.prototype.hoverPosition = function(index) {
|
||||||
|
var x, y, _ref;
|
||||||
|
_ref = this.hoverGetPosition(index), x = _ref[0], y = _ref[1];
|
||||||
|
return this.hover.css({
|
||||||
|
top: "" + (this.el.offset().top + y) + "px",
|
||||||
|
left: "" + (this.el.offset().left + x) + "px"
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Grid.prototype.hoverGetPosition = function(index) {
|
||||||
|
var miny, row, x, y;
|
||||||
|
row = this.data[index];
|
||||||
|
this.hoverWidth = this.hover.outerWidth(true);
|
||||||
|
this.hoverHeight = this.hover.outerHeight(true);
|
||||||
|
miny = y = Math.min.apply(null, ((function() {
|
||||||
|
var _i, _len, _ref, _results;
|
||||||
|
_ref = row._y;
|
||||||
|
_results = [];
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
y = _ref[_i];
|
||||||
|
if (y !== null) {
|
||||||
|
_results.push(y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _results;
|
||||||
|
})()).concat(this.bottom));
|
||||||
|
x = row._x - this.hoverWidth / 2;
|
||||||
|
y = miny;
|
||||||
|
y = y - this.hoverHeight - this.hoverOptions.pointMargin;
|
||||||
|
if (!this.hoverOptions.allowOverflow) {
|
||||||
|
if (x < this.left) {
|
||||||
|
x = row._x + this.hoverOptions.pointMargin;
|
||||||
|
} else if (x > this.right - this.hoverWidth) {
|
||||||
|
x = row._x - this.hoverWidth - this.hoverOptions.pointMargin;
|
||||||
|
}
|
||||||
|
y = Math.max(y, this.top);
|
||||||
|
y = Math.min(y, this.bottom - this.hoverHeight - this.hoverOptions.pointMargin);
|
||||||
|
if (y - miny < this.hoverWidth + this.hoverOptions.pointMargin) {
|
||||||
|
y = miny + this.hoverOptions.pointMargin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [x, y];
|
||||||
|
};
|
||||||
|
|
||||||
|
Grid.prototype.hoverFill = function(index, row) {
|
||||||
|
var i, xLabel, y, yLabel, _i, _len, _ref, _results;
|
||||||
|
xLabel = $("<h4/>");
|
||||||
|
xLabel.text(row.label);
|
||||||
|
xLabel.appendTo(this.hover);
|
||||||
|
_ref = row.y;
|
||||||
|
_results = [];
|
||||||
|
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
|
||||||
|
y = _ref[i];
|
||||||
|
yLabel = $("<p/>");
|
||||||
|
yLabel.css("color", this.colorFor(row, i, "hover"));
|
||||||
|
yLabel.text("" + this.options.labels[i] + ": " + (this.yLabelFormat(y)));
|
||||||
|
_results.push(yLabel.appendTo(this.hover));
|
||||||
|
}
|
||||||
|
return _results;
|
||||||
|
};
|
||||||
|
|
||||||
return Grid;
|
return Grid;
|
||||||
|
|
||||||
})(Morris.EventEmitter);
|
})(Morris.EventEmitter);
|
||||||
@ -589,179 +601,43 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Morris.Hover = {
|
Morris.Hover = (function() {
|
||||||
hoverConfigure: function(options) {
|
|
||||||
return this.hoverOptions = $.extend({}, this.hoverDefaults, options != null ? options : {});
|
function Hover(options) {
|
||||||
},
|
if (options == null) {
|
||||||
hoverInit: function() {
|
options = {};
|
||||||
if (this.hoverOptions.enableHover) {
|
|
||||||
this.hover = this.hoverBuild();
|
|
||||||
this.hoverBindEvents();
|
|
||||||
return this.hoverShow(this.hoverOptions.hideHover ? null : this.data.length - 1);
|
|
||||||
}
|
}
|
||||||
},
|
this.options = $.extend({}, Morris.Hover.defaults, options);
|
||||||
hoverDefaults: {
|
this.el = $("<div class='" + this.options["class"] + "'></div>");
|
||||||
enableHover: true,
|
this.el.hide();
|
||||||
popupClass: "morris-popup",
|
|
||||||
hideHover: false,
|
|
||||||
allowOverflow: false,
|
|
||||||
pointMargin: 10,
|
|
||||||
hoverFill: function(index, row) {
|
|
||||||
return this.hoverFill(index, row);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
hoverBindEvents: function() {
|
|
||||||
var touchHandler,
|
|
||||||
_this = this;
|
|
||||||
this.el.mousemove(function(evt) {
|
|
||||||
return _this.hoverUpdate(evt.pageX);
|
|
||||||
});
|
|
||||||
if (this.hoverOptions.hideHover) {
|
|
||||||
this.el.mouseout(function(evt) {
|
|
||||||
return _this.hoverShow(null);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
touchHandler = function(evt) {
|
|
||||||
var touch;
|
|
||||||
touch = evt.originalEvent.touches[0] || evt.originalEvent.changedTouches[0];
|
|
||||||
_this.hoverUpdate(touch.pageX);
|
|
||||||
return touch;
|
|
||||||
};
|
|
||||||
this.el.bind('touchstart', touchHandler);
|
|
||||||
this.el.bind('touchmove', touchHandler);
|
|
||||||
this.el.bind('touchend', touchHandler);
|
|
||||||
this.hover.mousemove(function(evt) {
|
|
||||||
return evt.stopPropagation();
|
|
||||||
});
|
|
||||||
this.hover.mouseout(function(evt) {
|
|
||||||
return evt.stopPropagation();
|
|
||||||
});
|
|
||||||
this.hover.bind('touchstart', function(evt) {
|
|
||||||
return evt.stopPropagation();
|
|
||||||
});
|
|
||||||
this.hover.bind('touchmove', function(evt) {
|
|
||||||
return evt.stopPropagation();
|
|
||||||
});
|
|
||||||
return this.hover.bind('touchend', function(evt) {
|
|
||||||
return evt.stopPropagation();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
hoverCalculateMargins: function() {
|
|
||||||
var i;
|
|
||||||
return this.hoverMargins = (function() {
|
|
||||||
var _i, _ref, _results;
|
|
||||||
_results = [];
|
|
||||||
for (i = _i = 1, _ref = this.data.length; 1 <= _ref ? _i < _ref : _i > _ref; i = 1 <= _ref ? ++_i : --_i) {
|
|
||||||
_results.push(this.left + i * this.width / this.data.length);
|
|
||||||
}
|
|
||||||
return _results;
|
|
||||||
}).call(this);
|
|
||||||
},
|
|
||||||
hoverBuild: function() {
|
|
||||||
var hover;
|
|
||||||
hover = $("<div/>");
|
|
||||||
hover.addClass("" + this.hoverOptions.popupClass + " js-morris-popup");
|
|
||||||
hover.appendTo(this.el);
|
|
||||||
hover.hide();
|
|
||||||
return hover;
|
|
||||||
},
|
|
||||||
hoverUpdate: function(x) {
|
|
||||||
var hoverIndex, _i, _ref;
|
|
||||||
x -= this.el.offset().left;
|
|
||||||
for (hoverIndex = _i = 0, _ref = this.hoverMargins.length; 0 <= _ref ? _i < _ref : _i > _ref; hoverIndex = 0 <= _ref ? ++_i : --_i) {
|
|
||||||
if (this.hoverMargins[hoverIndex] > x) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.hoverShow(hoverIndex);
|
|
||||||
},
|
|
||||||
hoverShow: function(index) {
|
|
||||||
if (index !== null) {
|
|
||||||
this.hover.html("");
|
|
||||||
this.hoverOptions.hoverFill.call(this, index, this.data[index]);
|
|
||||||
this.hoverPosition(index);
|
|
||||||
this.fire("hover.show", index);
|
|
||||||
this.hover.show();
|
|
||||||
}
|
|
||||||
if (!(index != null)) {
|
|
||||||
return this.hoverHide();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
hoverHide: function() {
|
|
||||||
return this.hover.hide();
|
|
||||||
},
|
|
||||||
colorFor: function(row, i, type) {
|
|
||||||
return "inherit";
|
|
||||||
},
|
|
||||||
yLabelFormat: function(label) {
|
|
||||||
return Morris.commas(label);
|
|
||||||
},
|
|
||||||
hoverPosition: function(index) {
|
|
||||||
var x, y, _ref;
|
|
||||||
_ref = this.hoverGetPosition(index), x = _ref[0], y = _ref[1];
|
|
||||||
return this.hover.css({
|
|
||||||
top: "" + (this.el.offset().top + y) + "px",
|
|
||||||
left: "" + (this.el.offset().left + x) + "px"
|
|
||||||
});
|
|
||||||
},
|
|
||||||
hoverGetPosition: function(index) {
|
|
||||||
var miny, row, x, y;
|
|
||||||
row = this.data[index];
|
|
||||||
this.hoverWidth = this.hover.outerWidth(true);
|
|
||||||
this.hoverHeight = this.hover.outerHeight(true);
|
|
||||||
miny = y = Math.min.apply(null, ((function() {
|
|
||||||
var _i, _len, _ref, _results;
|
|
||||||
_ref = row._y;
|
|
||||||
_results = [];
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
y = _ref[_i];
|
|
||||||
if (y !== null) {
|
|
||||||
_results.push(y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _results;
|
|
||||||
})()).concat(this.bottom));
|
|
||||||
x = row._x - this.hoverWidth / 2;
|
|
||||||
y = miny;
|
|
||||||
y = y - this.hoverHeight - this.hoverOptions.pointMargin;
|
|
||||||
if (!this.hoverOptions.allowOverflow) {
|
|
||||||
if (x < this.left) {
|
|
||||||
x = row._x + this.hoverOptions.pointMargin;
|
|
||||||
} else if (x > this.right - this.hoverWidth) {
|
|
||||||
x = row._x - this.hoverWidth - this.hoverOptions.pointMargin;
|
|
||||||
}
|
|
||||||
y = Math.max(y, this.top);
|
|
||||||
y = Math.min(y, this.bottom - this.hoverHeight - this.hoverOptions.pointMargin);
|
|
||||||
if (y - miny < this.hoverWidth + this.hoverOptions.pointMargin) {
|
|
||||||
y = miny + this.hoverOptions.pointMargin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return [x, y];
|
|
||||||
},
|
|
||||||
hoverFill: function(index, row) {
|
|
||||||
var i, xLabel, y, yLabel, _i, _len, _ref, _results;
|
|
||||||
xLabel = $("<h4/>");
|
|
||||||
xLabel.text(row.label);
|
|
||||||
xLabel.appendTo(this.hover);
|
|
||||||
_ref = row.y;
|
|
||||||
_results = [];
|
|
||||||
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
|
|
||||||
y = _ref[i];
|
|
||||||
yLabel = $("<p/>");
|
|
||||||
yLabel.css("color", this.colorFor(row, i, "hover"));
|
|
||||||
yLabel.text("" + this.options.labels[i] + ": " + (this.yLabelFormat(y)));
|
|
||||||
_results.push(yLabel.appendTo(this.hover));
|
|
||||||
}
|
|
||||||
return _results;
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
Hover.defaults = {
|
||||||
|
"class": 'morris-popup',
|
||||||
|
allowOverflow: false
|
||||||
|
};
|
||||||
|
|
||||||
|
Hover.prototype.show = function(x, y, data) {
|
||||||
|
if (typeof this.options.content === 'function') {
|
||||||
|
this.el.html(this.options.content(data));
|
||||||
|
} else {
|
||||||
|
this.el.html(this.options.content);
|
||||||
|
}
|
||||||
|
return this.el.show();
|
||||||
|
};
|
||||||
|
|
||||||
|
Hover.prototype.hide = function() {
|
||||||
|
return this.el.hide();
|
||||||
|
};
|
||||||
|
|
||||||
|
return Hover;
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
Morris.Line = (function(_super) {
|
Morris.Line = (function(_super) {
|
||||||
|
|
||||||
__extends(Line, _super);
|
__extends(Line, _super);
|
||||||
|
|
||||||
Line.include(Morris.Hover);
|
|
||||||
|
|
||||||
function Line(options) {
|
function Line(options) {
|
||||||
this.updateHilight = __bind(this.updateHilight, this);
|
this.updateHilight = __bind(this.updateHilight, this);
|
||||||
|
|
||||||
@ -1135,6 +1011,135 @@
|
|||||||
|
|
||||||
})(Morris.Grid);
|
})(Morris.Grid);
|
||||||
|
|
||||||
|
Morris.labelSeries = function(dmin, dmax, pxwidth, specName, xLabelFormat) {
|
||||||
|
var d, d0, ddensity, name, ret, s, spec, t, _i, _len, _ref;
|
||||||
|
ddensity = 200 * (dmax - dmin) / pxwidth;
|
||||||
|
d0 = new Date(dmin);
|
||||||
|
spec = Morris.LABEL_SPECS[specName];
|
||||||
|
if (spec === void 0) {
|
||||||
|
_ref = Morris.AUTO_LABEL_ORDER;
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
name = _ref[_i];
|
||||||
|
s = Morris.LABEL_SPECS[name];
|
||||||
|
if (ddensity >= s.span) {
|
||||||
|
spec = s;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (spec === void 0) {
|
||||||
|
spec = Morris.LABEL_SPECS["second"];
|
||||||
|
}
|
||||||
|
if (xLabelFormat) {
|
||||||
|
spec = $.extend({}, spec, {
|
||||||
|
fmt: xLabelFormat
|
||||||
|
});
|
||||||
|
}
|
||||||
|
d = spec.start(d0);
|
||||||
|
ret = [];
|
||||||
|
while ((t = d.getTime()) <= dmax) {
|
||||||
|
if (t >= dmin) {
|
||||||
|
ret.push([spec.fmt(d), t]);
|
||||||
|
}
|
||||||
|
spec.incr(d);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
minutesSpecHelper = function(interval) {
|
||||||
|
return {
|
||||||
|
span: interval * 60 * 1000,
|
||||||
|
start: function(d) {
|
||||||
|
return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours());
|
||||||
|
},
|
||||||
|
fmt: function(d) {
|
||||||
|
return "" + (Morris.pad2(d.getHours())) + ":" + (Morris.pad2(d.getMinutes()));
|
||||||
|
},
|
||||||
|
incr: function(d) {
|
||||||
|
return d.setMinutes(d.getMinutes() + interval);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
secondsSpecHelper = function(interval) {
|
||||||
|
return {
|
||||||
|
span: interval * 1000,
|
||||||
|
start: function(d) {
|
||||||
|
return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes());
|
||||||
|
},
|
||||||
|
fmt: function(d) {
|
||||||
|
return "" + (Morris.pad2(d.getHours())) + ":" + (Morris.pad2(d.getMinutes())) + ":" + (Morris.pad2(d.getSeconds()));
|
||||||
|
},
|
||||||
|
incr: function(d) {
|
||||||
|
return d.setSeconds(d.getSeconds() + interval);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Morris.LABEL_SPECS = {
|
||||||
|
"decade": {
|
||||||
|
span: 172800000000,
|
||||||
|
start: function(d) {
|
||||||
|
return new Date(d.getFullYear() - d.getFullYear() % 10, 0, 1);
|
||||||
|
},
|
||||||
|
fmt: function(d) {
|
||||||
|
return "" + (d.getFullYear());
|
||||||
|
},
|
||||||
|
incr: function(d) {
|
||||||
|
return d.setFullYear(d.getFullYear() + 10);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"year": {
|
||||||
|
span: 17280000000,
|
||||||
|
start: function(d) {
|
||||||
|
return new Date(d.getFullYear(), 0, 1);
|
||||||
|
},
|
||||||
|
fmt: function(d) {
|
||||||
|
return "" + (d.getFullYear());
|
||||||
|
},
|
||||||
|
incr: function(d) {
|
||||||
|
return d.setFullYear(d.getFullYear() + 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"month": {
|
||||||
|
span: 2419200000,
|
||||||
|
start: function(d) {
|
||||||
|
return new Date(d.getFullYear(), d.getMonth(), 1);
|
||||||
|
},
|
||||||
|
fmt: function(d) {
|
||||||
|
return "" + (d.getFullYear()) + "-" + (Morris.pad2(d.getMonth() + 1));
|
||||||
|
},
|
||||||
|
incr: function(d) {
|
||||||
|
return d.setMonth(d.getMonth() + 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"day": {
|
||||||
|
span: 86400000,
|
||||||
|
start: function(d) {
|
||||||
|
return new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
||||||
|
},
|
||||||
|
fmt: function(d) {
|
||||||
|
return "" + (d.getFullYear()) + "-" + (Morris.pad2(d.getMonth() + 1)) + "-" + (Morris.pad2(d.getDate()));
|
||||||
|
},
|
||||||
|
incr: function(d) {
|
||||||
|
return d.setDate(d.getDate() + 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hour": minutesSpecHelper(60),
|
||||||
|
"30min": minutesSpecHelper(30),
|
||||||
|
"15min": minutesSpecHelper(15),
|
||||||
|
"10min": minutesSpecHelper(10),
|
||||||
|
"5min": minutesSpecHelper(5),
|
||||||
|
"minute": minutesSpecHelper(1),
|
||||||
|
"30sec": secondsSpecHelper(30),
|
||||||
|
"15sec": secondsSpecHelper(15),
|
||||||
|
"10sec": secondsSpecHelper(10),
|
||||||
|
"5sec": secondsSpecHelper(5),
|
||||||
|
"second": secondsSpecHelper(1)
|
||||||
|
};
|
||||||
|
|
||||||
|
Morris.AUTO_LABEL_ORDER = ["decade", "year", "month", "day", "hour", "30min", "15min", "10min", "5min", "minute", "30sec", "15sec", "10sec", "5sec", "second"];
|
||||||
|
|
||||||
Morris.Area = (function(_super) {
|
Morris.Area = (function(_super) {
|
||||||
|
|
||||||
__extends(Area, _super);
|
__extends(Area, _super);
|
||||||
@ -1196,14 +1201,6 @@
|
|||||||
|
|
||||||
__extends(Bar, _super);
|
__extends(Bar, _super);
|
||||||
|
|
||||||
Bar.include(Morris.Hover);
|
|
||||||
|
|
||||||
Bar.prototype.hoverGetPosition = function(index) {
|
|
||||||
var x, y, _ref;
|
|
||||||
_ref = Morris.Hover.hoverGetPosition.call(this, index), x = _ref[0], y = _ref[1];
|
|
||||||
return [x, (this.top + this.bottom) / 2 - this.hoverHeight / 2];
|
|
||||||
};
|
|
||||||
|
|
||||||
function Bar(options) {
|
function Bar(options) {
|
||||||
if (!(this instanceof Morris.Bar)) {
|
if (!(this instanceof Morris.Bar)) {
|
||||||
return new Morris.Bar(options);
|
return new Morris.Bar(options);
|
||||||
@ -1350,6 +1347,12 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Bar.prototype.hoverGetPosition = function(index) {
|
||||||
|
var x, y, _ref;
|
||||||
|
_ref = Bar.__super__.hoverGetPosition.call(this, index), x = _ref[0], y = _ref[1];
|
||||||
|
return [x, (this.top + this.bottom) / 2 - this.hoverHeight / 2];
|
||||||
|
};
|
||||||
|
|
||||||
return Bar;
|
return Bar;
|
||||||
|
|
||||||
})(Morris.Grid);
|
})(Morris.Grid);
|
||||||
|
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