( function ( $ ) { var options = { axisLabels : { show : true } } ; function canvasSupported ( ) { return ! ! document . createElement ( 'canvas' ) . getContext ; } function canvasTextSupported ( ) { if ( ! canvasSupported ( ) ) { return false ; } var dummy_canvas = document . createElement ( 'canvas' ) ; var context = dummy_canvas . getContext ( '2d' ) ; return typeof context . fillText == 'function' ; } function css3TransitionSupported ( ) { var div = document . createElement ( 'div' ) ; return typeof div . style . MozTransition != 'undefined' || typeof div . style . OTransition != 'undefined' || typeof div . style . webkitTransition != 'undefined' || typeof div . style . transition != 'undefined' ; } function AxisLabel ( axisName , position , padding , plot , opts ) { this . axisName = axisName ; this . position = position ; this . padding = padding ; this . plot = plot ; this . opts = opts ; this . width = 0 ; this . height = 0 ; } AxisLabel . prototype . cleanup = function ( ) { } ; CanvasAxisLabel . prototype = new AxisLabel ( ) ; CanvasAxisLabel . prototype . constructor = CanvasAxisLabel ; function CanvasAxisLabel ( axisName , position , padding , plot , opts ) { AxisLabel . prototype . constructor . call ( this , axisName , position , padding , plot , opts ) ; } CanvasAxisLabel . prototype . calculateSize = function ( ) { if ( ! this . opts . axisLabelFontSizePixels ) this . opts . axisLabelFontSizePixels = 14 ; if ( ! this . opts . axisLabelFontFamily ) this . opts . axisLabelFontFamily = 'sans-serif' ; var textWidth = this . opts . axisLabelFontSizePixels + this . padding ; var textHeight = this . opts . axisLabelFontSizePixels + this . padding ; if ( this . position == 'left' || this . position == 'right' ) { this . width = this . opts . axisLabelFontSizePixels + this . padding ; this . height = 0 ; } else { this . width = 0 ; this . height = this . opts . axisLabelFontSizePixels + this . padding ; } } ; CanvasAxisLabel . prototype . draw = function ( box ) { if ( ! this . opts . axisLabelColour ) this . opts . axisLabelColour = 'black' ; var ctx = this . plot . getCanvas ( ) . getContext ( '2d' ) ; ctx . save ( ) ; ctx . font = this . opts . axisLabelFontSizePixels + 'px ' + this . opts . axisLabelFontFamily ; ctx . fillStyle = this . opts . axisLabelColour ; var width = ctx . measureText ( this . opts . axisLabel ) . width ; var height = this . opts . axisLabelFontSizePixels ; var x , y , angle = 0 ; if ( this . position == 'top' ) { x = box . left + box . width / 2 - width / 2 ; y = box . top + height * 0.72 ; } else if ( this . position == 'bottom' ) { x = box . left + box . width / 2 - width / 2 ; y = box . top + box . height - height * 0.72 ; } else if ( this . position == 'left' ) { x = box . left + height * 0.72 ; y = box . height / 2 + box . top + width / 2 ; angle = - Math . PI / 2 ; } else if ( this . position == 'right' ) { x = box . left + box . width - height * 0.72 ; y = box . height / 2 + box . top - width / 2 ; angle = Math . PI / 2 ; } ctx . translate ( x , y ) ; ctx . rotate ( angle ) ; ctx . fillText ( this . opts . axisLabel , 0 , 0 ) ; ctx . restore ( ) ; } ; HtmlAxisLabel . prototype = new AxisLabel ( ) ; HtmlAxisLabel . prototype . constructor = HtmlAxisLabel ; function HtmlAxisLabel ( axisName , position , padding , plot , opts ) { AxisLabel . prototype . constructor . call ( this , axisName , position , padding , plot , opts ) ; this . elem = null ; } HtmlAxisLabel . prototype . calculateSize = function ( ) { var elem = $ ( '<div class="axisLabels" style="position:absolute;">' + this . opts . axisLabel + '</div>' ) ; this . plot . getPlaceholder ( ) . append ( elem ) ; this . labelWidth = elem . outerWidth ( true ) ; this . labelHeight = elem . outerHeight ( true ) ; elem . remove ( ) ; this . width = this . height = 0 ; if ( this . position == 'left' || this . position == 'right' ) { this . width = this . labelWidth + this . padding ; } else { this . height = this . labelHeight + this . padding ; } } ; HtmlAxisLabel . prototype . cleanup = function ( ) { if ( this . elem ) { this . elem . remove ( ) ; } } ; HtmlAxisLabel . prototype . draw = function ( box ) { this . plot . getPlaceholder ( ) . find ( '#' + this . axisName + 'Label' ) . remove ( ) ; this . elem = $ ( '<div id="' + this . axisName + 'Label" " class="axisLabels" style="position:absolute;">' + this . opts . axisLabel + '</div>' ) ; this . plot . getPlaceholder ( ) . append ( this . elem ) ; if ( this . position == 'top' ) { this . elem . css ( 'left' , box . left + box . width / 2 - this . labelWidth / 2 + 'px' ) ; this . elem . css ( 'top' , box . top + 'px' ) ; } else if ( this . position == 'bottom' ) { this . elem . css ( 'left' , box . left + box . width / 2 - this . labelWidth / 2 + 'px' ) ; this . elem . css ( 'top' , box . top + box . height - this . labelHeight + 'px' ) ; } else if ( this . position == 'left' ) { this . elem . css ( 'top' , box . top + box . height / 2 - this . labelHeight / 2 + 'px' ) ; this . elem . css ( 'left' , box . left + 'px' ) ; } else if ( this . position == 'right' ) { this . elem . css ( 'top' , box . top + box . height / 2 - this . labelHeight / 2 + 'px' ) ; this . elem . css ( 'left' , box . left + box . width - this . labelWidth + 'px' ) ; } } ; CssTransformAxisLabel . prototype = new HtmlAxisLabel ( ) ; CssTransformAxisLabel . prototype . constructor = CssTransformAxisLabel ; function CssTransformAxisLabel ( axisName , position , padding , plot , opts ) { HtmlAxisLabel . prototype . constructor . call ( this , axisName , position , padding , plot , opts ) ; } CssTransformAxisLabel . prototype . calculateSize = function ( ) { HtmlAxisLabel . prototype . calculateSize . call ( this ) ; this . width = this . height = 0 ; if ( this . position == 'left' || this . position == 'right' ) { this . width = this . labelHeight + this . padding ; } else { this . height = this . labelHeight + this . padding ; } } ; CssTransformAxisLabel . prototype . transforms = function ( degrees , x , y ) { var stransforms = { '-moz-transform' : '' , '-webkit-transform' : '' , '-o-transform' : '' , '-ms-transform' : '' } ; if ( x != 0 || y != 0 ) { var stdTranslate = ' translate(' + x + 'px, ' + y + 'px)' ; stransforms [ '-moz-transform' ] += stdTranslate ; stransforms [ '-webkit-transform' ] += stdTranslate ; stransforms [ '-o-transform' ] += stdTranslate ; stransforms [ '-ms-transform' ] += stdTranslate ; } if ( degrees != 0 ) { var rotation = degrees / 90 ; var stdRotate = ' rotate(' + degrees + 'deg)' ; stransforms [ '-moz-transform' ] += stdRotate ; stransforms [ '-webkit-transform' ] += stdRotate ; stransforms [ '-o-transform' ] += stdRotate ; stransforms [ '-ms-transform' ] += stdRotate ; } var s = 'top: 0; left: 0; ' ; for ( var prop in stransforms ) { if ( stransforms [ prop ] ) { s += prop + ':' + stransforms [ prop ] + ';' ; } } s += ';' ; return s ; } ; CssTransformAxisLabel . prototype . calculateOffsets = function ( box ) { var offsets = { x : 0 , y : 0 , degrees : 0 } ; if ( this . position == 'bottom' ) { offsets . x = box . left + box . width / 2 - this . labelWidth / 2 ; offsets . y = box . top + box . height - this . labelHeight ; } else if ( this . position == 'top' ) { offsets . x = box . left + box . width / 2 - this . labelWidth / 2 ; offsets . y = box . top ; } else if ( this . position == 'left' ) { offsets . degrees = - 90 ; offsets . x = box . left - this . labelWidth / 2 + this . labelHeight / 2 ; offsets . y = box . height / 2 + box . top ; } else if ( this . position == 'right' ) { offsets . degrees = 90 ; offsets . x = box . left + box . width - this . labelWidth / 2 - this . labelHeight / 2 ; offsets . y = box . height / 2 + box . top ; } offsets . x = Math . round ( offsets . x ) ; offsets . y = Math . round ( offsets . y ) ; return offsets ; } ; CssTransformAxisLabel . prototype . draw = function ( box ) { this . plot . getPlaceholder ( ) . find ( "." + this . axisName + "Label" ) . remove ( ) ; var offsets = this . calculateOffsets ( box ) ; this . elem = $ ( '<div class="axisLabels ' + this . axisName + 'Label" style="position:absolute; ' + this . transforms ( offsets . degrees , offsets . x , offsets . y ) + '">' + this . opts . axisLabel + '</div>' ) ; this . plot . getPlaceholder ( ) . append ( this . elem ) ; } ; IeTransformAxisLabel . prototype = new CssTransformAxisLabel ( ) ; IeTransformAxisLabel . prototype . constructor = IeTransformAxisLabel ; function IeTransformAxisLabel ( axisName , position , padding , plot , opts ) { CssTransformAxisLabel . prototype . constructor . call ( this , axisName , position , padding , plot , opts ) ; this . requiresResize = false ; } IeTransformAxisLabel . prototype . transforms = function ( degrees , x , y ) { var s = '' ; if ( degrees != 0 ) { var rotation = degrees / 90 ; while ( rotation < 0 ) { rotation += 4 ; } s += ' filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=' + rotation + '); ' ; this . requiresResize = ( this . position == 'right' ) ; } if ( x != 0 ) { s += 'left: ' + x + 'px; ' ; } if ( y != 0 ) { s += 'top: ' + y + 'px; ' ; } return s ; } ; IeTransformAxisLabel . prototype . calculateOffsets = function ( box ) { var offsets = CssTransformAxisLabel . prototype . calculateOffsets . call ( this , box ) ; if ( this . position == 'top' ) { offsets . y = box . top + 1 ; } else if ( this . position == 'left' ) { offsets . x = box . left ; offsets . y = box . height / 2 + box . top - this . labelWidth / 2 ; } else if ( this . position == 'right' ) { offsets . x = box . left + box . width - this . labelHeight ; offsets . y = box . height / 2 + box . top - this . labelWidth / 2 ; } return offsets ; } ; IeTransformAxisLabel . prototype . draw = function ( box ) { CssTransformAxisLabel . prototype . draw . call ( this , box ) ; if ( this . requiresResize ) { this . elem = this . plot . getPlaceholder ( ) . find ( "." + this . axisName + "Label" ) ; this . elem . css ( 'width' , this . labelWidth ) ; this . elem . css ( 'height' , this . labelHeight ) ; } } ; function init ( plot ) { plot . hooks . processOptions . push ( function ( plot , options ) { if ( ! options . axisLabels . show ) return ; var secondPass = false ; var axisLabels = { } ; var axisOffsetCounts = { left : 0 , right : 0 , top : 0 , bottom : 0 } ; var defaultPadding = 2 ; plot . hooks . draw . push ( function ( plot , ctx ) { var hasAxisLabels = false ; if ( ! secondPass ) { $ . each ( plot . getAxes ( ) , function ( axisName , axis ) { var opts = axis . options || plot . getOptions ( ) [ axisName ] ; if ( axisName in axisLabels ) { axis . labelHeight = axis . labelHeight - axisLabels [ axisName ] . height ; axis . labelWidth = axis . labelWidth - axisLabels [ axisName ] . width ; opts . labelHeight = axis . labelHeight ; opts . labelWidth = axis . labelWidth ; axisLabels [ axisName ] . cleanup ( ) ; delete axisLabels [ axisName ] ; } if ( ! opts || ! opts . axisLabel || ! axis . show ) return ; hasAxisLabels = true ; var renderer = null ; if ( ! opts . axisLabelUseHtml && navigator . appName == 'Microsoft Internet Explorer' ) { var ua = navigator . userAgent ; var re = new RegExp ( "MSIE ([0-9]{1,}[\.0-9]{0,})" ) ; if ( re . exec ( ua ) != null ) { rv = parseFloat ( RegExp . $1 ) ; } if ( rv >= 9 && ! opts . axisLabelUseCanvas && ! opts . axisLabelUseHtml ) { renderer = CssTransformAxisLabel ; } else if ( ! opts . axisLabelUseCanvas && ! opts . axisLabelUseHtml ) { renderer = IeTransformAxisLabel ; } else if ( opts . axisLabelUseCanvas ) { renderer = CanvasAxisLabel ; } else { renderer = HtmlAxisLabel ; } } else { if ( opts . axisLabelUseHtml || ( ! css3TransitionSupported ( ) && ! canvasTextSupported ( ) ) && ! opts . axisLabelUseCanvas ) { renderer = HtmlAxisLabel ; } else if ( opts . axisLabelUseCanvas || ! css3TransitionSupported ( ) ) { renderer = CanvasAxisLabel ; } else { renderer = CssTransformAxisLabel ; } } var padding = opts . axisLabelPadding === undefined ? defaultPadding : opts . axisLabelPadding ; axisLabels [ axisName ] = new renderer ( axisName , axis . position , padding , plot , opts ) ; axisLabels [ axisName ] . calculateSize ( ) ; opts . labelHeight = axis . labelHeight + axisLabels [ axisName ] . height ; opts . labelWidth = axis . labelWidth + axisLabels [ axisName ] . width ; } ) ; if ( hasAxisLabels ) { secondPass = true ; plot . setupGrid ( ) ; plot . draw ( ) ; } } else { secondPass = false ; $ . each ( plot . getAxes ( ) , function ( axisName , axis ) { var opts = axis . options || plot . getOptions ( ) [ axisName ] ; if ( ! opts || ! opts . axisLabel || ! axis . show ) return ; axisLabels [ axisName ] . draw ( axis . box ) ; } ) ; } } ) ; } ) ; } $ . plot . plugins . push ( { init : init , options : options , name : 'axisLabels' , version : '2.0' } ) ; } ) ( jQuery ) ;