2016-04-19 03:26:24 +08:00
/*! jQuery v1.11.3 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */
! function ( a , b ) { "object" == typeof module && "object" == typeof module . exports ? module . exports = a . document ? b ( a , ! 0 ) : function ( a ) { if ( ! a . document ) throw new Error ( "jQuery requires a window with a document" ) ; return b ( a ) } : b ( a ) } ( "undefined" != typeof window ? window : this , function ( a , b ) { var c = [ ] , d = c . slice , e = c . concat , f = c . push , g = c . indexOf , h = { } , i = h . toString , j = h . hasOwnProperty , k = { } , l = "1.11.3" , m = function ( a , b ) { return new m . fn . init ( a , b ) } , n = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g , o = /^-ms-/ , p = /-([\da-z])/gi , q = function ( a , b ) { return b . toUpperCase ( ) } ; m . fn = m . prototype = { jquery : l , constructor : m , selector : "" , length : 0 , toArray : function ( ) { return d . call ( this ) } , get : function ( a ) { return null != a ? 0 > a ? this [ a + this . length ] : this [ a ] : d . call ( this ) } , pushStack : function ( a ) { var b = m . merge ( this . constructor ( ) , a ) ; return b . prevObject = this , b . context = this . context , b } , each : function ( a , b ) { return m . each ( this , a , b ) } , map : function ( a ) { return this . pushStack ( m . map ( this , function ( b , c ) { return a . call ( b , c , b ) } ) ) } , slice : function ( ) { return this . pushStack ( d . apply ( this , arguments ) ) } , first : function ( ) { return this . eq ( 0 ) } , last : function ( ) { return this . eq ( - 1 ) } , eq : function ( a ) { var b = this . length , c = + a + ( 0 > a ? b : 0 ) ; return this . pushStack ( c >= 0 && b > c ? [ this [ c ] ] : [ ] ) } , end : function ( ) { return this . prevObject || this . constructor ( null ) } , push : f , sort : c . sort , splice : c . splice } , m . extend = m . fn . extend = function ( ) { var a , b , c , d , e , f , g = arguments [ 0 ] || { } , h = 1 , i = arguments . length , j = ! 1 ; for ( "boolean" == typeof g && ( j = g , g = arguments [ h ] || { } , h ++ ) , "object" == typeof g || m . isFunction ( g ) || ( g = { } ) , h === i && ( g = this , h -- ) ; i > h ; h ++ ) if ( null != ( e = arguments [ h ] ) ) for ( d in e ) a = g [ d ] , c = e [ d ] , g !== c && ( j && c && ( m . isPlainObject ( c ) || ( b = m . isArray ( c ) ) ) ? ( b ? ( b = ! 1 , f = a && m . isArray ( a ) ? a : [ ] ) : f = a && m . isPlainObject ( a ) ? a : { } , g [ d ] = m . extend ( j , f , c ) ) : void 0 !== c && ( g [ d ] = c ) ) ; return g } , m . extend ( { expando : "jQuery" + ( l + Math . random ( ) ) . replace ( /\D/g , "" ) , isReady : ! 0 , error : function ( a ) { throw new Error ( a ) } , noop : function ( ) { } , isFunction : function ( a ) { return "function" === m . type ( a ) } , isArray : Array . isArray || function ( a ) { return "array" === m . type ( a ) } , isWindow : function ( a ) { return null != a && a == a . window } , isNumeric : function ( a ) { return ! m . isArray ( a ) && a - parseFloat ( a ) + 1 >= 0 } , isEmptyObject : function ( a ) { var b ; for ( b in a ) return ! 1 ; return ! 0 } , isPlainObject : function ( a ) { var b ; if ( ! a || "object" !== m . type ( a ) || a . nodeType || m . isWindow ( a ) ) return ! 1 ; try { if ( a . constructor && ! j . call ( a , "constructor" ) && ! j . call ( a . constructor . prototype , "isPrototypeOf" ) ) return ! 1 } catch ( c ) { return ! 1 } if ( k . ownLast ) for ( b in a ) return j . call ( a , b ) ; for ( b in a ) ; return void 0 === b || j . call ( a , b ) } , type : function ( a ) { return null == a ? a + "" : "object" == typeof a || "function" == typeof a ? h [ i . call ( a ) ] || "object" : typeof a } , globalEval : function ( b ) { b && m . trim ( b ) && ( a . execScript || function ( b ) { a . eval . call ( a , b ) } ) ( b ) } , camelCase : function ( a ) { return a . replace ( o , "ms-" ) . replace ( p , q ) } , nodeName : function ( a , b ) { return a . nodeName && a . nodeName . toLowerCase ( ) === b . toLowerCase ( ) } , each : function ( a , b , c ) { var d , e = 0 , f = a . length , g = r ( a ) ; if ( c ) { if ( g ) { for ( ; f > e ; e ++ ) if ( d = b . apply ( a [ e ] , c ) , d === ! 1 ) break } else for ( e in a ) if ( d = b . apply ( a [ e ] , c ) , d === ! 1 ) break } else if ( g ) { for ( ; f > e ; e ++ ) if ( d = b . call ( a [ e ] , e , a [ e ] ) , d === ! 1 ) break } else for ( e in a ) if ( d = b . call ( a [ e ] , e , a [ e ] ) , d === ! 1 ) break ; return a } , trim : function ( a ) { return null == a ? "" : ( a + "" ) . replace ( n , "" ) } , makeArray : function ( a , b ) { var c = b || [ ] ; return null != a && ( r ( Object ( a ) ) ? m . merge ( c , "string" == typeof a ? [ a ] : a ) : f . call ( c , a ) ) , c } , inArray : function ( a , b , c ) { var d ; if ( b ) { if ( g ) return g . call ( b , a , c ) ; for ( d = b . length , c = c ? 0 > c ? Math . max ( 0 , d + c ) : c : 0 ; d > c ; c ++ ) if ( c in b && b [ c ] === a ) return c } return - 1 } , merge : function ( a , b ) { var c = + b . length , d = 0 , e = a . length ; while ( c > d ) a [ e ++ ] = b [ d ++ ] ; if ( c !== c ) while ( void 0 !== b [ d ] ) a [ e ++ ] = b [ d ++ ] ; return a . length = e , a } , grep : function ( a , b , c ) { for ( var d , e = [ ] , f = 0 , g = a . length , h = ! c ; g > f ; f ++ ) d = ! b ( a [ f ] , f ) , d !== h && e . push ( a [ f ] ) ; return e } , map : function ( a , b , c ) { var d , f = 0 , g = a . length , h = r ( a ) , i = [ ] ; if ( h ) for ( ; g > f ; f ++ ) d = b ( a [ f ] , f , c ) , null != d && i . push ( d ) ; else for ( f in a ) d = b ( a [ f ] , f , c ) , null != d && i . push ( d ) ; return e . apply ( [ ] , i ) } , guid : 1 , proxy : function ( a , b ) { var c , e , f ; return "string" == typeof b && ( f = a [ b ] , b = a , a = f ) , m . isFunction ( a ) ? ( c = d . call ( arguments , 2 ) , e = function ( ) { return a . apply ( b || this , c . concat ( d . call ( arguments ) ) ) } , e . guid = a . guid = a . guid || m . guid ++ , e ) : void 0 } , now : function ( ) { return + new Date } , support : k } ) , m . each (
return ! 0 } function Q ( a , b , d , e ) { if ( m . acceptData ( a ) ) { var f , g , h = m . expando , i = a . nodeType , j = i ? m . cache : a , k = i ? a [ h ] : a [ h ] && h ; if ( k && j [ k ] && ( e || j [ k ] . data ) || void 0 !== d || "string" != typeof b ) return k || ( k = i ? a [ h ] = c . pop ( ) || m . guid ++ : h ) , j [ k ] || ( j [ k ] = i ? { } : { toJSON : m . noop } ) , ( "object" == typeof b || "function" == typeof b ) && ( e ? j [ k ] = m . extend ( j [ k ] , b ) : j [ k ] . data = m . extend ( j [ k ] . data , b ) ) , g = j [ k ] , e || ( g . data || ( g . data = { } ) , g = g . data ) , void 0 !== d && ( g [ m . camelCase ( b ) ] = d ) , "string" == typeof b ? ( f = g [ b ] , null == f && ( f = g [ m . camelCase ( b ) ] ) ) : f = g , f } } function R ( a , b , c ) { if ( m . acceptData ( a ) ) { var d , e , f = a . nodeType , g = f ? m . cache : a , h = f ? a [ m . expando ] : m . expando ; if ( g [ h ] ) { if ( b && ( d = c ? g [ h ] : g [ h ] . data ) ) { m . isArray ( b ) ? b = b . concat ( m . map ( b , m . camelCase ) ) : b in d ? b = [ b ] : ( b = m . camelCase ( b ) , b = b in d ? [ b ] : b . split ( " " ) ) , e = b . length ; while ( e -- ) delete d [ b [ e ] ] ; if ( c ? ! P ( d ) : ! m . isEmptyObject ( d ) ) return } ( c || ( delete g [ h ] . data , P ( g [ h ] ) ) ) && ( f ? m . cleanData ( [ a ] , ! 0 ) : k . deleteExpando || g != g . window ? delete g [ h ] : g [ h ] = null ) } } } m . extend ( { cache : { } , noData : { "applet " : ! 0 , "embed " : ! 0 , "object " : "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" } , hasData : function ( a ) { return a = a . nodeType ? m . cache [ a [ m . expando ] ] : a [ m . expando ] , ! ! a && ! P ( a ) } , data : function ( a , b , c ) { return Q ( a , b , c ) } , removeData : function ( a , b ) { return R ( a , b ) } , _data : function ( a , b , c ) { return Q ( a , b , c , ! 0 ) } , _removeData : function ( a , b ) { return R ( a , b , ! 0 ) } } ) , m . fn . extend ( { data : function ( a , b ) { var c , d , e , f = this [ 0 ] , g = f && f . attributes ; if ( void 0 === a ) { if ( this . length && ( e = m . data ( f ) , 1 === f . nodeType && ! m . _data ( f , "parsedAttrs" ) ) ) { c = g . length ; while ( c -- ) g [ c ] && ( d = g [ c ] . name , 0 === d . indexOf ( "data-" ) && ( d = m . camelCase ( d . slice ( 5 ) ) , O ( f , d , e [ d ] ) ) ) ; m . _data ( f , "parsedAttrs" , ! 0 ) } return e } return "object" == typeof a ? this . each ( function ( ) { m . data ( this , a ) } ) : arguments . length > 1 ? this . each ( function ( ) { m . data ( this , a , b ) } ) : f ? O ( f , a , m . data ( f , a ) ) : void 0 } , removeData : function ( a ) { return this . each ( function ( ) { m . removeData ( this , a ) } ) } } ) , m . extend ( { queue : function ( a , b , c ) { var d ; return a ? ( b = ( b || "fx" ) + "queue" , d = m . _data ( a , b ) , c && ( ! d || m . isArray ( c ) ? d = m . _data ( a , b , m . makeArray ( c ) ) : d . push ( c ) ) , d || [ ] ) : void 0 } , dequeue : function ( a , b ) { b = b || "fx" ; var c = m . queue ( a , b ) , d = c . length , e = c . shift ( ) , f = m . _queueHooks ( a , b ) , g = function ( ) { m . dequeue ( a , b ) } ; "inprogress" === e && ( e = c . shift ( ) , d -- ) , e && ( "fx" === b && c . unshift ( "inprogress" ) , delete f . stop , e . call ( a , g , f ) ) , ! d && f && f . empty . fire ( ) } , _queueHooks : function ( a , b ) { var c = b + "queueHooks" ; return m . _data ( a , c ) || m . _data ( a , c , { empty : m . Callbacks ( "once memory" ) . add ( function ( ) { m . _removeData ( a , b + "queue" ) , m . _removeData ( a , c ) } ) } ) } } ) , m . fn . extend ( { queue : function ( a , b ) { var c = 2 ; return "string" != typeof a && ( b = a , a = "fx" , c -- ) , arguments . length < c ? m . queue ( this [ 0 ] , a ) : void 0 === b ? this : this . each ( function ( ) { var c = m . queue ( this , a , b ) ; m . _queueHooks ( this , a ) , "fx" === a && "inprogress" !== c [ 0 ] && m . dequeue ( this , a ) } ) } , dequeue : function ( a ) { return this . each ( function ( ) { m . dequeue ( this , a ) } ) } , clearQueue : function ( a ) { return this . queue ( a || "fx" , [ ] ) } , promise : function ( a , b ) { var c , d = 1 , e = m . Deferred ( ) , f = this , g = this . length , h = function ( ) { -- d || e . resolveWith ( f , [ f ] ) } ; "string" != typeof a && ( b = a , a = void 0 ) , a = a || "fx" ; while ( g -- ) c = m . _data ( f [ g ] , a + "queueHooks" ) , c && c . empty && ( d ++ , c . empty . add ( h ) ) ; return h ( ) , e . promise ( b ) } } ) ; var S = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ . source , T = [ "Top" , "Right" , "Bottom" , "Left" ] , U = function ( a , b ) { return a = b || a , "none" === m . css ( a , "display" ) || ! m . contains ( a . ownerDocument , a ) } , V = m . access = function ( a , b , c , d , e , f , g ) { var h = 0 , i = a . length , j = null == c ; if ( "object" === m . type ( c ) ) { e = ! 0 ; for ( h in c ) m . access ( a , b , h , c [ h ] , ! 0 , f , g ) } else if ( void 0 !== d && ( e = ! 0 , m . isFunction ( d ) || ( g = ! 0 ) , j && ( g ? ( b . call ( a , d ) , b = null ) : ( j = b , b = function ( a , b , c ) { return j . call ( m ( a ) , c ) } ) ) , b ) ) for ( ; i > h ; h ++ ) b ( a [ h ] , c , g ? d : d . call ( a [ h ] , h , b ( a [ h ] , c ) ) ) ; return e ? a : j ? b . call ( a ) : i ? b ( a [ 0 ] , c ) : f } , W = /^(?:checkbox|radio)$/i ; ! function ( ) { var a = y . createElement ( "input" ) , b = y . createElement ( "div" ) , c = y . createDocumentFragment ( ) ; if ( b . innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>" , k . leadingWhitespace = 3 === b . firstChild . nodeType , k . tbody = ! b . getElementsByTagName ( "tbody" ) . length , k . htmlSerialize = ! ! b . getElementsByTagName ( "link" ) . length , k . html5Clone = "<:nav></:nav>" !== y . createElement ( "nav" ) . cloneNode ( ! 0 ) . outerHTML , a . type = "checkbox" , a . checked = ! 0 , c . appendChild ( a ) , k . appendChecked = a . checked , b . innerHTML = " < textarea > x < / t e x
return new Za . prototype . init ( a , b , c , d , e ) } m . Tween = Za , Za . prototype = { constructor : Za , init : function ( a , b , c , d , e , f ) { this . elem = a , this . prop = c , this . easing = e || "swing" , this . options = b , this . start = this . now = this . cur ( ) , this . end = d , this . unit = f || ( m . cssNumber [ c ] ? "" : "px" ) } , cur : function ( ) { var a = Za . propHooks [ this . prop ] ; return a && a . get ? a . get ( this ) : Za . propHooks . _default . get ( this ) } , run : function ( a ) { var b , c = Za . propHooks [ this . prop ] ; return this . options . duration ? this . pos = b = m . easing [ this . easing ] ( a , this . options . duration * a , 0 , 1 , this . options . duration ) : this . pos = b = a , this . now = ( this . end - this . start ) * b + this . start , this . options . step && this . options . step . call ( this . elem , this . now , this ) , c && c . set ? c . set ( this ) : Za . propHooks . _default . set ( this ) , this } } , Za . prototype . init . prototype = Za . prototype , Za . propHooks = { _default : { get : function ( a ) { var b ; return null == a . elem [ a . prop ] || a . elem . style && null != a . elem . style [ a . prop ] ? ( b = m . css ( a . elem , a . prop , "" ) , b && "auto" !== b ? b : 0 ) : a . elem [ a . prop ] } , set : function ( a ) { m . fx . step [ a . prop ] ? m . fx . step [ a . prop ] ( a ) : a . elem . style && ( null != a . elem . style [ m . cssProps [ a . prop ] ] || m . cssHooks [ a . prop ] ) ? m . style ( a . elem , a . prop , a . now + a . unit ) : a . elem [ a . prop ] = a . now } } } , Za . propHooks . scrollTop = Za . propHooks . scrollLeft = { set : function ( a ) { a . elem . nodeType && a . elem . parentNode && ( a . elem [ a . prop ] = a . now ) } } , m . easing = { linear : function ( a ) { return a } , swing : function ( a ) { return . 5 - Math . cos ( a * Math . PI ) / 2 } } , m . fx = Za . prototype . init , m . fx . step = { } ; var $a , _a , ab = /^(?:toggle|show|hide)$/ , bb = new RegExp ( "^(?:([+-])=|)(" + S + ")([a-z%]*)$" , "i" ) , cb = /queueHooks$/ , db = [ ib ] , eb = { "*" : [ function ( a , b ) { var c = this . createTween ( a , b ) , d = c . cur ( ) , e = bb . exec ( b ) , f = e && e [ 3 ] || ( m . cssNumber [ a ] ? "" : "px" ) , g = ( m . cssNumber [ a ] || "px" !== f && + d ) && bb . exec ( m . css ( c . elem , a ) ) , h = 1 , i = 20 ; if ( g && g [ 3 ] !== f ) { f = f || g [ 3 ] , e = e || [ ] , g = + d || 1 ; do h = h || ".5" , g /= h , m . style ( c . elem , a , g + f ) ; while ( h !== ( h = c . cur ( ) / d ) && 1 !== h && -- i ) } return e && ( g = c . start = + g || + d || 0 , c . unit = f , c . end = e [ 1 ] ? g + ( e [ 1 ] + 1 ) * e [ 2 ] : + e [ 2 ] ) , c } ] } ; function fb ( ) { return setTimeout ( function ( ) { $a = void 0 } ) , $a = m . now ( ) } function gb ( a , b ) { var c , d = { height : a } , e = 0 ; for ( b = b ? 1 : 0 ; 4 > e ; e += 2 - b ) c = T [ e ] , d [ "margin" + c ] = d [ "padding" + c ] = a ; return b && ( d . opacity = d . width = a ) , d } function hb ( a , b , c ) { for ( var d , e = ( eb [ b ] || [ ] ) . concat ( eb [ "*" ] ) , f = 0 , g = e . length ; g > f ; f ++ ) if ( d = e [ f ] . call ( c , b , a ) ) return d } function ib ( a , b , c ) { var d , e , f , g , h , i , j , l , n = this , o = { } , p = a . style , q = a . nodeType && U ( a ) , r = m . _data ( a , "fxshow" ) ; c . queue || ( h = m . _queueHooks ( a , "fx" ) , null == h . unqueued && ( h . unqueued = 0 , i = h . empty . fire , h . empty . fire = function ( ) { h . unqueued || i ( ) } ) , h . unqueued ++ , n . always ( function ( ) { n . always ( function ( ) { h . unqueued -- , m . queue ( a , "fx" ) . length || h . empty . fire ( ) } ) } ) ) , 1 === a . nodeType && ( "height" in b || "width" in b ) && ( c . overflow = [ p . overflow , p . overflowX , p . overflowY ] , j = m . css ( a , "display" ) , l = "none" === j ? m . _data ( a , "olddisplay" ) || Fa ( a . nodeName ) : j , "inline" === l && "none" === m . css ( a , "float" ) && ( k . inlineBlockNeedsLayout && "inline" !== Fa ( a . nodeName ) ? p . zoom = 1 : p . display = "inline-block" ) ) , c . overflow && ( p . overflow = "hidden" , k . shrinkWrapBlocks ( ) || n . always ( function ( ) { p . overflow = c . overflow [ 0 ] , p . overflowX = c . overflow [ 1 ] , p . overflowY = c . overflow [ 2 ] } ) ) ; for ( d in b ) if ( e = b [ d ] , ab . exec ( e ) ) { if ( delete b [ d ] , f = f || "toggle" === e , e === ( q ? "hide" : "show" ) ) { if ( "show" !== e || ! r || void 0 === r [ d ] ) continue ; q = ! 0 } o [ d ] = r && r [ d ] || m . style ( a , d ) } else j = void 0 ; if ( m . isEmptyObject ( o ) ) "inline" === ( "none" === j ? Fa ( a . nodeName ) : j ) && ( p . display = j ) ; else { r ? "hidden" in r && ( q = r . hidden ) : r = m . _data ( a , "fxshow" , { } ) , f && ( r . hidden = ! q ) , q ? m ( a ) . show ( ) : n . done ( function ( ) { m ( a ) . hide ( ) } ) , n . done ( function ( ) { var b ; m . _removeData ( a , "fxshow" ) ; for ( b in o ) m . style ( a , b , o [ b ] ) } ) ; for ( d in o ) g = hb ( q ? r [ d ] : 0 , d , n ) , d in r || ( r [ d ] = g . start , q && ( g . end = g . start , g . start = "width" === d || "height" === d ? 1 : 0 ) ) } } function jb ( a , b ) { var c , d , e , f , g ; for ( c in a ) if ( d = m . camelCase ( c ) , e = b [ d ] , f = a [ c ] , m . isArray ( f ) && ( e = f [ 1 ] , f = a [ c ] = f [ 0 ] ) , c !== d && ( a [ d ] = f , delete a [ c ] ) , g = m . cssHooks [ d ] , g && "expand" in g ) { f = g . expand ( f ) , delete a [ d ] ; for ( c in f ) c in a || ( a [ c ] = f [ c ] , b [ c ] = e ) } else b [ d ] = e } function kb ( a , b , c ) { var d , e , f = 0 , g = db . length , h = m . Deferred ( ) . always ( function ( ) { delete i . elem } ) , i = function ( ) { if ( e ) return ! 1 ; for ( var b = $a || fb ( ) , c = Math . max ( 0 , j . startTime + j . duration - b ) , d = c / j . duration || 0 , f = 1 - d , g = 0 , i = j . tweens . length ; i > g ; g ++ ) j . tweens [ g ] . run ( f ) ; return h . notifyWith ( a , [ j , f , c ] ) , 1 > f && i ? c : ( h . resolveWith ( a , [ j ] ) , ! 1 ) } , j = h
/ * J a v a s c r i p t p l o t t i n g l i b r a r y f o r j Q u e r y , v e r s i o n 0 . 8 . 3 .
Copyright ( c ) 2007 - 2014 IOLA and Ole Laursen .
Licensed under the MIT license .
* /
( function ( $ ) { $ . color = { } ; $ . color . make = function ( r , g , b , a ) { var o = { } ; o . r = r || 0 ; o . g = g || 0 ; o . b = b || 0 ; o . a = a != null ? a : 1 ; o . add = function ( c , d ) { for ( var i = 0 ; i < c . length ; ++ i ) o [ c . charAt ( i ) ] += d ; return o . normalize ( ) } ; o . scale = function ( c , f ) { for ( var i = 0 ; i < c . length ; ++ i ) o [ c . charAt ( i ) ] *= f ; return o . normalize ( ) } ; o . toString = function ( ) { if ( o . a >= 1 ) { return "rgb(" + [ o . r , o . g , o . b ] . join ( "," ) + ")" } else { return "rgba(" + [ o . r , o . g , o . b , o . a ] . join ( "," ) + ")" } } ; o . normalize = function ( ) { function clamp ( min , value , max ) { return value < min ? min : value > max ? max : value } o . r = clamp ( 0 , parseInt ( o . r ) , 255 ) ; o . g = clamp ( 0 , parseInt ( o . g ) , 255 ) ; o . b = clamp ( 0 , parseInt ( o . b ) , 255 ) ; o . a = clamp ( 0 , o . a , 1 ) ; return o } ; o . clone = function ( ) { return $ . color . make ( o . r , o . b , o . g , o . a ) } ; return o . normalize ( ) } ; $ . color . extract = function ( elem , css ) { var c ; do { c = elem . css ( css ) . toLowerCase ( ) ; if ( c != "" && c != "transparent" ) break ; elem = elem . parent ( ) } while ( elem . length && ! $ . nodeName ( elem . get ( 0 ) , "body" ) ) ; if ( c == "rgba(0, 0, 0, 0)" ) c = "transparent" ; return $ . color . parse ( c ) } ; $ . color . parse = function ( str ) { var res , m = $ . color . make ; if ( res = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/ . exec ( str ) ) return m ( parseInt ( res [ 1 ] , 10 ) , parseInt ( res [ 2 ] , 10 ) , parseInt ( res [ 3 ] , 10 ) ) ; if ( res = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/ . exec ( str ) ) return m ( parseInt ( res [ 1 ] , 10 ) , parseInt ( res [ 2 ] , 10 ) , parseInt ( res [ 3 ] , 10 ) , parseFloat ( res [ 4 ] ) ) ; if ( res = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/ . exec ( str ) ) return m ( parseFloat ( res [ 1 ] ) * 2.55 , parseFloat ( res [ 2 ] ) * 2.55 , parseFloat ( res [ 3 ] ) * 2.55 ) ; if ( res = /rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/ . exec ( str ) ) return m ( parseFloat ( res [ 1 ] ) * 2.55 , parseFloat ( res [ 2 ] ) * 2.55 , parseFloat ( res [ 3 ] ) * 2.55 , parseFloat ( res [ 4 ] ) ) ; if ( res = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/ . exec ( str ) ) return m ( parseInt ( res [ 1 ] , 16 ) , parseInt ( res [ 2 ] , 16 ) , parseInt ( res [ 3 ] , 16 ) ) ; if ( res = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/ . exec ( str ) ) return m ( parseInt ( res [ 1 ] + res [ 1 ] , 16 ) , parseInt ( res [ 2 ] + res [ 2 ] , 16 ) , parseInt ( res [ 3 ] + res [ 3 ] , 16 ) ) ; var name = $ . trim ( str ) . toLowerCase ( ) ; if ( name == "transparent" ) return m ( 255 , 255 , 255 , 0 ) ; else { res = lookupColors [ name ] || [ 0 , 0 , 0 ] ; return m ( res [ 0 ] , res [ 1 ] , res [ 2 ] ) } } ; var lookupColors = { aqua : [ 0 , 255 , 255 ] , azure : [ 240 , 255 , 255 ] , beige : [ 245 , 245 , 220 ] , black : [ 0 , 0 , 0 ] , blue : [ 0 , 0 , 255 ] , brown : [ 165 , 42 , 42 ] , cyan : [ 0 , 255 , 255 ] , darkblue : [ 0 , 0 , 139 ] , darkcyan : [ 0 , 139 , 139 ] , darkgrey : [ 169 , 169 , 169 ] , darkgreen : [ 0 , 100 , 0 ] , darkkhaki : [ 189 , 183 , 107 ] , darkmagenta : [ 139 , 0 , 139 ] , darkolivegreen : [ 85 , 107 , 47 ] , darkorange : [ 255 , 140 , 0 ] , darkorchid : [ 153 , 50 , 204 ] , darkred : [ 139 , 0 , 0 ] , darksalmon : [ 233 , 150 , 122 ] , darkviolet : [ 148 , 0 , 211 ] , fuchsia : [ 255 , 0 , 255 ] , gold : [ 255 , 215 , 0 ] , green : [ 0 , 128 , 0 ] , indigo : [ 75 , 0 , 130 ] , khaki : [ 240 , 230 , 140 ] , lightblue : [ 173 , 216 , 230 ] , lightcyan : [ 224 , 255 , 255 ] , lightgreen : [ 144 , 238 , 144 ] , lightgrey : [ 211 , 211 , 211 ] , lightpink : [ 255 , 182 , 193 ] , lightyellow : [ 255 , 255 , 224 ] , lime : [ 0 , 255 , 0 ] , magenta : [ 255 , 0 , 255 ] , maroon : [ 128 , 0 , 0 ] , navy : [ 0 , 0 , 128 ] , olive : [ 128 , 128 , 0 ] , orange : [ 255 , 165 , 0 ] , pink : [ 255 , 192 , 203 ] , purple : [ 128 , 0 , 128 ] , violet : [ 128 , 0 , 128 ] , red : [ 255 , 0 , 0 ] , silver : [ 192 , 192 , 192 ] , white : [ 255 , 255 , 255 ] , yellow : [ 255 , 255 , 0 ] } } ) ( jQuery ) ; ( function ( $ ) { var hasOwnProperty = Object . prototype . hasOwnProperty ; if ( ! $ . fn . detach ) { $ . fn . detach = function ( ) { return this . each ( function ( ) { if ( this . parentNode ) { this . parentNode . removeChild ( this ) } } ) } } function Canvas ( cls , container ) { var element = container . children ( "." + cls ) [ 0 ] ; if ( element == null ) { element = document . createElement ( "canvas" ) ; element . className = cls ; $ ( element ) . css ( { direction : "ltr" , position : "absolute" , left : 0 , top : 0 } ) . appendTo ( container ) ; if ( ! element . getContext ) { if ( window . G _vmlCanvasManager ) { element = window . G _vmlCanvasManager . initElement ( element ) } else { throw new Error ( "Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode." ) } } } this . element = element ; var context = this . context = element . getContext ( "2d" ) ; var devicePixelRatio = window . devicePixelRatio || 1 , backingStoreRatio = context . webkitBackingStorePixelRatio || context . mozBackingSto
if ( yrange . from == null ) yrange . from = yrange . axis . min ; if ( yrange . to == null ) yrange . to = yrange . axis . max ; if ( xrange . to < xrange . axis . min || xrange . from > xrange . axis . max || yrange . to < yrange . axis . min || yrange . from > yrange . axis . max ) continue ; xrange . from = Math . max ( xrange . from , xrange . axis . min ) ; xrange . to = Math . min ( xrange . to , xrange . axis . max ) ; yrange . from = Math . max ( yrange . from , yrange . axis . min ) ; yrange . to = Math . min ( yrange . to , yrange . axis . max ) ; var xequal = xrange . from === xrange . to , yequal = yrange . from === yrange . to ; if ( xequal && yequal ) { continue } xrange . from = Math . floor ( xrange . axis . p2c ( xrange . from ) ) ; xrange . to = Math . floor ( xrange . axis . p2c ( xrange . to ) ) ; yrange . from = Math . floor ( yrange . axis . p2c ( yrange . from ) ) ; yrange . to = Math . floor ( yrange . axis . p2c ( yrange . to ) ) ; if ( xequal || yequal ) { var lineWidth = m . lineWidth || options . grid . markingsLineWidth , subPixel = lineWidth % 2 ? . 5 : 0 ; ctx . beginPath ( ) ; ctx . strokeStyle = m . color || options . grid . markingsColor ; ctx . lineWidth = lineWidth ; if ( xequal ) { ctx . moveTo ( xrange . to + subPixel , yrange . from ) ; ctx . lineTo ( xrange . to + subPixel , yrange . to ) } else { ctx . moveTo ( xrange . from , yrange . to + subPixel ) ; ctx . lineTo ( xrange . to , yrange . to + subPixel ) } ctx . stroke ( ) } else { ctx . fillStyle = m . color || options . grid . markingsColor ; ctx . fillRect ( xrange . from , yrange . to , xrange . to - xrange . from , yrange . from - yrange . to ) } } } axes = allAxes ( ) ; bw = options . grid . borderWidth ; for ( var j = 0 ; j < axes . length ; ++ j ) { var axis = axes [ j ] , box = axis . box , t = axis . tickLength , x , y , xoff , yoff ; if ( ! axis . show || axis . ticks . length == 0 ) continue ; ctx . lineWidth = 1 ; if ( axis . direction == "x" ) { x = 0 ; if ( t == "full" ) y = axis . position == "top" ? 0 : plotHeight ; else y = box . top - plotOffset . top + ( axis . position == "top" ? box . height : 0 ) } else { y = 0 ; if ( t == "full" ) x = axis . position == "left" ? 0 : plotWidth ; else x = box . left - plotOffset . left + ( axis . position == "left" ? box . width : 0 ) } if ( ! axis . innermost ) { ctx . strokeStyle = axis . options . color ; ctx . beginPath ( ) ; xoff = yoff = 0 ; if ( axis . direction == "x" ) xoff = plotWidth + 1 ; else yoff = plotHeight + 1 ; if ( ctx . lineWidth == 1 ) { if ( axis . direction == "x" ) { y = Math . floor ( y ) + . 5 } else { x = Math . floor ( x ) + . 5 } } ctx . moveTo ( x , y ) ; ctx . lineTo ( x + xoff , y + yoff ) ; ctx . stroke ( ) } ctx . strokeStyle = axis . options . tickColor ; ctx . beginPath ( ) ; for ( i = 0 ; i < axis . ticks . length ; ++ i ) { var v = axis . ticks [ i ] . v ; xoff = yoff = 0 ; if ( isNaN ( v ) || v < axis . min || v > axis . max || t == "full" && ( typeof bw == "object" && bw [ axis . position ] > 0 || bw > 0 ) && ( v == axis . min || v == axis . max ) ) continue ; if ( axis . direction == "x" ) { x = axis . p2c ( v ) ; yoff = t == "full" ? - plotHeight : t ; if ( axis . position == "top" ) yoff = - yoff } else { y = axis . p2c ( v ) ; xoff = t == "full" ? - plotWidth : t ; if ( axis . position == "left" ) xoff = - xoff } if ( ctx . lineWidth == 1 ) { if ( axis . direction == "x" ) x = Math . floor ( x ) + . 5 ; else y = Math . floor ( y ) + . 5 } ctx . moveTo ( x , y ) ; ctx . lineTo ( x + xoff , y + yoff ) } ctx . stroke ( ) } if ( bw ) { bc = options . grid . borderColor ; if ( typeof bw == "object" || typeof bc == "object" ) { if ( typeof bw !== "object" ) { bw = { top : bw , right : bw , bottom : bw , left : bw } } if ( typeof bc !== "object" ) { bc = { top : bc , right : bc , bottom : bc , left : bc } } if ( bw . top > 0 ) { ctx . strokeStyle = bc . top ; ctx . lineWidth = bw . top ; ctx . beginPath ( ) ; ctx . moveTo ( 0 - bw . left , 0 - bw . top / 2 ) ; ctx . lineTo ( plotWidth , 0 - bw . top / 2 ) ; ctx . stroke ( ) } if ( bw . right > 0 ) { ctx . strokeStyle = bc . right ; ctx . lineWidth = bw . right ; ctx . beginPath ( ) ; ctx . moveTo ( plotWidth + bw . right / 2 , 0 - bw . top ) ; ctx . lineTo ( plotWidth + bw . right / 2 , plotHeight ) ; ctx . stroke ( ) } if ( bw . bottom > 0 ) { ctx . strokeStyle = bc . bottom ; ctx . lineWidth = bw . bottom ; ctx . beginPath ( ) ; ctx . moveTo ( plotWidth + bw . right , plotHeight + bw . bottom / 2 ) ; ctx . lineTo ( 0 , plotHeight + bw . bottom / 2 ) ; ctx . stroke ( ) } if ( bw . left > 0 ) { ctx . strokeStyle = bc . left ; ctx . lineWidth = bw . left ; ctx . beginPath ( ) ; ctx . moveTo ( 0 - bw . left / 2 , plotHeight + bw . bottom ) ; ctx . lineTo ( 0 - bw . left / 2 , 0 ) ; ctx . stroke ( ) } } else { ctx . lineWidth = bw ; ctx . strokeStyle = options . grid . borderColor ; ctx . strokeRect ( - bw / 2 , - bw / 2 , plotWidth + bw , plotHeight + bw ) } } ctx . restore ( ) } function drawAxisLabels ( ) { $ . each ( allAxes ( ) , function ( _ , axis ) { var box = axis . box , legacyStyles = axis . direction + "Axis " + axis . direction + axis . n + "Axis" , layer = "flot-" + axis . direction + "-axis flot-" + axis . direction + axis . n + "-axis " + legacyStyles , font = axis . options . font || "flot-tick-label tickLabel" , tick , x , y , halign , valign ; surface . removeText ( layer ) ; if ( ! axis . show || axis . ticks . length == 0 ) return ; for ( var i = 0 ; i < axis . ticks . length ; ++ i ) { tick = axis . ticks [ i ] ; if ( ! tick . label || tick . v < axis . min || tick . v > axis . max ) continue ; if ( axis . directi
/ * P r e t t y h a n d l i n g o f t i m e a x e s .
Copyright ( c ) 2007 - 2014 IOLA and Ole Laursen .
Licensed under the MIT license .
Set axis . mode to "time" to enable . See the section "Time series data" in
API . txt for details .
* /
( function ( $ ) {
var options = {
xaxis : {
timezone : null , // "browser" for local to the client or timezone for timezone-js
timeformat : null , // format string to use
twelveHourClock : false , // 12 or 24 time in time mode
monthNames : null // list of names of months
}
} ;
// round to nearby lower multiple of base
function floorInBase ( n , base ) {
return base * Math . floor ( n / base ) ;
}
// Returns a string with the date d formatted according to fmt.
// A subset of the Open Group's strftime format is supported.
function formatDate ( d , fmt , monthNames , dayNames ) {
if ( typeof d . strftime == "function" ) {
return d . strftime ( fmt ) ;
}
var leftPad = function ( n , pad ) {
n = "" + n ;
pad = "" + ( pad == null ? "0" : pad ) ;
return n . length == 1 ? pad + n : n ;
} ;
var r = [ ] ;
var escape = false ;
var hours = d . getHours ( ) ;
var isAM = hours < 12 ;
if ( monthNames == null ) {
monthNames = [ "Jan" , "Feb" , "Mar" , "Apr" , "May" , "Jun" , "Jul" , "Aug" , "Sep" , "Oct" , "Nov" , "Dec" ] ;
}
if ( dayNames == null ) {
dayNames = [ "Sun" , "Mon" , "Tue" , "Wed" , "Thu" , "Fri" , "Sat" ] ;
}
var hours12 ;
if ( hours > 12 ) {
hours12 = hours - 12 ;
} else if ( hours == 0 ) {
hours12 = 12 ;
} else {
hours12 = hours ;
}
for ( var i = 0 ; i < fmt . length ; ++ i ) {
var c = fmt . charAt ( i ) ;
if ( escape ) {
switch ( c ) {
case 'a' : c = "" + dayNames [ d . getDay ( ) ] ; break ;
case 'b' : c = "" + monthNames [ d . getMonth ( ) ] ; break ;
case 'd' : c = leftPad ( d . getDate ( ) ) ; break ;
case 'e' : c = leftPad ( d . getDate ( ) , " " ) ; break ;
case 'h' : // For back-compat with 0.7; remove in 1.0
case 'H' : c = leftPad ( hours ) ; break ;
case 'I' : c = leftPad ( hours12 ) ; break ;
case 'l' : c = leftPad ( hours12 , " " ) ; break ;
case 'm' : c = leftPad ( d . getMonth ( ) + 1 ) ; break ;
case 'M' : c = leftPad ( d . getMinutes ( ) ) ; break ;
// quarters not in Open Group's strftime specification
case 'q' :
c = "" + ( Math . floor ( d . getMonth ( ) / 3 ) + 1 ) ; break ;
case 'S' : c = leftPad ( d . getSeconds ( ) ) ; break ;
case 'y' : c = leftPad ( d . getFullYear ( ) % 100 ) ; break ;
case 'Y' : c = "" + d . getFullYear ( ) ; break ;
case 'p' : c = ( isAM ) ? ( "" + "am" ) : ( "" + "pm" ) ; break ;
case 'P' : c = ( isAM ) ? ( "" + "AM" ) : ( "" + "PM" ) ; break ;
case 'w' : c = "" + d . getDay ( ) ; break ;
}
r . push ( c ) ;
escape = false ;
} else {
if ( c == "%" ) {
escape = true ;
} else {
r . push ( c ) ;
}
}
}
return r . join ( "" ) ;
}
// To have a consistent view of time-based data independent of which time
// zone the client happens to be in we need a date-like object independent
// of time zones. This is done through a wrapper that only calls the UTC
// versions of the accessor methods.
function makeUtcWrapper ( d ) {
function addProxyMethod ( sourceObj , sourceMethod , targetObj , targetMethod ) {
sourceObj [ sourceMethod ] = function ( ) {
return targetObj [ targetMethod ] . apply ( targetObj , arguments ) ;
} ;
} ;
var utc = {
date : d
} ;
// support strftime, if found
if ( d . strftime != undefined ) {
addProxyMethod ( utc , "strftime" , d , "strftime" ) ;
}
addProxyMethod ( utc , "getTime" , d , "getTime" ) ;
addProxyMethod ( utc , "setTime" , d , "setTime" ) ;
var props = [ "Date" , "Day" , "FullYear" , "Hours" , "Milliseconds" , "Minutes" , "Month" , "Seconds" ] ;
for ( var p = 0 ; p < props . length ; p ++ ) {
addProxyMethod ( utc , "get" + props [ p ] , d , "getUTC" + props [ p ] ) ;
addProxyMethod ( utc , "set" + props [ p ] , d , "setUTC" + props [ p ] ) ;
}
return utc ;
} ;
// select time zone strategy. This returns a date-like object tied to the
// desired timezone
function dateGenerator ( ts , opts ) {
if ( opts . timezone == "browser" ) {
return new Date ( ts ) ;
} else if ( ! opts . timezone || opts . timezone == "utc" ) {
return makeUtcWrapper ( new Date ( ts ) ) ;
} else if ( typeof timezoneJS != "undefined" && typeof timezoneJS . Date != "undefined" ) {
var d = new timezoneJS . Date ( ) ;
// timezone-js is fickle, so be sure to set the time zone before
// setting the time.
d . setTimezone ( opts . timezone ) ;
d . setTime ( ts ) ;
return d ;
} else {
return makeUtcWrapper ( new Date ( ts ) ) ;
}
}
// map of app. size of time units in milliseconds
var timeUnitSize = {
"second" : 1000 ,
"minute" : 60 * 1000 ,
"hour" : 60 * 60 * 1000 ,
"day" : 24 * 60 * 60 * 1000 ,
"month" : 30 * 24 * 60 * 60 * 1000 ,
"quarter" : 3 * 30 * 24 * 60 * 60 * 1000 ,
"year" : 365.2425 * 24 * 60 * 60 * 1000
} ;
// the allowed tick sizes, after 1 year we use
// an integer algorithm
var baseSpec = [
[ 1 , "second" ] , [ 2 , "second" ] , [ 5 , "second" ] , [ 10 , "second" ] ,
[ 30 , "second" ] ,
[ 1 , "minute" ] , [ 2 , "minute" ] , [ 5 , "minute" ] , [ 10 , "minute" ] ,
[ 30 , "minute" ] ,
[ 1 , "hour" ] , [ 2 , "hour" ] , [ 4 , "hour" ] ,
[ 8 , "hour" ] , [ 12 , "hour" ] ,
[ 1 , "day" ] , [ 2 , "day" ] , [ 3 , "day" ] ,
[ 0.25 , "month" ] , [ 0.5 , "month" ] , [ 1 , "month" ] ,
[ 2 , "month" ]
] ;
// we don't know which variant(s) we'll need yet, but generating both is
// cheap
var specMonths = baseSpec . concat ( [ [ 3 , "month" ] , [ 6 , "month" ] ,
[ 1 , "year" ] ] ) ;
var specQuarters = baseSpec . concat ( [ [ 1 , "quarter" ] , [ 2 , "quarter" ] ,
[ 1 , "year" ] ] ) ;
function init ( plot ) {
plot . hooks . processOptions . push ( function ( plot , options ) {
$ . each ( plot . getAxes ( ) , function ( axisName , axis ) {
var opts = axis . options ;
if ( opts . mode == "time" ) {
axis . tickGenerator = function ( axis ) {
var ticks = [ ] ;
var d = dateGenerator ( axis . min , opts ) ;
var minSize = 0 ;
// make quarter use a possibility if quarters are
// mentioned in either of these options
var spec = ( opts . tickSize && opts . tickSize [ 1 ] ===
"quarter" ) ||
( opts . minTickSize && opts . minTickSize [ 1 ] ===
"quarter" ) ? specQuarters : specMonths ;
if ( opts . minTickSize != null ) {
if ( typeof opts . tickSize == "number" ) {
minSize = opts . tickSize ;
} else {
minSize = opts . minTickSize [ 0 ] * timeUnitSize [ opts . minTickSize [ 1 ] ] ;
}
}
for ( var i = 0 ; i < spec . length - 1 ; ++ i ) {
if ( axis . delta < ( spec [ i ] [ 0 ] * timeUnitSize [ spec [ i ] [ 1 ] ]
+ spec [ i + 1 ] [ 0 ] * timeUnitSize [ spec [ i + 1 ] [ 1 ] ] ) / 2
&& spec [ i ] [ 0 ] * timeUnitSize [ spec [ i ] [ 1 ] ] >= minSize ) {
break ;
}
}
var size = spec [ i ] [ 0 ] ;
var unit = spec [ i ] [ 1 ] ;
// special-case the possibility of several years
if ( unit == "year" ) {
// if given a minTickSize in years, just use it,
// ensuring that it's an integer
if ( opts . minTickSize != null && opts . minTickSize [ 1 ] == "year" ) {
size = Math . floor ( opts . minTickSize [ 0 ] ) ;
} else {
var magn = Math . pow ( 10 , Math . floor ( Math . log ( axis . delta / timeUnitSize . year ) / Math . LN10 ) ) ;
var norm = ( axis . delta / timeUnitSize . year ) / magn ;
if ( norm < 1.5 ) {
size = 1 ;
} else if ( norm < 3 ) {
size = 2 ;
} else if ( norm < 7.5 ) {
size = 5 ;
} else {
size = 10 ;
}
size *= magn ;
}
// minimum size for years is 1
if ( size < 1 ) {
size = 1 ;
}
}
axis . tickSize = opts . tickSize || [ size , unit ] ;
var tickSize = axis . tickSize [ 0 ] ;
unit = axis . tickSize [ 1 ] ;
var step = tickSize * timeUnitSize [ unit ] ;
if ( unit == "second" ) {
d . setSeconds ( floorInBase ( d . getSeconds ( ) , tickSize ) ) ;
} else if ( unit == "minute" ) {
d . setMinutes ( floorInBase ( d . getMinutes ( ) , tickSize ) ) ;
} else if ( unit == "hour" ) {
d . setHours ( floorInBase ( d . getHours ( ) , tickSize ) ) ;
} else if ( unit == "month" ) {
d . setMonth ( floorInBase ( d . getMonth ( ) , tickSize ) ) ;
} else if ( unit == "quarter" ) {
d . setMonth ( 3 * floorInBase ( d . getMonth ( ) / 3 ,
tickSize ) ) ;
} else if ( unit == "year" ) {
d . setFullYear ( floorInBase ( d . getFullYear ( ) , tickSize ) ) ;
}
// reset smaller components
d . setMilliseconds ( 0 ) ;
if ( step >= timeUnitSize . minute ) {
d . setSeconds ( 0 ) ;
}
if ( step >= timeUnitSize . hour ) {
d . setMinutes ( 0 ) ;
}
if ( step >= timeUnitSize . day ) {
d . setHours ( 0 ) ;
}
if ( step >= timeUnitSize . day * 4 ) {
d . setDate ( 1 ) ;
}
if ( step >= timeUnitSize . month * 2 ) {
d . setMonth ( floorInBase ( d . getMonth ( ) , 3 ) ) ;
}
if ( step >= timeUnitSize . quarter * 2 ) {
d . setMonth ( floorInBase ( d . getMonth ( ) , 6 ) ) ;
}
if ( step >= timeUnitSize . year ) {
d . setMonth ( 0 ) ;
}
var carry = 0 ;
var v = Number . NaN ;
var prev ;
do {
prev = v ;
v = d . getTime ( ) ;
ticks . push ( v ) ;
if ( unit == "month" || unit == "quarter" ) {
if ( tickSize < 1 ) {
// a bit complicated - we'll divide the
// month/quarter up but we need to take
// care of fractions so we don't end up in
// the middle of a day
d . setDate ( 1 ) ;
var start = d . getTime ( ) ;
d . setMonth ( d . getMonth ( ) +
( unit == "quarter" ? 3 : 1 ) ) ;
var end = d . getTime ( ) ;
d . setTime ( v + carry * timeUnitSize . hour + ( end - start ) * tickSize ) ;
carry = d . getHours ( ) ;
d . setHours ( 0 ) ;
} else {
d . setMonth ( d . getMonth ( ) +
tickSize * ( unit == "quarter" ? 3 : 1 ) ) ;
}
} else if ( unit == "year" ) {
d . setFullYear ( d . getFullYear ( ) + tickSize ) ;
} else {
d . setTime ( v + step ) ;
}
} while ( v < axis . max && v != prev ) ;
return ticks ;
} ;
axis . tickFormatter = function ( v , axis ) {
var d = dateGenerator ( v , axis . options ) ;
// first check global format
if ( opts . timeformat != null ) {
return formatDate ( d , opts . timeformat , opts . monthNames , opts . dayNames ) ;
}
// possibly use quarters if quarters are mentioned in
// any of these places
var useQuarters = ( axis . options . tickSize &&
axis . options . tickSize [ 1 ] == "quarter" ) ||
( axis . options . minTickSize &&
axis . options . minTickSize [ 1 ] == "quarter" ) ;
var t = axis . tickSize [ 0 ] * timeUnitSize [ axis . tickSize [ 1 ] ] ;
var span = axis . max - axis . min ;
var suffix = ( opts . twelveHourClock ) ? " %p" : "" ;
var hourCode = ( opts . twelveHourClock ) ? "%I" : "%H" ;
var fmt ;
if ( t < timeUnitSize . minute ) {
fmt = hourCode + ":%M:%S" + suffix ;
} else if ( t < timeUnitSize . day ) {
if ( span < 2 * timeUnitSize . day ) {
fmt = hourCode + ":%M" + suffix ;
} else {
fmt = "%b %d " + hourCode + ":%M" + suffix ;
}
} else if ( t < timeUnitSize . month ) {
fmt = "%b %d" ;
} else if ( ( useQuarters && t < timeUnitSize . quarter ) ||
( ! useQuarters && t < timeUnitSize . year ) ) {
if ( span < timeUnitSize . year ) {
fmt = "%b" ;
} else {
fmt = "%b %Y" ;
}
} else if ( useQuarters && t < timeUnitSize . year ) {
if ( span < timeUnitSize . year ) {
fmt = "Q%q" ;
} else {
fmt = "Q%q %Y" ;
}
} else {
fmt = "%Y" ;
}
var rt = formatDate ( d , fmt , opts . monthNames , opts . dayNames ) ;
return rt ;
} ;
}
} ) ;
} ) ;
}
$ . plot . plugins . push ( {
init : init ,
options : options ,
name : 'time' ,
version : '1.0'
} ) ;
// Time-axis support used to be in Flot core, which exposed the
// formatDate function on the plot object. Various plugins depend
// on the function, so we need to re-expose it here.
$ . plot . formatDate = formatDate ;
$ . plot . dateGenerator = dateGenerator ;
} ) ( jQuery ) ;
2016-04-19 20:08:54 +08:00
var ws = null ;
var connected = false ;
2016-04-19 03:26:24 +08:00
$ ( document ) . ready ( function ( ) {
var startTime = Date . now ( ) ;
var graphDurationSeconds = 30 ;
// Initialize graph
var createGraph = function ( title ) {
var $c = $ ( '<div class="graph"/>' ) . appendTo ( '#graphs' ) ;
var past = Date . now ( ) - graphDurationSeconds * 1000 ;
var options = {
lines : {
xfill : true ,
lineWidth : 1 ,
xfillColor : { colors : [ { opacity : 0 } , { opacity : 1 } ] }
} ,
grid : { borderWidth : 1 , borderColor : '#ccc' } ,
xaxis : { mode : 'time' , ticks : 5 } ,
legend : { labelBoxBorderColor : '#fff' } ,
xcolors : [ '#fec' , '#396' , '#e39' , '#9e2' ] ,
hooks : {
draw : [ function ( plot , canvas ) {
canvas . font = '15px sans-serif' ;
canvas . fillStyle = '#999' ;
canvas . fillText ( title , 35 , 25 ) ;
} ]
}
} ;
return $ . plot ( $c , [ ] , options ) ;
} ;
var updateGraph = function ( g ) {
2016-04-19 20:08:54 +08:00
if ( ! connected ) return ;
2016-04-19 03:26:24 +08:00
var now = Date . now ( ) ;
//if (now - g.lastUpdateTime < 50) return;
g . lastUpdateTime = now ;
var oldest = now - graphDurationSeconds * 1000 ;
g . data [ 0 ] . data = [ [ oldest , null ] , [ now , null ] ] ;
// Remove old points
$ . each ( g . data , function ( di , d ) {
while ( d . data . length > 0 && d . data [ 0 ] [ 0 ] < oldest ) {
d . data . shift ( ) ;
}
} ) ;
g . plot . setData ( g . data ) ;
g . plot . setupGrid ( ) ;
g . plot . draw ( ) ;
} ;
var graphs = {
led : {
title : 'LED state' ,
plot : null ,
lastUpdateTime : null ,
data : [
{ show : false , data : [ ] } ,
{ label : "LED state" , color : '#36c' , data : [ ] } ,
]
} ,
accel : {
title : 'Accelerometer' ,
plot : null ,
lastUpdateTime : null ,
data : [
{ show : false , data : [ ] } ,
{ label : "x" , color : '#f00' , data : [ ] } ,
{ label : "y" , color : '#0f0' , data : [ ] } ,
{ label : "z" , color : '#00f' , data : [ ] } ,
]
} ,
temp : {
2016-04-19 20:08:54 +08:00
title : 'Sensor die temperature' ,
2016-04-19 03:26:24 +08:00
plot : null ,
lastUpdateTime : null ,
data : [
{ show : false , data : [ ] } ,
{ label : 'Celsius' , color : '#36c' , data : [ ] } ,
]
} ,
} ;
$ . each ( graphs , function ( k , v ) {
v . plot = createGraph ( v . title ) ;
setInterval ( function ( ) { updateGraph ( v ) ; } , 100 ) ;
} ) ;
2016-04-19 20:08:54 +08:00
function wsConnect ( ) {
if ( ws != null ) return ;
var wsAddr = 'ws://' + location . host ;
console . log ( 'Connecting to' , wsAddr ) ;
ws = new WebSocket ( wsAddr ) ;
ws . onopen = function ( ) {
console . log ( 'Connected' ) ;
connected = true ;
} ;
ws . onclose = function ( ) {
console . log ( 'Disconnected' ) ;
connected = false ;
ws = null ;
} ;
ws . onmessage = handleWsMessage ;
}
function handleWsMessage ( ev ) {
2016-04-19 03:26:24 +08:00
try {
var obj = JSON . parse ( ev . data ) ;
//var timestamp = startTime + parseInt(obj.ts * 1000);
var timestamp = Date . now ( ) ;
if ( obj . t == 0 ) {
graphs . temp . data [ 1 ] . data . push ( [ timestamp , obj . dt ] ) ;
updateGraph ( graphs . temp ) ;
} else if ( obj . t == 1 ) {
graphs . led . data [ 1 ] . data . push ( [ timestamp , obj . v ] ) ;
updateGraph ( graphs . led ) ;
} else if ( obj . t == 2 ) {
graphs . accel . data [ 1 ] . data . push ( [ timestamp , obj . x ] ) ;
graphs . accel . data [ 2 ] . data . push ( [ timestamp , obj . y ] ) ;
graphs . accel . data [ 3 ] . data . push ( [ timestamp , obj . z ] ) ;
updateGraph ( graphs . accel ) ;
}
} catch ( e ) {
console . log ( e , ev . data ) ;
} ;
} ;
$ ( document ) . on ( 'click' , '#on_off_button' , function ( ) {
var state = $ ( this ) . text ( ) . match ( /off/ ) ? 0 : 1 ;
$ ( this ) . text ( state ? 'Switch LED off' : 'Switch LED on' ) ;
ws . send ( JSON . stringify ( { t : 1 , v : state } ) ) ;
} ) ;
2016-04-19 20:08:54 +08:00
wsConnect ( ) ;
setInterval ( wsConnect , 1000 ) ;
2016-04-19 03:26:24 +08:00
} ) ;