r22790 - gnucash/trunk/src/report - Update to jqplot 1.0.6
Geert Janssens
gjanssens at code.gnucash.org
Wed Feb 20 13:50:44 EST 2013
Author: gjanssens
Date: 2013-02-20 13:50:43 -0500 (Wed, 20 Feb 2013)
New Revision: 22790
Trac: http://svn.gnucash.org/trac/changeset/22790
Added:
gnucash/trunk/src/report/jqplot/MIT-LICENSE.txt
gnucash/trunk/src/report/jqplot/README.txt
gnucash/trunk/src/report/jqplot/changes.txt
gnucash/trunk/src/report/jqplot/copyright.txt
gnucash/trunk/src/report/jqplot/excanvas.js
gnucash/trunk/src/report/jqplot/excanvas.min.js
gnucash/trunk/src/report/jqplot/jqPlotCssStyling.txt
gnucash/trunk/src/report/jqplot/jqPlotOptions.txt
gnucash/trunk/src/report/jqplot/jquery.jqplot.min.css
gnucash/trunk/src/report/jqplot/jquery.jqplot.min.js
gnucash/trunk/src/report/jqplot/jquery.js
gnucash/trunk/src/report/jqplot/jquery.min.js
gnucash/trunk/src/report/jqplot/optionsTutorial.txt
gnucash/trunk/src/report/jqplot/plugins/jqplot.BezierCurveRenderer.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.barRenderer.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.blockRenderer.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.bubbleRenderer.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasAxisLabelRenderer.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasAxisTickRenderer.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasOverlay.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasOverlay.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasTextRenderer.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.categoryAxisRenderer.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.ciParser.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.cursor.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.dateAxisRenderer.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.donutRenderer.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.dragable.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.enhancedLegendRenderer.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.funnelRenderer.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.highlighter.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.json2.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.logAxisRenderer.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.mekkoAxisRenderer.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.mekkoRenderer.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.meterGaugeRenderer.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.mobile.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.mobile.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.ohlcRenderer.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.pieRenderer.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.pointLabels.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.pyramidAxisRenderer.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.pyramidAxisRenderer.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.pyramidGridRenderer.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.pyramidGridRenderer.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.pyramidRenderer.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.pyramidRenderer.min.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.trendline.min.js
gnucash/trunk/src/report/jqplot/usage.txt
Modified:
gnucash/trunk/src/report/jqplot/Makefile.am
gnucash/trunk/src/report/jqplot/jquery.jqplot.css
gnucash/trunk/src/report/jqplot/jquery.jqplot.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.BezierCurveRenderer.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.barRenderer.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.blockRenderer.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.bubbleRenderer.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasAxisLabelRenderer.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasAxisTickRenderer.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasTextRenderer.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.categoryAxisRenderer.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.ciParser.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.cursor.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.dateAxisRenderer.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.donutRenderer.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.dragable.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.enhancedLegendRenderer.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.funnelRenderer.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.highlighter.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.logAxisRenderer.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.mekkoAxisRenderer.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.mekkoRenderer.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.meterGaugeRenderer.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.ohlcRenderer.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.pieRenderer.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.pointLabels.js
gnucash/trunk/src/report/jqplot/plugins/jqplot.trendline.js
gnucash/trunk/src/report/report-system/html-barchart.scm
gnucash/trunk/src/report/report-system/html-piechart.scm
gnucash/trunk/src/report/report-system/html-scatter.scm
Log:
Update to jqplot 1.0.6
Added: gnucash/trunk/src/report/jqplot/MIT-LICENSE.txt
===================================================================
--- gnucash/trunk/src/report/jqplot/MIT-LICENSE.txt (rev 0)
+++ gnucash/trunk/src/report/jqplot/MIT-LICENSE.txt 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,21 @@
+Title: MIT License
+
+Copyright (c) 2009-2013 Chris Leonello
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
Modified: gnucash/trunk/src/report/jqplot/Makefile.am
===================================================================
--- gnucash/trunk/src/report/jqplot/Makefile.am 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/Makefile.am 2013-02-20 18:50:43 UTC (rev 22790)
@@ -2,7 +2,7 @@
gncjqplotdir = ${GNC_SHAREDIR}/jqplot/
gncjqplot_DATA = \
- jquery-1.4.2.min.js \
+ jquery.min.js \
jquery.jqplot.js \
jquery.jqplot.css \
plugins/jqplot.barRenderer.js \
Added: gnucash/trunk/src/report/jqplot/README.txt
===================================================================
--- gnucash/trunk/src/report/jqplot/README.txt (rev 0)
+++ gnucash/trunk/src/report/jqplot/README.txt 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,77 @@
+Title: jqPlot Readme
+
+Pure JavaScript plotting plugin for jQuery.
+
+To learn how to use jqPlot, start with the Basic Usage Instructions below. Then read the
+usage.txt and jqPlotOptions.txt files included with the distribution.
+
+The jqPlot home page is at <http://www.jqplot.com/>.
+
+Downloads can be found at <http://bitbucket.org/cleonello/jqplot/downloads/>.
+
+The mailing list is at <http://groups.google.com/group/jqplot-users>.
+
+Examples and unit tests are at <http://www.jqplot.com/tests/>.
+
+Documentation is at <http://www.jqplot.com/docs/>.
+
+The project page and source code are at <http://www.bitbucket.org/cleonello/jqplot/>.
+
+Bugs, issues, feature requests: <http://www.bitbucket.org/cleonello/jqplot/issues/>.
+
+Basic Usage Instructions:
+
+jqPlot requires jQuery (1.4+ required for certain features). jQuery 1.9.1 is included in
+the distribution. To use jqPlot include jQuery, the jqPlot jQuery plugin, the jqPlot css file and
+optionally the excanvas script to support IE version prior to IE 9 in your web page:
+
+> <!--[if lt IE 9]><script language="javascript" type="text/javascript" src="excanvas.js"></script><![endif]-->
+> <script language="javascript" type="text/javascript" src="jquery-1.4.4.min.js"></script>
+> <script language="javascript" type="text/javascript" src="jquery.jqplot.min.js"></script>
+> <link rel="stylesheet" type="text/css" href="jquery.jqplot.css" />
+
+For usage instructions, see <jqPlot Usage> in usage.txt. For available options, see
+<jqPlot Options> in jqPlotOptions.txt.
+
+Building from source:
+
+If you've cloned the repository, you can build a distribution from source.
+You need to have ant <http://ant.apache.org> installed. You can simply
+type "ant" from the jqplot directory to build the default "all" target.
+There are 6 pertinent targets: clean, dist, min, docs, compress and all. Use:
+
+> ant -p
+
+to get a description of the various build targets.
+
+Legal Notices:
+
+Copyright (c) 2009-2013 Chris Leonello
+jqPlot is currently available for use in all personal or commercial projects
+under both the MIT and GPL version 2.0 licenses. This means that you can
+choose the license that best suits your project and use it accordingly.
+
+Although not required, the author would appreciate an email letting him
+know of any substantial use of jqPlot. You can reach the author at:
+chris at jqplot or see http://www.jqplot.com/info.php .
+
+If you are feeling kind and generous, consider supporting the project by
+making a donation at: http://www.jqplot.com/donate.php .
+
+jqPlot includes date instance methods and printf/sprintf functions by other authors:
+
+Date instance methods:
+
+ author Ken Snyder (ken d snyder at gmail dot com)
+ date 2008-09-10
+ version 2.0.2 (http://kendsnyder.com/sandbox/date/)
+ license Creative Commons Attribution License 3.0 (http://creativecommons.org/licenses/by/3.0/)
+
+JavaScript printf/sprintf functions.
+
+ version 2007.04.27
+ author Ash Searle
+ http://hexmen.com/blog/2007/03/printf-sprintf/
+ http://hexmen.com/js/sprintf.js
+ The author (Ash Searle) has placed this code in the public domain:
+ "This code is unrestricted: you are free to use it however you like."
Added: gnucash/trunk/src/report/jqplot/changes.txt
===================================================================
--- gnucash/trunk/src/report/jqplot/changes.txt (rev 0)
+++ gnucash/trunk/src/report/jqplot/changes.txt 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,410 @@
+Title: Change Log
+
+1.0.6:
+* Add left sidebar navigation to examples
+* Update examples for jquery 1.9.1 and jquery ui 1.10.0
+* Add colorpicker.js to distribution
+* Fix some problems with examples when viewing with local file system
+* Add "minified" copyright notice for minified files, similar to jquery's notice.
+* Pull Request #25: jqplot.sprintf.js is no longer the last file in the concatenated jquery.jqplot.js
+* Pull Request #17: Fixed bug causing custom pointLabels passed with plot data to be ignored for horizontal bar graphs.
+* Pull Request #10: Build error by invalid encoding.
+* Issue #714: handle tickColor in meterGaugeRenderer
+* Issue #519: jsDate Polish Localization
+
+1.0.5:
+* Updated to jQuery 1.9
+
+1.0.0b2:
+* Major improvements in memory usage:
+** Merged in changes from Timo Besenruether to reuse canvas elements and improve
+ memory performance.
+** Fixed all identifiable DOM leaks.
+** Mergged in changes from cguillot for memory improvements in IE < 9.
+* Added vertical and dashed vertical line support for canvas overlay.
+* Fixed bug where initially hidden plots would not display.
+* Fixed bug with point labels and null data points.
+* Updated to jQuery 1.6.1.
+* Improved pie slice margin calculation and fixed slice margin and pie positioning
+ with small slices.
+* Improved bar renderer so bars always start at 0 if:
+** The axis is a linear axis (not log/date).
+** There are no other line types besides bars attached to the axis.
+** The data on the axis is all >= 0.
+** The user has not specified a pad, padMin or forceTickAt0 = true option.
+* Modified tick prefix behavious so prefix no added to all ticks, even if format
+ string is specified.
+* Fix to ensure original tick formats are applied when zooming and resetting
+ zoom.
+* Updated auto tick format string so format adjusted when zooming.
+* Modified auto tick computation to put less ticks on small plots and more
+ ticks on large plots.
+* Update bubble render to support gradients in IE 9.
+
+1.0.0b1:
+* Much improved tick generation algorithm to get precise rounded
+ tick values (Thanks Scott Prahl!).
+* Auto compute tick format string if none is provided.
+* Much better "slicing" of pie charts when using "sliceMargin" option to set
+ a gap between the slices.
+* Expanded canvasOverlay plugin to create arbitrary dashed and solid
+ horizontal and vertical lines on top of plot.
+* Added defaultColors and defaultNegativeColors options to $.jqplot.config.
+* Fixed issue #318, highlighter & bar renderer incompatability.
+* Improve highlighter tooltip positioning with negative bars.
+* Fixed #305, mispelling of jqlotDragStart and jqlotDragStop. MUST NOW BIND
+ TO jqplotDragStart and jqplotDragStop.
+* Fixed #290, some variables left in global scope.
+* Fixed #289, OHLC line widths hard coded at 1.5. Now set by lineWidth option.
+* Fixed #296 for determining databounds on log axes.
+* Updated to jQuery 1.5.1
+* Fixed waterfall plot to ensure first and last bars always fill to zero.
+* Added lineJoin and lineCap option to series lines.
+* Bar widths now based on width of grid, not plot target for better scaling.
+* Added looseZoom option to cursor so zooming can produce well rounded ticks.
+* Added forceTickAt0 and forceTickAt100 options to ensure there will always
+ be a tick at 0 or 100 in the plot.
+* Fixed bug where cursor legend didn't honor series showLabel option.
+
+
+1.0.0a:
+
+* Series can now be moved forward or backward in stack to e.g. bring a line
+ forward when mousing over a point.
+* Can now move outside of grid area while zooming. Can have zoom
+ constrained to grid area or allow zooming outside.
+* Fixed issue #142 with tooltip drawn on top of event canvas, hiding
+ mouse events.
+* Fixed #147 where pie slices with 0 value not rendering properly in IE.
+* Fixed #130 where stack data not sorted properly.
+* Fixed bug with null values not handled properly in category axes.
+* Fixed #156 where pie charts not rendering on QTWebKit.
+* Now using feature detection for canvas and canvas text capability
+ rather than browser version.
+* Added enahncedLegendRenderer plugin to allow multi row/column legends
+ and clickable labels to show/hide series.
+* Added fillToValue option to allow filled line plot to fill to an
+ arbitrary value.
+* Added block plot plugin.
+* Added funnel type charts.
+* Added meter gauge type charts.
+* Added plot theming support.
+* $.jqplot.config.enablePlugins now false by default.
+* Implemented highlighting on bar, pie, donut, funnel, etc. charts.
+* Fix to pointlabels plugin to align labels properly on multi series plots.
+* Added custom error handling to display error message in plot area.
+* Fixed issue where would call to draw grid border of 0 width would
+ result in a default border being drawn.
+* Added options to place legend outside of grid and shrink grid so everything
+ stays within plot div.
+* Fixed bug in color generator so now calls to get() continually cycle
+ through colors just like next().
+* Added defaultAxisStart option.
+* Added gradient fills to bubbles.
+* Added bubble charts.
+* Added showLabels option to bubble charts.
+* Pass bubble radius to event callback in bubble charts.
+* Fixed #207, typo in docs.
+* Fixed #206 where "value" pie slice data labels were displaying wrong
+ value.
+* Fixed #147 with 0 value slices in IE6.
+* Fixed issue #241, disabled varyBarColor option in stacked charts.
+* Added dataRenderer option to allow custom processors for JSON, AJAX
+ and anywhere else you might want to get data.
+* Fixed null value handling so plot now properly skip or join over nulls.
+* Fixed showTicks and showTickMarks option conflicts.
+* Fixed issue #185 where pointLabels plugin incompatibility could crash
+ pie, donut and other plots.
+* Fixed #23 and #143 to obey gridPadding option.
+* Fixed #233 with highlighter tooltip separator.
+* Fixed #224 where type checking failing on GWT.
+* Fixed #272 with pie highlighting not working on replot.
+* Memory performance improvements.
+* Changes to build script so everything should build when pulled from repo.
+* Fixed issue #275, IE 6/7 don't support array indexing of strings.
+* Added event listener hooks for mouseUp, mouseDown, etc. to all line plots.
+* Fixed bug with highlighter not working when null in data.
+* Updated to jQuery 1.4.4
+* Fixed bug where donut plots showed value of radians of slice instead
+ of actual data.
+* Reverted to excanvas r3 so IE8 no longer has to emulate IE7.
+* Added tooltipContentEditor option to highlighter, allowing callback
+ to manipulate tooltip content at run time (thanks Tim Bunce!).
+* Fixed bug where axes scale not resetting.
+* Fixed bug with date axes where data bounds not properly set.
+* Fixed issue where tick marks disappear if grid lines turned off.
+* Updated replot method to allow passing in axes options for more control.
+* Added experimental support for "broken" axes.
+* Fixed bug with pies where pies with 0 valued slices did not draw correctly.
+* Added canvasOverlay plugin to allow drawing of arbitrary shapes on a canvas
+ over the plot.
+* Added option to display arbitrary text/html (message, animated gif, etc.) if
+ plot is constructed without data. Allow a "data loading" indicator to be shown.
+* Added resetAxisValues method to manually update axis ticks without
+ redrawing the plot.
+* Fix to labels on negative bars so label postiion of 'n' will be below a negative bar,
+ just as it is above a positive bar (thanks guigod!).
+* Added thousands separator character (') to sprintf formatting (thanks yuichi1004!).
+* Re-factored date parsing/formatting to use new jsDate module which does not
+ extend the Date prototype.
+
+
+0.9.7:
+
+* Added Mekko chart plot type with enhanced legend and axes support.
+* Implemented vertical waterfall charts. Can create waterfall plot as
+ option to bar chart. See examples folder of distribution.
+* Enhanced plot labels for waterfall style.
+* Enhanced bar plots so you can now color each bar of a series
+ independently with the "varyBarColor" option.
+* Re-factored series drawing so that each series and series shadow drawn
+ on it's own canvas. Allows series to be redrawn independently of each other.
+* Added additional default series colors.
+* Added useNegativeColors option to turn off negative color array and use
+ only seriesColors array to define all bar/filled line colors.
+* Fix css for cursor legend.
+* Modified shape renderer so rectangles can be stroked and filled.
+* Re-factored date methods out of dateAxisRenderer so that date formatter
+ and methods can be accesses outside of dateAxisRenderer plugin.
+* Fixed #132, now trigger series change event on plot target instead of drag canvas.
+* Fixes issue #116 where some source files had mix of tabs and spaces
+ for indentation. Should have been all spaces.
+* Fixed issue #126, some links broken in docs section of web site.
+* Fixed issue #90, trendline plugin incompatibility with pie renderer.
+* Updated samples in examples folder of distribution to include navigation
+ links if web server is set up to process .html files with php.
+
+
+0.9.6:
+
+* New, easier to use, replot() method for placing plots in tabs, accordions,
+ resizable containers or for changing plot parameters programmatically.
+* Updated legend renderer for pie charts to draw swatches which will
+ print correctly.
+* Fixed issue #118 with patch from taum so autoscale option will
+ honor tickInterval and numberTicks options
+* Fix to plot diameter calculation for initially hidden plots.
+* Added examples for making plots in jQuery UI tabs and accordions.
+* Fixed issue #120 where pie chart with single slice not displaying
+ correctly in IE and Chrome
+
+
+0.9.5.2:
+
+* Fixed #102 where double clicking on plot that has zoom enabled, but
+ has not been zoomed resulted in error.
+* Fixed bug where candlestick coloring options not working.
+* Added option to turn individual series labels off in the legend.
+
+
+0.9.5.1:
+
+* Fixed bug where tooltip not working with OHLC and candlestick charts.
+* Added additional marker styles: plus, X and dash.
+
+
+0.9.5:
+
+* Implemented "zoomProxy". zoomProxy allows zooming one plot from another
+ such as an overview plot.
+* Zooming can now be constrained to just x or y axis.
+* Enhanced cursor plugin with vertical "dataTracking" line. This is a line
+ at the cursor location with a readout of data points at the line location
+ which are displayed in the chart legend.
+* Changed cursor tooltip format string. Now one format string is used for
+ entire tooltip.
+* Added mechanisms to specify plot size when plot target is hidden or plot
+ height/width otherwise cannot be determined from markup.
+* Added $.jqplot.config object to specify jqplot wide configuration options.
+ These include enablePlugins to globally set the default plugin state on/off
+ and defaultHeight/defaultWidth to specify default plot height/width.
+* Added fillToZero option which forces filled charts to fill to zero as opposed
+ to axis minimum. Thus negative filled bar/line values will fill upwards to
+ zero axis value.
+* Added option to disable stacking on individual lines.
+* Changed targetId property of the plot object so it now includes a "#" before
+ the id string.
+* Improved tick and body sizing of Open Hi Low Close and candlestick charts.
+* Removed lots of web site related files from the repository. This means that,
+ if working from the sources, user's won't be able to build the jqplot web
+ site and the docs/tests that are hosted on that site. The minified and
+ compressed distribution packages will build fine.
+* Lots of examples were added to a separate examples directory to better show
+ functionality of jqPlot for local testing with the distribution.
+* Many various bug fixes and other minor enhancements.
+
+
+0.9.4:
+
+* Implemented axis labels. Labels can be rendered in div tags or as canvas
+ elements supporting rotated text.
+* Improved rotated axis label positioning so labels will start or end at a
+ tick position.
+* Fixed bug where an empty data series would hang plot rendering.
+* completed issue #66 for misc. improvements to documentation.
+* Fixed issue #64 where the same ID's were assigned to cursor and highlighter
+ elements.
+* Added option to legend to encode special HTML characters.
+* Fixed undesirable behavior where point labels for points off the plot
+ were being rendered.
+* Added edgeTolerance option to point label renderer to control rendering of
+ labels near plot edges.
+
+
+0.9.3:
+
+* Preliminary support for axis labels. Currently rendered into DIV tags,
+ so no rotated label support. This feature is currently experimental.
+* Fixed bug #52, needed space in tick div tag between style and class declarations
+ or plot failed in certain application doctypes.
+* Fixed issue #54, miter style line join for chart lines causing spikes at steep
+ changes in slope. Changed miter style to round.
+* Added examples for new autoscaling algorithm.
+* Fixed bug #57, category axis labels disappear on redraw()
+* Improved algorithm which controlled maximum number of labels that would display
+ on a category axis.
+* Fixed bug #45 where null values causing errors in plotData and gridData.
+* Fixed issue #60 where seriesColors option was not working.
+
+
+0.9.2:
+
+* Fixed bug #45 where a plot could crash if series had different numbers of points.
+* Fixed issue #50, added option to turn off sorting of series data.
+* Fixed issue #31, implemented a better axis autoscaling algorithm and added an autoscale option.
+
+0.9.1:
+
+* Fixed bug #40, when axis pad, padMax, padMin set to 0, graph would fail to render.
+* Fixed bug #41 where pie and bar charts not rendered correctly on redraw().
+* Fixed bug #11, filled stacked line plots not rendering correctly in IE.
+* Fixed bug #42 where stacked charts not rendering with string date axis ticks.
+* Fixed bug in redraw() method where axes ticks were not reset.
+* Fixed "jqplotPreRedrawEvent" that should have been named "jqplotPostRedraw" event.
+
+0.9.0:
+
+* Added Open Hi Low Close charts, Candlestick charts and Hi Low Close charts.
+* Added support for arbitrary labels on the data points.
+* Enhanced highlighter plugin to allow custom formatting control of entire tooltip.
+* Enhanced highlighter to support multiple y values in a data point.
+* Fixed bug #38 where series with a single point with a negative value would fail.
+* Improvements to examples to show what plugins to include.
+* Expanded documentation for some of the plugins.
+
+0.8.5:
+
+* Added zooming ability with double click or single click options to reset zoom.
+* Modified default tick spacing algorithm for date axes to give more space to ticks.
+* Fixed bug #2 where tickInterval wasn't working properly.
+* Added neighborThreshold option to control how close mouse must be to
+ point to trigger neighbor detection.
+* Added double click event handler on plot.
+
+0.8.0:
+
+* Support for up to 9 y axes.
+* Added option to control padding at max/min bounds of axes separately.
+* Closed issue #21, added options to control grid line color and width.
+* Closed issue #20, added options to filled line charts to stoke above
+ fill and customize fill color and transparency.
+* Improved structure of on line documentation to make usage and options
+ docs default.
+* Added much documentation on options and css styling.
+
+0.7.1:
+
+* Bug fix release
+* Fixed bug #6, missing semi-colons messing up some javascript compressors.
+* Fixed bug #13 where 2D ticks array of [values, labels] would fail to
+ renderer with DateAxisRenderer.
+* Fixes bug #16 where pie renderer overwriting options for all plot types
+ and crashing non pie plots.
+* Fixes bug #17 constrainTo dragable option mispelled as "contstrainTo".
+ Fixed dragable color issue when used with trend lines.
+
+0.7.0:
+
+* Pie chart support
+* Enabled tooltipLocation option in highlighter.
+* Highlighter Tooltip will account for mark size and highlight size when
+ positioning itself.
+* Added ability to show just x, y or both axes in highlighter tooltip.
+* Added customization of separator between axes values in highlighter tooltip.
+* Modified how shadows are drawn for lines, bars and markers. Now drawn first,
+ so they are always behind the object.
+* Adjustments to shadow parameters on lines to account for new shadow positioning.
+* Added a ColorGenerator class to robustly return next available color
+ for a plot with wrap around to first color at end.
+* Udates to docs about css file.
+* Fixed bug with String x values in series and IE error on sorting (Category Axis).
+* Added cursor changes in dragable plugin when cursor near dragable point.
+
+0.6.6b:
+
+* Added excanvas.js and excanvas.min.js to compressed distributions.
+* Added example/test html pages I had locally into repository and to
+ compressed distributions.
+
+0.6.6a:
+
+* Removed absolute positioning from dom element and put back into css file.
+* Duplicate of 0.6.6 with a suffix to unambiguously differentiate between
+ previously posted 0.6.6 release.
+
+0.6.6:
+
+* Fixed bug #5, trend line plugin failing when no trend line options specified.
+* Added absolute position css spec to axis tick dom element.
+* Enhancement to category axes, more intuitive handling of series with
+ missing data values.
+
+0.6.5:
+
+* Fixed bug #4, series of unequal data length not rendering correctly.
+ This is a bugfix release only.
+
+0.6.4:
+
+* Fixed bug (issue #1 in tracker) where flat line data series (all x and/or y
+ values are euqal) or single value data series would crash.
+
+0.6.3:
+
+* Support for stacked line (a.k.a. area) and stacked bar (horizontal and
+ vertical) charts.
+* Refactored barRenderer to use default shape and shadow renderers.
+* Added info (contacts & support information) page to web site.
+
+0.6.2:
+
+* This is a minor upgrade to docs and build only. No functionality has changed.
+* Ant build script generates entire site, examples, tests and distribution.
+* Improvements to documentation.
+
+0.6.1:
+
+* New sprintf implementation from Ash Searle that implements %g.
+* Fix to sprintf e/f formats.
+* Created new format specifier, %p and %P to preserve significance.
+* Modified p/P format to better display larger numbers.
+* Fixed and simplified significant digits calculation for sprintf.
+* Added option to have cursor tooltip follow the mouse or not.
+* Added options to change size of highlight.
+* Updates to handle dates like '6-May-09'.
+* Mods to improve look of web site.
+* Updates to documentation.
+* Added license and copyright statement to source files.
+
+0.6.0:
+
+* Added rotated text support. Uses native canvas text functionality in
+ browsers that support it or draws text on canvas with Hershey font
+* metrics for non-supporting browsers.
+* Removed lots of lint in js code.
+* Moved tick css from js code into css file.
+* Fix to tick positioning css. y axis ticks were positioned to wrong side of axis div.
+* Re-factored axis tick renderer instantiation into the axes renderers themselves.
+
+
+For changes prior to 0.6.0 release, please see change log at http://bitbucket.org/cleonello/jqplot/changesets/
\ No newline at end of file
Added: gnucash/trunk/src/report/jqplot/copyright.txt
===================================================================
--- gnucash/trunk/src/report/jqplot/copyright.txt (rev 0)
+++ gnucash/trunk/src/report/jqplot/copyright.txt 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,56 @@
+/**
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: @VERSION
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
+ * jqPlot is currently available for use in all personal or commercial projects
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
+ * choose the license that best suits your project and use it accordingly.
+ *
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
+ *
+ * If you are feeling kind and generous, consider supporting the project by
+ * making a donation at: http://www.jqplot.com/donate.php .
+ *
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
+ *
+ * included jsDate library by Chris Leonello:
+ *
+ * Copyright (c) 2010-2013 Chris Leonello
+ *
+ * jsDate is currently available for use in all personal or commercial projects
+ * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * choose the license that best suits your project and use it accordingly.
+ *
+ * jsDate borrows many concepts and ideas from the Date Instance
+ * Methods by Ken Snyder along with some parts of Ken's actual code.
+ *
+ * Ken's origianl Date Instance Methods and copyright notice:
+ *
+ * Ken Snyder (ken d snyder at gmail dot com)
+ * 2008-09-10
+ * version 2.0.2 (http://kendsnyder.com/sandbox/date/)
+ * Creative Commons Attribution License 3.0 (http://creativecommons.org/licenses/by/3.0/)
+ *
+ * jqplotToImage function based on Larry Siden's export-jqplot-to-png.js.
+ * Larry has generously given permission to adapt his code for inclusion
+ * into jqPlot.
+ *
+ * Larry's original code can be found here:
+ *
+ * https://github.com/lsiden/export-jqplot-to-png
+ *
+ *
+ */
Added: gnucash/trunk/src/report/jqplot/excanvas.js
===================================================================
--- gnucash/trunk/src/report/jqplot/excanvas.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/excanvas.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,1438 @@
+// Memory Leaks patch from http://explorercanvas.googlecode.com/svn/trunk/
+// svn : r73
+// ------------------------------------------------------------------
+// Copyright 2006 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+// Known Issues:
+//
+// * Patterns only support repeat.
+// * Radial gradient are not implemented. The VML version of these look very
+// different from the canvas one.
+// * Clipping paths are not implemented.
+// * Coordsize. The width and height attribute have higher priority than the
+// width and height style values which isn't correct.
+// * Painting mode isn't implemented.
+// * Canvas width/height should is using content-box by default. IE in
+// Quirks mode will draw the canvas using border-box. Either change your
+// doctype to HTML5
+// (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype)
+// or use Box Sizing Behavior from WebFX
+// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html)
+// * Non uniform scaling does not correctly scale strokes.
+// * Optimize. There is always room for speed improvements.
+
+// Only add this code if we do not already have a canvas implementation
+if (!document.createElement('canvas').getContext) {
+
+(function() {
+
+ // alias some functions to make (compiled) code shorter
+ var m = Math;
+ var mr = m.round;
+ var ms = m.sin;
+ var mc = m.cos;
+ var abs = m.abs;
+ var sqrt = m.sqrt;
+
+ // this is used for sub pixel precision
+ var Z = 10;
+ var Z2 = Z / 2;
+
+ var IE_VERSION = +navigator.userAgent.match(/MSIE ([\d.]+)?/)[1];
+
+ /**
+ * This funtion is assigned to the <canvas> elements as element.getContext().
+ * @this {HTMLElement}
+ * @return {CanvasRenderingContext2D_}
+ */
+ function getContext() {
+ return this.context_ ||
+ (this.context_ = new CanvasRenderingContext2D_(this));
+ }
+
+ var slice = Array.prototype.slice;
+
+ /**
+ * Binds a function to an object. The returned function will always use the
+ * passed in {@code obj} as {@code this}.
+ *
+ * Example:
+ *
+ * g = bind(f, obj, a, b)
+ * g(c, d) // will do f.call(obj, a, b, c, d)
+ *
+ * @param {Function} f The function to bind the object to
+ * @param {Object} obj The object that should act as this when the function
+ * is called
+ * @param {*} var_args Rest arguments that will be used as the initial
+ * arguments when the function is called
+ * @return {Function} A new function that has bound this
+ */
+ function bind(f, obj, var_args) {
+ var a = slice.call(arguments, 2);
+ return function() {
+ return f.apply(obj, a.concat(slice.call(arguments)));
+ };
+ }
+
+ function encodeHtmlAttribute(s) {
+ return String(s).replace(/&/g, '&').replace(/"/g, '"');
+ }
+
+ function addNamespace(doc, prefix, urn) {
+ if (!doc.namespaces[prefix]) {
+ doc.namespaces.add(prefix, urn, '#default#VML');
+ }
+ }
+
+ function addNamespacesAndStylesheet(doc) {
+ addNamespace(doc, 'g_vml_', 'urn:schemas-microsoft-com:vml');
+ addNamespace(doc, 'g_o_', 'urn:schemas-microsoft-com:office:office');
+
+ // Setup default CSS. Only add one style sheet per document
+ if (!doc.styleSheets['ex_canvas_']) {
+ var ss = doc.createStyleSheet();
+ ss.owningElement.id = 'ex_canvas_';
+ ss.cssText = 'canvas{display:inline-block;overflow:hidden;' +
+ // default size is 300x150 in Gecko and Opera
+ 'text-align:left;width:300px;height:150px}';
+ }
+ }
+
+ // Add namespaces and stylesheet at startup.
+ addNamespacesAndStylesheet(document);
+
+ var G_vmlCanvasManager_ = {
+ init: function(opt_doc) {
+ var doc = opt_doc || document;
+ // Create a dummy element so that IE will allow canvas elements to be
+ // recognized.
+ doc.createElement('canvas');
+ doc.attachEvent('onreadystatechange', bind(this.init_, this, doc));
+ },
+
+ init_: function(doc) {
+ // find all canvas elements
+ var els = doc.getElementsByTagName('canvas');
+ for (var i = 0; i < els.length; i++) {
+ this.initElement(els[i]);
+ }
+ },
+
+ /**
+ * Public initializes a canvas element so that it can be used as canvas
+ * element from now on. This is called automatically before the page is
+ * loaded but if you are creating elements using createElement you need to
+ * make sure this is called on the element.
+ * @param {HTMLElement} el The canvas element to initialize.
+ * @return {HTMLElement} the element that was created.
+ */
+ initElement: function(el) {
+ if (!el.getContext) {
+ el.getContext = getContext;
+
+ // Add namespaces and stylesheet to document of the element.
+ addNamespacesAndStylesheet(el.ownerDocument);
+
+ // Remove fallback content. There is no way to hide text nodes so we
+ // just remove all childNodes. We could hide all elements and remove
+ // text nodes but who really cares about the fallback content.
+ el.innerHTML = '';
+
+ // do not use inline function because that will leak memory
+ el.attachEvent('onpropertychange', onPropertyChange);
+ el.attachEvent('onresize', onResize);
+
+ var attrs = el.attributes;
+ if (attrs.width && attrs.width.specified) {
+ // TODO: use runtimeStyle and coordsize
+ // el.getContext().setWidth_(attrs.width.nodeValue);
+ el.style.width = attrs.width.nodeValue + 'px';
+ } else {
+ el.width = el.clientWidth;
+ }
+ if (attrs.height && attrs.height.specified) {
+ // TODO: use runtimeStyle and coordsize
+ // el.getContext().setHeight_(attrs.height.nodeValue);
+ el.style.height = attrs.height.nodeValue + 'px';
+ } else {
+ el.height = el.clientHeight;
+ }
+ //el.getContext().setCoordsize_()
+ }
+ return el;
+ },
+
+ // Memory Leaks patch : see http://code.google.com/p/explorercanvas/issues/detail?id=82
+ uninitElement: function(el){
+ if (el.getContext) {
+ var ctx = el.getContext();
+ delete ctx.element_;
+ delete ctx.canvas;
+ el.innerHTML = "";
+ //el.outerHTML = "";
+ el.context_ = null;
+ el.getContext = null;
+ el.detachEvent("onpropertychange", onPropertyChange);
+ el.detachEvent("onresize", onResize);
+ }
+ }
+ };
+
+ function onPropertyChange(e) {
+ var el = e.srcElement;
+
+ switch (e.propertyName) {
+ case 'width':
+ el.getContext().clearRect();
+ el.style.width = el.attributes.width.nodeValue + 'px';
+ // In IE8 this does not trigger onresize.
+ el.firstChild.style.width = el.clientWidth + 'px';
+ break;
+ case 'height':
+ el.getContext().clearRect();
+ el.style.height = el.attributes.height.nodeValue + 'px';
+ el.firstChild.style.height = el.clientHeight + 'px';
+ break;
+ }
+ }
+
+ function onResize(e) {
+ var el = e.srcElement;
+ if (el.firstChild) {
+ el.firstChild.style.width = el.clientWidth + 'px';
+ el.firstChild.style.height = el.clientHeight + 'px';
+ }
+ }
+
+ G_vmlCanvasManager_.init();
+
+ // precompute "00" to "FF"
+ var decToHex = [];
+ for (var i = 0; i < 16; i++) {
+ for (var j = 0; j < 16; j++) {
+ decToHex[i * 16 + j] = i.toString(16) + j.toString(16);
+ }
+ }
+
+ function createMatrixIdentity() {
+ return [
+ [1, 0, 0],
+ [0, 1, 0],
+ [0, 0, 1]
+ ];
+ }
+
+ function matrixMultiply(m1, m2) {
+ var result = createMatrixIdentity();
+
+ for (var x = 0; x < 3; x++) {
+ for (var y = 0; y < 3; y++) {
+ var sum = 0;
+
+ for (var z = 0; z < 3; z++) {
+ sum += m1[x][z] * m2[z][y];
+ }
+
+ result[x][y] = sum;
+ }
+ }
+ return result;
+ }
+
+ function copyState(o1, o2) {
+ o2.fillStyle = o1.fillStyle;
+ o2.lineCap = o1.lineCap;
+ o2.lineJoin = o1.lineJoin;
+ o2.lineWidth = o1.lineWidth;
+ o2.miterLimit = o1.miterLimit;
+ o2.shadowBlur = o1.shadowBlur;
+ o2.shadowColor = o1.shadowColor;
+ o2.shadowOffsetX = o1.shadowOffsetX;
+ o2.shadowOffsetY = o1.shadowOffsetY;
+ o2.strokeStyle = o1.strokeStyle;
+ o2.globalAlpha = o1.globalAlpha;
+ o2.font = o1.font;
+ o2.textAlign = o1.textAlign;
+ o2.textBaseline = o1.textBaseline;
+ o2.arcScaleX_ = o1.arcScaleX_;
+ o2.arcScaleY_ = o1.arcScaleY_;
+ o2.lineScale_ = o1.lineScale_;
+ }
+
+ var colorData = {
+ aliceblue: '#F0F8FF',
+ antiquewhite: '#FAEBD7',
+ aquamarine: '#7FFFD4',
+ azure: '#F0FFFF',
+ beige: '#F5F5DC',
+ bisque: '#FFE4C4',
+ black: '#000000',
+ blanchedalmond: '#FFEBCD',
+ blueviolet: '#8A2BE2',
+ brown: '#A52A2A',
+ burlywood: '#DEB887',
+ cadetblue: '#5F9EA0',
+ chartreuse: '#7FFF00',
+ chocolate: '#D2691E',
+ coral: '#FF7F50',
+ cornflowerblue: '#6495ED',
+ cornsilk: '#FFF8DC',
+ crimson: '#DC143C',
+ cyan: '#00FFFF',
+ darkblue: '#00008B',
+ darkcyan: '#008B8B',
+ darkgoldenrod: '#B8860B',
+ darkgray: '#A9A9A9',
+ darkgreen: '#006400',
+ darkgrey: '#A9A9A9',
+ darkkhaki: '#BDB76B',
+ darkmagenta: '#8B008B',
+ darkolivegreen: '#556B2F',
+ darkorange: '#FF8C00',
+ darkorchid: '#9932CC',
+ darkred: '#8B0000',
+ darksalmon: '#E9967A',
+ darkseagreen: '#8FBC8F',
+ darkslateblue: '#483D8B',
+ darkslategray: '#2F4F4F',
+ darkslategrey: '#2F4F4F',
+ darkturquoise: '#00CED1',
+ darkviolet: '#9400D3',
+ deeppink: '#FF1493',
+ deepskyblue: '#00BFFF',
+ dimgray: '#696969',
+ dimgrey: '#696969',
+ dodgerblue: '#1E90FF',
+ firebrick: '#B22222',
+ floralwhite: '#FFFAF0',
+ forestgreen: '#228B22',
+ gainsboro: '#DCDCDC',
+ ghostwhite: '#F8F8FF',
+ gold: '#FFD700',
+ goldenrod: '#DAA520',
+ grey: '#808080',
+ greenyellow: '#ADFF2F',
+ honeydew: '#F0FFF0',
+ hotpink: '#FF69B4',
+ indianred: '#CD5C5C',
+ indigo: '#4B0082',
+ ivory: '#FFFFF0',
+ khaki: '#F0E68C',
+ lavender: '#E6E6FA',
+ lavenderblush: '#FFF0F5',
+ lawngreen: '#7CFC00',
+ lemonchiffon: '#FFFACD',
+ lightblue: '#ADD8E6',
+ lightcoral: '#F08080',
+ lightcyan: '#E0FFFF',
+ lightgoldenrodyellow: '#FAFAD2',
+ lightgreen: '#90EE90',
+ lightgrey: '#D3D3D3',
+ lightpink: '#FFB6C1',
+ lightsalmon: '#FFA07A',
+ lightseagreen: '#20B2AA',
+ lightskyblue: '#87CEFA',
+ lightslategray: '#778899',
+ lightslategrey: '#778899',
+ lightsteelblue: '#B0C4DE',
+ lightyellow: '#FFFFE0',
+ limegreen: '#32CD32',
+ linen: '#FAF0E6',
+ magenta: '#FF00FF',
+ mediumaquamarine: '#66CDAA',
+ mediumblue: '#0000CD',
+ mediumorchid: '#BA55D3',
+ mediumpurple: '#9370DB',
+ mediumseagreen: '#3CB371',
+ mediumslateblue: '#7B68EE',
+ mediumspringgreen: '#00FA9A',
+ mediumturquoise: '#48D1CC',
+ mediumvioletred: '#C71585',
+ midnightblue: '#191970',
+ mintcream: '#F5FFFA',
+ mistyrose: '#FFE4E1',
+ moccasin: '#FFE4B5',
+ navajowhite: '#FFDEAD',
+ oldlace: '#FDF5E6',
+ olivedrab: '#6B8E23',
+ orange: '#FFA500',
+ orangered: '#FF4500',
+ orchid: '#DA70D6',
+ palegoldenrod: '#EEE8AA',
+ palegreen: '#98FB98',
+ paleturquoise: '#AFEEEE',
+ palevioletred: '#DB7093',
+ papayawhip: '#FFEFD5',
+ peachpuff: '#FFDAB9',
+ peru: '#CD853F',
+ pink: '#FFC0CB',
+ plum: '#DDA0DD',
+ powderblue: '#B0E0E6',
+ rosybrown: '#BC8F8F',
+ royalblue: '#4169E1',
+ saddlebrown: '#8B4513',
+ salmon: '#FA8072',
+ sandybrown: '#F4A460',
+ seagreen: '#2E8B57',
+ seashell: '#FFF5EE',
+ sienna: '#A0522D',
+ skyblue: '#87CEEB',
+ slateblue: '#6A5ACD',
+ slategray: '#708090',
+ slategrey: '#708090',
+ snow: '#FFFAFA',
+ springgreen: '#00FF7F',
+ steelblue: '#4682B4',
+ tan: '#D2B48C',
+ thistle: '#D8BFD8',
+ tomato: '#FF6347',
+ turquoise: '#40E0D0',
+ violet: '#EE82EE',
+ wheat: '#F5DEB3',
+ whitesmoke: '#F5F5F5',
+ yellowgreen: '#9ACD32'
+ };
+
+
+ function getRgbHslContent(styleString) {
+ var start = styleString.indexOf('(', 3);
+ var end = styleString.indexOf(')', start + 1);
+ var parts = styleString.substring(start + 1, end).split(',');
+ // add alpha if needed
+ if (parts.length != 4 || styleString.charAt(3) != 'a') {
+ parts[3] = 1;
+ }
+ return parts;
+ }
+
+ function percent(s) {
+ return parseFloat(s) / 100;
+ }
+
+ function clamp(v, min, max) {
+ return Math.min(max, Math.max(min, v));
+ }
+
+ function hslToRgb(parts){
+ var r, g, b, h, s, l;
+ h = parseFloat(parts[0]) / 360 % 360;
+ if (h < 0)
+ h++;
+ s = clamp(percent(parts[1]), 0, 1);
+ l = clamp(percent(parts[2]), 0, 1);
+ if (s == 0) {
+ r = g = b = l; // achromatic
+ } else {
+ var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
+ var p = 2 * l - q;
+ r = hueToRgb(p, q, h + 1 / 3);
+ g = hueToRgb(p, q, h);
+ b = hueToRgb(p, q, h - 1 / 3);
+ }
+
+ return '#' + decToHex[Math.floor(r * 255)] +
+ decToHex[Math.floor(g * 255)] +
+ decToHex[Math.floor(b * 255)];
+ }
+
+ function hueToRgb(m1, m2, h) {
+ if (h < 0)
+ h++;
+ if (h > 1)
+ h--;
+
+ if (6 * h < 1)
+ return m1 + (m2 - m1) * 6 * h;
+ else if (2 * h < 1)
+ return m2;
+ else if (3 * h < 2)
+ return m1 + (m2 - m1) * (2 / 3 - h) * 6;
+ else
+ return m1;
+ }
+
+ var processStyleCache = {};
+
+ function processStyle(styleString) {
+ if (styleString in processStyleCache) {
+ return processStyleCache[styleString];
+ }
+
+ var str, alpha = 1;
+
+ styleString = String(styleString);
+ if (styleString.charAt(0) == '#') {
+ str = styleString;
+ } else if (/^rgb/.test(styleString)) {
+ var parts = getRgbHslContent(styleString);
+ var str = '#', n;
+ for (var i = 0; i < 3; i++) {
+ if (parts[i].indexOf('%') != -1) {
+ n = Math.floor(percent(parts[i]) * 255);
+ } else {
+ n = +parts[i];
+ }
+ str += decToHex[clamp(n, 0, 255)];
+ }
+ alpha = +parts[3];
+ } else if (/^hsl/.test(styleString)) {
+ var parts = getRgbHslContent(styleString);
+ str = hslToRgb(parts);
+ alpha = parts[3];
+ } else {
+ str = colorData[styleString] || styleString;
+ }
+ return processStyleCache[styleString] = {color: str, alpha: alpha};
+ }
+
+ var DEFAULT_STYLE = {
+ style: 'normal',
+ variant: 'normal',
+ weight: 'normal',
+ size: 10,
+ family: 'sans-serif'
+ };
+
+ // Internal text style cache
+ var fontStyleCache = {};
+
+ function processFontStyle(styleString) {
+ if (fontStyleCache[styleString]) {
+ return fontStyleCache[styleString];
+ }
+
+ var el = document.createElement('div');
+ var style = el.style;
+ try {
+ style.font = styleString;
+ } catch (ex) {
+ // Ignore failures to set to invalid font.
+ }
+
+ return fontStyleCache[styleString] = {
+ style: style.fontStyle || DEFAULT_STYLE.style,
+ variant: style.fontVariant || DEFAULT_STYLE.variant,
+ weight: style.fontWeight || DEFAULT_STYLE.weight,
+ size: style.fontSize || DEFAULT_STYLE.size,
+ family: style.fontFamily || DEFAULT_STYLE.family
+ };
+ }
+
+ function getComputedStyle(style, element) {
+ var computedStyle = {};
+
+ for (var p in style) {
+ computedStyle[p] = style[p];
+ }
+
+ // Compute the size
+ var canvasFontSize = parseFloat(element.currentStyle.fontSize),
+ fontSize = parseFloat(style.size);
+
+ if (typeof style.size == 'number') {
+ computedStyle.size = style.size;
+ } else if (style.size.indexOf('px') != -1) {
+ computedStyle.size = fontSize;
+ } else if (style.size.indexOf('em') != -1) {
+ computedStyle.size = canvasFontSize * fontSize;
+ } else if(style.size.indexOf('%') != -1) {
+ computedStyle.size = (canvasFontSize / 100) * fontSize;
+ } else if (style.size.indexOf('pt') != -1) {
+ computedStyle.size = fontSize / .75;
+ } else {
+ computedStyle.size = canvasFontSize;
+ }
+
+ // Different scaling between normal text and VML text. This was found using
+ // trial and error to get the same size as non VML text.
+ computedStyle.size *= 0.981;
+
+ // Fix for VML handling of bare font family names. Add a '' around font family names.
+ computedStyle.family = "'" + computedStyle.family.replace(/(\'|\")/g,'').replace(/\s*,\s*/g, "', '") + "'";
+
+ return computedStyle;
+ }
+
+ function buildStyle(style) {
+ return style.style + ' ' + style.variant + ' ' + style.weight + ' ' +
+ style.size + 'px ' + style.family;
+ }
+
+ var lineCapMap = {
+ 'butt': 'flat',
+ 'round': 'round'
+ };
+
+ function processLineCap(lineCap) {
+ return lineCapMap[lineCap] || 'square';
+ }
+
+ /**
+ * This class implements CanvasRenderingContext2D interface as described by
+ * the WHATWG.
+ * @param {HTMLElement} canvasElement The element that the 2D context should
+ * be associated with
+ */
+ function CanvasRenderingContext2D_(canvasElement) {
+ this.m_ = createMatrixIdentity();
+
+ this.mStack_ = [];
+ this.aStack_ = [];
+ this.currentPath_ = [];
+
+ // Canvas context properties
+ this.strokeStyle = '#000';
+ this.fillStyle = '#000';
+
+ this.lineWidth = 1;
+ this.lineJoin = 'miter';
+ this.lineCap = 'butt';
+ this.miterLimit = Z * 1;
+ this.globalAlpha = 1;
+ this.font = '10px sans-serif';
+ this.textAlign = 'left';
+ this.textBaseline = 'alphabetic';
+ this.canvas = canvasElement;
+
+ var cssText = 'width:' + canvasElement.clientWidth + 'px;height:' +
+ canvasElement.clientHeight + 'px;overflow:hidden;position:absolute';
+ var el = canvasElement.ownerDocument.createElement('div');
+ el.style.cssText = cssText;
+ canvasElement.appendChild(el);
+
+ var overlayEl = el.cloneNode(false);
+ // Use a non transparent background.
+ overlayEl.style.backgroundColor = 'red';
+ overlayEl.style.filter = 'alpha(opacity=0)';
+ canvasElement.appendChild(overlayEl);
+
+ this.element_ = el;
+ this.arcScaleX_ = 1;
+ this.arcScaleY_ = 1;
+ this.lineScale_ = 1;
+ }
+
+ var contextPrototype = CanvasRenderingContext2D_.prototype;
+ contextPrototype.clearRect = function() {
+ if (this.textMeasureEl_) {
+ this.textMeasureEl_.removeNode(true);
+ this.textMeasureEl_ = null;
+ }
+ this.element_.innerHTML = '';
+ };
+
+ contextPrototype.beginPath = function() {
+ // TODO: Branch current matrix so that save/restore has no effect
+ // as per safari docs.
+ this.currentPath_ = [];
+ };
+
+ contextPrototype.moveTo = function(aX, aY) {
+ var p = getCoords(this, aX, aY);
+ this.currentPath_.push({type: 'moveTo', x: p.x, y: p.y});
+ this.currentX_ = p.x;
+ this.currentY_ = p.y;
+ };
+
+ contextPrototype.lineTo = function(aX, aY) {
+ var p = getCoords(this, aX, aY);
+ this.currentPath_.push({type: 'lineTo', x: p.x, y: p.y});
+
+ this.currentX_ = p.x;
+ this.currentY_ = p.y;
+ };
+
+ contextPrototype.bezierCurveTo = function(aCP1x, aCP1y,
+ aCP2x, aCP2y,
+ aX, aY) {
+ var p = getCoords(this, aX, aY);
+ var cp1 = getCoords(this, aCP1x, aCP1y);
+ var cp2 = getCoords(this, aCP2x, aCP2y);
+ bezierCurveTo(this, cp1, cp2, p);
+ };
+
+ // Helper function that takes the already fixed cordinates.
+ function bezierCurveTo(self, cp1, cp2, p) {
+ self.currentPath_.push({
+ type: 'bezierCurveTo',
+ cp1x: cp1.x,
+ cp1y: cp1.y,
+ cp2x: cp2.x,
+ cp2y: cp2.y,
+ x: p.x,
+ y: p.y
+ });
+ self.currentX_ = p.x;
+ self.currentY_ = p.y;
+ }
+
+ contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) {
+ // the following is lifted almost directly from
+ // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes
+
+ var cp = getCoords(this, aCPx, aCPy);
+ var p = getCoords(this, aX, aY);
+
+ var cp1 = {
+ x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_),
+ y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_)
+ };
+ var cp2 = {
+ x: cp1.x + (p.x - this.currentX_) / 3.0,
+ y: cp1.y + (p.y - this.currentY_) / 3.0
+ };
+
+ bezierCurveTo(this, cp1, cp2, p);
+ };
+
+ contextPrototype.arc = function(aX, aY, aRadius,
+ aStartAngle, aEndAngle, aClockwise) {
+ aRadius *= Z;
+ var arcType = aClockwise ? 'at' : 'wa';
+
+ var xStart = aX + mc(aStartAngle) * aRadius - Z2;
+ var yStart = aY + ms(aStartAngle) * aRadius - Z2;
+
+ var xEnd = aX + mc(aEndAngle) * aRadius - Z2;
+ var yEnd = aY + ms(aEndAngle) * aRadius - Z2;
+
+ // IE won't render arches drawn counter clockwise if xStart == xEnd.
+ if (xStart == xEnd && !aClockwise) {
+ xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something
+ // that can be represented in binary
+ }
+
+ var p = getCoords(this, aX, aY);
+ var pStart = getCoords(this, xStart, yStart);
+ var pEnd = getCoords(this, xEnd, yEnd);
+
+ this.currentPath_.push({type: arcType,
+ x: p.x,
+ y: p.y,
+ radius: aRadius,
+ xStart: pStart.x,
+ yStart: pStart.y,
+ xEnd: pEnd.x,
+ yEnd: pEnd.y});
+
+ };
+
+ contextPrototype.rect = function(aX, aY, aWidth, aHeight) {
+ this.moveTo(aX, aY);
+ this.lineTo(aX + aWidth, aY);
+ this.lineTo(aX + aWidth, aY + aHeight);
+ this.lineTo(aX, aY + aHeight);
+ this.closePath();
+ };
+
+ contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) {
+ var oldPath = this.currentPath_;
+ this.beginPath();
+
+ this.moveTo(aX, aY);
+ this.lineTo(aX + aWidth, aY);
+ this.lineTo(aX + aWidth, aY + aHeight);
+ this.lineTo(aX, aY + aHeight);
+ this.closePath();
+ this.stroke();
+
+ this.currentPath_ = oldPath;
+ };
+
+ contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) {
+ var oldPath = this.currentPath_;
+ this.beginPath();
+
+ this.moveTo(aX, aY);
+ this.lineTo(aX + aWidth, aY);
+ this.lineTo(aX + aWidth, aY + aHeight);
+ this.lineTo(aX, aY + aHeight);
+ this.closePath();
+ this.fill();
+
+ this.currentPath_ = oldPath;
+ };
+
+ contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) {
+ var gradient = new CanvasGradient_('gradient');
+ gradient.x0_ = aX0;
+ gradient.y0_ = aY0;
+ gradient.x1_ = aX1;
+ gradient.y1_ = aY1;
+ return gradient;
+ };
+
+ contextPrototype.createRadialGradient = function(aX0, aY0, aR0,
+ aX1, aY1, aR1) {
+ var gradient = new CanvasGradient_('gradientradial');
+ gradient.x0_ = aX0;
+ gradient.y0_ = aY0;
+ gradient.r0_ = aR0;
+ gradient.x1_ = aX1;
+ gradient.y1_ = aY1;
+ gradient.r1_ = aR1;
+ return gradient;
+ };
+
+ contextPrototype.drawImage = function(image, var_args) {
+ var dx, dy, dw, dh, sx, sy, sw, sh;
+
+ // to find the original width we overide the width and height
+ var oldRuntimeWidth = image.runtimeStyle.width;
+ var oldRuntimeHeight = image.runtimeStyle.height;
+ image.runtimeStyle.width = 'auto';
+ image.runtimeStyle.height = 'auto';
+
+ // get the original size
+ var w = image.width;
+ var h = image.height;
+
+ // and remove overides
+ image.runtimeStyle.width = oldRuntimeWidth;
+ image.runtimeStyle.height = oldRuntimeHeight;
+
+ if (arguments.length == 3) {
+ dx = arguments[1];
+ dy = arguments[2];
+ sx = sy = 0;
+ sw = dw = w;
+ sh = dh = h;
+ } else if (arguments.length == 5) {
+ dx = arguments[1];
+ dy = arguments[2];
+ dw = arguments[3];
+ dh = arguments[4];
+ sx = sy = 0;
+ sw = w;
+ sh = h;
+ } else if (arguments.length == 9) {
+ sx = arguments[1];
+ sy = arguments[2];
+ sw = arguments[3];
+ sh = arguments[4];
+ dx = arguments[5];
+ dy = arguments[6];
+ dw = arguments[7];
+ dh = arguments[8];
+ } else {
+ throw Error('Invalid number of arguments');
+ }
+
+ var d = getCoords(this, dx, dy);
+
+ var w2 = sw / 2;
+ var h2 = sh / 2;
+
+ var vmlStr = [];
+
+ var W = 10;
+ var H = 10;
+
+ // For some reason that I've now forgotten, using divs didn't work
+ vmlStr.push(' <g_vml_:group',
+ ' coordsize="', Z * W, ',', Z * H, '"',
+ ' coordorigin="0,0"' ,
+ ' style="width:', W, 'px;height:', H, 'px;position:absolute;');
+
+ // If filters are necessary (rotation exists), create them
+ // filters are bog-slow, so only create them if abbsolutely necessary
+ // The following check doesn't account for skews (which don't exist
+ // in the canvas spec (yet) anyway.
+
+ if (this.m_[0][0] != 1 || this.m_[0][1] ||
+ this.m_[1][1] != 1 || this.m_[1][0]) {
+ var filter = [];
+
+ // Note the 12/21 reversal
+ filter.push('M11=', this.m_[0][0], ',',
+ 'M12=', this.m_[1][0], ',',
+ 'M21=', this.m_[0][1], ',',
+ 'M22=', this.m_[1][1], ',',
+ 'Dx=', mr(d.x / Z), ',',
+ 'Dy=', mr(d.y / Z), '');
+
+ // Bounding box calculation (need to minimize displayed area so that
+ // filters don't waste time on unused pixels.
+ var max = d;
+ var c2 = getCoords(this, dx + dw, dy);
+ var c3 = getCoords(this, dx, dy + dh);
+ var c4 = getCoords(this, dx + dw, dy + dh);
+
+ max.x = m.max(max.x, c2.x, c3.x, c4.x);
+ max.y = m.max(max.y, c2.y, c3.y, c4.y);
+
+ vmlStr.push('padding:0 ', mr(max.x / Z), 'px ', mr(max.y / Z),
+ 'px 0;filter:progid:DXImageTransform.Microsoft.Matrix(',
+ filter.join(''), ", sizingmethod='clip');");
+
+ } else {
+ vmlStr.push('top:', mr(d.y / Z), 'px;left:', mr(d.x / Z), 'px;');
+ }
+
+ vmlStr.push(' ">' ,
+ '<g_vml_:image src="', image.src, '"',
+ ' style="width:', Z * dw, 'px;',
+ ' height:', Z * dh, 'px"',
+ ' cropleft="', sx / w, '"',
+ ' croptop="', sy / h, '"',
+ ' cropright="', (w - sx - sw) / w, '"',
+ ' cropbottom="', (h - sy - sh) / h, '"',
+ ' />',
+ '</g_vml_:group>');
+
+ this.element_.insertAdjacentHTML('BeforeEnd', vmlStr.join(''));
+ };
+
+ contextPrototype.stroke = function(aFill) {
+ var lineStr = [];
+ var lineOpen = false;
+
+ var W = 10;
+ var H = 10;
+
+ lineStr.push('<g_vml_:shape',
+ ' filled="', !!aFill, '"',
+ ' style="position:absolute;width:', W, 'px;height:', H, 'px;"',
+ ' coordorigin="0,0"',
+ ' coordsize="', Z * W, ',', Z * H, '"',
+ ' stroked="', !aFill, '"',
+ ' path="');
+
+ var newSeq = false;
+ var min = {x: null, y: null};
+ var max = {x: null, y: null};
+
+ for (var i = 0; i < this.currentPath_.length; i++) {
+ var p = this.currentPath_[i];
+ var c;
+
+ switch (p.type) {
+ case 'moveTo':
+ c = p;
+ lineStr.push(' m ', mr(p.x), ',', mr(p.y));
+ break;
+ case 'lineTo':
+ lineStr.push(' l ', mr(p.x), ',', mr(p.y));
+ break;
+ case 'close':
+ lineStr.push(' x ');
+ p = null;
+ break;
+ case 'bezierCurveTo':
+ lineStr.push(' c ',
+ mr(p.cp1x), ',', mr(p.cp1y), ',',
+ mr(p.cp2x), ',', mr(p.cp2y), ',',
+ mr(p.x), ',', mr(p.y));
+ break;
+ case 'at':
+ case 'wa':
+ lineStr.push(' ', p.type, ' ',
+ mr(p.x - this.arcScaleX_ * p.radius), ',',
+ mr(p.y - this.arcScaleY_ * p.radius), ' ',
+ mr(p.x + this.arcScaleX_ * p.radius), ',',
+ mr(p.y + this.arcScaleY_ * p.radius), ' ',
+ mr(p.xStart), ',', mr(p.yStart), ' ',
+ mr(p.xEnd), ',', mr(p.yEnd));
+ break;
+ }
+
+
+ // TODO: Following is broken for curves due to
+ // move to proper paths.
+
+ // Figure out dimensions so we can do gradient fills
+ // properly
+ if (p) {
+ if (min.x == null || p.x < min.x) {
+ min.x = p.x;
+ }
+ if (max.x == null || p.x > max.x) {
+ max.x = p.x;
+ }
+ if (min.y == null || p.y < min.y) {
+ min.y = p.y;
+ }
+ if (max.y == null || p.y > max.y) {
+ max.y = p.y;
+ }
+ }
+ }
+ lineStr.push(' ">');
+
+ if (!aFill) {
+ appendStroke(this, lineStr);
+ } else {
+ appendFill(this, lineStr, min, max);
+ }
+
+ lineStr.push('</g_vml_:shape>');
+
+ this.element_.insertAdjacentHTML('beforeEnd', lineStr.join(''));
+ };
+
+ function appendStroke(ctx, lineStr) {
+ var a = processStyle(ctx.strokeStyle);
+ var color = a.color;
+ var opacity = a.alpha * ctx.globalAlpha;
+ var lineWidth = ctx.lineScale_ * ctx.lineWidth;
+
+ // VML cannot correctly render a line if the width is less than 1px.
+ // In that case, we dilute the color to make the line look thinner.
+ if (lineWidth < 1) {
+ opacity *= lineWidth;
+ }
+
+ lineStr.push(
+ '<g_vml_:stroke',
+ ' opacity="', opacity, '"',
+ ' joinstyle="', ctx.lineJoin, '"',
+ ' miterlimit="', ctx.miterLimit, '"',
+ ' endcap="', processLineCap(ctx.lineCap), '"',
+ ' weight="', lineWidth, 'px"',
+ ' color="', color, '" />'
+ );
+ }
+
+ function appendFill(ctx, lineStr, min, max) {
+ var fillStyle = ctx.fillStyle;
+ var arcScaleX = ctx.arcScaleX_;
+ var arcScaleY = ctx.arcScaleY_;
+ var width = max.x - min.x;
+ var height = max.y - min.y;
+ if (fillStyle instanceof CanvasGradient_) {
+ // TODO: Gradients transformed with the transformation matrix.
+ var angle = 0;
+ var focus = {x: 0, y: 0};
+
+ // additional offset
+ var shift = 0;
+ // scale factor for offset
+ var expansion = 1;
+
+ if (fillStyle.type_ == 'gradient') {
+ var x0 = fillStyle.x0_ / arcScaleX;
+ var y0 = fillStyle.y0_ / arcScaleY;
+ var x1 = fillStyle.x1_ / arcScaleX;
+ var y1 = fillStyle.y1_ / arcScaleY;
+ var p0 = getCoords(ctx, x0, y0);
+ var p1 = getCoords(ctx, x1, y1);
+ var dx = p1.x - p0.x;
+ var dy = p1.y - p0.y;
+ angle = Math.atan2(dx, dy) * 180 / Math.PI;
+
+ // The angle should be a non-negative number.
+ if (angle < 0) {
+ angle += 360;
+ }
+
+ // Very small angles produce an unexpected result because they are
+ // converted to a scientific notation string.
+ if (angle < 1e-6) {
+ angle = 0;
+ }
+ } else {
+ var p0 = getCoords(ctx, fillStyle.x0_, fillStyle.y0_);
+ focus = {
+ x: (p0.x - min.x) / width,
+ y: (p0.y - min.y) / height
+ };
+
+ width /= arcScaleX * Z;
+ height /= arcScaleY * Z;
+ var dimension = m.max(width, height);
+ shift = 2 * fillStyle.r0_ / dimension;
+ expansion = 2 * fillStyle.r1_ / dimension - shift;
+ }
+
+ // We need to sort the color stops in ascending order by offset,
+ // otherwise IE won't interpret it correctly.
+ var stops = fillStyle.colors_;
+ stops.sort(function(cs1, cs2) {
+ return cs1.offset - cs2.offset;
+ });
+
+ var length = stops.length;
+ var color1 = stops[0].color;
+ var color2 = stops[length - 1].color;
+ var opacity1 = stops[0].alpha * ctx.globalAlpha;
+ var opacity2 = stops[length - 1].alpha * ctx.globalAlpha;
+
+ var colors = [];
+ for (var i = 0; i < length; i++) {
+ var stop = stops[i];
+ colors.push(stop.offset * expansion + shift + ' ' + stop.color);
+ }
+
+ // When colors attribute is used, the meanings of opacity and o:opacity2
+ // are reversed.
+ lineStr.push('<g_vml_:fill type="', fillStyle.type_, '"',
+ ' method="none" focus="100%"',
+ ' color="', color1, '"',
+ ' color2="', color2, '"',
+ ' colors="', colors.join(','), '"',
+ ' opacity="', opacity2, '"',
+ ' g_o_:opacity2="', opacity1, '"',
+ ' angle="', angle, '"',
+ ' focusposition="', focus.x, ',', focus.y, '" />');
+ } else if (fillStyle instanceof CanvasPattern_) {
+ if (width && height) {
+ var deltaLeft = -min.x;
+ var deltaTop = -min.y;
+ lineStr.push('<g_vml_:fill',
+ ' position="',
+ deltaLeft / width * arcScaleX * arcScaleX, ',',
+ deltaTop / height * arcScaleY * arcScaleY, '"',
+ ' type="tile"',
+ // TODO: Figure out the correct size to fit the scale.
+ //' size="', w, 'px ', h, 'px"',
+ ' src="', fillStyle.src_, '" />');
+ }
+ } else {
+ var a = processStyle(ctx.fillStyle);
+ var color = a.color;
+ var opacity = a.alpha * ctx.globalAlpha;
+ lineStr.push('<g_vml_:fill color="', color, '" opacity="', opacity,
+ '" />');
+ }
+ }
+
+ contextPrototype.fill = function() {
+ this.stroke(true);
+ };
+
+ contextPrototype.closePath = function() {
+ this.currentPath_.push({type: 'close'});
+ };
+
+ function getCoords(ctx, aX, aY) {
+ var m = ctx.m_;
+ return {
+ x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2,
+ y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2
+ };
+ };
+
+ contextPrototype.save = function() {
+ var o = {};
+ copyState(this, o);
+ this.aStack_.push(o);
+ this.mStack_.push(this.m_);
+ this.m_ = matrixMultiply(createMatrixIdentity(), this.m_);
+ };
+
+ contextPrototype.restore = function() {
+ if (this.aStack_.length) {
+ copyState(this.aStack_.pop(), this);
+ this.m_ = this.mStack_.pop();
+ }
+ };
+
+ function matrixIsFinite(m) {
+ return isFinite(m[0][0]) && isFinite(m[0][1]) &&
+ isFinite(m[1][0]) && isFinite(m[1][1]) &&
+ isFinite(m[2][0]) && isFinite(m[2][1]);
+ }
+
+ function setM(ctx, m, updateLineScale) {
+ if (!matrixIsFinite(m)) {
+ return;
+ }
+ ctx.m_ = m;
+
+ if (updateLineScale) {
+ // Get the line scale.
+ // Determinant of this.m_ means how much the area is enlarged by the
+ // transformation. So its square root can be used as a scale factor
+ // for width.
+ var det = m[0][0] * m[1][1] - m[0][1] * m[1][0];
+ ctx.lineScale_ = sqrt(abs(det));
+ }
+ }
+
+ contextPrototype.translate = function(aX, aY) {
+ var m1 = [
+ [1, 0, 0],
+ [0, 1, 0],
+ [aX, aY, 1]
+ ];
+
+ setM(this, matrixMultiply(m1, this.m_), false);
+ };
+
+ contextPrototype.rotate = function(aRot) {
+ var c = mc(aRot);
+ var s = ms(aRot);
+
+ var m1 = [
+ [c, s, 0],
+ [-s, c, 0],
+ [0, 0, 1]
+ ];
+
+ setM(this, matrixMultiply(m1, this.m_), false);
+ };
+
+ contextPrototype.scale = function(aX, aY) {
+ this.arcScaleX_ *= aX;
+ this.arcScaleY_ *= aY;
+ var m1 = [
+ [aX, 0, 0],
+ [0, aY, 0],
+ [0, 0, 1]
+ ];
+
+ setM(this, matrixMultiply(m1, this.m_), true);
+ };
+
+ contextPrototype.transform = function(m11, m12, m21, m22, dx, dy) {
+ var m1 = [
+ [m11, m12, 0],
+ [m21, m22, 0],
+ [dx, dy, 1]
+ ];
+
+ setM(this, matrixMultiply(m1, this.m_), true);
+ };
+
+ contextPrototype.setTransform = function(m11, m12, m21, m22, dx, dy) {
+ var m = [
+ [m11, m12, 0],
+ [m21, m22, 0],
+ [dx, dy, 1]
+ ];
+
+ setM(this, m, true);
+ };
+
+ /**
+ * The text drawing function.
+ * The maxWidth argument isn't taken in account, since no browser supports
+ * it yet.
+ */
+ contextPrototype.drawText_ = function(text, x, y, maxWidth, stroke) {
+ var m = this.m_,
+ delta = 1000,
+ left = 0,
+ right = delta,
+ offset = {x: 0, y: 0},
+ lineStr = [];
+
+ var fontStyle = getComputedStyle(processFontStyle(this.font), this.element_);
+
+ var fontStyleString = buildStyle(fontStyle);
+
+ var elementStyle = this.element_.currentStyle;
+ var textAlign = this.textAlign.toLowerCase();
+ switch (textAlign) {
+ case 'left':
+ case 'center':
+ case 'right':
+ break;
+ case 'end':
+ textAlign = elementStyle.direction == 'ltr' ? 'right' : 'left';
+ break;
+ case 'start':
+ textAlign = elementStyle.direction == 'rtl' ? 'right' : 'left';
+ break;
+ default:
+ textAlign = 'left';
+ }
+
+ // 1.75 is an arbitrary number, as there is no info about the text baseline
+ switch (this.textBaseline) {
+ case 'hanging':
+ case 'top':
+ offset.y = fontStyle.size / 1.75;
+ break;
+ case 'middle':
+ break;
+ default:
+ case null:
+ case 'alphabetic':
+ case 'ideographic':
+ case 'bottom':
+ offset.y = -fontStyle.size / 2.25;
+ break;
+ }
+
+ switch(textAlign) {
+ case 'right':
+ left = delta;
+ right = 0.05;
+ break;
+ case 'center':
+ left = right = delta / 2;
+ break;
+ }
+
+ var d = getCoords(this, x + offset.x, y + offset.y);
+
+ lineStr.push('<g_vml_:line from="', -left ,' 0" to="', right ,' 0.05" ',
+ ' coordsize="100 100" coordorigin="0 0"',
+ ' filled="', !stroke, '" stroked="', !!stroke,
+ '" style="position:absolute;width:1px;height:1px;">');
+
+ if (stroke) {
+ appendStroke(this, lineStr);
+ } else {
+ // TODO: Fix the min and max params.
+ appendFill(this, lineStr, {x: -left, y: 0},
+ {x: right, y: fontStyle.size});
+ }
+
+ var skewM = m[0][0].toFixed(3) + ',' + m[1][0].toFixed(3) + ',' +
+ m[0][1].toFixed(3) + ',' + m[1][1].toFixed(3) + ',0,0';
+
+ var skewOffset = mr(d.x / Z + 1 - m[0][0]) + ',' + mr(d.y / Z - 2 * m[1][0]);
+
+
+ lineStr.push('<g_vml_:skew on="t" matrix="', skewM ,'" ',
+ ' offset="', skewOffset, '" origin="', left ,' 0" />',
+ '<g_vml_:path textpathok="true" />',
+ '<g_vml_:textpath on="true" string="',
+ encodeHtmlAttribute(text),
+ '" style="v-text-align:', textAlign,
+ ';font:', encodeHtmlAttribute(fontStyleString),
+ '" /></g_vml_:line>');
+
+ this.element_.insertAdjacentHTML('beforeEnd', lineStr.join(''));
+ };
+
+ contextPrototype.fillText = function(text, x, y, maxWidth) {
+ this.drawText_(text, x, y, maxWidth, false);
+ };
+
+ contextPrototype.strokeText = function(text, x, y, maxWidth) {
+ this.drawText_(text, x, y, maxWidth, true);
+ };
+
+ contextPrototype.measureText = function(text) {
+ if (!this.textMeasureEl_) {
+ var s = '<span style="position:absolute;' +
+ 'top:-20000px;left:0;padding:0;margin:0;border:none;' +
+ 'white-space:pre;"></span>';
+ this.element_.insertAdjacentHTML('beforeEnd', s);
+ this.textMeasureEl_ = this.element_.lastChild;
+ }
+ var doc = this.element_.ownerDocument;
+ this.textMeasureEl_.innerHTML = '';
+ this.textMeasureEl_.style.font = this.font;
+ // Don't use innerHTML or innerText because they allow markup/whitespace.
+ this.textMeasureEl_.appendChild(doc.createTextNode(text));
+ return {width: this.textMeasureEl_.offsetWidth};
+ };
+
+ /******** STUBS ********/
+ contextPrototype.clip = function() {
+ // TODO: Implement
+ };
+
+ contextPrototype.arcTo = function() {
+ // TODO: Implement
+ };
+
+ contextPrototype.createPattern = function(image, repetition) {
+ return new CanvasPattern_(image, repetition);
+ };
+
+ // Gradient / Pattern Stubs
+ function CanvasGradient_(aType) {
+ this.type_ = aType;
+ this.x0_ = 0;
+ this.y0_ = 0;
+ this.r0_ = 0;
+ this.x1_ = 0;
+ this.y1_ = 0;
+ this.r1_ = 0;
+ this.colors_ = [];
+ }
+
+ CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) {
+ aColor = processStyle(aColor);
+ this.colors_.push({offset: aOffset,
+ color: aColor.color,
+ alpha: aColor.alpha});
+ };
+
+ function CanvasPattern_(image, repetition) {
+ assertImageIsValid(image);
+ switch (repetition) {
+ case 'repeat':
+ case null:
+ case '':
+ this.repetition_ = 'repeat';
+ break;
+ case 'repeat-x':
+ case 'repeat-y':
+ case 'no-repeat':
+ this.repetition_ = repetition;
+ break;
+ default:
+ throwException('SYNTAX_ERR');
+ }
+
+ this.src_ = image.src;
+ this.width_ = image.width;
+ this.height_ = image.height;
+ }
+
+ function throwException(s) {
+ throw new DOMException_(s);
+ }
+
+ function assertImageIsValid(img) {
+ if (!img || img.nodeType != 1 || img.tagName != 'IMG') {
+ throwException('TYPE_MISMATCH_ERR');
+ }
+ if (img.readyState != 'complete') {
+ throwException('INVALID_STATE_ERR');
+ }
+ }
+
+ function DOMException_(s) {
+ this.code = this[s];
+ this.message = s +': DOM Exception ' + this.code;
+ }
+ var p = DOMException_.prototype = new Error;
+ p.INDEX_SIZE_ERR = 1;
+ p.DOMSTRING_SIZE_ERR = 2;
+ p.HIERARCHY_REQUEST_ERR = 3;
+ p.WRONG_DOCUMENT_ERR = 4;
+ p.INVALID_CHARACTER_ERR = 5;
+ p.NO_DATA_ALLOWED_ERR = 6;
+ p.NO_MODIFICATION_ALLOWED_ERR = 7;
+ p.NOT_FOUND_ERR = 8;
+ p.NOT_SUPPORTED_ERR = 9;
+ p.INUSE_ATTRIBUTE_ERR = 10;
+ p.INVALID_STATE_ERR = 11;
+ p.SYNTAX_ERR = 12;
+ p.INVALID_MODIFICATION_ERR = 13;
+ p.NAMESPACE_ERR = 14;
+ p.INVALID_ACCESS_ERR = 15;
+ p.VALIDATION_ERR = 16;
+ p.TYPE_MISMATCH_ERR = 17;
+
+ // set up externs
+ G_vmlCanvasManager = G_vmlCanvasManager_;
+ CanvasRenderingContext2D = CanvasRenderingContext2D_;
+ CanvasGradient = CanvasGradient_;
+ CanvasPattern = CanvasPattern_;
+ DOMException = DOMException_;
+ G_vmlCanvasManager._version = 888;
+})();
+
+} // if
Added: gnucash/trunk/src/report/jqplot/excanvas.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/excanvas.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/excanvas.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot @VERSION | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */if(!document.createElement("canvas").getContext){(function(){var ab=Math;var n=ab.round;var l=ab.sin;var A=ab.cos;var H=ab.abs;var N=ab.sqrt;var d=10;var f=d/2;var z=+navigator.userAgent.match(/MSIE ([\d.]+)?/)[1];function y(){return this.context_||(this.context_=new D(this))}var t=Array.prototype.slice;function g(j,m,p){var i=t.call(arguments,2);return function(){return j.apply(m,i.concat(t.call(arguments)))}}function af(i){return String(i).replace(/&/g,"&").replace(/"/g,""")}function Y(m,j,i){if(!m.namespaces[j]){m.namespaces.add(j,i,"#default#VML")}}function R(j){Y(j,"g_vml_","urn:schemas-microsoft-com:vml");Y(j,"g_o_","urn:schemas-microsoft-com:office:office");if(!j.styleSheets.ex_canvas_){var i=j.createStyleSheet();i.owningElement.id="ex_canvas_";i.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}"}}R(document);var e={init:function(i){var j=i||document;j.createElement("canvas");j.attachEvent("onreadystatechange",g(this.init_,this,j))},init_:function(p){var m=p.getElementsByTagName("canvas");for(var j=0;j<m.length;j++){this.initElement(m[j])}},initElement:function(j){if(!j.getContext){j.getContext=y;R(j.ownerDocument);j.innerHTML="";j.attachEvent("onpropertychange",x);j.attachEvent("onresize",W);var i=j.attributes;if(i.width&&i.width.specified){j.style.width=i.width.nodeValue+"px"}else{j.width=j.clientWidth}if(i.height&&i.height.specified){j.style.height=i.height.nodeValue+"px"}else{j.height=j.clientHeight}}return j},uninitElement:function(j){if(j.getContext){var i=j.getContext();delete i.element_;delete i.canvas;j.innerHTML="";j.context_=null;j.getContext=null;j.detachEvent("onpropertychange",x);j.detachEvent("onresize",W)}}};function x(j){var i=j.srcElement;switch(j.propertyName){case"width":i.getContext().clearRect();i.style.width=i.attributes.width.nodeValue+"px";i.firstChild.style.width=i.clientWidth+"px";break;case"height":i.getContext().clearRect();i.style.height=i.attributes.height.nodeValue+"px";i.firstChild.style.height=i.clientHeigh!
t+"px";break}}function W(j){var i=j.srcElement;if(i.firstChild){i.firstChild.style.width=i.clientWidth+"px";i.firstChild.style.height=i.clientHeight+"px"}}e.init();var k=[];for(var ae=0;ae<16;ae++){for(var ad=0;ad<16;ad++){k[ae*16+ad]=ae.toString(16)+ad.toString(16)}}function B(){return[[1,0,0],[0,1,0],[0,0,1]]}function J(p,m){var j=B();for(var i=0;i<3;i++){for(var ah=0;ah<3;ah++){var Z=0;for(var ag=0;ag<3;ag++){Z+=p[i][ag]*m[ag][ah]}j[i][ah]=Z}}return j}function v(j,i){i.fillStyle=j.fillStyle;i.lineCap=j.lineCap;i.lineJoin=j.lineJoin;i.lineWidth=j.lineWidth;i.miterLimit=j.miterLimit;i.shadowBlur=j.shadowBlur;i.shadowColor=j.shadowColor;i.shadowOffsetX=j.shadowOffsetX;i.shadowOffsetY=j.shadowOffsetY;i.strokeStyle=j.strokeStyle;i.globalAlpha=j.globalAlpha;i.font=j.font;i.textAlign=j.textAlign;i.textBaseline=j.textBaseline;i.arcScaleX_=j.arcScaleX_;i.arcScaleY_=j.arcScaleY_;i.lineScale_=j.lineScale_}var b={aliceblue:"#F0F8FF",antiquewhite:"#FAEBD7",aquamarine:"#7FFFD4",azure:"#F0FFFF",beige:"#F5F5DC",bisque:"#FFE4C4",black:"#000000",blanchedalmond:"#FFEBCD",blueviolet:"#8A2BE2",brown:"#A52A2A",burlywood:"#DEB887",cadetblue:"#5F9EA0",chartreuse:"#7FFF00",chocolate:"#D2691E",coral:"#FF7F50",cornflowerblue:"#6495ED",cornsilk:"#FFF8DC",crimson:"#DC143C",cyan:"#00FFFF",darkblue:"#00008B",darkcyan:"#008B8B",darkgoldenrod:"#B8860B",darkgray:"#A9A9A9",darkgreen:"#006400",darkgrey:"#A9A9A9",darkkhaki:"#BDB76B",darkmagenta:"#8B008B",darkolivegreen:"#556B2F",darkorange:"#FF8C00",darkorchid:"#9932CC",darkred:"#8B0000",darksalmon:"#E9967A",darkseagreen:"#8FBC8F",darkslateblue:"#483D8B",darkslategray:"#2F4F4F",darkslategrey:"#2F4F4F",darkturquoise:"#00CED1",darkviolet:"#9400D3",deeppink:"#FF1493",deepskyblue:"#00BFFF",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1E90FF",firebrick:"#B22222",floralwhite:"#FFFAF0",forestgreen:"#228B22",gainsboro:"#DCDCDC",ghostwhite:"#F8F8FF",gold:"#FFD700",goldenrod:"#DAA520",grey:"#808080",greenyellow:"#ADFF2F",honeydew:"#F0FFF0",hotpink:"#FF69B4",indianred:"#CD5C5C",indigo:"#4B0082",ivory:"!
#FFFFF0",khaki:"#F0E68C",lavender:"#E6E6FA",lavenderblush:"#FFF0F5",lawngreen:"#7CFC00",lemonchiffon:"#FFFACD",lightblue:"#ADD8E6",lightcoral:"#F08080",lightcyan:"#E0FFFF",lightgoldenrodyellow:"#FAFAD2",lightgreen:"#90EE90",lightgrey:"#D3D3D3",lightpink:"#FFB6C1",lightsalmon:"#FFA07A",lightseagreen:"#20B2AA",lightskyblue:"#87CEFA",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#B0C4DE",lightyellow:"#FFFFE0",limegreen:"#32CD32",linen:"#FAF0E6",magenta:"#FF00FF",mediumaquamarine:"#66CDAA",mediumblue:"#0000CD",mediumorchid:"#BA55D3",mediumpurple:"#9370DB",mediumseagreen:"#3CB371",mediumslateblue:"#7B68EE",mediumspringgreen:"#00FA9A",mediumturquoise:"#48D1CC",mediumvioletred:"#C71585",midnightblue:"#191970",mintcream:"#F5FFFA",mistyrose:"#FFE4E1",moccasin:"#FFE4B5",navajowhite:"#FFDEAD",oldlace:"#FDF5E6",olivedrab:"#6B8E23",orange:"#FFA500",orangered:"#FF4500",orchid:"#DA70D6",palegoldenrod:"#EEE8AA",palegreen:"#98FB98",paleturquoise:"#AFEEEE",palevioletred:"#DB7093",papayawhip:"#FFEFD5",peachpuff:"#FFDAB9",peru:"#CD853F",pink:"#FFC0CB",plum:"#DDA0DD",powderblue:"#B0E0E6",rosybrown:"#BC8F8F",royalblue:"#4169E1",saddlebrown:"#8B4513",salmon:"#FA8072",sandybrown:"#F4A460",seagreen:"#2E8B57",seashell:"#FFF5EE",sienna:"#A0522D",skyblue:"#87CEEB",slateblue:"#6A5ACD",slategray:"#708090",slategrey:"#708090",snow:"#FFFAFA",springgreen:"#00FF7F",steelblue:"#4682B4",tan:"#D2B48C",thistle:"#D8BFD8",tomato:"#FF6347",turquoise:"#40E0D0",violet:"#EE82EE",wheat:"#F5DEB3",whitesmoke:"#F5F5F5",yellowgreen:"#9ACD32"};function M(j){var p=j.indexOf("(",3);var i=j.indexOf(")",p+1);var m=j.substring(p+1,i).split(",");if(m.length!=4||j.charAt(3)!="a"){m[3]=1}return m}function c(i){return parseFloat(i)/100}function r(j,m,i){return Math.min(i,Math.max(m,j))}function I(ag){var i,ai,aj,ah,ak,Z;ah=parseFloat(ag[0])/360%360;if(ah<0){ah++}ak=r(c(ag[1]),0,1);Z=r(c(ag[2]),0,1);if(ak==0){i=ai=aj=Z}else{var j=Z<0.5?Z*(1+ak):Z+ak-Z*ak;var m=2*Z-j;i=a(m,j,ah+1/3);ai=a(m,j,ah);aj=a(m,j,ah-1/3)}return"#"+k[Math.floor(i*255)]+k[Math.fl!
oor(ai*255)]+k[Math.floor(aj*255)]}function a(j,i,m){if(m<0){m++}if(m>1){m--}if(6*m<1){return j+(i-j)*6*m}else{if(2*m<1){return i}else{if(3*m<2){return j+(i-j)*(2/3-m)*6}else{return j}}}}var C={};function F(j){if(j in C){return C[j]}var ag,Z=1;j=String(j);if(j.charAt(0)=="#"){ag=j}else{if(/^rgb/.test(j)){var p=M(j);var ag="#",ah;for(var m=0;m<3;m++){if(p[m].indexOf("%")!=-1){ah=Math.floor(c(p[m])*255)}else{ah=+p[m]}ag+=k[r(ah,0,255)]}Z=+p[3]}else{if(/^hsl/.test(j)){var p=M(j);ag=I(p);Z=p[3]}else{ag=b[j]||j}}}return C[j]={color:ag,alpha:Z}}var o={style:"normal",variant:"normal",weight:"normal",size:10,family:"sans-serif"};var L={};function E(i){if(L[i]){return L[i]}var p=document.createElement("div");var m=p.style;try{m.font=i}catch(j){}return L[i]={style:m.fontStyle||o.style,variant:m.fontVariant||o.variant,weight:m.fontWeight||o.weight,size:m.fontSize||o.size,family:m.fontFamily||o.family}}function u(m,j){var i={};for(var ah in m){i[ah]=m[ah]}var ag=parseFloat(j.currentStyle.fontSize),Z=parseFloat(m.size);if(typeof m.size=="number"){i.size=m.size}else{if(m.size.indexOf("px")!=-1){i.size=Z}else{if(m.size.indexOf("em")!=-1){i.size=ag*Z}else{if(m.size.indexOf("%")!=-1){i.size=(ag/100)*Z}else{if(m.size.indexOf("pt")!=-1){i.size=Z/0.75}else{i.size=ag}}}}}i.size*=0.981;i.family="'"+i.family.replace(/(\'|\")/g,"").replace(/\s*,\s*/g,"', '")+"'";return i}function ac(i){return i.style+" "+i.variant+" "+i.weight+" "+i.size+"px "+i.family}var s={butt:"flat",round:"round"};function S(i){return s[i]||"square"}function D(i){this.m_=B();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=d*1;this.globalAlpha=1;this.font="10px sans-serif";this.textAlign="left";this.textBaseline="alphabetic";this.canvas=i;var m="width:"+i.clientWidth+"px;height:"+i.clientHeight+"px;overflow:hidden;position:absolute";var j=i.ownerDocument.createElement("div");j.style.cssText=m;i.appendChild(j);var p=j.cloneNode(false);p.style!
.backgroundColor="red";p.style.filter="alpha(opacity=0)";i.appendChild(p);this.element_=j;this.arcScaleX_=1;this.arcScaleY_=1;this.lineScale_=1}var q=D.prototype;q.clearRect=function(){if(this.textMeasureEl_){this.textMeasureEl_.removeNode(true);this.textMeasureEl_=null}this.element_.innerHTML=""};q.beginPath=function(){this.currentPath_=[]};q.moveTo=function(j,i){var m=V(this,j,i);this.currentPath_.push({type:"moveTo",x:m.x,y:m.y});this.currentX_=m.x;this.currentY_=m.y};q.lineTo=function(j,i){var m=V(this,j,i);this.currentPath_.push({type:"lineTo",x:m.x,y:m.y});this.currentX_=m.x;this.currentY_=m.y};q.bezierCurveTo=function(m,j,ak,aj,ai,ag){var i=V(this,ai,ag);var ah=V(this,m,j);var Z=V(this,ak,aj);K(this,ah,Z,i)};function K(i,Z,m,j){i.currentPath_.push({type:"bezierCurveTo",cp1x:Z.x,cp1y:Z.y,cp2x:m.x,cp2y:m.y,x:j.x,y:j.y});i.currentX_=j.x;i.currentY_=j.y}q.quadraticCurveTo=function(ai,m,j,i){var ah=V(this,ai,m);var ag=V(this,j,i);var aj={x:this.currentX_+2/3*(ah.x-this.currentX_),y:this.currentY_+2/3*(ah.y-this.currentY_)};var Z={x:aj.x+(ag.x-this.currentX_)/3,y:aj.y+(ag.y-this.currentY_)/3};K(this,aj,Z,ag)};q.arc=function(al,aj,ak,ag,j,m){ak*=d;var ap=m?"at":"wa";var am=al+A(ag)*ak-f;var ao=aj+l(ag)*ak-f;var i=al+A(j)*ak-f;var an=aj+l(j)*ak-f;if(am==i&&!m){am+=0.125}var Z=V(this,al,aj);var ai=V(this,am,ao);var ah=V(this,i,an);this.currentPath_.push({type:ap,x:Z.x,y:Z.y,radius:ak,xStart:ai.x,yStart:ai.y,xEnd:ah.x,yEnd:ah.y})};q.rect=function(m,j,i,p){this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath()};q.strokeRect=function(m,j,i,p){var Z=this.currentPath_;this.beginPath();this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath();this.stroke();this.currentPath_=Z};q.fillRect=function(m,j,i,p){var Z=this.currentPath_;this.beginPath();this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath();this.fill();this.currentPath_=Z};q.createLinearGradient=function(j,p,i,m){var Z=new U("gradient");Z.x0_=j;Z.y0_=p!
;Z.x1_=i;Z.y1_=m;return Z};q.createRadialGradient=function(p,ag,m,j,Z,i){var ah=new U("gradientradial");ah.x0_=p;ah.y0_=ag;ah.r0_=m;ah.x1_=j;ah.y1_=Z;ah.r1_=i;return ah};q.drawImage=function(aq,m){var aj,ah,al,ay,ao,am,at,aA;var ak=aq.runtimeStyle.width;var ap=aq.runtimeStyle.height;aq.runtimeStyle.width="auto";aq.runtimeStyle.height="auto";var ai=aq.width;var aw=aq.height;aq.runtimeStyle.width=ak;aq.runtimeStyle.height=ap;if(arguments.length==3){aj=arguments[1];ah=arguments[2];ao=am=0;at=al=ai;aA=ay=aw}else{if(arguments.length==5){aj=arguments[1];ah=arguments[2];al=arguments[3];ay=arguments[4];ao=am=0;at=ai;aA=aw}else{if(arguments.length==9){ao=arguments[1];am=arguments[2];at=arguments[3];aA=arguments[4];aj=arguments[5];ah=arguments[6];al=arguments[7];ay=arguments[8]}else{throw Error("Invalid number of arguments")}}}var az=V(this,aj,ah);var p=at/2;var j=aA/2;var ax=[];var i=10;var ag=10;ax.push(" <g_vml_:group",' coordsize="',d*i,",",d*ag,'"',' coordorigin="0,0"',' style="width:',i,"px;height:",ag,"px;position:absolute;");if(this.m_[0][0]!=1||this.m_[0][1]||this.m_[1][1]!=1||this.m_[1][0]){var Z=[];Z.push("M11=",this.m_[0][0],",","M12=",this.m_[1][0],",","M21=",this.m_[0][1],",","M22=",this.m_[1][1],",","Dx=",n(az.x/d),",","Dy=",n(az.y/d),"");var av=az;var au=V(this,aj+al,ah);var ar=V(this,aj,ah+ay);var an=V(this,aj+al,ah+ay);av.x=ab.max(av.x,au.x,ar.x,an.x);av.y=ab.max(av.y,au.y,ar.y,an.y);ax.push("padding:0 ",n(av.x/d),"px ",n(av.y/d),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",Z.join(""),", sizingmethod='clip');")}else{ax.push("top:",n(az.y/d),"px;left:",n(az.x/d),"px;")}ax.push(' ">','<g_vml_:image src="',aq.src,'"',' style="width:',d*al,"px;"," height:",d*ay,'px"',' cropleft="',ao/ai,'"',' croptop="',am/aw,'"',' cropright="',(ai-ao-at)/ai,'"',' cropbottom="',(aw-am-aA)/aw,'"'," />","</g_vml_:group>");this.element_.insertAdjacentHTML("BeforeEnd",ax.join(""))};q.stroke=function(al){var aj=[];var Z=false;var m=10;var am=10;aj.push("<g_vml_:shape",' filled="',!!al,'"',' style="position:absolute;wid!
th:',m,"px;height:",am,'px;"',' coordorigin="0,0"',' coordsize="',d*m,",",d*am,'"',' stroked="',!al,'"',' path="');var an=false;var ag={x:null,y:null};var ak={x:null,y:null};for(var ah=0;ah<this.currentPath_.length;ah++){var j=this.currentPath_[ah];var ai;switch(j.type){case"moveTo":ai=j;aj.push(" m ",n(j.x),",",n(j.y));break;case"lineTo":aj.push(" l ",n(j.x),",",n(j.y));break;case"close":aj.push(" x ");j=null;break;case"bezierCurveTo":aj.push(" c ",n(j.cp1x),",",n(j.cp1y),",",n(j.cp2x),",",n(j.cp2y),",",n(j.x),",",n(j.y));break;case"at":case"wa":aj.push(" ",j.type," ",n(j.x-this.arcScaleX_*j.radius),",",n(j.y-this.arcScaleY_*j.radius)," ",n(j.x+this.arcScaleX_*j.radius),",",n(j.y+this.arcScaleY_*j.radius)," ",n(j.xStart),",",n(j.yStart)," ",n(j.xEnd),",",n(j.yEnd));break}if(j){if(ag.x==null||j.x<ag.x){ag.x=j.x}if(ak.x==null||j.x>ak.x){ak.x=j.x}if(ag.y==null||j.y<ag.y){ag.y=j.y}if(ak.y==null||j.y>ak.y){ak.y=j.y}}}aj.push(' ">');if(!al){w(this,aj)}else{G(this,aj,ag,ak)}aj.push("</g_vml_:shape>");this.element_.insertAdjacentHTML("beforeEnd",aj.join(""))};function w(m,ag){var j=F(m.strokeStyle);var p=j.color;var Z=j.alpha*m.globalAlpha;var i=m.lineScale_*m.lineWidth;if(i<1){Z*=i}ag.push("<g_vml_:stroke",' opacity="',Z,'"',' joinstyle="',m.lineJoin,'"',' miterlimit="',m.miterLimit,'"',' endcap="',S(m.lineCap),'"',' weight="',i,'px"',' color="',p,'" />')}function G(aq,ai,aK,ar){var aj=aq.fillStyle;var aB=aq.arcScaleX_;var aA=aq.arcScaleY_;var j=ar.x-aK.x;var p=ar.y-aK.y;if(aj instanceof U){var an=0;var aF={x:0,y:0};var ax=0;var am=1;if(aj.type_=="gradient"){var al=aj.x0_/aB;var m=aj.y0_/aA;var ak=aj.x1_/aB;var aM=aj.y1_/aA;var aJ=V(aq,al,m);var aI=V(aq,ak,aM);var ag=aI.x-aJ.x;var Z=aI.y-aJ.y;an=Math.atan2(ag,Z)*180/Math.PI;if(an<0){an+=360}if(an<0.000001){an=0}}else{var aJ=V(aq,aj.x0_,aj.y0_);aF={x:(aJ.x-aK.x)/j,y:(aJ.y-aK.y)/p};j/=aB*d;p/=aA*d;var aD=ab.max(j,p);ax=2*aj.r0_/aD;am=2*aj.r1_/aD-ax}var av=aj.colors_;av.sort(function(aN,i){return aN.offset-i.offset});var ap=av.length;var au=av[0].color;var at=av[ap-1].co!
lor;var az=av[0].alpha*aq.globalAlpha;var ay=av[ap-1].alpha*aq.globalAlpha;var aE=[];for(var aH=0;aH<ap;aH++){var ao=av[aH];aE.push(ao.offset*am+ax+" "+ao.color)}ai.push('<g_vml_:fill type="',aj.type_,'"',' method="none" focus="100%"',' color="',au,'"',' color2="',at,'"',' colors="',aE.join(","),'"',' opacity="',ay,'"',' g_o_:opacity2="',az,'"',' angle="',an,'"',' focusposition="',aF.x,",",aF.y,'" />')}else{if(aj instanceof T){if(j&&p){var ah=-aK.x;var aC=-aK.y;ai.push("<g_vml_:fill",' position="',ah/j*aB*aB,",",aC/p*aA*aA,'"',' type="tile"',' src="',aj.src_,'" />')}}else{var aL=F(aq.fillStyle);var aw=aL.color;var aG=aL.alpha*aq.globalAlpha;ai.push('<g_vml_:fill color="',aw,'" opacity="',aG,'" />')}}}q.fill=function(){this.stroke(true)};q.closePath=function(){this.currentPath_.push({type:"close"})};function V(j,Z,p){var i=j.m_;return{x:d*(Z*i[0][0]+p*i[1][0]+i[2][0])-f,y:d*(Z*i[0][1]+p*i[1][1]+i[2][1])-f}}q.save=function(){var i={};v(this,i);this.aStack_.push(i);this.mStack_.push(this.m_);this.m_=J(B(),this.m_)};q.restore=function(){if(this.aStack_.length){v(this.aStack_.pop(),this);this.m_=this.mStack_.pop()}};function h(i){return isFinite(i[0][0])&&isFinite(i[0][1])&&isFinite(i[1][0])&&isFinite(i[1][1])&&isFinite(i[2][0])&&isFinite(i[2][1])}function aa(j,i,p){if(!h(i)){return}j.m_=i;if(p){var Z=i[0][0]*i[1][1]-i[0][1]*i[1][0];j.lineScale_=N(H(Z))}}q.translate=function(m,j){var i=[[1,0,0],[0,1,0],[m,j,1]];aa(this,J(i,this.m_),false)};q.rotate=function(j){var p=A(j);var m=l(j);var i=[[p,m,0],[-m,p,0],[0,0,1]];aa(this,J(i,this.m_),false)};q.scale=function(m,j){this.arcScaleX_*=m;this.arcScaleY_*=j;var i=[[m,0,0],[0,j,0],[0,0,1]];aa(this,J(i,this.m_),true)};q.transform=function(Z,p,ah,ag,j,i){var m=[[Z,p,0],[ah,ag,0],[j,i,1]];aa(this,J(m,this.m_),true)};q.setTransform=function(ag,Z,ai,ah,p,j){var i=[[ag,Z,0],[ai,ah,0],[p,j,1]];aa(this,i,true)};q.drawText_=function(am,ak,aj,ap,ai){var ao=this.m_,at=1000,j=0,ar=at,ah={x:0,y:0},ag=[];var i=u(E(this.font),this.element_);var p=ac(i);var au=this.element_.currentStyle;va!
r Z=this..textAlign.toLowerCase();switch(Z){case"left":case"center":case"right":break;case"end":Z=au.direction=="ltr"?"right":"left";break;case"start":Z=au.direction=="rtl"?"right":"left";break;default:Z="left"}switch(this.textBaseline){case"hanging":case"top":ah.y=i.size/1.75;break;case"middle":break;default:case null:case"alphabetic":case"ideographic":case"bottom":ah.y=-i.size/2.25;break}switch(Z){case"right":j=at;ar=0.05;break;case"center":j=ar=at/2;break}var aq=V(this,ak+ah.x,aj+ah.y);ag.push('<g_vml_:line from="',-j,' 0" to="',ar,' 0.05" ',' coordsize="100 100" coordorigin="0 0"',' filled="',!ai,'" stroked="',!!ai,'" style="position:absolute;width:1px;height:1px;">');if(ai){w(this,ag)}else{G(this,ag,{x:-j,y:0},{x:ar,y:i.size})}var an=ao[0][0].toFixed(3)+","+ao[1][0].toFixed(3)+","+ao[0][1].toFixed(3)+","+ao[1][1].toFixed(3)+",0,0";var al=n(aq.x/d+1-ao[0][0])+","+n(aq.y/d-2*ao[1][0]);ag.push('<g_vml_:skew on="t" matrix="',an,'" ',' offset="',al,'" origin="',j,' 0" />','<g_vml_:path textpathok="true" />','<g_vml_:textpath on="true" string="',af(am),'" style="v-text-align:',Z,";font:",af(p),'" /></g_vml_:line>');this.element_.insertAdjacentHTML("beforeEnd",ag.join(""))};q.fillText=function(m,i,p,j){this.drawText_(m,i,p,j,false)};q.strokeText=function(m,i,p,j){this.drawText_(m,i,p,j,true)};q.measureText=function(m){if(!this.textMeasureEl_){var i='<span style="position:absolute;top:-20000px;left:0;padding:0;margin:0;border:none;white-space:pre;"></span>';this.element_.insertAdjacentHTML("beforeEnd",i);this.textMeasureEl_=this.element_.lastChild}var j=this.element_.ownerDocument;this.textMeasureEl_.innerHTML="";this.textMeasureEl_.style.font=this.font;this.textMeasureEl_.appendChild(j.createTextNode(m));return{width:this.textMeasureEl_.offsetWidth}};q.clip=function(){};q.arcTo=function(){};q.createPattern=function(j,i){return new T(j,i)};function U(i){this.type_=i;this.x0_=0;this.y0_=0;this.r0_=0;this.x1_=0;this.y1_=0;this.r1_=0;this.colors_=[]}U.prototype.addColorStop=function(j,i){i=F(i);this.colors_.push({offse!
t:j,color:i.color,alpha:i.alpha})};function T(j,i){Q(j);switch(i){case"repeat":case null:case"":this.repetition_="repeat";break;case"repeat-x":case"repeat-y":case"no-repeat":this.repetition_=i;break;default:O("SYNTAX_ERR")}this.src_=j.src;this.width_=j.width;this.height_=j.height}function O(i){throw new P(i)}function Q(i){if(!i||i.nodeType!=1||i.tagName!="IMG"){O("TYPE_MISMATCH_ERR")}if(i.readyState!="complete"){O("INVALID_STATE_ERR")}}function P(i){this.code=this[i];this.message=i+": DOM Exception "+this.code}var X=P.prototype=new Error;X.INDEX_SIZE_ERR=1;X.DOMSTRING_SIZE_ERR=2;X.HIERARCHY_REQUEST_ERR=3;X.WRONG_DOCUMENT_ERR=4;X.INVALID_CHARACTER_ERR=5;X.NO_DATA_ALLOWED_ERR=6;X.NO_MODIFICATION_ALLOWED_ERR=7;X.NOT_FOUND_ERR=8;X.NOT_SUPPORTED_ERR=9;X.INUSE_ATTRIBUTE_ERR=10;X.INVALID_STATE_ERR=11;X.SYNTAX_ERR=12;X.INVALID_MODIFICATION_ERR=13;X.NAMESPACE_ERR=14;X.INVALID_ACCESS_ERR=15;X.VALIDATION_ERR=16;X.TYPE_MISMATCH_ERR=17;G_vmlCanvasManager=e;CanvasRenderingContext2D=D;CanvasGradient=U;CanvasPattern=T;DOMException=P;G_vmlCanvasManager._version=888})()};
\ No newline at end of file
Added: gnucash/trunk/src/report/jqplot/jqPlotCssStyling.txt
===================================================================
--- gnucash/trunk/src/report/jqplot/jqPlotCssStyling.txt (rev 0)
+++ gnucash/trunk/src/report/jqplot/jqPlotCssStyling.txt 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,53 @@
+Title: jqPlot CSS Customization
+
+Much of the styling of jqPlot is done by css. The jqPlot css file is, unremarkably,
+jquery.jqplot.css and resides in the same directory as jqPlot itself.
+
+There exist some styling related javascript properties on the plot objects themselves
+(like fontStyle, fontSize, etc.). These can be set with the options object at plot creation.
+Generally, setting these options is *NOT* the preferred way to customize the look of the
+plot. Use the css file instead. *These options are deprecated and may disappear*. The
+exceptions are certain background and color options which control attributes of something
+renderered on a canvas. This would be line color, grid background, etc. These must
+be set by the options object. For a list of available options, see <jqPlot Options>.
+
+Objects in the plot that can be customized by css are given a css class like ".jqplot-*".
+For example, the plot title will have a ".jqplot-title" class, the axes ".jqplot-axis", etc.
+
+Currently assigned classes in jqPlot
+are as follows:
+
+.jqplot-target - Styles for the plot target div. These will be cascaded down
+to all plot elements according to css rules.
+
+.jqplot-axis - Styles for all axes
+
+.jqplot-xaxis - Styles applied to the primary x axis only.
+
+.jqplot-yaxis - Styles applied to the primary y axis only.
+
+.jqplot-x2axis, .jqplot-x3axis, ... - Styles applied to the 2nd, 3rd, etc. x axis only.
+
+.jqplot-y2axis, .jqplot-y3axis, ... - Styles applied to the 2nd, 3rd, etc.y axis only.
+
+.jqplot-axis-tick - Styles applied to all axis ticks
+
+.jqplot-xaxis-tick - Styles applied to primary x axis ticks only.
+
+.jqplot-x2axis-tick - Styles applied to secondary x axis ticks only.
+
+.jqplot-yaxis-tick - Styles applied to primary y axis ticks only.
+
+.jqplot-y2axis-tick - Styles applied to secondary y axis ticks only.
+
+table.jqplot-table-legend - Styles applied to the legend box table.
+
+.jqplot-title - Styles applied to the title.
+
+.jqplot-cursor-tooltip - Styles applied to the cursor tooltip
+
+.jqplot-highlighter-tooltip - Styles applied to the highlighter tooltip.
+
+div.jqplot-table-legend-swatch - the div element used for the colored swatch on the legend.
+
+Note that axes will be assigned 2 classes like: class=".jqplot-axis .jqplot-xaxis".
\ No newline at end of file
Added: gnucash/trunk/src/report/jqplot/jqPlotOptions.txt
===================================================================
--- gnucash/trunk/src/report/jqplot/jqPlotOptions.txt (rev 0)
+++ gnucash/trunk/src/report/jqplot/jqPlotOptions.txt 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,276 @@
+Title: jqPlot Options
+
+**This document is out of date. While the options described here should still be
+relavent and valid, it has not been updated for many new options. Sorry for
+this inconvenience.**
+
+This document describes the options available to jqPlot. These are set with the
+third argument to the $.jqplot('target', data, options) function. Options are
+using the following convention:
+
+{{{
+property: default, // notes
+}}}
+
+This document is not complete! Not all options are shown! Also, Options marked
+with ** in the notes are post 0.7.1 additions. They will be available in the next
+release. Further information about the options can be found in the online API
+documentation. For details on how the options relate to the API documentation,
+see the <Options Tutorial> in the optionsTutorial.txt file.
+
+{{{
+options =
+{
+ seriesColors: [ "#4bb2c5", "#c5b47f", "#EAA228", "#579575", "#839557", "#958c12",
+ "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc"], // colors that will
+ // be assigned to the series. If there are more series than colors, colors
+ // will wrap around and start at the beginning again.
+
+ stackSeries: false, // if true, will create a stack plot.
+ // Currently supported by line and bar graphs.
+
+ title: '', // Title for the plot. Can also be specified as an object like:
+
+ title: {
+ text: '', // title for the plot,
+ show: true,
+ },
+
+ axesDefaults: {
+ show: false, // wether or not to renderer the axis. Determined automatically.
+ min: null, // minimum numerical value of the axis. Determined automatically.
+ max: null, // maximum numverical value of the axis. Determined automatically.
+ pad: 1.2, // a factor multiplied by the data range on the axis to give the
+ // axis range so that data points don't fall on the edges of the axis.
+ ticks: [], // a 1D [val1, val2, ...], or 2D [[val, label], [val, label], ...]
+ // array of ticks to use. Computed automatically.
+ numberTicks: undefined,
+ renderer: $.jqplot.LinearAxisRenderer, // renderer to use to draw the axis,
+ rendererOptions: {}, // options to pass to the renderer. LinearAxisRenderer
+ // has no options,
+ tickOptions: {
+ mark: 'outside', // Where to put the tick mark on the axis
+ // 'outside', 'inside' or 'cross',
+ showMark: true,
+ showGridline: true, // wether to draw a gridline (across the whole grid) at this tick,
+ markSize: 4, // length the tick will extend beyond the grid in pixels. For
+ // 'cross', length will be added above and below the grid boundary,
+ show: true, // wether to show the tick (mark and label),
+ showLabel: true, // wether to show the text label at the tick,
+ formatString: '', // format string to use with the axis tick formatter
+ }
+ showTicks: true, // wether or not to show the tick labels,
+ showTickMarks: true, // wether or not to show the tick marks
+ },
+
+ axes: {
+ xaxis: {
+ // same options as axesDefaults
+ },
+ yaxis: {
+ // same options as axesDefaults
+ },
+ x2axis: {
+ // same options as axesDefaults
+ },
+ y2axis: {
+ // same options as axesDefaults
+ }
+ },
+
+ seriesDefaults: {
+ show: true, // wether to render the series.
+ xaxis: 'xaxis', // either 'xaxis' or 'x2axis'.
+ yaxis: 'yaxis', // either 'yaxis' or 'y2axis'.
+ label: '', // label to use in the legend for this line.
+ color: '', // CSS color spec to use for the line. Determined automatically.
+ lineWidth: 2.5, // Width of the line in pixels.
+ shadow: true, // show shadow or not.
+ shadowAngle: 45, // angle (degrees) of the shadow, clockwise from x axis.
+ shadowOffset: 1.25, // offset from the line of the shadow.
+ shadowDepth: 3, // Number of strokes to make when drawing shadow. Each
+ // stroke offset by shadowOffset from the last.
+ shadowAlpha: 0.1, // Opacity of the shadow.
+ showLine: true, // whether to render the line segments or not.
+ showMarker: true, // render the data point markers or not.
+ fill: false, // fill under the line,
+ fillAndStroke: false, // **stroke a line at top of fill area.
+ fillColor: undefined, // **custom fill color for filled lines (default is line color).
+ fillAlpha: undefined, // **custom alpha to apply to fillColor.
+ renderer: $.jqplot.LineRenderer], // renderer used to draw the series.
+ rendererOptions: {}, // options passed to the renderer. LineRenderer has no options.
+ markerRenderer: $.jqplot.MarkerRenderer, // renderer to use to draw the data
+ // point markers.
+ markerOptions: {
+ show: true, // wether to show data point markers.
+ style: 'filledCircle', // circle, diamond, square, filledCircle.
+ // filledDiamond or filledSquare.
+ lineWidth: 2, // width of the stroke drawing the marker.
+ size: 9, // size (diameter, edge length, etc.) of the marker.
+ color: '#666666' // color of marker, set to color of line by default.
+ shadow: true, // wether to draw shadow on marker or not.
+ shadowAngle: 45, // angle of the shadow. Clockwise from x axis.
+ shadowOffset: 1, // offset from the line of the shadow,
+ shadowDepth: 3, // Number of strokes to make when drawing shadow. Each stroke
+ // offset by shadowOffset from the last.
+ shadowAlpha: 0.07 // Opacity of the shadow
+ }
+ },
+
+ series:[
+ {Each series has same options as seriesDefaults},
+ {You can override each series individually here}
+ ],
+
+ legend: {
+ show: false,
+ location: 'ne', // compass direction, nw, n, ne, e, se, s, sw, w.
+ xoffset: 12, // pixel offset of the legend box from the x (or x2) axis.
+ yoffset: 12, // pixel offset of the legend box from the y (or y2) axis.
+ },
+
+ grid: {
+ drawGridLines: true, // wether to draw lines across the grid or not.
+ gridLineColor: '#cccccc' // **Color of the grid lines.
+ background: '#fffdf6', // CSS color spec for background color of grid.
+ borderColor: '#999999', // CSS color spec for border around grid.
+ borderWidth: 2.0, // pixel width of border around grid.
+ shadow: true, // draw a shadow for grid.
+ shadowAngle: 45, // angle of the shadow. Clockwise from x axis.
+ shadowOffset: 1.5, // offset from the line of the shadow.
+ shadowWidth: 3, // width of the stroke for the shadow.
+ shadowDepth: 3, // Number of strokes to make when drawing shadow.
+ // Each stroke offset by shadowOffset from the last.
+ shadowAlpha: 0.07 // Opacity of the shadow
+ renderer: $.jqplot.CanvasGridRenderer, // renderer to use to draw the grid.
+ rendererOptions: {} // options to pass to the renderer. Note, the default
+ // CanvasGridRenderer takes no additional options.
+ },
+
+ // Plugin and renderer options.
+
+ // BarRenderer.
+ // With BarRenderer, you can specify additional options in the rendererOptions object
+ // on the series or on the seriesDefaults object. Note, some options are respecified
+ // (like shadowDepth) to override lineRenderer defaults from which BarRenderer inherits.
+
+ seriesDefaults: {
+ rendererOptions: {
+ barPadding: 8, // number of pixels between adjacent bars in the same
+ // group (same category or bin).
+ barMargin: 10, // number of pixels between adjacent groups of bars.
+ barDirection: 'vertical', // vertical or horizontal.
+ barWidth: null, // width of the bars. null to calculate automatically.
+ shadowOffset: 2, // offset from the bar edge to stroke the shadow.
+ shadowDepth: 5, // nuber of strokes to make for the shadow.
+ shadowAlpha: 0.8, // transparency of the shadow.
+ }
+ },
+
+ // Cursor
+ // Options are passed to the cursor plugin through the "cursor" object at the top
+ // level of the options object.
+
+ cursor: {
+ style: 'crosshair', // A CSS spec for the cursor type to change the
+ // cursor to when over plot.
+ show: true,
+ showTooltip: true, // show a tooltip showing cursor position.
+ followMouse: false, // wether tooltip should follow the mouse or be stationary.
+ tooltipLocation: 'se', // location of the tooltip either relative to the mouse
+ // (followMouse=true) or relative to the plot. One of
+ // the compass directions, n, ne, e, se, etc.
+ tooltipOffset: 6, // pixel offset of the tooltip from the mouse or the axes.
+ showTooltipGridPosition: false, // show the grid pixel coordinates of the mouse
+ // in the tooltip.
+ showTooltipUnitPosition: true, // show the coordinates in data units of the mouse
+ // in the tooltip.
+ tooltipFormatString: '%.4P', // sprintf style format string for tooltip values.
+ useAxesFormatters: true, // wether to use the same formatter and formatStrings
+ // as used by the axes, or to use the formatString
+ // specified on the cursor with sprintf.
+ tooltipAxesGroups: [], // show only specified axes groups in tooltip. Would specify like:
+ // [['xaxis', 'yaxis'], ['xaxis', 'y2axis']]. By default, all axes
+ // combinations with for the series in the plot are shown.
+
+ },
+
+ // Dragable
+ // Dragable options are specified with the "dragable" object at the top level
+ // of the options object.
+
+ dragable: {
+ color: undefined, // custom color to use for the dragged point and dragged line
+ // section. default will use a transparent variant of the line color.
+ constrainTo: 'none', // Constrain dragging motion to an axis: 'x', 'y', or 'none'.
+ },
+
+ // Highlighter
+ // Highlighter options are specified with the "highlighter" object at the top level
+ // of the options object.
+
+ highlighter: {
+ lineWidthAdjust: 2.5, // pixels to add to the size line stroking the data point marker
+ // when showing highlight. Only affects non filled data point markers.
+ sizeAdjust: 5, // pixels to add to the size of filled markers when drawing highlight.
+ showTooltip: true, // show a tooltip with data point values.
+ tooltipLocation: 'nw', // location of tooltip: n, ne, e, se, s, sw, w, nw.
+ fadeTooltip: true, // use fade effect to show/hide tooltip.
+ tooltipFadeSpeed: "fast"// slow, def, fast, or a number of milliseconds.
+ tooltipOffset: 2, // pixel offset of tooltip from the highlight.
+ tooltipAxes: 'both', // which axis values to display in the tooltip, x, y or both.
+ tooltipSeparator: ', ' // separator between values in the tooltip.
+ useAxesFormatters: true // use the same format string and formatters as used in the axes to
+ // display values in the tooltip.
+ tooltipFormatString: '%.5P' // sprintf format string for the tooltip. only used if
+ // useAxesFormatters is false. Will use sprintf formatter with
+ // this string, not the axes formatters.
+ },
+
+ // LogAxisRenderer
+ // LogAxisRenderer add 2 options to the axes object. These options are specified directly on
+ // the axes or axesDefaults object.
+
+ axesDefaults: {
+ base: 10, // the logarithmic base.
+ tickDistribution: 'even', // 'even' or 'power'. 'even' will produce with even visiual (pixel)
+ // spacing on the axis. 'power' will produce ticks spaced by
+ // increasing powers of the log base.
+ },
+
+ // PieRenderer
+ // PieRenderer accepts options from the rendererOptions object of the series or seriesDefaults object.
+
+ seriesDefaults: {
+ rendererOptions: {
+ diameter: undefined, // diameter of pie, auto computed by default.
+ padding: 20, // padding between pie and neighboring legend or plot margin.
+ sliceMargin: 0, // gap between slices.
+ fill: true, // render solid (filled) slices.
+ shadowOffset: 2, // offset of the shadow from the chart.
+ shadowDepth: 5, // Number of strokes to make when drawing shadow. Each stroke
+ // offset by shadowOffset from the last.
+ shadowAlpha: 0.07 // Opacity of the shadow
+ }
+ },
+
+ // Trendline
+ // Trendline takes options on the trendline object of the series or seriesDefaults object.
+
+ seriesDefaults: {
+ trendline: {
+ show: true, // show the trend line
+ color: '#666666', // CSS color spec for the trend line.
+ label: '', // label for the trend line.
+ type: 'linear', // 'linear', 'exponential' or 'exp'
+ shadow: true, // show the trend line shadow.
+ lineWidth: 1.5, // width of the trend line.
+ shadowAngle: 45, // angle of the shadow. Clockwise from x axis.
+ shadowOffset: 1.5, // offset from the line of the shadow.
+ shadowDepth: 3, // Number of strokes to make when drawing shadow.
+ // Each stroke offset by shadowOffset from the last.
+ shadowAlpha: 0.07 // Opacity of the shadow
+ }
+ }
+}
+}}}
\ No newline at end of file
Modified: gnucash/trunk/src/report/jqplot/jquery.jqplot.css
===================================================================
--- gnucash/trunk/src/report/jqplot/jquery.jqplot.css 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/jquery.jqplot.css 2013-02-20 18:50:43 UTC (rev 22790)
@@ -25,14 +25,15 @@
margin-right: 10px;
}
-.jqplot-y2axis, .jqplot-y3axis, .jqplot-y4axis, .jqplot-y5axis, .jqplot-y6axis, .jqplot-y7axis, .jqplot-y8axis, .jqplot-y9axis {
+.jqplot-y2axis, .jqplot-y3axis, .jqplot-y4axis, .jqplot-y5axis, .jqplot-y6axis, .jqplot-y7axis, .jqplot-y8axis, .jqplot-y9axis, .jqplot-yMidAxis {
margin-left: 10px;
margin-right: 10px;
}
/*rules applied to all axis tick divs*/
-.jqplot-axis-tick, .jqplot-xaxis-tick, .jqplot-yaxis-tick, .jqplot-x2axis-tick, .jqplot-y2axis-tick, .jqplot-y3axis-tick, .jqplot-y4axis-tick, .jqplot-y5axis-tick, .jqplot-y6axis-tick, .jqplot-y7axis-tick, .jqplot-y8axis-tick, .jqplot-y9axis-tick {
+.jqplot-axis-tick, .jqplot-xaxis-tick, .jqplot-yaxis-tick, .jqplot-x2axis-tick, .jqplot-y2axis-tick, .jqplot-y3axis-tick, .jqplot-y4axis-tick, .jqplot-y5axis-tick, .jqplot-y6axis-tick, .jqplot-y7axis-tick, .jqplot-y8axis-tick, .jqplot-y9axis-tick, .jqplot-yMidAxis-tick {
position: absolute;
+ white-space: pre;
}
@@ -60,6 +61,15 @@
text-align: right;
}
+.jqplot-yaxis-tick.jqplot-breakTick {
+ right: -20px;
+ margin-right: 0px;
+ padding:1px 5px 1px 5px;
+/* background-color: white;*/
+ z-index: 2;
+ font-size: 1.5em;
+}
+
.jqplot-y2axis-tick, .jqplot-y3axis-tick, .jqplot-y4axis-tick, .jqplot-y5axis-tick, .jqplot-y6axis-tick, .jqplot-y7axis-tick, .jqplot-y8axis-tick, .jqplot-y9axis-tick {
left: 0px;
/* initial position untill tick is drawn in proper place */
@@ -69,15 +79,11 @@
text-align: left;
}
-.jqplot-meterGauge-tick {
- font-size: 0.75em;
- color: #999999;
+.jqplot-yMidAxis-tick {
+ text-align: center;
+ white-space: nowrap;
}
-.jqplot-meterGauge-label {
- font-size: 1em;
- color: #999999;
-}
.jqplot-xaxis-label {
margin-top: 10px;
font-size: 11pt;
@@ -97,12 +103,28 @@
position: absolute;
}
+.jqplot-yMidAxis-label {
+ font-size: 11pt;
+ position: absolute;
+}
+
.jqplot-y2axis-label, .jqplot-y3axis-label, .jqplot-y4axis-label, .jqplot-y5axis-label, .jqplot-y6axis-label, .jqplot-y7axis-label, .jqplot-y8axis-label, .jqplot-y9axis-label {
/* text-align: center;*/
font-size: 11pt;
+ margin-left: 10px;
position: absolute;
}
+.jqplot-meterGauge-tick {
+ font-size: 0.75em;
+ color: #999999;
+}
+
+.jqplot-meterGauge-label {
+ font-size: 1em;
+ color: #999999;
+}
+
table.jqplot-table-legend {
margin-top: 12px;
margin-bottom: 12px;
@@ -121,11 +143,31 @@
vertical-align:middle;
}
+/*
+These rules could be used instead of assigning
+element styles and relying on js object properties.
+*/
+
+/*
+td.jqplot-table-legend-swatch {
+ padding-top: 0.5em;
+ text-align: center;
+}
+
+tr.jqplot-table-legend:first td.jqplot-table-legend-swatch {
+ padding-top: 0px;
+}
+*/
+
td.jqplot-seriesToggle:hover, td.jqplot-seriesToggle:active {
cursor: pointer;
}
-td.jqplot-table-legend > div {
+.jqplot-table-legend .jqplot-series-hidden {
+ text-decoration: line-through;
+}
+
+div.jqplot-table-legend-swatch-outline {
border: 1px solid #cccccc;
padding:1px;
}
@@ -164,7 +206,7 @@
padding: 1px;
}
-.jqplot-highlighter-tooltip {
+.jqplot-highlighter-tooltip, .jqplot-canvasOverlay-tooltip {
border: 1px solid #cccccc;
font-size: 0.75em;
white-space: nowrap;
@@ -178,13 +220,13 @@
}
td.jqplot-cursor-legend-swatch {
-vertical-align:middle;
-text-align:center;
+ vertical-align: middle;
+ text-align: center;
}
div.jqplot-cursor-legend-swatch {
-width:1.2em;
-height:0.7em;
+ width: 1.2em;
+ height: 0.7em;
}
.jqplot-error {
@@ -209,4 +251,9 @@
div.jqplot-bubble-label.jqplot-bubble-label-highlight {
background: rgba(90%, 90%, 90%, 0.7);
-}
\ No newline at end of file
+}
+
+div.jqplot-noData-container {
+ text-align: center;
+ background-color: rgba(96%, 96%, 96%, 0.3);
+}
Modified: gnucash/trunk/src/report/jqplot/jquery.jqplot.js
===================================================================
--- gnucash/trunk/src/report/jqplot/jquery.jqplot.js 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/jquery.jqplot.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -5,11 +5,12 @@
*
* About: Version
*
- * 0.9.7r635
+ * version: 1.0.6
+ * revision: 1138
*
* About: Copyright & License
*
- * Copyright (c) 2009 - 2010 Chris Leonello
+ * Copyright (c) 2009-2013 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
* under both the MIT and GPL version 2.0 licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
@@ -22,18 +23,9 @@
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php.
+ *
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
*
- * jqPlot includes `date instance methods and printf/sprintf functions by other authors:
- *
- * Date instance methods:
- *
- * author Ken Snyder (ken d snyder at gmail dot com)
- * date 2008-09-10
- * version 2.0.2 (http://kendsnyder.com/sandbox/date/)
- * license Creative Commons Attribution License 3.0 (http://creativecommons.org/licenses/by/3.0/)
- *
- * JavaScript printf/sprintf functions:
- *
* version 2007.04.27
* author Ash Searle
* http://hexmen.com/blog/2007/03/printf-sprintf/
@@ -44,12 +36,12 @@
*
* About: Introduction
*
- * jqPlot requires jQuery (1.4+ required for certain features). jQuery 1.4.1 is included in the distribution.
+ * jqPlot requires jQuery (1.4+ required for certain features). jQuery 1.4.2 is included in the distribution.
* To use jqPlot include jQuery, the jqPlot jQuery plugin, the jqPlot css file and optionally
* the excanvas script for IE support in your web page:
*
- * > <!--[if IE]><script language="javascript" type="text/javascript" src="excanvas.js"></script><![endif]-->
- * > <script language="javascript" type="text/javascript" src="jquery-1.4.2.min.js"></script>
+ * > <!--[if lt IE 9]><script language="javascript" type="text/javascript" src="excanvas.js"></script><![endif]-->
+ * > <script language="javascript" type="text/javascript" src="jquery-1.4.4.min.js"></script>
* > <script language="javascript" type="text/javascript" src="jquery.jqplot.min.js"></script>
* > <link rel="stylesheet" type="text/css" href="jquery.jqplot.css" />
*
@@ -93,9 +85,90 @@
(function($) {
// make sure undefined is undefined
var undefined;
+
+ $.fn.emptyForce = function() {
+ for ( var i = 0, elem; (elem = $(this)[i]) != null; i++ ) {
+ // Remove element nodes and prevent memory leaks
+ if ( elem.nodeType === 1 ) {
+ $.cleanData( elem.getElementsByTagName("*") );
+ }
+
+ // Remove any remaining nodes
+ if ($.jqplot.use_excanvas) {
+ elem.outerHTML = "";
+ }
+ else {
+ while ( elem.firstChild ) {
+ elem.removeChild( elem.firstChild );
+ }
+ }
+ elem = null;
+ }
+
+ return $(this);
+ };
+
+ $.fn.removeChildForce = function(parent) {
+ while ( parent.firstChild ) {
+ this.removeChildForce( parent.firstChild );
+ parent.removeChild( parent.firstChild );
+ }
+ };
+
+ $.fn.jqplot = function() {
+ var datas = [];
+ var options = [];
+ // see how many data arrays we have
+ for (var i=0, l=arguments.length; i<l; i++) {
+ if ($.isArray(arguments[i])) {
+ datas.push(arguments[i]);
+ }
+ else if ($.isPlainObject(arguments[i])) {
+ options.push(arguments[i]);
+ }
+ }
+
+ return this.each(function(index) {
+ var tid,
+ plot,
+ $this = $(this),
+ dl = datas.length,
+ ol = options.length,
+ data,
+ opts;
+
+ if (index < dl) {
+ data = datas[index];
+ }
+ else {
+ data = dl ? datas[dl-1] : null;
+ }
+
+ if (index < ol) {
+ opts = options[index];
+ }
+ else {
+ opts = ol ? options[ol-1] : null;
+ }
+
+ // does el have an id?
+ // if not assign it one.
+ tid = $this.attr('id');
+ if (tid === undefined) {
+ tid = 'jqplot_target_' + $.jqplot.targetCounter++;
+ $this.attr('id', tid);
+ }
+
+ plot = $.jqplot(tid, data, opts);
+
+ $this.data('jqplot', plot);
+ });
+ };
+
+
/**
- * Class: $.jqplot
+ * Namespace: $.jqplot
* jQuery function called by the user to create a plot.
*
* Parameters:
@@ -119,23 +192,27 @@
*/
$.jqplot = function(target, data, options) {
- var _data, _options;
-
- if (options == null) {
- if (data instanceof Array) {
+ var _data = null, _options = null;
+
+ if (arguments.length === 3) {
+ _data = data;
+ _options = options;
+ }
+
+ else if (arguments.length === 2) {
+ if ($.isArray(data)) {
_data = data;
- _options = null;
}
-
- else if (data.constructor == Object) {
- _data = null;
+
+ else if ($.isPlainObject(data)) {
_options = data;
}
}
- else {
- _data = data;
- _options = options;
+
+ if (_data === null && _options !== null && _options.data) {
+ _data = _options.data;
}
+
var plot = new jqPlot();
// remove any error class that may be stuck on target.
$('#'+target).removeClass('jqplot-error');
@@ -166,10 +243,100 @@
return plot;
}
};
+
+ $.jqplot.version = "1.0.6";
+ $.jqplot.revision = "1138";
+
+ $.jqplot.targetCounter = 1;
+
+ // canvas manager to reuse canvases on the plot.
+ // Should help solve problem of canvases not being freed and
+ // problem of waiting forever for firefox to decide to free memory.
+ $.jqplot.CanvasManager = function() {
+ // canvases are managed globally so that they can be reused
+ // across plots after they have been freed
+ if (typeof $.jqplot.CanvasManager.canvases == 'undefined') {
+ $.jqplot.CanvasManager.canvases = [];
+ $.jqplot.CanvasManager.free = [];
+ }
- $.jqplot.debug = 1;
+ var myCanvases = [];
+
+ this.getCanvas = function() {
+ var canvas;
+ var makeNew = true;
+
+ if (!$.jqplot.use_excanvas) {
+ for (var i = 0, l = $.jqplot.CanvasManager.canvases.length; i < l; i++) {
+ if ($.jqplot.CanvasManager.free[i] === true) {
+ makeNew = false;
+ canvas = $.jqplot.CanvasManager.canvases[i];
+ // $(canvas).removeClass('jqplot-canvasManager-free').addClass('jqplot-canvasManager-inuse');
+ $.jqplot.CanvasManager.free[i] = false;
+ myCanvases.push(i);
+ break;
+ }
+ }
+ }
+
+ if (makeNew) {
+ canvas = document.createElement('canvas');
+ myCanvases.push($.jqplot.CanvasManager.canvases.length);
+ $.jqplot.CanvasManager.canvases.push(canvas);
+ $.jqplot.CanvasManager.free.push(false);
+ }
+
+ return canvas;
+ };
+
+ // this method has to be used after settings the dimesions
+ // on the element returned by getCanvas()
+ this.initCanvas = function(canvas) {
+ if ($.jqplot.use_excanvas) {
+ return window.G_vmlCanvasManager.initElement(canvas);
+ }
+ return canvas;
+ };
+
+ this.freeAllCanvases = function() {
+ for (var i = 0, l=myCanvases.length; i < l; i++) {
+ this.freeCanvas(myCanvases[i]);
+ }
+ myCanvases = [];
+ };
+
+ this.freeCanvas = function(idx) {
+ if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) {
+ // excanvas can't be reused, but properly unset
+ window.G_vmlCanvasManager.uninitElement($.jqplot.CanvasManager.canvases[idx]);
+ $.jqplot.CanvasManager.canvases[idx] = null;
+ }
+ else {
+ var canvas = $.jqplot.CanvasManager.canvases[idx];
+ canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height);
+ $(canvas).unbind().removeAttr('class').removeAttr('style');
+ // Style attributes seemed to be still hanging around. wierd. Some ticks
+ // still retained a left: 0px attribute after reusing a canvas.
+ $(canvas).css({left: '', top: '', position: ''});
+ // setting size to 0 may save memory of unused canvases?
+ canvas.width = 0;
+ canvas.height = 0;
+ $.jqplot.CanvasManager.free[idx] = true;
+ }
+ };
+
+ };
+
+
+ // Convienence function that won't hang IE or FF without FireBug.
+ $.jqplot.log = function() {
+ if (window.console) {
+ window.console.log.apply(window.console, arguments);
+ }
+ };
+
$.jqplot.config = {
- debug:1,
+ addDomReference: false,
enablePlugins:false,
defaultHeight:300,
defaultWidth:400,
@@ -183,24 +350,52 @@
errorFontStyle: '',
errorFontWeight: '',
catchErrors: false,
- defaultTickFormatString: "%.1f"
+ defaultTickFormatString: "%.1f",
+ defaultColors: [ "#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"],
+ defaultNegativeColors: [ "#498991", "#C08840", "#9F9274", "#546D61", "#646C4A", "#6F6621", "#6E3F5F", "#4F64B0", "#A89050", "#C45923", "#187399", "#945381", "#959E5C", "#C7AF7B", "#478396", "#907294"],
+ dashLength: 4,
+ gapLength: 4,
+ dotGapLength: 2.5,
+ srcLocation: 'jqplot/src/',
+ pluginLocation: 'jqplot/src/plugins/'
};
+
+ $.jqplot.arrayMax = function( array ){
+ return Math.max.apply( Math, array );
+ };
+
+ $.jqplot.arrayMin = function( array ){
+ return Math.min.apply( Math, array );
+ };
+
$.jqplot.enablePlugins = $.jqplot.config.enablePlugins;
// canvas related tests taken from modernizer:
- // Copyright © 20092010 Faruk Ates.
+ // Copyright (c) 2009 - 2010 Faruk Ates.
// http://www.modernizr.com
$.jqplot.support_canvas = function() {
- return !!document.createElement('canvas').getContext;
+ if (typeof $.jqplot.support_canvas.result == 'undefined') {
+ $.jqplot.support_canvas.result = !!document.createElement('canvas').getContext;
+ }
+ return $.jqplot.support_canvas.result;
};
$.jqplot.support_canvas_text = function() {
- return !!(document.createElement('canvas').getContext && typeof document.createElement('canvas').getContext('2d').fillText == 'function');
+ if (typeof $.jqplot.support_canvas_text.result == 'undefined') {
+ if (window.G_vmlCanvasManager !== undefined && window.G_vmlCanvasManager._version > 887) {
+ $.jqplot.support_canvas_text.result = true;
+ }
+ else {
+ $.jqplot.support_canvas_text.result = !!(document.createElement('canvas').getContext && typeof document.createElement('canvas').getContext('2d').fillText == 'function');
+ }
+
+ }
+ return $.jqplot.support_canvas_text.result;
};
- $.jqplot.use_excanvas = ($.browser.msie && !$.jqplot.support_canvas()) ? true : false;
+ $.jqplot.use_excanvas = ((!$.support.boxModel || !$.support.objectAll || !$support.leadingWhitespace) && !$.jqplot.support_canvas()) ? true : false;
/**
*
@@ -264,6 +459,8 @@
this._elem.addClass(klass);
this._elem.css(cssopts);
this._elem.attr(attrib);
+ // avoid memory leak;
+ elem = null;
return this._elem;
};
@@ -332,8 +529,8 @@
// > y2axis: {ticks:[22, 44, 66, 88]}
// > }
// > }
- // There are 4 axes, 'xaxis', 'yaxis', 'x2axis', 'y2axis'. Any or all of
- // which may be specified.
+ // There are 2 x axes, 'xaxis' and 'x2axis', and
+ // 9 yaxes, 'yaxis', 'y2axis'. 'y3axis', ... Any or all of which may be specified.
this.name = name;
this._series = [];
// prop: show
@@ -360,16 +557,13 @@
this.showLabel = true;
// prop: min
// minimum value of the axis (in data units, not pixels).
- this.min=null;
+ this.min = null;
// prop: max
// maximum value of the axis (in data units, not pixels).
- this.max=null;
+ this.max = null;
// prop: autoscale
- // Autoscale the axis min and max values to provide sensible tick spacing.
- // If axis min or max are set, autoscale will be turned off.
- // The numberTicks, tickInterval and pad options do work with
- // autoscale, although tickInterval has not been tested yet.
- // padMin and padMax do nothing when autoscale is on.
+ // DEPRECATED
+ // the default scaling algorithm produces superior results.
this.autoscale = false;
// prop: pad
// Padding to extend the range above and below the data bounds.
@@ -413,8 +607,19 @@
this.showTickMarks = true;
// prop: showMinorTicks
// Wether or not to show minor ticks. This is renderer dependent.
- // The default <$.jqplot.LinearAxisRenderer> does not have minor ticks.
this.showMinorTicks = true;
+ // prop: drawMajorGridlines
+ // True to draw gridlines for major axis ticks.
+ this.drawMajorGridlines = true;
+ // prop: drawMinorGridlines
+ // True to draw gridlines for minor ticks.
+ this.drawMinorGridlines = false;
+ // prop: drawMajorTickMarks
+ // True to draw tick marks for major axis ticks.
+ this.drawMajorTickMarks = true;
+ // prop: drawMinorTickMarks
+ // True to draw tick marks for minor ticks. This is renderer dependent.
+ this.drawMinorTickMarks = true;
// prop: useSeriesColor
// Use the color of the first series associated with this axis for the
// tick marks and line bordering this axis.
@@ -426,8 +631,14 @@
// prop: borderColor
// color of the border adjacent to the axis. Defaults to grid border color.
this.borderColor = null;
+ // prop: scaleToHiddenSeries
+ // True to include hidden series when computing axes bounds and scaling.
+ this.scaleToHiddenSeries = false;
// minimum and maximum values on the axis.
this._dataBounds = {min:null, max:null};
+ // statistics (min, max, mean) as well as actual data intervals for each series attached to axis.
+ // holds collection of {intervals:[], min:, max:, mean: } objects for each series on axis.
+ this._intervalStats = [];
// pixel position from the top left of the min value and max value on the axis.
this._offsets = {min:null, max:null};
this._ticks=[];
@@ -449,13 +660,17 @@
this._tickInterval = null;
this._numberTicks = null;
this.__ticks = null;
+ // hold original user options.
+ this._options = {};
}
Axis.prototype = new $.jqplot.ElemContainer();
Axis.prototype.constructor = Axis;
Axis.prototype.init = function() {
- this.renderer = new this.renderer();
+ if ($.isFunction(this.renderer)) {
+ this.renderer = new this.renderer();
+ }
// set the axis name
this.tickOptions.axis = this.name;
// if showMark or showLabel tick options not specified, use value of axis option.
@@ -514,8 +729,13 @@
};
- Axis.prototype.draw = function(ctx) {
- return this.renderer.draw.call(this, ctx);
+ Axis.prototype.draw = function(ctx, plot) {
+ // Memory Leaks patch
+ if (this.__ticks) {
+ this.__ticks = null;
+ }
+
+ return this.renderer.draw.call(this, ctx, plot);
};
@@ -542,13 +762,89 @@
this.renderer.reset.call(this);
};
- Axis.prototype.resetScale = function() {
- this.min = null;
- this.max = null;
- this.numberTicks = null;
- this.tickInterval = null;
+ Axis.prototype.resetScale = function(opts) {
+ $.extend(true, this, {min: null, max: null, numberTicks: null, tickInterval: null, _ticks: [], ticks: []}, opts);
+ this.resetDataBounds();
};
+
+ Axis.prototype.resetDataBounds = function() {
+ // Go through all the series attached to this axis and find
+ // the min/max bounds for this axis.
+ var db = this._dataBounds;
+ db.min = null;
+ db.max = null;
+ var l, s, d;
+ // check for when to force min 0 on bar series plots.
+ var doforce = (this.show) ? true : false;
+ for (var i=0; i<this._series.length; i++) {
+ s = this._series[i];
+ if (s.show || this.scaleToHiddenSeries) {
+ d = s._plotData;
+ if (s._type === 'line' && s.renderer.bands.show && this.name.charAt(0) !== 'x') {
+ d = [[0, s.renderer.bands._min], [1, s.renderer.bands._max]];
+ }
+ var minyidx = 1, maxyidx = 1;
+
+ if (s._type != null && s._type == 'ohlc') {
+ minyidx = 3;
+ maxyidx = 2;
+ }
+
+ for (var j=0, l=d.length; j<l; j++) {
+ if (this.name == 'xaxis' || this.name == 'x2axis') {
+ if ((d[j][0] != null && d[j][0] < db.min) || db.min == null) {
+ db.min = d[j][0];
+ }
+ if ((d[j][0] != null && d[j][0] > db.max) || db.max == null) {
+ db.max = d[j][0];
+ }
+ }
+ else {
+ if ((d[j][minyidx] != null && d[j][minyidx] < db.min) || db.min == null) {
+ db.min = d[j][minyidx];
+ }
+ if ((d[j][maxyidx] != null && d[j][maxyidx] > db.max) || db.max == null) {
+ db.max = d[j][maxyidx];
+ }
+ }
+ }
+
+ // Hack to not pad out bottom of bar plots unless user has specified a padding.
+ // every series will have a chance to set doforce to false. once it is set to
+ // false, it cannot be reset to true.
+ // If any series attached to axis is not a bar, wont force 0.
+ if (doforce && s.renderer.constructor !== $.jqplot.BarRenderer) {
+ doforce = false;
+ }
+
+ else if (doforce && this._options.hasOwnProperty('forceTickAt0') && this._options.forceTickAt0 == false) {
+ doforce = false;
+ }
+
+ else if (doforce && s.renderer.constructor === $.jqplot.BarRenderer) {
+ if (s.barDirection == 'vertical' && this.name != 'xaxis' && this.name != 'x2axis') {
+ if (this._options.pad != null || this._options.padMin != null) {
+ doforce = false;
+ }
+ }
+
+ else if (s.barDirection == 'horizontal' && (this.name == 'xaxis' || this.name == 'x2axis')) {
+ if (this._options.pad != null || this._options.padMin != null) {
+ doforce = false;
+ }
+ }
+
+ }
+ }
+ }
+
+ if (doforce && this.renderer.constructor === $.jqplot.LinearAxisRenderer && db.min >= 0) {
+ this.padMin = 1.0;
+ this.forceTickAt0 = true;
+ }
+ };
+
/**
* Class: Legend
* Legend object. Cannot be instantiated directly, but created
@@ -640,7 +936,9 @@
// CSS style for the margin which will override any style sheet setting.
// The default will be taken from the stylesheet.
this.marginLeft = null;
-
+ // prop: escapeHtml
+ // True to escape special characters with their html entity equivalents
+ // in legend text. "<" becomes < and so on, so html tags are not rendered.
this.escapeHtml = false;
this._series = [];
@@ -657,7 +955,9 @@
// if user has specified xoffset or yoffset, copy these to
// the margin properties.
- if (this.placement == 'inside') this.placement = 'insideGrid';
+ if (this.placement == 'inside') {
+ this.placement = 'insideGrid';
+ }
if (this.xoffset >0) {
if (this.placement == 'insideGrid') {
@@ -757,15 +1057,17 @@
};
Legend.prototype.init = function() {
- this.renderer = new this.renderer();
+ if ($.isFunction(this.renderer)) {
+ this.renderer = new this.renderer();
+ }
this.renderer.init.call(this, this.rendererOptions);
};
- Legend.prototype.draw = function(offsets) {
+ Legend.prototype.draw = function(offsets, plot) {
for (var i=0; i<$.jqplot.preDrawLegendHooks.length; i++){
$.jqplot.preDrawLegendHooks[i].call(this, offsets);
}
- return this.renderer.draw.call(this, offsets);
+ return this.renderer.draw.call(this, offsets, plot);
};
Legend.prototype.pack = function(offsets) {
@@ -810,13 +1112,19 @@
// prop: rendererOptions
// renderer specific options passed to the renderer.
this.rendererOptions = {};
+ // prop: escapeHtml
+ // True to escape special characters with their html entity equivalents
+ // in title text. "<" becomes < and so on, so html tags are not rendered.
+ this.escapeHtml = false;
}
Title.prototype = new $.jqplot.ElemContainer();
Title.prototype.constructor = Title;
Title.prototype.init = function() {
- this.renderer = new this.renderer();
+ if ($.isFunction(this.renderer)) {
+ this.renderer = new this.renderer();
+ }
this.renderer.init.call(this, this.rendererOptions);
};
@@ -835,7 +1143,8 @@
* by the Plot oject. Series properties can be set or overriden by the
* options passed in from the user.
*/
- function Series() {
+ function Series(options) {
+ options = options || {};
$.jqplot.ElemContainer.call(this);
// Group: Properties
// Properties will be assigned from a series array at the top level of the
@@ -848,7 +1157,7 @@
// > {yaxis: 'y2axis', shadow: false, label:'bad line'}
// > ]
// > }
-
+
// prop: show
// wether or not to draw the series.
this.show = true;
@@ -879,11 +1188,25 @@
// prop: color
// css color spec for the series
this.color;
+ // prop: negativeColor
+ // css color spec used for filled (area) plots that are filled to zero and
+ // the "useNegativeColors" option is true.
+ this.negativeColor;
// prop: lineWidth
// width of the line in pixels. May have different meanings depending on renderer.
this.lineWidth = 2.5;
- // prop: shadow
- // wether or not to draw a shadow on the line
+ // prop: lineJoin
+ // Canvas lineJoin style between segments of series.
+ this.lineJoin = 'round';
+ // prop: lineCap
+ // Canvas lineCap style at ends of line.
+ this.lineCap = 'round';
+ // prop: linePattern
+ // line pattern 'dashed', 'dotted', 'solid', some combination
+ // of '-' and '.' characters such as '.-.' or a numerical array like
+ // [draw, skip, draw, skip, ...] such as [1, 10] to draw a dotted line,
+ // [1, 10, 20, 10] to draw a dot-dash line, and so on.
+ this.linePattern = 'solid';
this.shadow = true;
// prop: shadowAngle
// Shadow angle in degrees
@@ -898,7 +1221,7 @@
// Alpha channel transparency of shadow. 0 = transparent.
this.shadowAlpha = '0.1';
// prop: breakOnNull
- // Not implemented. wether line segments should be be broken at null value.
+ // Wether line segments should be be broken at null value.
// False will join point on either side of line.
this.breakOnNull = false;
// prop: markerRenderer
@@ -983,6 +1306,7 @@
// sum of y values in this series.
this._sumy = 0;
this._sumx = 0;
+ this._type = '';
}
Series.prototype = new $.jqplot.ElemContainer();
@@ -993,8 +1317,8 @@
this.index = index;
this.gridBorderWidth = gridbw;
var d = this.data;
- var temp = [], i;
- for (i=0; i<d.length; i++) {
+ var temp = [], i, l;
+ for (i=0, l=d.length; i<l; i++) {
if (! this.breakOnNull) {
if (d[i] == null || d[i][0] == null || d[i][1] == null) {
continue;
@@ -1013,6 +1337,18 @@
}
}
this.data = temp;
+
+ // parse the renderer options and apply default colors if not provided
+ // Set color even if not shown, so series don't change colors when other
+ // series on plot shown/hidden.
+ if (!this.color) {
+ this.color = plot.colorGenerator.get(this.index);
+ }
+ if (!this.negativeColor) {
+ this.negativeColor = plot.negativeColorGenerator.get(this.index);
+ }
+
+
if (!this.fillColor) {
this.fillColor = this.color;
}
@@ -1021,7 +1357,9 @@
var comp = $.jqplot.getColorComponents(comp);
this.fillColor = 'rgba('+comp[0]+','+comp[1]+','+comp[2]+','+this.fillAlpha+')';
}
- this.renderer = new this.renderer();
+ if ($.isFunction(this.renderer)) {
+ this.renderer = new this.renderer();
+ }
this.renderer.init.call(this, this.rendererOptions, plot);
this.markerRenderer = new this.markerRenderer();
if (!this.markerOptions.color) {
@@ -1041,9 +1379,12 @@
Series.prototype.draw = function(sctx, opts, plot) {
var options = (opts == undefined) ? {} : opts;
sctx = (sctx == undefined) ? this.canvas._ctx : sctx;
+
+ var j, data, gridData;
+
// hooks get called even if series not shown
// we don't clear canvas here, it would wipe out all other series as well.
- for (var j=0; j<$.jqplot.preDrawSeriesHooks.length; j++) {
+ for (j=0; j<$.jqplot.preDrawSeriesHooks.length; j++) {
$.jqplot.preDrawSeriesHooks[j].call(this, sctx, options);
}
if (this.show) {
@@ -1051,7 +1392,7 @@
if (!options.preventJqPlotSeriesDrawTrigger) {
$(sctx.canvas).trigger('jqplotSeriesDraw', [this.data, this.gridData]);
}
- var data = [];
+ data = [];
if (options.data) {
data = options.data;
}
@@ -1061,27 +1402,37 @@
else {
data = this._plotData;
}
- var gridData = options.gridData || this.renderer.makeGridData.call(this, data, plot);
+ gridData = options.gridData || this.renderer.makeGridData.call(this, data, plot);
+
+ if (this._type === 'line' && this.renderer.smooth && this.renderer._smoothedData.length) {
+ gridData = this.renderer._smoothedData;
+ }
+
this.renderer.draw.call(this, sctx, gridData, options, plot);
}
- for (var j=0; j<$.jqplot.postDrawSeriesHooks.length; j++) {
- $.jqplot.postDrawSeriesHooks[j].call(this, sctx, options);
+ for (j=0; j<$.jqplot.postDrawSeriesHooks.length; j++) {
+ $.jqplot.postDrawSeriesHooks[j].call(this, sctx, options, plot);
}
+
+ sctx = opts = plot = j = data = gridData = null;
};
Series.prototype.drawShadow = function(sctx, opts, plot) {
var options = (opts == undefined) ? {} : opts;
sctx = (sctx == undefined) ? this.shadowCanvas._ctx : sctx;
+
+ var j, data, gridData;
+
// hooks get called even if series not shown
// we don't clear canvas here, it would wipe out all other series as well.
- for (var j=0; j<$.jqplot.preDrawSeriesShadowHooks.length; j++) {
+ for (j=0; j<$.jqplot.preDrawSeriesShadowHooks.length; j++) {
$.jqplot.preDrawSeriesShadowHooks[j].call(this, sctx, options);
}
if (this.shadow) {
this.renderer.setGridData.call(this, plot);
- var data = [];
+ data = [];
if (options.data) {
data = options.data;
}
@@ -1091,19 +1442,21 @@
else {
data = this._plotData;
}
- var gridData = options.gridData || this.renderer.makeGridData.call(this, data, plot);
+ gridData = options.gridData || this.renderer.makeGridData.call(this, data, plot);
- this.renderer.drawShadow.call(this, sctx, gridData, options);
+ this.renderer.drawShadow.call(this, sctx, gridData, options, plot);
}
- for (var j=0; j<$.jqplot.postDrawSeriesShadowHooks.length; j++) {
+ for (j=0; j<$.jqplot.postDrawSeriesShadowHooks.length; j++) {
$.jqplot.postDrawSeriesShadowHooks[j].call(this, sctx, options);
}
+ sctx = opts = plot = j = data = gridData = null;
+
};
// toggles series display on plot, e.g. show/hide series
- Series.prototype.toggleDisplay = function(ev) {
+ Series.prototype.toggleDisplay = function(ev, callback) {
var s, speed;
if (ev.data.series) {
s = ev.data.series;
@@ -1111,38 +1464,53 @@
else {
s = this;
}
+
if (ev.data.speed) {
speed = ev.data.speed;
}
if (speed) {
- if (s.canvas._elem.is(':hidden')) {
+ // this can be tricky because series may not have a canvas element if replotting.
+ if (s.canvas._elem.is(':hidden') || !s.show) {
+ s.show = true;
+
+ s.canvas._elem.removeClass('jqplot-series-hidden');
if (s.shadowCanvas._elem) {
s.shadowCanvas._elem.fadeIn(speed);
}
- s.canvas._elem.fadeIn(speed);
+ s.canvas._elem.fadeIn(speed, callback);
s.canvas._elem.nextAll('.jqplot-point-label.jqplot-series-'+s.index).fadeIn(speed);
}
else {
+ s.show = false;
+
+ s.canvas._elem.addClass('jqplot-series-hidden');
if (s.shadowCanvas._elem) {
s.shadowCanvas._elem.fadeOut(speed);
}
- s.canvas._elem.fadeOut(speed);
+ s.canvas._elem.fadeOut(speed, callback);
s.canvas._elem.nextAll('.jqplot-point-label.jqplot-series-'+s.index).fadeOut(speed);
}
}
else {
- if (s.canvas._elem.is(':hidden')) {
+ // this can be tricky because series may not have a canvas element if replotting.
+ if (s.canvas._elem.is(':hidden') || !s.show) {
+ s.show = true;
+
+ s.canvas._elem.removeClass('jqplot-series-hidden');
if (s.shadowCanvas._elem) {
s.shadowCanvas._elem.show();
}
- s.canvas._elem.show();
+ s.canvas._elem.show(0, callback);
s.canvas._elem.nextAll('.jqplot-point-label.jqplot-series-'+s.index).show();
}
else {
+ s.show = false;
+
+ s.canvas._elem.addClass('jqplot-series-hidden');
if (s.shadowCanvas._elem) {
s.shadowCanvas._elem.hide();
}
- s.canvas._elem.hide();
+ s.canvas._elem.hide(0, callback);
s.canvas._elem.nextAll('.jqplot-point-label.jqplot-series-'+s.index).hide();
}
}
@@ -1227,13 +1595,15 @@
Grid.prototype.constructor = Grid;
Grid.prototype.init = function() {
- this.renderer = new this.renderer();
+ if ($.isFunction(this.renderer)) {
+ this.renderer = new this.renderer();
+ }
this.renderer.init.call(this, this.rendererOptions);
};
- Grid.prototype.createElement = function(offsets) {
+ Grid.prototype.createElement = function(offsets,plot) {
this._offsets = offsets;
- return this.renderer.createElement.call(this);
+ return this.renderer.createElement.call(this, plot);
};
Grid.prototype.draw = function() {
@@ -1248,22 +1618,18 @@
$.jqplot.GenericCanvas.prototype = new $.jqplot.ElemContainer();
$.jqplot.GenericCanvas.prototype.constructor = $.jqplot.GenericCanvas;
- $.jqplot.GenericCanvas.prototype.createElement = function(offsets, clss, plotDimensions) {
+ $.jqplot.GenericCanvas.prototype.createElement = function(offsets, clss, plotDimensions, plot) {
this._offsets = offsets;
var klass = 'jqplot';
if (clss != undefined) {
klass = clss;
}
var elem;
- // if this canvas already has a dom element, don't make a new one.
- if (this._elem) {
- elem = this._elem.get(0);
- }
- else {
- elem = document.createElement('canvas');
- }
+
+ elem = plot.canvasManager.getCanvas();
+
// if new plotDimensions supplied, use them.
- if (plotDimensions != undefined) {
+ if (plotDimensions != null) {
this._plotDimensions = plotDimensions;
}
@@ -1273,10 +1639,10 @@
this._elem.css({ position: 'absolute', left: this._offsets.left, top: this._offsets.top });
this._elem.addClass(klass);
- if ($.jqplot.use_excanvas) {
- window.G_vmlCanvasManager.init_(document);
- elem = window.G_vmlCanvasManager.initElement(elem);
- }
+
+ elem = plot.canvasManager.initCanvas(elem);
+
+ elem = null;
return this._elem;
};
@@ -1285,24 +1651,43 @@
return this._ctx;
};
+ // Memory Leaks patch
+ $.jqplot.GenericCanvas.prototype.resetCanvas = function() {
+ if (this._elem) {
+ if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) {
+ window.G_vmlCanvasManager.uninitElement(this._elem.get(0));
+ }
+
+ //this._elem.remove();
+ this._elem.emptyForce();
+ }
+
+ this._ctx = null;
+ };
+
$.jqplot.HooksManager = function () {
this.hooks =[];
+ this.args = [];
};
- $.jqplot.HooksManager.prototype.addOnce = function(fn) {
- var havehook = false, i;
- for (i=0; i<this.hooks.length; i++) {
- if (this.hooks[i][0] == fn) {
+ $.jqplot.HooksManager.prototype.addOnce = function(fn, args) {
+ args = args || [];
+ var havehook = false;
+ for (var i=0, l=this.hooks.length; i<l; i++) {
+ if (this.hooks[i] == fn) {
havehook = true;
}
}
if (!havehook) {
this.hooks.push(fn);
+ this.args.push(args);
}
};
- $.jqplot.HooksManager.prototype.add = function(fn) {
+ $.jqplot.HooksManager.prototype.add = function(fn, args) {
+ args = args || [];
this.hooks.push(fn);
+ this.args.push(args);
};
$.jqplot.EventListenerManager = function () {
@@ -1311,7 +1696,7 @@
$.jqplot.EventListenerManager.prototype.addOnce = function(ev, fn) {
var havehook = false, h, i;
- for (i=0; i<this.hooks.length; i++) {
+ for (var i=0, l=this.hooks.length; i<l; i++) {
h = this.hooks[i];
if (h[0] == ev && h[1] == fn) {
havehook = true;
@@ -1326,6 +1711,9 @@
this.hooks.push([ev, fn]);
};
+
+ var _axisNames = ['yMidAxis', 'xaxis', 'yaxis', 'x2axis', 'y2axis', 'y3axis', 'y4axis', 'y5axis', 'y6axis', 'y7axis', 'y8axis', 'y9axis'];
+
/**
* Class: jqPlot
* Plot object returned by call to $.jqplot. Handles parsing user options,
@@ -1341,6 +1729,25 @@
// > title: 'A Plot'
// > }
//
+
+ // prop: animate
+ // True to animate the series on initial plot draw (renderer dependent).
+ // Actual animation functionality must be supported in the renderer.
+ this.animate = false;
+ // prop: animateReplot
+ // True to animate series after a call to the replot() method.
+ // Use with caution! Replots can happen very frequently under
+ // certain circumstances (e.g. resizing, dragging points) and
+ // animation in these situations can cause problems.
+ this.animateReplot = false;
+ // prop: axes
+ // up to 4 axes are supported, each with it's own options,
+ // See <Axis> for axis specific options.
+ this.axes = {xaxis: new Axis('xaxis'), yaxis: new Axis('yaxis'), x2axis: new Axis('x2axis'), y2axis: new Axis('y2axis'), y3axis: new Axis('y3axis'), y4axis: new Axis('y4axis'), y5axis: new Axis('y5axis'), y6axis: new Axis('y6axis'), y7axis: new Axis('y7axis'), y8axis: new Axis('y8axis'), y9axis: new Axis('y9axis'), yMidAxis: new Axis('yMidAxis')};
+ this.baseCanvas = new $.jqplot.GenericCanvas();
+ // true to intercept right click events and fire a 'jqplotRightClick' event.
+ // this will also block the context menu.
+ this.captureRightClick = false;
// prop: data
// user's data. Data should *NOT* be specified in the options object,
// but be passed in as the second argument to the $.jqplot() function.
@@ -1348,108 +1755,134 @@
// The data should be in the form of an array of 2D or 1D arrays like
// > [ [[x1, y1], [x2, y2],...], [y1, y2, ...] ].
this.data = [];
- // prop dataRenderer
+ // prop: dataRenderer
// A callable which can be used to preprocess data passed into the plot.
// Will be called with 2 arguments, the plot data and a reference to the plot.
this.dataRenderer;
- // prop dataRendererOptions
+ // prop: dataRendererOptions
// Options that will be passed to the dataRenderer.
// Can be of any type.
this.dataRendererOptions;
- // The id of the dom element to render the plot into
- this.targetId = null;
- // the jquery object for the dom target.
- this.target = null;
this.defaults = {
// prop: axesDefaults
// default options that will be applied to all axes.
// see <Axis> for axes options.
axesDefaults: {},
- axes: {xaxis:{}, yaxis:{}, x2axis:{}, y2axis:{}, y3axis:{}, y4axis:{}, y5axis:{}, y6axis:{}, y7axis:{}, y8axis:{}, y9axis:{}},
+ axes: {xaxis:{}, yaxis:{}, x2axis:{}, y2axis:{}, y3axis:{}, y4axis:{}, y5axis:{}, y6axis:{}, y7axis:{}, y8axis:{}, y9axis:{}, yMidAxis:{}},
// prop: seriesDefaults
// default options that will be applied to all series.
// see <Series> for series options.
seriesDefaults: {},
- gridPadding: {top:10, right:10, bottom:23, left:10},
series:[]
};
- // prop: series
- // Array of series object options.
- // see <Series> for series specific options.
- this.series = [];
- // prop: axes
- // up to 4 axes are supported, each with it's own options,
- // See <Axis> for axis specific options.
- this.axes = {xaxis: new Axis('xaxis'), yaxis: new Axis('yaxis'), x2axis: new Axis('x2axis'), y2axis: new Axis('y2axis'), y3axis: new Axis('y3axis'), y4axis: new Axis('y4axis'), y5axis: new Axis('y5axis'), y6axis: new Axis('y6axis'), y7axis: new Axis('y7axis'), y8axis: new Axis('y8axis'), y9axis: new Axis('y9axis')};
+ // prop: defaultAxisStart
+ // 1-D data series are internally converted into 2-D [x,y] data point arrays
+ // by jqPlot. This is the default starting value for the missing x or y value.
+ // The added data will be a monotonically increasing series (e.g. [1, 2, 3, ...])
+ // starting at this value.
+ this.defaultAxisStart = 1;
+ // this.doCustomEventBinding = true;
+ // prop: drawIfHidden
+ // True to execute the draw method even if the plot target is hidden.
+ // Generally, this should be false. Most plot elements will not be sized/
+ // positioned correclty if renderered into a hidden container. To render into
+ // a hidden container, call the replot method when the container is shown.
+ this.drawIfHidden = false;
+ this.eventCanvas = new $.jqplot.GenericCanvas();
+ // prop: fillBetween
+ // Fill between 2 line series in a plot.
+ // Options object:
+ // {
+ // series1: first index (0 based) of series in fill
+ // series2: second index (0 based) of series in fill
+ // color: color of fill [default fillColor of series1]
+ // baseSeries: fill will be drawn below this series (0 based index)
+ // fill: false to turn off fill [default true].
+ // }
+ this.fillBetween = {
+ series1: null,
+ series2: null,
+ color: null,
+ baseSeries: 0,
+ fill: true
+ };
+ // prop; fontFamily
+ // css spec for the font-family attribute. Default for the entire plot.
+ this.fontFamily;
+ // prop: fontSize
+ // css spec for the font-size attribute. Default for the entire plot.
+ this.fontSize;
// prop: grid
// See <Grid> for grid specific options.
this.grid = new Grid();
// prop: legend
// see <$.jqplot.TableLegendRenderer>
this.legend = new Legend();
- this.baseCanvas = new $.jqplot.GenericCanvas();
+ // prop: noDataIndicator
+ // Options to set up a mock plot with a data loading indicator if no data is specified.
+ this.negativeSeriesColors = $.jqplot.config.defaultNegativeColors;
+ this.noDataIndicator = {
+ show: false,
+ indicator: 'Loading Data...',
+ axes: {
+ xaxis: {
+ min: 0,
+ max: 10,
+ tickInterval: 2,
+ show: true
+ },
+ yaxis: {
+ min: 0,
+ max: 12,
+ tickInterval: 3,
+ show: true
+ }
+ }
+ };
+ // container to hold all of the merged options. Convienence for plugins.
+ this.options = {};
+ this.previousSeriesStack = [];
+ // Namespece to hold plugins. Generally non-renderer plugins add themselves to here.
+ this.plugins = {};
+ // prop: series
+ // Array of series object options.
+ // see <Series> for series specific options.
+ this.series = [];
// array of series indicies. Keep track of order
// which series canvases are displayed, lowest
// to highest, back to front.
this.seriesStack = [];
- this.previousSeriesStack = [];
- this.eventCanvas = new $.jqplot.GenericCanvas();
- this._width = null;
- this._height = null;
- this._plotDimensions = {height:null, width:null};
- this._gridPadding = {top:10, right:10, bottom:10, left:10};
- // a shortcut for axis syncTicks options. Not implemented yet.
- this.syncXTicks = true;
- // a shortcut for axis syncTicks options. Not implemented yet.
- this.syncYTicks = true;
// prop: seriesColors
// Ann array of CSS color specifications that will be applied, in order,
// to the series in the plot. Colors will wrap around so, if their
// are more series than colors, colors will be reused starting at the
// beginning. For pie charts, this specifies the colors of the slices.
- this.seriesColors = [ "#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"];
- this.negativeSeriesColors = [ "#498991", "#C08840", "#9F9274", "#546D61", "#646C4A", "#6F6621", "#6E3F5F", "#4F64B0", "#A89050", "#C45923", "#187399", "#945381", "#959E5C", "#C7AF7B", "#478396", "#907294"];
+ this.seriesColors = $.jqplot.config.defaultColors;
// prop: sortData
// false to not sort the data passed in by the user.
// Many bar, stakced and other graphs as well as many plugins depend on
// having sorted data.
this.sortData = true;
- var seriesColorsIndex = 0;
+ // prop: stackSeries
+ // true or false, creates a stack or "mountain" plot.
+ // Not all series renderers may implement this option.
+ this.stackSeries = false;
+ // a shortcut for axis syncTicks options. Not implemented yet.
+ this.syncXTicks = true;
+ // a shortcut for axis syncTicks options. Not implemented yet.
+ this.syncYTicks = true;
+ // the jquery object for the dom target.
+ this.target = null;
+ // The id of the dom element to render the plot into
+ this.targetId = null;
// prop textColor
// css spec for the css color attribute. Default for the entire plot.
this.textColor;
- // prop; fontFamily
- // css spec for the font-family attribute. Default for the entire plot.
- this.fontFamily;
- // prop: fontSize
- // css spec for the font-size attribute. Default for the entire plot.
- this.fontSize;
// prop: title
// Title object. See <Title> for specific options. As a shortcut, you
// can specify the title option as just a string like: title: 'My Plot'
// and this will create a new title object with the specified text.
this.title = new Title();
- // container to hold all of the merged options. Convienence for plugins.
- this.options = {};
- // prop: stackSeries
- // true or false, creates a stack or "mountain" plot.
- // Not all series renderers may implement this option.
- this.stackSeries = false;
- // prop: defaultAxisStart
- // 1-D data series are internally converted into 2-D [x,y] data point arrays
- // by jqPlot. This is the default starting value for the missing x or y value.
- // The added data will be a monotonically increasing series (e.g. [1, 2, 3, ...])
- // starting at this value.
- this.defaultAxisStart = 1;
- // array to hold the cumulative stacked series data.
- // used to ajust the individual series data, which won't have access to other
- // series data.
- this._stackData = [];
- // array that holds the data to be plotted. This will be the series data
- // merged with the the appropriate data from _stackData according to the stackAxis.
- this._plotData = [];
- // Namespece to hold plugins. Generally non-renderer plugins add themselves to here.
- this.plugins = {};
// Count how many times the draw method has been called while the plot is visible.
// Mostly used to test if plot has never been dran (=0), has been successfully drawn
// into a visible container once (=1) or draw more than once into a visible container.
@@ -1457,21 +1890,25 @@
// After plot has been visibly drawn once, it generally doesn't need redrawn if its
// container is hidden and shown.
this._drawCount = 0;
- // this.doCustomEventBinding = true;
- // prop: drawIfHidden
- // True to execute the draw method even if the plot target is hidden.
- // Generally, this should be false. Most plot elements will not be sized/
- // positioned correclty if renderered into a hidden container. To render into
- // a hidden container, call the replot method when the container is shown.
- this.drawIfHidden = false;
- // true to intercept right click events and fire a 'jqplotRightClick' event.
- // this will also block the context menu.
- this.captureRightClick = false;
- this.themeEngine = new $.jqplot.ThemeEngine();
// sum of y values for all series in plot.
// used in mekko chart.
this._sumy = 0;
this._sumx = 0;
+ // array to hold the cumulative stacked series data.
+ // used to ajust the individual series data, which won't have access to other
+ // series data.
+ this._stackData = [];
+ // array that holds the data to be plotted. This will be the series data
+ // merged with the the appropriate data from _stackData according to the stackAxis.
+ this._plotData = [];
+ this._width = null;
+ this._height = null;
+ this._plotDimensions = {height:null, width:null};
+ this._gridPadding = {top:null, right:null, bottom:null, left:null};
+ this._defaultGridPadding = {top:10, right:10, bottom:23, left:10};
+
+ this._addDomReference = $.jqplot.config.addDomReference;
+
this.preInitHooks = new $.jqplot.HooksManager();
this.postInitHooks = new $.jqplot.HooksManager();
this.preParseOptionsHooks = new $.jqplot.HooksManager();
@@ -1490,14 +1927,22 @@
this.preDrawSeriesShadowHooks = new $.jqplot.HooksManager();
this.postDrawSeriesShadowHooks = new $.jqplot.HooksManager();
- this.colorGenerator = $.jqplot.ColorGenerator;
+ this.colorGenerator = new $.jqplot.ColorGenerator();
+ this.negativeColorGenerator = new $.jqplot.ColorGenerator();
+
+ this.canvasManager = new $.jqplot.CanvasManager();
+
+ this.themeEngine = new $.jqplot.ThemeEngine();
+ var seriesColorsIndex = 0;
+
// Group: methods
//
// method: init
// sets the plot target, checks data and applies user
// options to plot.
this.init = function(target, data, options) {
+ options = options || {};
for (var i=0; i<$.jqplot.preInitHooks.length; i++) {
$.jqplot.preInitHooks[i].call(this, target, data, options);
}
@@ -1508,6 +1953,13 @@
this.targetId = '#'+target;
this.target = $('#'+target);
+
+ //////
+ // Add a reference to plot
+ //////
+ if (this._addDomReference) {
+ this.target.data('jqplot', this);
+ }
// remove any error class that may be stuck on target.
this.target.removeClass('jqplot-error');
if (!this.target.get(0)) {
@@ -1538,7 +1990,7 @@
this.target.css('height', h+'px');
}
else {
- this._height = this.target.height();
+ this._height = h = this.target.height();
}
if (!this.target.width()) {
var w;
@@ -1555,8 +2007,12 @@
this.target.css('width', w+'px');
}
else {
- this._width = this.target.width();
+ this._width = w = this.target.width();
}
+
+ for (var i=0, l=_axisNames.length; i<l; i++) {
+ this.axes[_axisNames[i]] = new Axis(_axisNames[i]);
+ }
this._plotDimensions.height = this._height;
this._plotDimensions.width = this._width;
@@ -1569,7 +2025,7 @@
throw "Canvas dimension not set";
}
- if (options.dataRenderer && typeof(options.dataRenderer) == "function") {
+ if (options.dataRenderer && $.isFunction(options.dataRenderer)) {
if (options.dataRendererOptions) {
this.dataRendererOptions = options.dataRendererOptions;
}
@@ -1577,21 +2033,52 @@
data = this.dataRenderer(data, this, this.dataRendererOptions);
}
- if (data == null) {
- throw{
- name: "DataError",
- message: "No data to plot."
- };
+ if (options.noDataIndicator && $.isPlainObject(options.noDataIndicator)) {
+ $.extend(true, this.noDataIndicator, options.noDataIndicator);
}
- if (data.constructor != Array || data.length == 0 || data[0].constructor != Array || data[0].length == 0) {
- throw{
- name: "DataError",
- message: "No data to plot."
- };
+ if (data == null || $.isArray(data) == false || data.length == 0 || $.isArray(data[0]) == false || data[0].length == 0) {
+
+ if (this.noDataIndicator.show == false) {
+ throw "No Data";
+ }
+
+ else {
+ // have to be descructive here in order for plot to not try and render series.
+ // This means that $.jqplot() will have to be called again when there is data.
+ //delete options.series;
+
+ for (var ax in this.noDataIndicator.axes) {
+ for (var prop in this.noDataIndicator.axes[ax]) {
+ this.axes[ax][prop] = this.noDataIndicator.axes[ax][prop];
+ }
+ }
+
+ this.postDrawHooks.add(function() {
+ var eh = this.eventCanvas.getHeight();
+ var ew = this.eventCanvas.getWidth();
+ var temp = $('<div class="jqplot-noData-container" style="position:absolute;"></div>');
+ this.target.append(temp);
+ temp.height(eh);
+ temp.width(ew);
+ temp.css('top', this.eventCanvas._offsets.top);
+ temp.css('left', this.eventCanvas._offsets.left);
+
+ var temp2 = $('<div class="jqplot-noData-contents" style="text-align:center; position:relative; margin-left:auto; margin-right:auto;"></div>');
+ temp.append(temp2);
+ temp2.html(this.noDataIndicator.indicator);
+ var th = temp2.height();
+ var tw = temp2.width();
+ temp2.height(th);
+ temp2.width(tw);
+ temp2.css('top', (eh - th)/2 + 'px');
+ });
+
+ }
}
- this.data = data;
+ // make a copy of the data
+ this.data = $.extend(true, [], data);
this.parseOptions(options);
@@ -1609,6 +2096,7 @@
this.legend.init();
this._sumy = 0;
this._sumx = 0;
+ this.computePlotData();
for (var i=0; i<this.series.length; i++) {
// set default stacking order for series canvases
this.seriesStack.push(i);
@@ -1616,27 +2104,39 @@
this.series[i].shadowCanvas._plotDimensions = this._plotDimensions;
this.series[i].canvas._plotDimensions = this._plotDimensions;
for (var j=0; j<$.jqplot.preSeriesInitHooks.length; j++) {
- $.jqplot.preSeriesInitHooks[j].call(this.series[i], target, data, this.options.seriesDefaults, this.options.series[i], this);
+ $.jqplot.preSeriesInitHooks[j].call(this.series[i], target, this.data, this.options.seriesDefaults, this.options.series[i], this);
}
for (var j=0; j<this.preSeriesInitHooks.hooks.length; j++) {
- this.preSeriesInitHooks.hooks[j].call(this.series[i], target, data, this.options.seriesDefaults, this.options.series[i], this);
+ this.preSeriesInitHooks.hooks[j].call(this.series[i], target, this.data, this.options.seriesDefaults, this.options.series[i], this);
}
- this.populatePlotData(this.series[i], i);
+ // this.populatePlotData(this.series[i], i);
this.series[i]._plotDimensions = this._plotDimensions;
this.series[i].init(i, this.grid.borderWidth, this);
for (var j=0; j<$.jqplot.postSeriesInitHooks.length; j++) {
- $.jqplot.postSeriesInitHooks[j].call(this.series[i], target, data, this.options.seriesDefaults, this.options.series[i], this);
+ $.jqplot.postSeriesInitHooks[j].call(this.series[i], target, this.data, this.options.seriesDefaults, this.options.series[i], this);
}
for (var j=0; j<this.postSeriesInitHooks.hooks.length; j++) {
- this.postSeriesInitHooks.hooks[j].call(this.series[i], target, data, this.options.seriesDefaults, this.options.series[i], this);
+ this.postSeriesInitHooks.hooks[j].call(this.series[i], target, this.data, this.options.seriesDefaults, this.options.series[i], this);
}
this._sumy += this.series[i]._sumy;
this._sumx += this.series[i]._sumx;
}
- for (var name in this.axes) {
- this.axes[name]._plotDimensions = this._plotDimensions;
- this.axes[name].init();
+ var name,
+ axis;
+ for (var i=0, l=_axisNames.length; i<l; i++) {
+ name = _axisNames[i];
+ axis = this.axes[name];
+ axis._plotDimensions = this._plotDimensions;
+ axis.init();
+ if (this.axes[name].borderColor == null) {
+ if (name.charAt(0) !== 'x' && axis.useSeriesColor === true && axis.show) {
+ axis.borderColor = axis._series[0].color;
+ }
+ else {
+ axis.borderColor = this.grid.borderColor;
+ }
+ }
}
if (this.sortData) {
@@ -1648,11 +2148,11 @@
this.legend._series = this.series;
for (var i=0; i<$.jqplot.postInitHooks.length; i++) {
- $.jqplot.postInitHooks[i].call(this, target, data, options);
+ $.jqplot.postInitHooks[i].call(this, target, this.data, options);
}
for (var i=0; i<this.postInitHooks.hooks.length; i++) {
- this.postInitHooks.hooks[i].call(this, target, data, options);
+ this.postInitHooks.hooks[i].call(this, target, this.data, options);
}
};
@@ -1662,65 +2162,204 @@
//
// Parameters:
// axes - Boolean to reset or not reset all axes or an array or object of axis names to reset.
- this.resetAxesScale = function(axes) {
- var ax = (axes != undefined) ? axes : this.axes;
+ this.resetAxesScale = function(axes, options) {
+ var opts = options || {};
+ var ax = axes || this.axes;
if (ax === true) {
ax = this.axes;
}
- if (ax.constructor === Array) {
+ if ($.isArray(ax)) {
for (var i = 0; i < ax.length; i++) {
- this.axes[ax[i]].resetScale();
+ this.axes[ax[i]].resetScale(opts[ax[i]]);
}
}
- else if (ax.constructor === Object) {
+ else if (typeof(ax) === 'object') {
for (var name in ax) {
- this.axes[name].resetScale();
+ this.axes[name].resetScale(opts[name]);
}
}
};
// method: reInitialize
// reinitialize plot for replotting.
// not called directly.
- this.reInitialize = function () {
+ this.reInitialize = function (data, opts) {
// Plot should be visible and have a height and width.
// If plot doesn't have height and width for some
// reason, set it by other means. Plot must not have
// a display:none attribute, however.
- if (!this.target.height()) {
- var h;
- if (options && options.height) {
- h = parseInt(options.height, 10);
+
+ var options = $.extend(true, {}, this.options, opts);
+
+ var target = this.targetId.substr(1);
+ var tdata = (data == null) ? this.data : data;
+
+ for (var i=0; i<$.jqplot.preInitHooks.length; i++) {
+ $.jqplot.preInitHooks[i].call(this, target, tdata, options);
+ }
+
+ for (var i=0; i<this.preInitHooks.hooks.length; i++) {
+ this.preInitHooks.hooks[i].call(this, target, tdata, options);
+ }
+
+ this._height = this.target.height();
+ this._width = this.target.width();
+
+ if (this._height <=0 || this._width <=0 || !this._height || !this._width) {
+ throw "Target dimension not set";
+ }
+
+ this._plotDimensions.height = this._height;
+ this._plotDimensions.width = this._width;
+ this.grid._plotDimensions = this._plotDimensions;
+ this.title._plotDimensions = this._plotDimensions;
+ this.baseCanvas._plotDimensions = this._plotDimensions;
+ this.eventCanvas._plotDimensions = this._plotDimensions;
+ this.legend._plotDimensions = this._plotDimensions;
+
+ var name,
+ t,
+ j,
+ axis;
+
+ for (var i=0, l=_axisNames.length; i<l; i++) {
+ name = _axisNames[i];
+ axis = this.axes[name];
+
+ // Memory Leaks patch : clear ticks elements
+ t = axis._ticks;
+ for (var j = 0, tlen = t.length; j < tlen; j++) {
+ var el = t[j]._elem;
+ if (el) {
+ // if canvas renderer
+ if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) {
+ window.G_vmlCanvasManager.uninitElement(el.get(0));
+ }
+ el.emptyForce();
+ el = null;
+ t._elem = null;
+ }
}
- else if (this.target.attr('data-height')) {
- h = parseInt(this.target.attr('data-height'), 10);
+ t = null;
+
+ delete axis.ticks;
+ delete axis._ticks;
+ this.axes[name] = new Axis(name);
+ this.axes[name]._plotWidth = this._width;
+ this.axes[name]._plotHeight = this._height;
+ }
+
+ if (data) {
+ if (options.dataRenderer && $.isFunction(options.dataRenderer)) {
+ if (options.dataRendererOptions) {
+ this.dataRendererOptions = options.dataRendererOptions;
+ }
+ this.dataRenderer = options.dataRenderer;
+ data = this.dataRenderer(data, this, this.dataRendererOptions);
}
- else {
- h = parseInt($.jqplot.config.defaultHeight, 10);
- }
- this._height = h;
- this.target.css('height', h+'px');
+
+ // make a copy of the data
+ this.data = $.extend(true, [], data);
}
- else {
- this._height = this.target.height();
+
+ if (opts) {
+ this.parseOptions(options);
}
- if (!this.target.width()) {
- var w;
- if (options && options.width) {
- w = parseInt(options.width, 10);
+
+ this.title._plotWidth = this._width;
+
+ if (this.textColor) {
+ this.target.css('color', this.textColor);
+ }
+ if (this.fontFamily) {
+ this.target.css('font-family', this.fontFamily);
+ }
+ if (this.fontSize) {
+ this.target.css('font-size', this.fontSize);
+ }
+
+ this.title.init();
+ this.legend.init();
+ this._sumy = 0;
+ this._sumx = 0;
+
+ this.seriesStack = [];
+ this.previousSeriesStack = [];
+
+ this.computePlotData();
+ for (var i=0, l=this.series.length; i<l; i++) {
+ // set default stacking order for series canvases
+ this.seriesStack.push(i);
+ this.previousSeriesStack.push(i);
+ this.series[i].shadowCanvas._plotDimensions = this._plotDimensions;
+ this.series[i].canvas._plotDimensions = this._plotDimensions;
+ for (var j=0; j<$.jqplot.preSeriesInitHooks.length; j++) {
+ $.jqplot.preSeriesInitHooks[j].call(this.series[i], target, this.data, this.options.seriesDefaults, this.options.series[i], this);
}
- else if (this.target.attr('data-width')) {
- w = parseInt(this.target.attr('data-width'), 10);
+ for (var j=0; j<this.preSeriesInitHooks.hooks.length; j++) {
+ this.preSeriesInitHooks.hooks[j].call(this.series[i], target, this.data, this.options.seriesDefaults, this.options.series[i], this);
}
- else {
- w = parseInt($.jqplot.config.defaultWidth, 10);
+ // this.populatePlotData(this.series[i], i);
+ this.series[i]._plotDimensions = this._plotDimensions;
+ this.series[i].init(i, this.grid.borderWidth, this);
+ for (var j=0; j<$.jqplot.postSeriesInitHooks.length; j++) {
+ $.jqplot.postSeriesInitHooks[j].call(this.series[i], target, this.data, this.options.seriesDefaults, this.options.series[i], this);
}
- this._width = w;
- this.target.css('width', w+'px');
+ for (var j=0; j<this.postSeriesInitHooks.hooks.length; j++) {
+ this.postSeriesInitHooks.hooks[j].call(this.series[i], target, this.data, this.options.seriesDefaults, this.options.series[i], this);
+ }
+ this._sumy += this.series[i]._sumy;
+ this._sumx += this.series[i]._sumx;
}
- else {
- this._width = this.target.width();
+
+ for (var i=0, l=_axisNames.length; i<l; i++) {
+ name = _axisNames[i];
+ axis = this.axes[name];
+
+ axis._plotDimensions = this._plotDimensions;
+ axis.init();
+ if (axis.borderColor == null) {
+ if (name.charAt(0) !== 'x' && axis.useSeriesColor === true && axis.show) {
+ axis.borderColor = axis._series[0].color;
+ }
+ else {
+ axis.borderColor = this.grid.borderColor;
+ }
+ }
}
+ if (this.sortData) {
+ sortData(this.series);
+ }
+ this.grid.init();
+ this.grid._axes = this.axes;
+
+ this.legend._series = this.series;
+
+ for (var i=0, l=$.jqplot.postInitHooks.length; i<l; i++) {
+ $.jqplot.postInitHooks[i].call(this, target, this.data, options);
+ }
+
+ for (var i=0, l=this.postInitHooks.hooks.length; i<l; i++) {
+ this.postInitHooks.hooks[i].call(this, target, this.data, options);
+ }
+ };
+
+
+
+ // method: quickInit
+ //
+ // Quick reinitialization plot for replotting.
+ // Does not parse options ore recreate axes and series.
+ // not called directly.
+ this.quickInit = function () {
+ // Plot should be visible and have a height and width.
+ // If plot doesn't have height and width for some
+ // reason, set it by other means. Plot must not have
+ // a display:none attribute, however.
+
+ this._height = this.target.height();
+ this._width = this.target.width();
+
if (this._height <=0 || this._width <=0 || !this._height || !this._width) {
throw "Target dimension not set";
}
@@ -1752,19 +2391,42 @@
this._sumy = 0;
this._sumx = 0;
+ this.computePlotData();
for (var i=0; i<this.series.length; i++) {
- this.populatePlotData(this.series[i], i);
+ // this.populatePlotData(this.series[i], i);
+ if (this.series[i]._type === 'line' && this.series[i].renderer.bands.show) {
+ this.series[i].renderer.initBands.call(this.series[i], this.series[i].renderer.options, this);
+ }
this.series[i]._plotDimensions = this._plotDimensions;
this.series[i].canvas._plotDimensions = this._plotDimensions;
//this.series[i].init(i, this.grid.borderWidth);
this._sumy += this.series[i]._sumy;
this._sumx += this.series[i]._sumx;
}
+
+ var name;
- for (var name in this.axes) {
+ for (var j=0; j<12; j++) {
+ name = _axisNames[j];
+ // Memory Leaks patch : clear ticks elements
+ var t = this.axes[name]._ticks;
+ for (var i = 0; i < t.length; i++) {
+ var el = t[i]._elem;
+ if (el) {
+ // if canvas renderer
+ if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) {
+ window.G_vmlCanvasManager.uninitElement(el.get(0));
+ }
+ el.emptyForce();
+ el = null;
+ t._elem = null;
+ }
+ }
+ t = null;
+
this.axes[name]._plotDimensions = this._plotDimensions;
this.axes[name]._ticks = [];
- this.axes[name].renderer.init.call(this.axes[name], {});
+ // this.axes[name].renderer.init.call(this.axes[name], {});
}
if (this.sortData) {
@@ -1780,10 +2442,6 @@
function sortData(series) {
var d, sd, pd, ppd, ret;
for (var i=0; i<series.length; i++) {
- // d = series[i].data;
- // sd = series[i]._stackData;
- // pd = series[i]._plotData;
- // ppd = series[i]._prevPlotData;
var check;
var bat = [series[i].data, series[i]._stackData, series[i]._plotData, series[i]._prevPlotData];
for (var n=0; n<4; n++) {
@@ -1798,9 +2456,6 @@
}
if (check) {
d.sort(function(a,b) { return a[1] - b[1]; });
- // sd.sort(function(a,b) { return a[1] - b[1]; });
- // pd.sort(function(a,b) { return a[1] - b[1]; });
- // ppd.sort(function(a,b) { return a[1] - b[1]; });
}
}
else {
@@ -1812,15 +2467,87 @@
}
if (check) {
d.sort(function(a,b) { return a[0] - b[0]; });
- // sd.sort(function(a,b) { return a[0] - b[0]; });
- // pd.sort(function(a,b) { return a[0] - b[0]; });
- // ppd.sort(function(a,b) { return a[0] - b[0]; });
}
}
}
}
}
+
+ this.computePlotData = function() {
+ this._plotData = [];
+ this._stackData = [];
+ var series,
+ index,
+ l;
+
+
+ for (index=0, l=this.series.length; index<l; index++) {
+ series = this.series[index];
+ this._plotData.push([]);
+ this._stackData.push([]);
+ var cd = series.data;
+ this._plotData[index] = $.extend(true, [], cd);
+ this._stackData[index] = $.extend(true, [], cd);
+ series._plotData = this._plotData[index];
+ series._stackData = this._stackData[index];
+ var plotValues = {x:[], y:[]};
+
+ if (this.stackSeries && !series.disableStack) {
+ series._stack = true;
+ ///////////////////////////
+ // have to check for nulls
+ ///////////////////////////
+ var sidx = (series._stackAxis === 'x') ? 0 : 1;
+
+ for (var k=0, cdl=cd.length; k<cdl; k++) {
+ var temp = cd[k][sidx];
+ if (temp == null) {
+ temp = 0;
+ }
+ this._plotData[index][k][sidx] = temp;
+ this._stackData[index][k][sidx] = temp;
+
+ if (index > 0) {
+ for (var j=index; j--;) {
+ var prevval = this._plotData[j][k][sidx];
+ // only need to sum up the stack axis column of data
+ // and only sum if it is of same sign.
+ // if previous series isn't same sign, keep looking
+ // at earlier series untill we find one of same sign.
+ if (temp * prevval >= 0) {
+ this._plotData[index][k][sidx] += prevval;
+ this._stackData[index][k][sidx] += prevval;
+ break;
+ }
+ }
+ }
+ }
+
+ }
+ else {
+ for (var i=0; i<series.data.length; i++) {
+ plotValues.x.push(series.data[i][0]);
+ plotValues.y.push(series.data[i][1]);
+ }
+ this._stackData.push(series.data);
+ this.series[index]._stackData = series.data;
+ this._plotData.push(series.data);
+ series._plotData = series.data;
+ series._plotValues = plotValues;
+ }
+ if (index>0) {
+ series._prevPlotData = this.series[index-1]._plotData;
+ }
+ series._sumy = 0;
+ series._sumx = 0;
+ for (i=series.data.length-1; i>-1; i--) {
+ series._sumy += series.data[i][1];
+ series._sumx += series.data[i][0];
+ }
+ }
+
+ };
// populate the _stackData and _plotData arrays for the plot and the series.
this.populatePlotData = function(series, index) {
@@ -1832,21 +2559,29 @@
var plotValues = {x:[], y:[]};
if (this.stackSeries && !series.disableStack) {
series._stack = true;
- var sidx = series._stackAxis == 'x' ? 0 : 1;
- var idx = sidx ? 0 : 1;
+ var sidx = (series._stackAxis === 'x') ? 0 : 1;
+ // var idx = sidx ? 0 : 1;
// push the current data into stackData
//this._stackData.push(this.series[i].data);
var temp = $.extend(true, [], series.data);
// create the data that will be plotted for this series
var plotdata = $.extend(true, [], series.data);
+ var tempx, tempy, dval, stackval, comparator;
// for first series, nothing to add to stackData.
for (var j=0; j<index; j++) {
var cd = this.series[j].data;
for (var k=0; k<cd.length; k++) {
- temp[k][0] += cd[k][0];
- temp[k][1] += cd[k][1];
+ dval = cd[k];
+ tempx = (dval[0] != null) ? dval[0] : 0;
+ tempy = (dval[1] != null) ? dval[1] : 0;
+ temp[k][0] += tempx;
+ temp[k][1] += tempy;
+ stackval = (sidx) ? tempy : tempx;
// only need to sum up the stack axis column of data
- plotdata[k][sidx] += cd[k][sidx];
+ // and only sum if it is of same sign.
+ if (series.data[k][sidx] * stackval >= 0) {
+ plotdata[k][sidx] += stackval;
+ }
}
}
for (var i=0; i<plotdata.length; i++) {
@@ -1905,45 +2640,66 @@
$.jqplot.preParseOptionsHooks[i].call(this, options);
}
this.options = $.extend(true, {}, this.defaults, options);
- this.stackSeries = this.options.stackSeries;
- if (this.options.seriesColors) {
- this.seriesColors = this.options.seriesColors;
+ var opts = this.options;
+ this.animate = opts.animate;
+ this.animateReplot = opts.animateReplot;
+ this.stackSeries = opts.stackSeries;
+ if ($.isPlainObject(opts.fillBetween)) {
+
+ var temp = ['series1', 'series2', 'color', 'baseSeries', 'fill'],
+ tempi;
+
+ for (var i=0, l=temp.length; i<l; i++) {
+ tempi = temp[i];
+ if (opts.fillBetween[tempi] != null) {
+ this.fillBetween[tempi] = opts.fillBetween[tempi];
+ }
+ }
}
- if (this.options.negativeSeriesColors) {
- this.negativeSeriesColors = this.options.negativeSeriesColors;
+
+ if (opts.seriesColors) {
+ this.seriesColors = opts.seriesColors;
}
- if (this.options.captureRightClick) {
- this.captureRightClick = this.options.captureRightClick;
+ if (opts.negativeSeriesColors) {
+ this.negativeSeriesColors = opts.negativeSeriesColors;
}
+ if (opts.captureRightClick) {
+ this.captureRightClick = opts.captureRightClick;
+ }
this.defaultAxisStart = (options && options.defaultAxisStart != null) ? options.defaultAxisStart : this.defaultAxisStart;
- var cg = new this.colorGenerator(this.seriesColors);
+ this.colorGenerator.setColors(this.seriesColors);
+ this.negativeColorGenerator.setColors(this.negativeSeriesColors);
+ // var cg = new this.colorGenerator(this.seriesColors);
+ // var ncg = new this.colorGenerator(this.negativeSeriesColors);
// this._gridPadding = this.options.gridPadding;
- $.extend(true, this._gridPadding, this.options.gridPadding);
- this.sortData = (this.options.sortData != null) ? this.options.sortData : this.sortData;
- for (var n in this.axes) {
+ $.extend(true, this._gridPadding, opts.gridPadding);
+ this.sortData = (opts.sortData != null) ? opts.sortData : this.sortData;
+ for (var i=0; i<12; i++) {
+ var n = _axisNames[i];
var axis = this.axes[n];
- $.extend(true, axis, this.options.axesDefaults, this.options.axes[n]);
+ axis._options = $.extend(true, {}, opts.axesDefaults, opts.axes[n]);
+ $.extend(true, axis, opts.axesDefaults, opts.axes[n]);
axis._plotWidth = this._width;
axis._plotHeight = this._height;
}
- if (this.data.length == 0) {
- this.data = [];
- for (var i=0; i<this.options.series.length; i++) {
- this.data.push(this.options.series.data);
- }
- }
+ // if (this.data.length == 0) {
+ // this.data = [];
+ // for (var i=0; i<this.options.series.length; i++) {
+ // this.data.push(this.options.series.data);
+ // }
+ // }
var normalizeData = function(data, dir, start) {
// return data as an array of point arrays,
// in form [[x1,y1...], [x2,y2...], ...]
var temp = [];
- var i;
+ var i, l;
dir = dir || 'vertical';
- if (!(data[0] instanceof Array)) {
+ if (!$.isArray(data[0])) {
// we have a series of scalars. One line with just y values.
// turn the scalar list of data into a data array of form:
// [[1, data[0]], [2, data[1]], ...]
- for (i=0; i<data.length; i++) {
+ for (i=0, l=data.length; i<l; i++) {
if (dir == 'vertical') {
temp.push([start + i, data[i]]);
}
@@ -1959,18 +2715,26 @@
return temp;
};
- for (var i=0; i<this.data.length; i++) {
- var temp = new Series();
+ var colorIndex = 0;
+ this.series = [];
+ for (var i=0; i<this.data.length; i++) {
+ var sopts = $.extend(true, {index: i}, {seriesColors:this.seriesColors, negativeSeriesColors:this.negativeSeriesColors}, this.options.seriesDefaults, this.options.series[i], {rendererOptions:{animation:{show: this.animate}}});
+ // pass in options in case something needs set prior to initialization.
+ var temp = new Series(sopts);
for (var j=0; j<$.jqplot.preParseSeriesOptionsHooks.length; j++) {
$.jqplot.preParseSeriesOptionsHooks[j].call(temp, this.options.seriesDefaults, this.options.series[i]);
}
for (var j=0; j<this.preParseSeriesOptionsHooks.hooks.length; j++) {
this.preParseSeriesOptionsHooks.hooks[j].call(temp, this.options.seriesDefaults, this.options.series[i]);
}
- $.extend(true, temp, {seriesColors:this.seriesColors, negativeSeriesColors:this.negativeSeriesColors}, this.options.seriesDefaults, this.options.series[i]);
+ // Now go back and apply the options to the series. Really should just do this during initializaiton, but don't want to
+ // mess up preParseSeriesOptionsHooks at this point.
+ $.extend(true, temp, sopts);
var dir = 'vertical';
- if (temp.renderer.constructor == $.jqplot.barRenderer && temp.rendererOptions && temp.rendererOptions.barDirection == 'horizontal') {
+ if (temp.renderer === $.jqplot.BarRenderer && temp.rendererOptions && temp.rendererOptions.barDirection == 'horizontal') {
dir = 'horizontal';
+ temp._stackAxis = 'x';
+ temp._primaryAxis = '_yaxis';
}
temp.data = normalizeData(this.data[i], dir, this.defaultAxisStart);
switch (temp.xaxis) {
@@ -1990,11 +2754,24 @@
temp._xaxis.show = true;
temp._yaxis.show = true;
}
+ else {
+ if (temp._xaxis.scaleToHiddenSeries) {
+ temp._xaxis.show = true;
+ }
+ if (temp._yaxis.scaleToHiddenSeries) {
+ temp._yaxis.show = true;
+ }
+ }
- // parse the renderer options and apply default colors if not provided
- if (!temp.color && temp.show != false) {
- temp.color = cg.next();
- }
+ // // parse the renderer options and apply default colors if not provided
+ // if (!temp.color && temp.show != false) {
+ // temp.color = cg.next();
+ // colorIndex = cg.getIndex() - 1;;
+ // }
+ // if (!temp.negativeColor && temp.show != false) {
+ // temp.negativeColor = ncg.get(colorIndex);
+ // ncg.setIndex(colorIndex);
+ // }
if (!temp.label) {
temp.label = 'Series '+ (i+1).toString();
}
@@ -2012,19 +2789,12 @@
// copy the grid and title options into this object.
$.extend(true, this.grid, this.options.grid);
// if axis border properties aren't set, set default.
- for (var n in this.axes) {
+ for (var i=0, l=_axisNames.length; i<l; i++) {
+ var n = _axisNames[i];
var axis = this.axes[n];
if (axis.borderWidth == null) {
axis.borderWidth =this.grid.borderWidth;
}
- if (axis.borderColor == null) {
- if (n != 'xaxis' && n != 'x2axis' && axis.useSeriesColor === true && axis.show) {
- axis.borderColor = axis._series[0].color;
- }
- else {
- axis.borderColor = this.grid.borderColor;
- }
- }
}
if (typeof this.options.title == 'string') {
@@ -2044,6 +2814,22 @@
}
};
+ // method: destroy
+ // Releases all resources occupied by the plot
+ this.destroy = function() {
+ this.canvasManager.freeAllCanvases();
+ if (this.eventCanvas && this.eventCanvas._elem) {
+ this.eventCanvas._elem.unbind();
+ }
+ // Couple of posts on Stack Overflow indicate that empty() doesn't
+ // always cear up the dom and release memory. Sometimes setting
+ // innerHTML property to null is needed. Particularly on IE, may
+ // have to directly set it to null, bypassing $.
+ this.target.empty();
+
+ this.target[0].innerHTML = '';
+ };
+
// method: replot
// Does a reinitialization of the plot followed by
// a redraw. Method could be used to interactively
@@ -2057,17 +2843,31 @@
// resetAxes - true to reset all axes min, max, numberTicks and tickInterval setting so axes will rescale themselves.
// optionally pass in list of axes to reset (e.g. ['xaxis', 'y2axis']) (default: false).
this.replot = function(options) {
- var opts = (options != undefined) ? options : {};
- var clear = (opts.clear != undefined) ? opts.clear : true;
- var resetAxes = (opts.resetAxes != undefined) ? opts.resetAxes : false;
+ var opts = options || {};
+ var data = opts.data || null;
+ var clear = (opts.clear === false) ? false : true;
+ var resetAxes = opts.resetAxes || false;
+ delete opts.data;
+ delete opts.clear;
+ delete opts.resetAxes;
+
this.target.trigger('jqplotPreReplot');
+
if (clear) {
- this.target.empty();
+ this.destroy();
}
+ // if have data or other options, full reinit.
+ // otherwise, quickinit.
+ if (data || !$.isEmptyObject(opts)) {
+ this.reInitialize(data, opts);
+ }
+ else {
+ this.quickInit();
+ }
+
if (resetAxes) {
- this.resetAxesScale(resetAxes);
+ this.resetAxesScale(resetAxes, opts.axes);
}
- this.reInitialize();
this.draw();
this.target.trigger('jqplotPostReplot');
};
@@ -2087,17 +2887,23 @@
clear = (clear != null) ? clear : true;
this.target.trigger('jqplotPreRedraw');
if (clear) {
+ this.canvasManager.freeAllCanvases();
+ this.eventCanvas._elem.unbind();
+ // Dont think I bind any events to the target, this shouldn't be necessary.
+ // It will remove user's events.
+ // this.target.unbind();
this.target.empty();
}
for (var ax in this.axes) {
this.axes[ax]._ticks = [];
}
- for (var i=0; i<this.series.length; i++) {
- this.populatePlotData(this.series[i], i);
- }
+ this.computePlotData();
+ // for (var i=0; i<this.series.length; i++) {
+ // this.populatePlotData(this.series[i], i);
+ // }
this._sumy = 0;
this._sumx = 0;
- for (i=0; i<this.series.length; i++) {
+ for (var i=0, tsl = this.series.length; i<tsl; i++) {
this._sumy += this.series[i]._sumy;
this._sumx += this.series[i]._sumx;
}
@@ -2111,21 +2917,25 @@
this.draw = function(){
if (this.drawIfHidden || this.target.is(':visible')) {
this.target.trigger('jqplotPreDraw');
- var i, j;
- for (i=0; i<$.jqplot.preDrawHooks.length; i++) {
+ var i,
+ j,
+ l,
+ tempseries;
+ for (i=0, l=$.jqplot.preDrawHooks.length; i<l; i++) {
$.jqplot.preDrawHooks[i].call(this);
}
- for (i=0; i<this.preDrawHooks.hooks.length; i++) {
- this.preDrawHooks.hooks[i].call(this);
+ for (i=0, l=this.preDrawHooks.length; i<l; i++) {
+ this.preDrawHooks.hooks[i].apply(this, this.preDrawSeriesHooks.args[i]);
}
// create an underlying canvas to be used for special features.
- this.target.append(this.baseCanvas.createElement({left:0, right:0, top:0, bottom:0}, 'jqplot-base-canvas'));
+ this.target.append(this.baseCanvas.createElement({left:0, right:0, top:0, bottom:0}, 'jqplot-base-canvas', null, this));
this.baseCanvas.setContext();
this.target.append(this.title.draw());
this.title.pack({top:0, left:0});
// make room for the legend between the grid and the edge.
- var legendElem = this.legend.draw();
+ // pass a dummy offsets object and a reference to the plot.
+ var legendElem = this.legend.draw({}, this);
var gridPadding = {top:0, left:0, bottom:0, right:0};
@@ -2157,8 +2967,11 @@
}
var ax = this.axes;
- for (var name in ax) {
- this.target.append(ax[name].draw(this.baseCanvas._ctx));
+ var name;
+ // draw the yMidAxis first, so xaxis of pyramid chart can adjust itself if needed.
+ for (i=0; i<12; i++) {
+ name = _axisNames[i];
+ this.target.append(ax[name].draw(this.baseCanvas._ctx, this));
ax[name].set();
}
if (ax.yaxis.show) {
@@ -2186,47 +2999,76 @@
}
// end of gridPadding adjustments.
+
+ // if user passed in gridDimensions option, check against calculated gridPadding
+ if (this.options.gridDimensions && $.isPlainObject(this.options.gridDimensions)) {
+ var gdw = parseInt(this.options.gridDimensions.width, 10) || 0;
+ var gdh = parseInt(this.options.gridDimensions.height, 10) || 0;
+ var widthAdj = (this._width - gridPadding.left - gridPadding.right - gdw)/2;
+ var heightAdj = (this._height - gridPadding.top - gridPadding.bottom - gdh)/2;
+
+ if (heightAdj >= 0 && widthAdj >= 0) {
+ gridPadding.top += heightAdj;
+ gridPadding.bottom += heightAdj;
+ gridPadding.left += widthAdj;
+ gridPadding.right += widthAdj;
+ }
+ }
var arr = ['top', 'bottom', 'left', 'right'];
for (var n in arr) {
- if (gridPadding[arr[n]]) {
+ if (this._gridPadding[arr[n]] == null && gridPadding[arr[n]] > 0) {
this._gridPadding[arr[n]] = gridPadding[arr[n]];
}
+ else if (this._gridPadding[arr[n]] == null) {
+ this._gridPadding[arr[n]] = this._defaultGridPadding[arr[n]];
+ }
}
- var legendPadding = (this.legend.placement == 'outsideGrid') ? {top:this.title.getHeight(), left: 0, right: 0, bottom: 0} : this._gridPadding;
-
+ var legendPadding = this._gridPadding;
+
+ if (this.legend.placement === 'outsideGrid') {
+ legendPadding = {top:this.title.getHeight(), left: 0, right: 0, bottom: 0};
+ if (this.legend.location === 's') {
+ legendPadding.left = this._gridPadding.left;
+ legendPadding.right = this._gridPadding.right;
+ }
+ }
+
ax.xaxis.pack({position:'absolute', bottom:this._gridPadding.bottom - ax.xaxis.getHeight(), left:0, width:this._width}, {min:this._gridPadding.left, max:this._width - this._gridPadding.right});
ax.yaxis.pack({position:'absolute', top:0, left:this._gridPadding.left - ax.yaxis.getWidth(), height:this._height}, {min:this._height - this._gridPadding.bottom, max: this._gridPadding.top});
ax.x2axis.pack({position:'absolute', top:this._gridPadding.top - ax.x2axis.getHeight(), left:0, width:this._width}, {min:this._gridPadding.left, max:this._width - this._gridPadding.right});
for (i=8; i>0; i--) {
ax[ra[i-1]].pack({position:'absolute', top:0, right:this._gridPadding.right - rapad[i-1]}, {min:this._height - this._gridPadding.bottom, max: this._gridPadding.top});
}
- // ax.y2axis.pack({position:'absolute', top:0, right:0}, {min:this._height - this._gridPadding.bottom, max: this._gridPadding.top});
+ var ltemp = (this._width - this._gridPadding.left - this._gridPadding.right)/2.0 + this._gridPadding.left - ax.yMidAxis.getWidth()/2.0;
+ ax.yMidAxis.pack({position:'absolute', top:0, left:ltemp, zIndex:9, textAlign: 'center'}, {min:this._height - this._gridPadding.bottom, max: this._gridPadding.top});
- this.target.append(this.grid.createElement(this._gridPadding));
+ this.target.append(this.grid.createElement(this._gridPadding, this));
this.grid.draw();
+ var series = this.series;
+ var seriesLength = series.length;
// put the shadow canvases behind the series canvases so shadows don't overlap on stacked bars.
- for (i=0; i<this.series.length; i++) {
+ for (i=0, l=seriesLength; i<l; i++) {
// draw series in order of stacking. This affects only
// order in which canvases are added to dom.
j = this.seriesStack[i];
- this.target.append(this.series[j].shadowCanvas.createElement(this._gridPadding, 'jqplot-series-shadowCanvas'));
- this.series[j].shadowCanvas.setContext();
- this.series[j].shadowCanvas._elem.data('seriesIndex', j);
+ this.target.append(series[j].shadowCanvas.createElement(this._gridPadding, 'jqplot-series-shadowCanvas', null, this));
+ series[j].shadowCanvas.setContext();
+ series[j].shadowCanvas._elem.data('seriesIndex', j);
}
- for (i=0; i<this.series.length; i++) {
+ for (i=0, l=seriesLength; i<l; i++) {
// draw series in order of stacking. This affects only
// order in which canvases are added to dom.
j = this.seriesStack[i];
- this.target.append(this.series[j].canvas.createElement(this._gridPadding, 'jqplot-series-canvas'));
- this.series[j].canvas.setContext();
- this.series[j].canvas._elem.data('seriesIndex', j);
+ this.target.append(series[j].canvas.createElement(this._gridPadding, 'jqplot-series-canvas', null, this));
+ series[j].canvas.setContext();
+ series[j].canvas._elem.data('seriesIndex', j);
}
// Need to use filled canvas to capture events in IE.
// Also, canvas seems to block selection of other elements in document on FF.
- this.target.append(this.eventCanvas.createElement(this._gridPadding, 'jqplot-event-canvas'));
+ this.target.append(this.eventCanvas.createElement(this._gridPadding, 'jqplot-event-canvas', null, this));
this.eventCanvas.setContext();
this.eventCanvas._ctx.fillStyle = 'rgba(0,0,0,0)';
this.eventCanvas._ctx.fillRect(0,0,this.eventCanvas._ctx.canvas.width, this.eventCanvas._ctx.canvas.height);
@@ -2247,39 +3089,102 @@
}
else { // draw series before legend
this.drawSeries();
- $(this.series[this.series.length-1].canvas._elem).after(legendElem);
+ if (seriesLength) {
+ $(series[seriesLength-1].canvas._elem).after(legendElem);
+ }
this.legend.pack(legendPadding);
}
// register event listeners on the overlay canvas
- for (var i=0; i<$.jqplot.eventListenerHooks.length; i++) {
+ for (var i=0, l=$.jqplot.eventListenerHooks.length; i<l; i++) {
// in the handler, this will refer to the eventCanvas dom element.
// make sure there are references back into plot objects.
this.eventCanvas._elem.bind($.jqplot.eventListenerHooks[i][0], {plot:this}, $.jqplot.eventListenerHooks[i][1]);
}
// register event listeners on the overlay canvas
- for (var i=0; i<this.eventListenerHooks.hooks.length; i++) {
+ for (var i=0, l=this.eventListenerHooks.hooks.length; i<l; i++) {
// in the handler, this will refer to the eventCanvas dom element.
// make sure there are references back into plot objects.
this.eventCanvas._elem.bind(this.eventListenerHooks.hooks[i][0], {plot:this}, this.eventListenerHooks.hooks[i][1]);
}
- for (var i=0; i<$.jqplot.postDrawHooks.length; i++) {
+ var fb = this.fillBetween;
+ if (fb.fill && fb.series1 !== fb.series2 && fb.series1 < seriesLength && fb.series2 < seriesLength && series[fb.series1]._type === 'line' && series[fb.series2]._type === 'line') {
+ this.doFillBetweenLines();
+ }
+
+ for (var i=0, l=$.jqplot.postDrawHooks.length; i<l; i++) {
$.jqplot.postDrawHooks[i].call(this);
}
- for (var i=0; i<this.postDrawHooks.hooks.length; i++) {
- this.postDrawHooks.hooks[i].call(this);
+ for (var i=0, l=this.postDrawHooks.hooks.length; i<l; i++) {
+ this.postDrawHooks.hooks[i].apply(this, this.postDrawHooks.args[i]);
}
if (this.target.is(':visible')) {
this._drawCount += 1;
}
+
+ var temps,
+ tempr,
+ sel,
+ _els;
+ // ughh. ideally would hide all series then show them.
+ for (i=0, l=seriesLength; i<l; i++) {
+ temps = series[i];
+ tempr = temps.renderer;
+ sel = '.jqplot-point-label.jqplot-series-'+i;
+ if (tempr.animation && tempr.animation._supported && tempr.animation.show && (this._drawCount < 2 || this.animateReplot)) {
+ _els = this.target.find(sel);
+ _els.stop(true, true).hide();
+ temps.canvas._elem.stop(true, true).hide();
+ temps.shadowCanvas._elem.stop(true, true).hide();
+ temps.canvas._elem.jqplotEffect('blind', {mode: 'show', direction: tempr.animation.direction}, tempr.animation.speed);
+ temps.shadowCanvas._elem.jqplotEffect('blind', {mode: 'show', direction: tempr.animation.direction}, tempr.animation.speed);
+ _els.fadeIn(tempr.animation.speed*0.8);
+ }
+ }
+ _els = null;
this.target.trigger('jqplotPostDraw', [this]);
}
};
+
+ jqPlot.prototype.doFillBetweenLines = function () {
+ var fb = this.fillBetween;
+ var sid1 = fb.series1;
+ var sid2 = fb.series2;
+ // first series should always be lowest index
+ var id1 = (sid1 < sid2) ? sid1 : sid2;
+ var id2 = (sid2 > sid1) ? sid2 : sid1;
+
+ var series1 = this.series[id1];
+ var series2 = this.series[id2];
+
+ if (series2.renderer.smooth) {
+ var tempgd = series2.renderer._smoothedData.slice(0).reverse();
+ }
+ else {
+ var tempgd = series2.gridData.slice(0).reverse();
+ }
+
+ if (series1.renderer.smooth) {
+ var gd = series1.renderer._smoothedData.concat(tempgd);
+ }
+ else {
+ var gd = series1.gridData.concat(tempgd);
+ }
+
+ var color = (fb.color !== null) ? fb.color : this.series[sid1].fillColor;
+ var baseSeries = (fb.baseSeries !== null) ? fb.baseSeries : id1;
+
+ // now apply a fill to the shape on the lower series shadow canvas,
+ // so it is behind both series.
+ var sr = this.series[baseSeries].renderer.shapeRenderer;
+ var opts = {fillStyle: color, fill: true, closePath: true};
+ sr.draw(series1.shadowCanvas._ctx, gd, opts);
+ };
this.bindCustomEvents = function() {
this.eventCanvas._elem.bind('click', {plot:this}, this.onClick);
@@ -2291,8 +3196,8 @@
if (this.captureRightClick) {
this.eventCanvas._elem.bind('mouseup', {plot:this}, this.onRightClick);
this.eventCanvas._elem.get(0).oncontextmenu = function() {
- return false;
- };
+ return false;
+ };
}
else {
this.eventCanvas._elem.bind('mouseup', {plot:this}, this.onMouseUp);
@@ -2303,8 +3208,8 @@
var plot = ev.data.plot;
var go = plot.eventCanvas._elem.offset();
var gridPos = {x:ev.pageX - go.left, y:ev.pageY - go.top};
- var dataPos = {xaxis:null, yaxis:null, x2axis:null, y2axis:null, y3axis:null, y4axis:null, y5axis:null, y6axis:null, y7axis:null, y8axis:null, y9axis:null};
- var an = ['xaxis', 'yaxis', 'x2axis', 'y2axis', 'y3axis', 'y4axis', 'y5axis', 'y6axis', 'y7axis', 'y8axis', 'y9axis'];
+ var dataPos = {xaxis:null, yaxis:null, x2axis:null, y2axis:null, y3axis:null, y4axis:null, y5axis:null, y6axis:null, y7axis:null, y8axis:null, y9axis:null, yMidAxis:null};
+ var an = ['xaxis', 'yaxis', 'x2axis', 'y2axis', 'y3axis', 'y4axis', 'y5axis', 'y6axis', 'y7axis', 'y8axis', 'y9axis', 'yMidAxis'];
var ax = plot.axes;
var n, axis;
for (n=11; n>0; n--) {
@@ -2322,22 +3227,35 @@
function checkIntersection(gridpos, plot) {
var series = plot.series;
var i, j, k, s, r, x, y, theta, sm, sa, minang, maxang;
- var d0, d, p, pp, points, bw;
+ var d0, d, p, pp, points, bw, hp;
var threshold, t;
for (k=plot.seriesStack.length-1; k>=0; k--) {
i = plot.seriesStack[k];
s = series[i];
+ hp = s._highlightThreshold;
switch (s.renderer.constructor) {
case $.jqplot.BarRenderer:
x = gridpos.x;
y = gridpos.y;
- for (j=s.gridData.length-1; j>=0; j--) {
+ for (j=0; j<s._barPoints.length; j++) {
points = s._barPoints[j];
+ p = s.gridData[j];
if (x>points[0][0] && x<points[2][0] && y>points[2][1] && y<points[0][1]) {
return {seriesIndex:s.index, pointIndex:j, gridData:p, data:s.data[j], points:s._barPoints[j]};
}
}
break;
+ case $.jqplot.PyramidRenderer:
+ x = gridpos.x;
+ y = gridpos.y;
+ for (j=0; j<s._barPoints.length; j++) {
+ points = s._barPoints[j];
+ p = s.gridData[j];
+ if (x > points[0][0] + hp[0][0] && x < points[2][0] + hp[2][0] && y > points[2][1] && y < points[0][1]) {
+ return {seriesIndex:s.index, pointIndex:j, gridData:p, data:s.data[j], points:s._barPoints[j]};
+ }
+ }
+ break;
case $.jqplot.DonutRenderer:
sa = s.startAngle/180*Math.PI;
@@ -2443,7 +3361,9 @@
ret = {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]};
}
}
- if (ret != null) return ret;
+ if (ret != null) {
+ return ret;
+ }
}
break;
@@ -2454,7 +3374,8 @@
vfirst = v[0],
vlast = v[v.length-1],
lex,
- rex;
+ rex,
+ cv;
// equations of right and left sides, returns x, y values given height of section (y value and 2 points)
@@ -2482,7 +3403,7 @@
y = gridpos.y;
r = s.renderer;
if (s.show) {
- if (s.fill) {
+ if ((s.fill || (s.renderer.bands.show && s.renderer.bands.fill)) && (!plot.plugins.highlighter || !plot.plugins.highlighter.show)) {
// first check if it is in bounding box
var inside = false;
if (x>s._boundingBox[0][0] && x<s._boundingBox[1][0] && y>s._boundingBox[1][1] && y<s._boundingBox[0][1]) {
@@ -2493,16 +3414,16 @@
var j = numPoints-1;
for(var ii=0; ii < numPoints; ii++) {
- var vertex1 = [s._areaPoints[ii][0], s._areaPoints[ii][1]];
- var vertex2 = [s._areaPoints[j][0], s._areaPoints[j][1]];
+ var vertex1 = [s._areaPoints[ii][0], s._areaPoints[ii][1]];
+ var vertex2 = [s._areaPoints[j][0], s._areaPoints[j][1]];
- if (vertex1[1] < y && vertex2[1] >= y || vertex2[1] < y && vertex1[1] >= y) {
- if (vertex1[0] + (y - vertex1[1]) / (vertex2[1] - vertex1[1]) * (vertex2[0] - vertex1[0]) < x) {
- inside = !inside;
- }
- }
+ if (vertex1[1] < y && vertex2[1] >= y || vertex2[1] < y && vertex1[1] >= y) {
+ if (vertex1[0] + (y - vertex1[1]) / (vertex2[1] - vertex1[1]) * (vertex2[0] - vertex1[0]) < x) {
+ inside = !inside;
+ }
+ }
- j = ii;
+ j = ii;
}
}
if (inside) {
@@ -2511,6 +3432,7 @@
break;
}
+
else {
t = s.markerRenderer.size/2+s.neighborThreshold;
threshold = (t > 0) ? t : 0;
@@ -2609,7 +3531,7 @@
var positions = getEventPosition(ev);
var p = ev.data.plot;
var neighbor = checkIntersection(positions.gridPos, p);
- var evt = jQuery.Event('jqplotClick');
+ var evt = $.Event('jqplotClick');
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
$(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]);
@@ -2621,7 +3543,7 @@
var positions = getEventPosition(ev);
var p = ev.data.plot;
var neighbor = checkIntersection(positions.gridPos, p);
- var evt = jQuery.Event('jqplotDblClick');
+ var evt = $.Event('jqplotDblClick');
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
$(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]);
@@ -2631,7 +3553,7 @@
var positions = getEventPosition(ev);
var p = ev.data.plot;
var neighbor = checkIntersection(positions.gridPos, p);
- var evt = jQuery.Event('jqplotMouseDown');
+ var evt = $.Event('jqplotMouseDown');
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
$(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]);
@@ -2639,7 +3561,7 @@
this.onMouseUp = function(ev) {
var positions = getEventPosition(ev);
- var evt = jQuery.Event('jqplotMouseUp');
+ var evt = $.Event('jqplotMouseUp');
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
$(this).trigger(evt, [positions.gridPos, positions.dataPos, null, ev.data.plot]);
@@ -2651,13 +3573,13 @@
var neighbor = checkIntersection(positions.gridPos, p);
if (p.captureRightClick) {
if (ev.which == 3) {
- var evt = jQuery.Event('jqplotRightClick');
+ var evt = $.Event('jqplotRightClick');
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
$(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]);
}
else {
- var evt = jQuery.Event('jqplotMouseUp');
+ var evt = $.Event('jqplotMouseUp');
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
$(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]);
@@ -2669,7 +3591,7 @@
var positions = getEventPosition(ev);
var p = ev.data.plot;
var neighbor = checkIntersection(positions.gridPos, p);
- var evt = jQuery.Event('jqplotMouseMove');
+ var evt = $.Event('jqplotMouseMove');
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
$(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]);
@@ -2678,18 +3600,20 @@
this.onMouseEnter = function(ev) {
var positions = getEventPosition(ev);
var p = ev.data.plot;
- var evt = jQuery.Event('jqplotMouseEnter');
+ var evt = $.Event('jqplotMouseEnter');
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
+ evt.relatedTarget = ev.relatedTarget;
$(this).trigger(evt, [positions.gridPos, positions.dataPos, null, p]);
};
this.onMouseLeave = function(ev) {
var positions = getEventPosition(ev);
var p = ev.data.plot;
- var evt = jQuery.Event('jqplotMouseLeave');
+ var evt = $.Event('jqplotMouseLeave');
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
+ evt.relatedTarget = ev.relatedTarget;
$(this).trigger(evt, [positions.gridPos, positions.dataPos, null, p]);
};
@@ -2702,8 +3626,8 @@
this.drawSeries = function(options, idx){
var i, series, ctx;
// if only one argument passed in and it is a number, use it ad idx.
- idx = (typeof(options) == "number" && idx == null) ? options : idx;
- options = (typeof(options) == "object") ? options : {};
+ idx = (typeof(options) === "number" && idx == null) ? options : idx;
+ options = (typeof(options) === "object") ? options : {};
// draw specified series
if (idx != undefined) {
series = this.series[idx];
@@ -2735,6 +3659,7 @@
series.draw(ctx, options, this);
}
}
+ options = idx = i = series = ctx = null;
};
// method: moveSeriesToFront
@@ -2797,7 +3722,7 @@
// Useful to put a series back where it belongs after moving
// it to the front.
this.restorePreviousSeriesOrder = function () {
- var i, j, serelem, shadelem, temp;
+ var i, j, serelem, shadelem, temp, move, keep;
// if no change, return.
if (this.seriesStack == this.previousSeriesStack) {
return;
@@ -2820,7 +3745,7 @@
// Restore the series canvas order to its original order
// when the plot was created.
this.restoreOriginalSeriesOrder = function () {
- var i, j, arr=[];
+ var i, j, arr=[], serelem, shadelem;
for (i=0; i<this.series.length; i++) {
arr.push(i);
}
@@ -2846,7 +3771,7 @@
// conpute a highlight color or array of highlight colors from given colors.
$.jqplot.computeHighlightColors = function(colors) {
var ret;
- if (typeof(colors) == "array") {
+ if ($.isArray(colors)) {
ret = [];
for (var i=0; i<colors.length; i++){
var rgba = $.jqplot.getColorComponents(colors[i]);
@@ -2854,10 +3779,14 @@
var sum = newrgb[0] + newrgb[1] + newrgb[2];
for (var j=0; j<3; j++) {
// when darkening, lowest color component can be is 60.
- newrgb[j] = (sum > 570) ? newrgb[j] * 0.8 : newrgb[j] + 0.3 * (255 - newrgb[j]);
+ newrgb[j] = (sum > 660) ? newrgb[j] * 0.85 : 0.73 * newrgb[j] + 90;
newrgb[j] = parseInt(newrgb[j], 10);
+ (newrgb[j] > 255) ? 255 : newrgb[j];
}
- ret.push('rgb('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+')');
+ // newrgb[3] = (rgba[3] > 0.4) ? rgba[3] * 0.4 : rgba[3] * 1.5;
+ // newrgb[3] = (rgba[3] > 0.5) ? 0.8 * rgba[3] - .1 : rgba[3] + 0.2;
+ newrgb[3] = 0.3 + 0.35 * rgba[3];
+ ret.push('rgba('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+','+newrgb[3]+')');
}
}
else {
@@ -2866,15 +3795,22 @@
var sum = newrgb[0] + newrgb[1] + newrgb[2];
for (var j=0; j<3; j++) {
// when darkening, lowest color component can be is 60.
- newrgb[j] = (sum > 570) ? newrgb[j] * 0.8 : newrgb[j] + 0.3 * (255 - newrgb[j]);
+ // newrgb[j] = (sum > 570) ? newrgb[j] * 0.8 : newrgb[j] + 0.3 * (255 - newrgb[j]);
+ // newrgb[j] = parseInt(newrgb[j], 10);
+ newrgb[j] = (sum > 660) ? newrgb[j] * 0.85 : 0.73 * newrgb[j] + 90;
newrgb[j] = parseInt(newrgb[j], 10);
+ (newrgb[j] > 255) ? 255 : newrgb[j];
}
- ret = 'rgb('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+')';
+ // newrgb[3] = (rgba[3] > 0.4) ? rgba[3] * 0.4 : rgba[3] * 1.5;
+ // newrgb[3] = (rgba[3] > 0.5) ? 0.8 * rgba[3] - .1 : rgba[3] + 0.2;
+ newrgb[3] = 0.3 + 0.35 * rgba[3];
+ ret = 'rgba('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+','+newrgb[3]+')';
}
return ret;
};
$.jqplot.ColorGenerator = function(colors) {
+ colors = colors || $.jqplot.config.defaultColors;
var idx = 0;
this.next = function () {
@@ -2910,6 +3846,14 @@
this.reset = function() {
idx = 0;
};
+
+ this.getIndex = function() {
+ return idx;
+ };
+
+ this.setIndex = function(index) {
+ idx = index;
+ };
};
// convert a hex color string to rgb string.
@@ -2918,7 +3862,7 @@
$.jqplot.hex2rgb = function(h, a) {
h = h.replace('#', '');
if (h.length == 3) {
- h = h[0]+h[0]+h[1]+h[1]+h[2]+h[2];
+ h = h.charAt(0)+h.charAt(0)+h.charAt(1)+h.charAt(1)+h.charAt(2)+h.charAt(2);
}
var rgb;
rgb = 'rgba('+parseInt(h.slice(0,2), 16)+', '+parseInt(h.slice(2,4), 16)+', '+parseInt(h.slice(4,6), 16);
@@ -2934,7 +3878,7 @@
var pat = /rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *(?:, *[0-9.]*)?\)/;
var m = s.match(pat);
var h = '#';
- for (i=1; i<4; i++) {
+ for (var i=1; i<4; i++) {
var temp;
if (m[i].search(/%/) != -1) {
temp = parseInt(255*m[i]/100, 10).toString(16);
@@ -2974,7 +3918,7 @@
var pat = /rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *,? *([0-9.]* *)?\)/;
var m = rgb.match(pat);
var ret = [];
- for (i=1; i<4; i++) {
+ for (var i=1; i<4; i++) {
if (m[i].search(/%/) != -1) {
ret[i-1] = parseInt(255*m[i]/100, 10);
}
@@ -2986,20 +3930,156 @@
return ret;
};
- $.jqplot.colorKeywordMap = {aliceblue: 'rgb(240, 248, 255)', antiquewhite: 'rgb(250, 235, 215)', aqua: 'rgb( 0, 255, 255)', aquamarine: 'rgb(127, 255, 212)', azure: 'rgb(240, 255, 255)', beige: 'rgb(245, 245, 220)', bisque: 'rgb(255, 228, 196)', black: 'rgb( 0, 0, 0)', blanchedalmond: 'rgb(255, 235, 205)', blue: 'rgb( 0, 0, 255)', blueviolet: 'rgb(138, 43, 226)', brown: 'rgb(165, 42, 42)', burlywood: 'rgb(222, 184, 135)', cadetblue: 'rgb( 95, 158, 160)', chartreuse: 'rgb(127, 255, 0)', chocolate: 'rgb(210, 105, 30)', coral: 'rgb(255, 127, 80)', cornflowerblue: 'rgb(100, 149, 237)', cornsilk: 'rgb(255, 248, 220)', crimson: 'rgb(220, 20, 60)', cyan: 'rgb( 0, 255, 255)', darkblue: 'rgb( 0, 0, 139)', darkcyan: 'rgb( 0, 139, 139)', darkgoldenrod: 'rgb(184, 134, 11)', darkgray: 'rgb(169, 169, 169)', darkgreen: 'rgb( 0, 100, 0)', darkgrey: 'rgb(169, 169, 169)', darkkhaki: 'rgb(189, 183, 107)', darkmagenta: 'rgb(139, 0, 139)', darkolivegreen: 'rgb( 85, 107, 47)', darkorange: 'rgb(255, 140, 0)', darkorchid: 'rgb(153, 50, 204)', darkred: 'rgb(139, 0, 0)', darksalmon: 'rgb(233, 150, 122)', darkseagreen: 'rgb(143, 188, 143)', darkslateblue: 'rgb( 72, 61, 139)', darkslategray: 'rgb( 47, 79, 79)', darkslategrey: 'rgb( 47, 79, 79)', darkturquoise: 'rgb( 0, 206, 209)', darkviolet: 'rgb(148, 0, 211)', deeppink: 'rgb(255, 20, 147)', deepskyblue: 'rgb( 0, 191, 255)', dimgray: 'rgb(105, 105, 105)', dimgrey: 'rgb(105, 105, 105)', dodgerblue: 'rgb( 30, 144, 255)', firebrick: 'rgb(178, 34, 34)', floralwhite: 'rgb(255, 250, 240)', forestgreen: 'rgb( 34, 139, 34)', fuchsia: 'rgb(255, 0, 255)', gainsboro: 'rgb(220, 220, 220)', ghostwhite: 'rgb(248, 248, 255)', gold: 'rgb(255, 215, 0)', goldenrod: 'rgb(218, 165, 32)', gray: 'rgb(128, 128, 128)', grey: 'rgb(128, 128, 128)', green: 'rgb( 0, 128, 0)', greenyellow: 'rgb(173, 255, 47)', honeydew: 'rgb(240, 255, 240)', hotpink: 'rgb(255, 105, 180)', indianred: 'rgb(205, 92, 92)', indigo: 'rgb( 75, 0, 130)', ivory: 'rgb(255, 255, 240)', khaki: 'rgb(240, 230, 140)', lavender: 'rgb(23!
0, 230, 250)', lavenderblush: 'rgb(255, 240, 245)', lawngreen: 'rgb(124, 252, 0)', lemonchiffon: 'rgb(255, 250, 205)', lightblue: 'rgb(173, 216, 230)', lightcoral: 'rgb(240, 128, 128)', lightcyan: 'rgb(224, 255, 255)', lightgoldenrodyellow: 'rgb(250, 250, 210)', lightgray: 'rgb(211, 211, 211)', lightgreen: 'rgb(144, 238, 144)', lightgrey: 'rgb(211, 211, 211)', lightpink: 'rgb(255, 182, 193)', lightsalmon: 'rgb(255, 160, 122)', lightseagreen: 'rgb( 32, 178, 170)', lightskyblue: 'rgb(135, 206, 250)', lightslategray: 'rgb(119, 136, 153)', lightslategrey: 'rgb(119, 136, 153)', lightsteelblue: 'rgb(176, 196, 222)', lightyellow: 'rgb(255, 255, 224)', lime: 'rgb( 0, 255, 0)', limegreen: 'rgb( 50, 205, 50)', linen: 'rgb(250, 240, 230)', magenta: 'rgb(255, 0, 255)', maroon: 'rgb(128, 0, 0)', mediumaquamarine: 'rgb(102, 205, 170)', mediumblue: 'rgb( 0, 0, 205)', mediumorchid: 'rgb(186, 85, 211)', mediumpurple: 'rgb(147, 112, 219)', mediumseagreen: 'rgb( 60, 179, 113)', mediumslateblue: 'rgb(123, 104, 238)', mediumspringgreen: 'rgb( 0, 250, 154)', mediumturquoise: 'rgb( 72, 209, 204)', mediumvioletred: 'rgb(199, 21, 133)', midnightblue: 'rgb( 25, 25, 112)', mintcream: 'rgb(245, 255, 250)', mistyrose: 'rgb(255, 228, 225)', moccasin: 'rgb(255, 228, 181)', navajowhite: 'rgb(255, 222, 173)', navy: 'rgb( 0, 0, 128)', oldlace: 'rgb(253, 245, 230)', olive: 'rgb(128, 128, 0)', olivedrab: 'rgb(107, 142, 35)', orange: 'rgb(255, 165, 0)', orangered: 'rgb(255, 69, 0)', orchid: 'rgb(218, 112, 214)', palegoldenrod: 'rgb(238, 232, 170)', palegreen: 'rgb(152, 251, 152)', paleturquoise: 'rgb(175, 238, 238)', palevioletred: 'rgb(219, 112, 147)', papayawhip: 'rgb(255, 239, 213)', peachpuff: 'rgb(255, 218, 185)', peru: 'rgb(205, 133, 63)', pink: 'rgb(255, 192, 203)', plum: 'rgb(221, 160, 221)', powderblue: 'rgb(176, 224, 230)', purple: 'rgb(128, 0, 128)', red: 'rgb(255, 0, 0)', rosybrown: 'rgb(188, 143, 143)', royalblue: 'rgb( 65, 105, 225)', saddlebrown: 'rgb(139, 69, 19)', salmon: 'rgb(250, 128, 114)', sandybrown: 'rgb(244, 164, 96)', seagr!
een: 'rgb( 46, 139, 87)', seashell: 'rgb(255, 245, 238)', sienna: 'rgb(160, 82, 45)', silver: 'rgb(192, 192, 192)', skyblue: 'rgb(135, 206, 235)', slateblue: 'rgb(106, 90, 205)', slategray: 'rgb(112, 128, 144)', slategrey: 'rgb(112, 128, 144)', snow: 'rgb(255, 250, 250)', springgreen: 'rgb( 0, 255, 127)', steelblue: 'rgb( 70, 130, 180)', tan: 'rgb(210, 180, 140)', teal: 'rgb( 0, 128, 128)', thistle: 'rgb(216, 191, 216)', tomato: 'rgb(255, 99, 71)', turquoise: 'rgb( 64, 224, 208)', violet: 'rgb(238, 130, 238)', wheat: 'rgb(245, 222, 179)', white: 'rgb(255, 255, 255)', whitesmoke: 'rgb(245, 245, 245)', yellow: 'rgb(255, 255, 0)', yellowgreen: 'rgb(154, 205, 50)'};
-
- // Convienence function that won't hang IE.
- $.jqplot.log = function() {
- if (window.console && $.jqplot.debug) {
- if (arguments.length == 1) {
- console.log (arguments[0]);
- }
- else {
- console.log(arguments);
- }
- }
+ $.jqplot.colorKeywordMap = {
+ aliceblue: 'rgb(240, 248, 255)',
+ antiquewhite: 'rgb(250, 235, 215)',
+ aqua: 'rgb( 0, 255, 255)',
+ aquamarine: 'rgb(127, 255, 212)',
+ azure: 'rgb(240, 255, 255)',
+ beige: 'rgb(245, 245, 220)',
+ bisque: 'rgb(255, 228, 196)',
+ black: 'rgb( 0, 0, 0)',
+ blanchedalmond: 'rgb(255, 235, 205)',
+ blue: 'rgb( 0, 0, 255)',
+ blueviolet: 'rgb(138, 43, 226)',
+ brown: 'rgb(165, 42, 42)',
+ burlywood: 'rgb(222, 184, 135)',
+ cadetblue: 'rgb( 95, 158, 160)',
+ chartreuse: 'rgb(127, 255, 0)',
+ chocolate: 'rgb(210, 105, 30)',
+ coral: 'rgb(255, 127, 80)',
+ cornflowerblue: 'rgb(100, 149, 237)',
+ cornsilk: 'rgb(255, 248, 220)',
+ crimson: 'rgb(220, 20, 60)',
+ cyan: 'rgb( 0, 255, 255)',
+ darkblue: 'rgb( 0, 0, 139)',
+ darkcyan: 'rgb( 0, 139, 139)',
+ darkgoldenrod: 'rgb(184, 134, 11)',
+ darkgray: 'rgb(169, 169, 169)',
+ darkgreen: 'rgb( 0, 100, 0)',
+ darkgrey: 'rgb(169, 169, 169)',
+ darkkhaki: 'rgb(189, 183, 107)',
+ darkmagenta: 'rgb(139, 0, 139)',
+ darkolivegreen: 'rgb( 85, 107, 47)',
+ darkorange: 'rgb(255, 140, 0)',
+ darkorchid: 'rgb(153, 50, 204)',
+ darkred: 'rgb(139, 0, 0)',
+ darksalmon: 'rgb(233, 150, 122)',
+ darkseagreen: 'rgb(143, 188, 143)',
+ darkslateblue: 'rgb( 72, 61, 139)',
+ darkslategray: 'rgb( 47, 79, 79)',
+ darkslategrey: 'rgb( 47, 79, 79)',
+ darkturquoise: 'rgb( 0, 206, 209)',
+ darkviolet: 'rgb(148, 0, 211)',
+ deeppink: 'rgb(255, 20, 147)',
+ deepskyblue: 'rgb( 0, 191, 255)',
+ dimgray: 'rgb(105, 105, 105)',
+ dimgrey: 'rgb(105, 105, 105)',
+ dodgerblue: 'rgb( 30, 144, 255)',
+ firebrick: 'rgb(178, 34, 34)',
+ floralwhite: 'rgb(255, 250, 240)',
+ forestgreen: 'rgb( 34, 139, 34)',
+ fuchsia: 'rgb(255, 0, 255)',
+ gainsboro: 'rgb(220, 220, 220)',
+ ghostwhite: 'rgb(248, 248, 255)',
+ gold: 'rgb(255, 215, 0)',
+ goldenrod: 'rgb(218, 165, 32)',
+ gray: 'rgb(128, 128, 128)',
+ grey: 'rgb(128, 128, 128)',
+ green: 'rgb( 0, 128, 0)',
+ greenyellow: 'rgb(173, 255, 47)',
+ honeydew: 'rgb(240, 255, 240)',
+ hotpink: 'rgb(255, 105, 180)',
+ indianred: 'rgb(205, 92, 92)',
+ indigo: 'rgb( 75, 0, 130)',
+ ivory: 'rgb(255, 255, 240)',
+ khaki: 'rgb(240, 230, 140)',
+ lavender: 'rgb(230, 230, 250)',
+ lavenderblush: 'rgb(255, 240, 245)',
+ lawngreen: 'rgb(124, 252, 0)',
+ lemonchiffon: 'rgb(255, 250, 205)',
+ lightblue: 'rgb(173, 216, 230)',
+ lightcoral: 'rgb(240, 128, 128)',
+ lightcyan: 'rgb(224, 255, 255)',
+ lightgoldenrodyellow: 'rgb(250, 250, 210)',
+ lightgray: 'rgb(211, 211, 211)',
+ lightgreen: 'rgb(144, 238, 144)',
+ lightgrey: 'rgb(211, 211, 211)',
+ lightpink: 'rgb(255, 182, 193)',
+ lightsalmon: 'rgb(255, 160, 122)',
+ lightseagreen: 'rgb( 32, 178, 170)',
+ lightskyblue: 'rgb(135, 206, 250)',
+ lightslategray: 'rgb(119, 136, 153)',
+ lightslategrey: 'rgb(119, 136, 153)',
+ lightsteelblue: 'rgb(176, 196, 222)',
+ lightyellow: 'rgb(255, 255, 224)',
+ lime: 'rgb( 0, 255, 0)',
+ limegreen: 'rgb( 50, 205, 50)',
+ linen: 'rgb(250, 240, 230)',
+ magenta: 'rgb(255, 0, 255)',
+ maroon: 'rgb(128, 0, 0)',
+ mediumaquamarine: 'rgb(102, 205, 170)',
+ mediumblue: 'rgb( 0, 0, 205)',
+ mediumorchid: 'rgb(186, 85, 211)',
+ mediumpurple: 'rgb(147, 112, 219)',
+ mediumseagreen: 'rgb( 60, 179, 113)',
+ mediumslateblue: 'rgb(123, 104, 238)',
+ mediumspringgreen: 'rgb( 0, 250, 154)',
+ mediumturquoise: 'rgb( 72, 209, 204)',
+ mediumvioletred: 'rgb(199, 21, 133)',
+ midnightblue: 'rgb( 25, 25, 112)',
+ mintcream: 'rgb(245, 255, 250)',
+ mistyrose: 'rgb(255, 228, 225)',
+ moccasin: 'rgb(255, 228, 181)',
+ navajowhite: 'rgb(255, 222, 173)',
+ navy: 'rgb( 0, 0, 128)',
+ oldlace: 'rgb(253, 245, 230)',
+ olive: 'rgb(128, 128, 0)',
+ olivedrab: 'rgb(107, 142, 35)',
+ orange: 'rgb(255, 165, 0)',
+ orangered: 'rgb(255, 69, 0)',
+ orchid: 'rgb(218, 112, 214)',
+ palegoldenrod: 'rgb(238, 232, 170)',
+ palegreen: 'rgb(152, 251, 152)',
+ paleturquoise: 'rgb(175, 238, 238)',
+ palevioletred: 'rgb(219, 112, 147)',
+ papayawhip: 'rgb(255, 239, 213)',
+ peachpuff: 'rgb(255, 218, 185)',
+ peru: 'rgb(205, 133, 63)',
+ pink: 'rgb(255, 192, 203)',
+ plum: 'rgb(221, 160, 221)',
+ powderblue: 'rgb(176, 224, 230)',
+ purple: 'rgb(128, 0, 128)',
+ red: 'rgb(255, 0, 0)',
+ rosybrown: 'rgb(188, 143, 143)',
+ royalblue: 'rgb( 65, 105, 225)',
+ saddlebrown: 'rgb(139, 69, 19)',
+ salmon: 'rgb(250, 128, 114)',
+ sandybrown: 'rgb(244, 164, 96)',
+ seagreen: 'rgb( 46, 139, 87)',
+ seashell: 'rgb(255, 245, 238)',
+ sienna: 'rgb(160, 82, 45)',
+ silver: 'rgb(192, 192, 192)',
+ skyblue: 'rgb(135, 206, 235)',
+ slateblue: 'rgb(106, 90, 205)',
+ slategray: 'rgb(112, 128, 144)',
+ slategrey: 'rgb(112, 128, 144)',
+ snow: 'rgb(255, 250, 250)',
+ springgreen: 'rgb( 0, 255, 127)',
+ steelblue: 'rgb( 70, 130, 180)',
+ tan: 'rgb(210, 180, 140)',
+ teal: 'rgb( 0, 128, 128)',
+ thistle: 'rgb(216, 191, 216)',
+ tomato: 'rgb(255, 99, 71)',
+ turquoise: 'rgb( 64, 224, 208)',
+ violet: 'rgb(238, 130, 238)',
+ wheat: 'rgb(245, 222, 179)',
+ white: 'rgb(255, 255, 255)',
+ whitesmoke: 'rgb(245, 245, 245)',
+ yellow: 'rgb(255, 255, 0)',
+ yellowgreen: 'rgb(154, 205, 50)'
};
- var log = $.jqplot.log;
+
// class: $.jqplot.AxisLabelRenderer
@@ -3033,7 +4113,13 @@
$.extend(true, this, options);
};
- $.jqplot.AxisLabelRenderer.prototype.draw = function() {
+ $.jqplot.AxisLabelRenderer.prototype.draw = function(ctx, plot) {
+ // Memory Leaks patch
+ if (this._elem) {
+ this._elem.emptyForce();
+ this._elem = null;
+ }
+
this._elem = $('<div style="position:absolute;" class="jqplot-'+this.axis+'-label"></div>');
if (Number(this.label)) {
@@ -3097,15 +4183,20 @@
// prop: showLabel
// wether or not to show the label.
this.showLabel = true;
- this.label = '';
+ this.label = null;
this.value = null;
this._styles = {};
// prop: formatter
// A class of a formatter for the tick text. sprintf by default.
this.formatter = $.jqplot.DefaultTickFormatter;
// prop: prefix
- // string appended to the tick label if no formatString is specified.
+ // String to prepend to the tick label.
+ // Prefix is prepended to the formatted tick label.
this.prefix = '';
+ // prop: suffix
+ // String to append to the tick label.
+ // Suffix is appended to the formatted tick label.
+ this.suffix = '';
// prop: formatString
// string passed to the formatter.
this.formatString = '';
@@ -3118,7 +4209,11 @@
// prop: textColor
// css spec for the color attribute.
this.textColor;
+ // prop: escapeHTML
+ // true to escape HTML entities in the label.
+ this.escapeHTML = false;
this._elem;
+ this._breakTick = false;
$.extend(true, this, options);
};
@@ -3140,19 +4235,32 @@
};
$.jqplot.AxisTickRenderer.prototype.draw = function() {
- if (!this.label) {
- this.label = this.formatter(this.formatString, this.value);
+ if (this.label === null) {
+ this.label = this.prefix + this.formatter(this.formatString, this.value) + this.suffix;
}
- // add prefix if needed
- if (this.prefix && !this.formatString) {
- this.label = this.prefix + this.label;
- }
- style ='style="position:absolute;';
+ var style = {position: 'absolute'};
if (Number(this.label)) {
- style +='white-space:nowrap;';
+ style['whitSpace'] = 'nowrap';
}
- style += '"';
- this._elem = $('<div '+style+' class="jqplot-'+this.axis+'-tick">'+this.label+'</div>');
+
+ // Memory Leaks patch
+ if (this._elem) {
+ this._elem.emptyForce();
+ this._elem = null;
+ }
+
+ this._elem = $(document.createElement('div'));
+ this._elem.addClass("jqplot-"+this.axis+"-tick");
+
+ if (!this.escapeHTML) {
+ this._elem.html(this.label);
+ }
+ else {
+ this._elem.text(this.label);
+ }
+
+ this._elem.css(style);
+
for (var s in this._styles) {
this._elem.css(s, this._styles[s]);
}
@@ -3165,6 +4273,10 @@
if (this.textColor) {
this._elem.css('color', this.textColor);
}
+ if (this._breakTick) {
+ this._elem.addClass('jqplot-breakTick');
+ }
+
return this._elem;
};
@@ -3179,6 +4291,19 @@
return String(val);
}
};
+
+ $.jqplot.PercentTickFormatter = function (format, val) {
+ if (typeof val == 'number') {
+ val = 100 * val;
+ if (!format) {
+ format = $.jqplot.config.defaultTickFormatString;
+ }
+ return $.jqplot.sprintf(format, val);
+ }
+ else {
+ return String(val);
+ }
+ };
$.jqplot.AxisTickRenderer.prototype.pack = function() {
};
@@ -3200,8 +4325,22 @@
};
// called with context of Grid.
- $.jqplot.CanvasGridRenderer.prototype.createElement = function() {
- var elem = document.createElement('canvas');
+ $.jqplot.CanvasGridRenderer.prototype.createElement = function(plot) {
+ var elem;
+ // Memory Leaks patch
+ if (this._elem) {
+ if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) {
+ elem = this._elem.get(0);
+ window.G_vmlCanvasManager.uninitElement(elem);
+ elem = null;
+ }
+
+ this._elem.emptyForce();
+ this._elem = null;
+ }
+
+ elem = plot.canvasManager.getCanvas();
+
var w = this._plotDimensions.width;
var h = this._plotDimensions.height;
elem.width = w;
@@ -3209,18 +4348,17 @@
this._elem = $(elem);
this._elem.addClass('jqplot-grid-canvas');
this._elem.css({ position: 'absolute', left: 0, top: 0 });
- if ($.jqplot.use_excanvas) {
- window.G_vmlCanvasManager.init_(document);
- }
- if ($.jqplot.use_excanvas) {
- elem = window.G_vmlCanvasManager.initElement(elem);
- }
+
+ elem = plot.canvasManager.initCanvas(elem);
+
this._top = this._offsets.top;
this._bottom = h - this._offsets.bottom;
this._left = this._offsets.left;
this._right = w - this._offsets.right;
this._width = this._right - this._left;
this._height = this._bottom - this._top;
+ // avoid memory leak
+ elem = null;
return this._elem;
};
@@ -3234,229 +4372,260 @@
ctx.fillStyle = this.backgroundColor || this.background;
ctx.fillRect(this._left, this._top, this._width, this._height);
- if (this.drawGridlines) {
- ctx.save();
- ctx.lineJoin = 'miter';
- ctx.lineCap = 'butt';
- ctx.lineWidth = this.gridLineWidth;
- ctx.strokeStyle = this.gridLineColor;
- var b, e;
- var ax = ['xaxis', 'yaxis', 'x2axis', 'y2axis'];
- for (var i=4; i>0; i--) {
- var name = ax[i-1];
- var axis = axes[name];
- var ticks = axis._ticks;
- if (axis.show) {
- for (var j=ticks.length; j>0; j--) {
- var t = ticks[j-1];
- if (t.show) {
- var pos = Math.round(axis.u2p(t.value)) + 0.5;
- switch (name) {
- case 'xaxis':
- // draw the grid line
- if (t.showGridline) {
- drawLine(pos, this._top, pos, this._bottom);
+ ctx.save();
+ ctx.lineJoin = 'miter';
+ ctx.lineCap = 'butt';
+ ctx.lineWidth = this.gridLineWidth;
+ ctx.strokeStyle = this.gridLineColor;
+ var b, e, s, m;
+ var ax = ['xaxis', 'yaxis', 'x2axis', 'y2axis'];
+ for (var i=4; i>0; i--) {
+ var name = ax[i-1];
+ var axis = axes[name];
+ var ticks = axis._ticks;
+ var numticks = ticks.length;
+ if (axis.show) {
+ if (axis.drawBaseline) {
+ var bopts = {};
+ if (axis.baselineWidth !== null) {
+ bopts.lineWidth = axis.baselineWidth;
+ }
+ if (axis.baselineColor !== null) {
+ bopts.strokeStyle = axis.baselineColor;
+ }
+ switch (name) {
+ case 'xaxis':
+ drawLine (this._left, this._bottom, this._right, this._bottom, bopts);
+ break;
+ case 'yaxis':
+ drawLine (this._left, this._bottom, this._left, this._top, bopts);
+ break;
+ case 'x2axis':
+ drawLine (this._left, this._bottom, this._right, this._bottom, bopts);
+ break;
+ case 'y2axis':
+ drawLine (this._right, this._bottom, this._right, this._top, bopts);
+ break;
+ }
+ }
+ for (var j=numticks; j>0; j--) {
+ var t = ticks[j-1];
+ if (t.show) {
+ var pos = Math.round(axis.u2p(t.value)) + 0.5;
+ switch (name) {
+ case 'xaxis':
+ // draw the grid line if we should
+ if (t.showGridline && this.drawGridlines && ((!t.isMinorTick && axis.drawMajorGridlines) || (t.isMinorTick && axis.drawMinorGridlines)) ) {
+ drawLine(pos, this._top, pos, this._bottom);
+ }
+ // draw the mark
+ if (t.showMark && t.mark && ((!t.isMinorTick && axis.drawMajorTickMarks) || (t.isMinorTick && axis.drawMinorTickMarks)) ) {
+ s = t.markSize;
+ m = t.mark;
+ var pos = Math.round(axis.u2p(t.value)) + 0.5;
+ switch (m) {
+ case 'outside':
+ b = this._bottom;
+ e = this._bottom+s;
+ break;
+ case 'inside':
+ b = this._bottom-s;
+ e = this._bottom;
+ break;
+ case 'cross':
+ b = this._bottom-s;
+ e = this._bottom+s;
+ break;
+ default:
+ b = this._bottom;
+ e = this._bottom+s;
+ break;
}
-
- // draw the mark
- if (t.showMark && t.mark) {
- s = t.markSize;
- m = t.mark;
- var pos = Math.round(axis.u2p(t.value)) + 0.5;
- switch (m) {
- case 'outside':
- b = this._bottom;
- e = this._bottom+s;
- break;
- case 'inside':
- b = this._bottom-s;
- e = this._bottom;
- break;
- case 'cross':
- b = this._bottom-s;
- e = this._bottom+s;
- break;
- default:
- b = this._bottom;
- e = this._bottom+s;
- break;
- }
- // draw the shadow
- if (this.shadow) {
- this.renderer.shadowRenderer.draw(ctx, [[pos,b],[pos,e]], {lineCap:'butt', lineWidth:this.gridLineWidth, offset:this.gridLineWidth*0.75, depth:2, fill:false, closePath:false});
- }
- // draw the line
- drawLine(pos, b, pos, e);
+ // draw the shadow
+ if (this.shadow) {
+ this.renderer.shadowRenderer.draw(ctx, [[pos,b],[pos,e]], {lineCap:'butt', lineWidth:this.gridLineWidth, offset:this.gridLineWidth*0.75, depth:2, fill:false, closePath:false});
}
- break;
- case 'yaxis':
- // draw the grid line
- if (t.showGridline) {
- drawLine(this._right, pos, this._left, pos);
+ // draw the line
+ drawLine(pos, b, pos, e);
+ }
+ break;
+ case 'yaxis':
+ // draw the grid line
+ if (t.showGridline && this.drawGridlines && ((!t.isMinorTick && axis.drawMajorGridlines) || (t.isMinorTick && axis.drawMinorGridlines)) ) {
+ drawLine(this._right, pos, this._left, pos);
+ }
+ // draw the mark
+ if (t.showMark && t.mark && ((!t.isMinorTick && axis.drawMajorTickMarks) || (t.isMinorTick && axis.drawMinorTickMarks)) ) {
+ s = t.markSize;
+ m = t.mark;
+ var pos = Math.round(axis.u2p(t.value)) + 0.5;
+ switch (m) {
+ case 'outside':
+ b = this._left-s;
+ e = this._left;
+ break;
+ case 'inside':
+ b = this._left;
+ e = this._left+s;
+ break;
+ case 'cross':
+ b = this._left-s;
+ e = this._left+s;
+ break;
+ default:
+ b = this._left-s;
+ e = this._left;
+ break;
+ }
+ // draw the shadow
+ if (this.shadow) {
+ this.renderer.shadowRenderer.draw(ctx, [[b, pos], [e, pos]], {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false});
}
- // draw the mark
- if (t.showMark && t.mark) {
- s = t.markSize;
- m = t.mark;
- var pos = Math.round(axis.u2p(t.value)) + 0.5;
- switch (m) {
- case 'outside':
- b = this._left-s;
- e = this._left;
- break;
- case 'inside':
- b = this._left;
- e = this._left+s;
- break;
- case 'cross':
- b = this._left-s;
- e = this._left+s;
- break;
- default:
- b = this._left-s;
- e = this._left;
- break;
- }
- // draw the shadow
- if (this.shadow) {
- this.renderer.shadowRenderer.draw(ctx, [[b, pos], [e, pos]], {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false});
- }
- drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor});
+ drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor});
+ }
+ break;
+ case 'x2axis':
+ // draw the grid line
+ if (t.showGridline && this.drawGridlines && ((!t.isMinorTick && axis.drawMajorGridlines) || (t.isMinorTick && axis.drawMinorGridlines)) ) {
+ drawLine(pos, this._bottom, pos, this._top);
+ }
+ // draw the mark
+ if (t.showMark && t.mark && ((!t.isMinorTick && axis.drawMajorTickMarks) || (t.isMinorTick && axis.drawMinorTickMarks)) ) {
+ s = t.markSize;
+ m = t.mark;
+ var pos = Math.round(axis.u2p(t.value)) + 0.5;
+ switch (m) {
+ case 'outside':
+ b = this._top-s;
+ e = this._top;
+ break;
+ case 'inside':
+ b = this._top;
+ e = this._top+s;
+ break;
+ case 'cross':
+ b = this._top-s;
+ e = this._top+s;
+ break;
+ default:
+ b = this._top-s;
+ e = this._top;
+ break;
+ }
+ // draw the shadow
+ if (this.shadow) {
+ this.renderer.shadowRenderer.draw(ctx, [[pos,b],[pos,e]], {lineCap:'butt', lineWidth:this.gridLineWidth, offset:this.gridLineWidth*0.75, depth:2, fill:false, closePath:false});
}
- break;
- case 'x2axis':
- // draw the grid line
- if (t.showGridline) {
- drawLine(pos, this._bottom, pos, this._top);
+ drawLine(pos, b, pos, e);
+ }
+ break;
+ case 'y2axis':
+ // draw the grid line
+ if (t.showGridline && this.drawGridlines && ((!t.isMinorTick && axis.drawMajorGridlines) || (t.isMinorTick && axis.drawMinorGridlines)) ) {
+ drawLine(this._left, pos, this._right, pos);
+ }
+ // draw the mark
+ if (t.showMark && t.mark && ((!t.isMinorTick && axis.drawMajorTickMarks) || (t.isMinorTick && axis.drawMinorTickMarks)) ) {
+ s = t.markSize;
+ m = t.mark;
+ var pos = Math.round(axis.u2p(t.value)) + 0.5;
+ switch (m) {
+ case 'outside':
+ b = this._right;
+ e = this._right+s;
+ break;
+ case 'inside':
+ b = this._right-s;
+ e = this._right;
+ break;
+ case 'cross':
+ b = this._right-s;
+ e = this._right+s;
+ break;
+ default:
+ b = this._right;
+ e = this._right+s;
+ break;
+ }
+ // draw the shadow
+ if (this.shadow) {
+ this.renderer.shadowRenderer.draw(ctx, [[b, pos], [e, pos]], {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false});
}
- // draw the mark
- if (t.showMark && t.mark) {
- s = t.markSize;
- m = t.mark;
- var pos = Math.round(axis.u2p(t.value)) + 0.5;
- switch (m) {
- case 'outside':
- b = this._top-s;
- e = this._top;
- break;
- case 'inside':
- b = this._top;
- e = this._top+s;
- break;
- case 'cross':
- b = this._top-s;
- e = this._top+s;
- break;
- default:
- b = this._top-s;
- e = this._top;
- break;
- }
- // draw the shadow
- if (this.shadow) {
- this.renderer.shadowRenderer.draw(ctx, [[pos,b],[pos,e]], {lineCap:'butt', lineWidth:this.gridLineWidth, offset:this.gridLineWidth*0.75, depth:2, fill:false, closePath:false});
- }
- drawLine(pos, b, pos, e);
- }
- break;
- case 'y2axis':
- // draw the grid line
- if (t.showGridline) {
- drawLine(this._left, pos, this._right, pos);
- }
- // draw the mark
- if (t.showMark && t.mark) {
- s = t.markSize;
- m = t.mark;
- var pos = Math.round(axis.u2p(t.value)) + 0.5;
- switch (m) {
- case 'outside':
- b = this._right;
- e = this._right+s;
- break;
- case 'inside':
- b = this._right-s;
- e = this._right;
- break;
- case 'cross':
- b = this._right-s;
- e = this._right+s;
- break;
- default:
- b = this._right;
- e = this._right+s;
- break;
- }
- // draw the shadow
- if (this.shadow) {
- this.renderer.shadowRenderer.draw(ctx, [[b, pos], [e, pos]], {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false});
- }
- drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor});
- }
- break;
- default:
- break;
- }
+ drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor});
+ }
+ break;
+ default:
+ break;
}
}
}
+ t = null;
}
- // Now draw grid lines for additional y axes
- ax = ['y3axis', 'y4axis', 'y5axis', 'y6axis', 'y7axis', 'y8axis', 'y9axis'];
- for (var i=7; i>0; i--) {
- var axis = axes[ax[i-1]];
- var ticks = axis._ticks;
- if (axis.show) {
- var tn = ticks[axis.numberTicks-1];
- var t0 = ticks[0];
- var left = axis.getLeft();
- var points = [[left, tn.getTop() + tn.getHeight()/2], [left, t0.getTop() + t0.getHeight()/2 + 1.0]];
- // draw the shadow
- if (this.shadow) {
- this.renderer.shadowRenderer.draw(ctx, points, {lineCap:'butt', fill:false, closePath:false});
- }
- // draw the line
- drawLine(points[0][0], points[0][1], points[1][0], points[1][1], {lineCap:'butt', strokeStyle:axis.borderColor, lineWidth:axis.borderWidth});
- // draw the tick marks
- for (var j=ticks.length; j>0; j--) {
- var t = ticks[j-1];
- s = t.markSize;
- m = t.mark;
- var pos = Math.round(axis.u2p(t.value)) + 0.5;
- if (t.showMark && t.mark) {
- switch (m) {
- case 'outside':
- b = left;
- e = left+s;
- break;
- case 'inside':
- b = left-s;
- e = left;
- break;
- case 'cross':
- b = left-s;
- e = left+s;
- break;
- default:
- b = left;
- e = left+s;
- break;
- }
- points = [[b,pos], [e,pos]];
- // draw the shadow
- if (this.shadow) {
- this.renderer.shadowRenderer.draw(ctx, points, {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false});
- }
- // draw the line
- drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor});
+ axis = null;
+ ticks = null;
+ }
+ // Now draw grid lines for additional y axes
+ //////
+ // TO DO: handle yMidAxis
+ //////
+ ax = ['y3axis', 'y4axis', 'y5axis', 'y6axis', 'y7axis', 'y8axis', 'y9axis', 'yMidAxis'];
+ for (var i=7; i>0; i--) {
+ var axis = axes[ax[i-1]];
+ var ticks = axis._ticks;
+ if (axis.show) {
+ var tn = ticks[axis.numberTicks-1];
+ var t0 = ticks[0];
+ var left = axis.getLeft();
+ var points = [[left, tn.getTop() + tn.getHeight()/2], [left, t0.getTop() + t0.getHeight()/2 + 1.0]];
+ // draw the shadow
+ if (this.shadow) {
+ this.renderer.shadowRenderer.draw(ctx, points, {lineCap:'butt', fill:false, closePath:false});
+ }
+ // draw the line
+ drawLine(points[0][0], points[0][1], points[1][0], points[1][1], {lineCap:'butt', strokeStyle:axis.borderColor, lineWidth:axis.borderWidth});
+ // draw the tick marks
+ for (var j=ticks.length; j>0; j--) {
+ var t = ticks[j-1];
+ s = t.markSize;
+ m = t.mark;
+ var pos = Math.round(axis.u2p(t.value)) + 0.5;
+ if (t.showMark && t.mark) {
+ switch (m) {
+ case 'outside':
+ b = left;
+ e = left+s;
+ break;
+ case 'inside':
+ b = left-s;
+ e = left;
+ break;
+ case 'cross':
+ b = left-s;
+ e = left+s;
+ break;
+ default:
+ b = left;
+ e = left+s;
+ break;
}
+ points = [[b,pos], [e,pos]];
+ // draw the shadow
+ if (this.shadow) {
+ this.renderer.shadowRenderer.draw(ctx, points, {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false});
+ }
+ // draw the line
+ drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor});
}
+ t = null;
}
+ t0 = null;
}
-
- ctx.restore();
+ axis = null;
+ ticks = null;
}
+ ctx.restore();
+
function drawLine(bx, by, ex, ey, opts) {
ctx.save();
opts = opts || {};
@@ -3486,576 +4655,11 @@
// ctx.strokeStyle = this.borderColor;
// ctx.strokeRect(this._left, this._top, this._width, this._height);
-
ctx.restore();
+ ctx = null;
+ axes = null;
};
-
- /**
- * Date instance methods
- *
- * @author Ken Snyder (ken d snyder at gmail dot com)
- * @date 2008-09-10
- * @version 2.0.2 (http://kendsnyder.com/sandbox/date/)
- * @license Creative Commons Attribution License 3.0 (http://creativecommons.org/licenses/by/3.0/)
- *
- * @contributions Chris Leonello
- * @comment Bug fix to 12 hour time and additions to handle milliseconds and
- * @comment 24 hour time without am/pm suffix
- *
- */
- // begin by creating a scope for utility variables
-
- //
- // pre-calculate the number of milliseconds in a day
- //
-
- var day = 24 * 60 * 60 * 1000;
- //
- // function to add leading zeros
- //
- var zeroPad = function(number, digits) {
- number = String(number);
- while (number.length < digits) {
- number = '0' + number;
- }
- return number;
- };
- //
- // set up integers and functions for adding to a date or subtracting two dates
- //
- var multipliers = {
- millisecond: 1,
- second: 1000,
- minute: 60 * 1000,
- hour: 60 * 60 * 1000,
- day: day,
- week: 7 * day,
- month: {
- // add a number of months
- add: function(d, number) {
- // add any years needed (increments of 12)
- multipliers.year.add(d, Math[number > 0 ? 'floor' : 'ceil'](number / 12));
- // ensure that we properly wrap betwen December and January
- var prevMonth = d.getMonth() + (number % 12);
- if (prevMonth == 12) {
- prevMonth = 0;
- d.setYear(d.getFullYear() + 1);
- } else if (prevMonth == -1) {
- prevMonth = 11;
- d.setYear(d.getFullYear() - 1);
- }
- d.setMonth(prevMonth);
- },
- // get the number of months between two Date objects (decimal to the nearest day)
- diff: function(d1, d2) {
- // get the number of years
- var diffYears = d1.getFullYear() - d2.getFullYear();
- // get the number of remaining months
- var diffMonths = d1.getMonth() - d2.getMonth() + (diffYears * 12);
- // get the number of remaining days
- var diffDays = d1.getDate() - d2.getDate();
- // return the month difference with the days difference as a decimal
- return diffMonths + (diffDays / 30);
- }
- },
- year: {
- // add a number of years
- add: function(d, number) {
- d.setYear(d.getFullYear() + Math[number > 0 ? 'floor' : 'ceil'](number));
- },
- // get the number of years between two Date objects (decimal to the nearest day)
- diff: function(d1, d2) {
- return multipliers.month.diff(d1, d2) / 12;
- }
- }
- };
- //
- // alias each multiplier with an 's' to allow 'year' and 'years' for example
- //
- for (var unit in multipliers) {
- if (unit.substring(unit.length - 1) != 's') { // IE will iterate newly added properties :|
- multipliers[unit + 's'] = multipliers[unit];
- }
- }
- //
- // take a date instance and a format code and return the formatted value
- //
- var format = function(d, code) {
- if (Date.prototype.strftime.formatShortcuts[code]) {
- // process any shortcuts recursively
- return d.strftime(Date.prototype.strftime.formatShortcuts[code]);
- } else {
- // get the format code function and toPaddedString() argument
- var getter = (Date.prototype.strftime.formatCodes[code] || '').split('.');
- var nbr = d['get' + getter[0]] ? d['get' + getter[0]]() : '';
- // run toPaddedString() if specified
- if (getter[1]) {
- nbr = zeroPad(nbr, getter[1]);
- }
- // prepend the leading character
- return nbr;
- }
- };
- //
- // Add methods to Date instances
- //
- var instanceMethods = {
- //
- // Return a date one day ahead (or any other unit)
- //
- // @param string unit
- // units: year | month | day | week | hour | minute | second | millisecond
- // @return object Date
- //
- succ: function(unit) {
- return this.clone().add(1, unit);
- },
- //
- // Add an arbitrary amount to the currently stored date
- //
- // @param integer/float number
- // @param string unit
- // @return object Date (chainable)
- //
- add: function(number, unit) {
- var factor = multipliers[unit] || multipliers.day;
- if (typeof factor == 'number') {
- this.setTime(this.getTime() + (factor * number));
- } else {
- factor.add(this, number);
- }
- return this;
- },
- //
- // Find the difference between the current and another date
- //
- // @param string/object dateObj
- // @param string unit
- // @param boolean allowDecimal
- // @return integer/float
- //
- diff: function(dateObj, unit, allowDecimal) {
- // ensure we have a Date object
- dateObj = Date.create(dateObj);
- if (dateObj === null) {
- return null;
- }
- // get the multiplying factor integer or factor function
- var factor = multipliers[unit] || multipliers.day;
- if (typeof factor == 'number') {
- // multiply
- var unitDiff = (this.getTime() - dateObj.getTime()) / factor;
- } else {
- // run function
- var unitDiff = factor.diff(this, dateObj);
- }
- // if decimals are not allowed, round toward zero
- return (allowDecimal ? unitDiff : Math[unitDiff > 0 ? 'floor' : 'ceil'](unitDiff));
- },
- //
- // Convert a date to a string using traditional strftime format codes
- //
- // @param string formatStr
- // @return string
- //
- strftime: function(formatStr) {
- // default the format string to year-month-day
- var source = formatStr || '%Y-%m-%d', result = '', match;
- // Account for display of time in local time or as UTC time
- // var val = ($.jqplot.comfig.convertUTCtoLocaltime) ? this :
- // replace each format code
- while (source.length > 0) {
- if (match = source.match(Date.prototype.strftime.formatCodes.matcher)) {
- result += source.slice(0, match.index);
- result += (match[1] || '') + format(this, match[2]);
- source = source.slice(match.index + match[0].length);
- } else {
- result += source;
- source = '';
- }
- }
- return result;
- },
- //
- // Return a proper two-digit year integer
- //
- // @return integer
- //
- getShortYear: function() {
- return this.getYear() % 100;
- },
- //
- // Get the number of the current month, 1-12
- //
- // @return integer
- //
- getMonthNumber: function() {
- return this.getMonth() + 1;
- },
- //
- // Get the name of the current month
- //
- // @return string
- //
- getMonthName: function() {
- return Date.MONTHNAMES[this.getMonth()];
- },
- //
- // Get the abbreviated name of the current month
- //
- // @return string
- //
- getAbbrMonthName: function() {
- return Date.ABBR_MONTHNAMES[this.getMonth()];
- },
- //
- // Get the name of the current week day
- //
- // @return string
- //
- getDayName: function() {
- return Date.DAYNAMES[this.getDay()];
- },
- //
- // Get the abbreviated name of the current week day
- //
- // @return string
- //
- getAbbrDayName: function() {
- return Date.ABBR_DAYNAMES[this.getDay()];
- },
- //
- // Get the ordinal string associated with the day of the month (i.e. st, nd, rd, th)
- //
- // @return string
- //
- getDayOrdinal: function() {
- return Date.ORDINALNAMES[this.getDate() % 10];
- },
- //
- // Get the current hour on a 12-hour scheme
- //
- // @return integer
- //
- getHours12: function() {
- var hours = this.getHours();
- return hours > 12 ? hours - 12 : (hours == 0 ? 12 : hours);
- },
- //
- // Get the AM or PM for the current time
- //
- // @return string
- //
- getAmPm: function() {
- return this.getHours() >= 12 ? 'PM' : 'AM';
- },
- //
- // Get the current date as a Unix timestamp
- //
- // @return integer
- //
- getUnix: function() {
- return Math.round(this.getTime() / 1000, 0);
- },
- //
- // Get the GMT offset in hours and minutes (e.g. +06:30)
- //
- // @return string
- //
- getGmtOffset: function() {
- // divide the minutes offset by 60
- var hours = this.getTimezoneOffset() / 60;
- // decide if we are ahead of or behind GMT
- var prefix = hours < 0 ? '+' : '-';
- // remove the negative sign if any
- hours = Math.abs(hours);
- // add the +/- to the padded number of hours to : to the padded minutes
- return prefix + zeroPad(Math.floor(hours), 2) + ':' + zeroPad((hours % 1) * 60, 2);
- },
- //
- // Get the browser-reported name for the current timezone (e.g. MDT, Mountain Daylight Time)
- //
- // @return string
- //
- getTimezoneName: function() {
- var match = /(?:\((.+)\)$| ([A-Z]{3}) )/.exec(this.toString());
- return match[1] || match[2] || 'GMT' + this.getGmtOffset();
- },
- //
- // Convert the current date to an 8-digit integer (%Y%m%d)
- //
- // @return int
- //
- toYmdInt: function() {
- return (this.getFullYear() * 10000) + (this.getMonthNumber() * 100) + this.getDate();
- },
- //
- // Create a copy of a date object
- //
- // @return object
- //
- clone: function() {
- return new Date(this.getTime());
- }
- };
- for (var name in instanceMethods) {
- Date.prototype[name] = instanceMethods[name];
- }
- //
- // Add static methods to the date object
- //
- var staticMethods = {
- //
- // The heart of the date functionality: returns a date object if given a convertable value
- //
- // @param string/object/integer date
- // @return object Date
- //
- create: function(date) {
- // If the passed value is already a date object, return it
- if (date instanceof Date) {
- return date;
- }
- // if (typeof date == 'number') return new Date(date);
- // If the passed value is an integer, interpret it as a javascript timestamp
- if (typeof date == 'number') {
- return new Date(date);
- }
- // If the passed value is a string, attempt to parse it using Date.parse()
- var parsable = String(date).replace(/^\s*(.+)\s*$/, '$1'), i = 0, length = Date.create.patterns.length, pattern;
- var current = parsable;
- while (i < length) {
- ms = Date.parse(current);
- if (!isNaN(ms)) {
- return new Date(ms);
- }
- pattern = Date.create.patterns[i];
- if (typeof pattern == 'function') {
- obj = pattern(current);
- if (obj instanceof Date) {
- return obj;
- }
- } else {
- current = parsable.replace(pattern[0], pattern[1]);
- }
- i++;
- }
- return NaN;
- },
- //
- // constants representing month names, day names, and ordinal names
- // (same names as Ruby Date constants)
- //
- MONTHNAMES : 'January February March April May June July August September October November December'.split(' '),
- ABBR_MONTHNAMES : 'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split(' '),
- DAYNAMES : 'Sunday Monday Tuesday Wednesday Thursday Friday Saturday'.split(' '),
- ABBR_DAYNAMES : 'Sun Mon Tue Wed Thu Fri Sat'.split(' '),
- ORDINALNAMES : 'th st nd rd th th th th th th'.split(' '),
- //
- // Shortcut for full ISO-8601 date conversion
- //
- ISO: '%Y-%m-%dT%H:%M:%S.%N%G',
- //
- // Shortcut for SQL-type formatting
- //
- SQL: '%Y-%m-%d %H:%M:%S',
- //
- // Setter method for month, day, and ordinal names for i18n
- //
- // @param object newNames
- //
- daysInMonth: function(year, month) {
- if (month == 2) {
- return new Date(year, 1, 29).getDate() == 29 ? 29 : 28;
- }
- return [undefined,31,undefined,31,30,31,30,31,31,30,31,30,31][month];
- }
- };
- for (var name in staticMethods) {
- Date[name] = staticMethods[name];
- }
- //
- // format codes for strftime
- //
- // each code must be an array where the first member is the name of a Date.prototype function
- // and optionally a second member indicating the number to pass to Number#toPaddedString()
- //
- Date.prototype.strftime.formatCodes = {
- //
- // 2-part regex matcher for format codes
- //
- // first match must be the character before the code (to account for escaping)
- // second match must be the format code character(s)
- //
- matcher: /()%(#?(%|[a-z]))/i,
- // year
- Y: 'FullYear',
- y: 'ShortYear.2',
- // month
- m: 'MonthNumber.2',
- '#m': 'MonthNumber',
- B: 'MonthName',
- b: 'AbbrMonthName',
- // day
- d: 'Date.2',
- '#d': 'Date',
- e: 'Date',
- A: 'DayName',
- a: 'AbbrDayName',
- w: 'Day',
- o: 'DayOrdinal',
- // hours
- H: 'Hours.2',
- '#H': 'Hours',
- I: 'Hours12.2',
- '#I': 'Hours12',
- p: 'AmPm',
- // minutes
- M: 'Minutes.2',
- '#M': 'Minutes',
- // seconds
- S: 'Seconds.2',
- '#S': 'Seconds',
- s: 'Unix',
- // milliseconds
- N: 'Milliseconds.3',
- '#N': 'Milliseconds',
- // timezone
- O: 'TimezoneOffset',
- Z: 'TimezoneName',
- G: 'GmtOffset'
- };
- //
- // shortcuts that will be translated into their longer version
- //
- // be sure that format shortcuts do not refer to themselves: this will cause an infinite loop
- //
- Date.prototype.strftime.formatShortcuts = {
- // date
- F: '%Y-%m-%d',
- // time
- T: '%H:%M:%S',
- X: '%H:%M:%S',
- // local format date
- x: '%m/%d/%y',
- D: '%m/%d/%y',
- // local format extended
- '#c': '%a %b %e %H:%M:%S %Y',
- // local format short
- v: '%e-%b-%Y',
- R: '%H:%M',
- r: '%I:%M:%S %p',
- // tab and newline
- t: '\t',
- n: '\n',
- '%': '%'
- };
- //
- // A list of conversion patterns (array arguments sent directly to gsub)
- // Add, remove or splice a patterns to customize date parsing ability
- //
- Date.create.patterns = [
- [/-/g, '/'], // US-style time with dashes => Parsable US-style time
- [/st|nd|rd|th/g, ''], // remove st, nd, rd and th
- [/(3[01]|[0-2]\d)\s*\.\s*(1[0-2]|0\d)\s*\.\s*([1-9]\d{3})/, '$2/$1/$3'], // World time => Parsable US-style time
- [/([1-9]\d{3})\s*-\s*(1[0-2]|0\d)\s*-\s*(3[01]|[0-2]\d)/, '$2/$3/$1'], // ISO-style time => Parsable US-style time
- function(str) { // 12-hour or 24 hour time with milliseconds
- // var match = str.match(/^(?:(.+)\s+)?([1-9]|1[012])(?:\s*\:\s*(\d\d))?(?:\s*\:\s*(\d\d))?\s*(am|pm)\s*$/i);
- var match = str.match(/^(?:(.+)\s+)?([012]?\d)(?:\s*\:\s*(\d\d))?(?:\s*\:\s*(\d\d(\.\d*)?))?\s*(am|pm)?\s*$/i);
- // opt. date hour opt. minute opt. second opt. msec opt. am or pm
- if (match) {
- if (match[1]) {
- var d = Date.create(match[1]);
- if (isNaN(d)) {
- return;
- }
- } else {
- var d = new Date();
- d.setMilliseconds(0);
- }
- var hour = parseFloat(match[2]);
- if (match[6]) {
- hour = match[6].toLowerCase() == 'am' ? (hour == 12 ? 0 : hour) : (hour == 12 ? 12 : hour + 12);
- }
- d.setHours(hour, parseInt(match[3] || 0, 10), parseInt(match[4] || 0, 10), ((parseFloat(match[5] || 0)) || 0)*1000);
- return d;
- }
- else {
- return str;
- }
- },
- function(str) { // ISO timestamp with time zone.
- var match = str.match(/^(?:(.+))[T|\s+]([012]\d)(?:\:(\d\d))(?:\:(\d\d))(?:\.\d+)([\+\-]\d\d\:\d\d)$/i);
- if (match) {
- if (match[1]) {
- var d = Date.create(match[1]);
- if (isNaN(d)) {
- return;
- }
- } else {
- var d = new Date();
- d.setMilliseconds(0);
- }
- var hour = parseFloat(match[2]);
- d.setHours(hour, parseInt(match[3], 10), parseInt(match[4], 10), parseFloat(match[5])*1000);
- return d;
- }
- else {
- return str;
- }
- },
- function(str) {
- var match = str.match(/^([0-3]?\d)\s*[-\/.\s]{1}\s*([a-zA-Z]{3,9})\s*[-\/.\s]{1}\s*([0-3]?\d)$/);
- if (match) {
- var d = new Date();
- var y = parseFloat(String(d.getFullYear()).slice(2,4));
- var cent = parseInt(String(d.getFullYear())/100, 10)*100;
- var centoffset = 1;
- var m1 = parseFloat(match[1]);
- var m3 = parseFloat(match[3]);
- var ny, nd, nm;
- if (m1 > 31) { // first number is a year
- nd = match[3];
- if (m1 < y+centoffset) { // if less than 1 year out, assume it is this century.
- ny = cent + m1;
- }
- else {
- ny = cent - 100 + m1;
- }
- }
-
- else { // last number is the year
- nd = match[1];
- if (m3 < y+centoffset) { // if less than 1 year out, assume it is this century.
- ny = cent + m3;
- }
- else {
- ny = cent - 100 + m3;
- }
- }
-
- var nm = $.inArray(match[2], Date.ABBR_MONTHNAMES);
-
- if (nm == -1) {
- nm = $.inArray(match[2], Date.MONTHNAMES);
- }
-
- d.setFullYear(ny, nm, nd);
- d.setHours(0,0,0,0);
- return d;
- }
-
- else {
- return str;
- }
- }
- ];
-
- if ($.jqplot.config.debug) {
- $.date = Date.create;
- }
-
// Class: $.jqplot.DivTitleRenderer
// The default title renderer for jqPlot. This class has no options beyond the <Title> class.
$.jqplot.DivTitleRenderer = function() {
@@ -4066,10 +4670,21 @@
};
$.jqplot.DivTitleRenderer.prototype.draw = function() {
+ // Memory Leaks patch
+ if (this._elem) {
+ this._elem.emptyForce();
+ this._elem = null;
+ }
+
var r = this.renderer;
+ var elem = document.createElement('div');
+ this._elem = $(elem);
+ this._elem.addClass('jqplot-title');
+
if (!this.text) {
this.show = false;
- this._elem = $('<div class="jqplot-title" style="height:0px;width:0px;"></div>');
+ this._elem.height(0);
+ this._elem.width(0);
}
else if (this.text) {
var color;
@@ -4079,18 +4694,53 @@
else if (this.textColor) {
color = this.textColor;
}
+
// don't trust that a stylesheet is present, set the position.
- var styletext = 'position:absolute;top:0px;left:0px;';
- styletext += (this._plotWidth) ? 'width:'+this._plotWidth+'px;' : '';
- styletext += (this.fontSize) ? 'font-size:'+this.fontSize+';' : '';
- styletext += (this.textAlign) ? 'text-align:'+this.textAlign+';' : 'text-align:center;';
- styletext += (color) ? 'color:'+color+';' : '';
- styletext += (this.paddingBottom) ? 'padding-bottom:'+this.paddingBottom+';' : '';
- this._elem = $('<div class="jqplot-title" style="'+styletext+'">'+this.text+'</div>');
+ var styles = {position:'absolute', top:'0px', left:'0px'};
+
+ if (this._plotWidth) {
+ styles['width'] = this._plotWidth+'px';
+ }
+ if (this.fontSize) {
+ styles['fontSize'] = this.fontSize;
+ }
+ if (typeof this.textAlign === 'string') {
+ styles['textAlign'] = this.textAlign;
+ }
+ else {
+ styles['textAlign'] = 'center';
+ }
+ if (color) {
+ styles['color'] = color;
+ }
+ if (this.paddingBottom) {
+ styles['paddingBottom'] = this.paddingBottom;
+ }
if (this.fontFamily) {
- this._elem.css('font-family', this.fontFamily);
+ styles['fontFamily'] = this.fontFamily;
}
+
+ this._elem.css(styles);
+ if (this.escapeHtml) {
+ this._elem.text(this.text);
+ }
+ else {
+ this._elem.html(this.text);
+ }
+
+
+ // styletext += (this._plotWidth) ? 'width:'+this._plotWidth+'px;' : '';
+ // styletext += (this.fontSize) ? 'font-size:'+this.fontSize+';' : '';
+ // styletext += (this.textAlign) ? 'text-align:'+this.textAlign+';' : 'text-align:center;';
+ // styletext += (color) ? 'color:'+color+';' : '';
+ // styletext += (this.paddingBottom) ? 'padding-bottom:'+this.paddingBottom+';' : '';
+ // this._elem = $('<div class="jqplot-title" style="'+styletext+'">'+this.text+'</div>');
+ // if (this.fontFamily) {
+ // this._elem.css('font-family', this.fontFamily);
+ // }
}
+
+ elem = null;
return this._elem;
};
@@ -4099,6 +4749,116 @@
// nothing to do here
};
+
+ var dotlen = 0.1;
+
+ $.jqplot.LinePattern = function (ctx, pattern) {
+
+ var defaultLinePatterns = {
+ dotted: [ dotlen, $.jqplot.config.dotGapLength ],
+ dashed: [ $.jqplot.config.dashLength, $.jqplot.config.gapLength ],
+ solid: null
+ };
+
+ if (typeof pattern === 'string') {
+ if (pattern[0] === '.' || pattern[0] === '-') {
+ var s = pattern;
+ pattern = [];
+ for (var i=0, imax=s.length; i<imax; i++) {
+ if (s[i] === '.') {
+ pattern.push( dotlen );
+ }
+ else if (s[i] === '-') {
+ pattern.push( $.jqplot.config.dashLength );
+ }
+ else {
+ continue;
+ }
+ pattern.push( $.jqplot.config.gapLength );
+ }
+ }
+ else {
+ pattern = defaultLinePatterns[pattern];
+ }
+ }
+
+ if (!(pattern && pattern.length)) {
+ return ctx;
+ }
+
+ var patternIndex = 0;
+ var patternDistance = pattern[0];
+ var px = 0;
+ var py = 0;
+ var pathx0 = 0;
+ var pathy0 = 0;
+
+ var moveTo = function (x, y) {
+ ctx.moveTo( x, y );
+ px = x;
+ py = y;
+ pathx0 = x;
+ pathy0 = y;
+ };
+
+ var lineTo = function (x, y) {
+ var scale = ctx.lineWidth;
+ var dx = x - px;
+ var dy = y - py;
+ var dist = Math.sqrt(dx*dx+dy*dy);
+ if ((dist > 0) && (scale > 0)) {
+ dx /= dist;
+ dy /= dist;
+ while (true) {
+ var dp = scale * patternDistance;
+ if (dp < dist) {
+ px += dp * dx;
+ py += dp * dy;
+ if ((patternIndex & 1) == 0) {
+ ctx.lineTo( px, py );
+ }
+ else {
+ ctx.moveTo( px, py );
+ }
+ dist -= dp;
+ patternIndex++;
+ if (patternIndex >= pattern.length) {
+ patternIndex = 0;
+ }
+ patternDistance = pattern[patternIndex];
+ }
+ else {
+ px = x;
+ py = y;
+ if ((patternIndex & 1) == 0) {
+ ctx.lineTo( px, py );
+ }
+ else {
+ ctx.moveTo( px, py );
+ }
+ patternDistance -= dist / scale;
+ break;
+ }
+ }
+ }
+ };
+
+ var beginPath = function () {
+ ctx.beginPath();
+ };
+
+ var closePath = function () {
+ lineTo( pathx0, pathy0 );
+ };
+
+ return {
+ moveTo: moveTo,
+ lineTo: lineTo,
+ beginPath: beginPath,
+ closePath: closePath
+ };
+ };
+
// Class: $.jqplot.LineRenderer
// The default line renderer for jqPlot, this class has no options beyond the <Series> class.
// Draws series as a line.
@@ -4109,7 +4869,94 @@
// called with scope of series.
$.jqplot.LineRenderer.prototype.init = function(options, plot) {
+ // Group: Properties
+ //
options = options || {};
+ this._type='line';
+ this.renderer.animation = {
+ show: false,
+ direction: 'left',
+ speed: 2500,
+ _supported: true
+ };
+ // prop: smooth
+ // True to draw a smoothed (interpolated) line through the data points
+ // with automatically computed number of smoothing points.
+ // Set to an integer number > 2 to specify number of smoothing points
+ // to use between each data point.
+ this.renderer.smooth = false; // true or a number > 2 for smoothing.
+ this.renderer.tension = null; // null to auto compute or a number typically > 6. Fewer points requires higher tension.
+ // prop: constrainSmoothing
+ // True to use a more accurate smoothing algorithm that will
+ // not overshoot any data points. False to allow overshoot but
+ // produce a smoother looking line.
+ this.renderer.constrainSmoothing = true;
+ // this is smoothed data in grid coordinates, like gridData
+ this.renderer._smoothedData = [];
+ // this is smoothed data in plot units (plot coordinates), like plotData.
+ this.renderer._smoothedPlotData = [];
+ this.renderer._hiBandGridData = [];
+ this.renderer._lowBandGridData = [];
+ this.renderer._hiBandSmoothedData = [];
+ this.renderer._lowBandSmoothedData = [];
+
+ // prop: bandData
+ // Data used to draw error bands or confidence intervals above/below a line.
+ //
+ // bandData can be input in 3 forms. jqPlot will figure out which is the
+ // low band line and which is the high band line for all forms:
+ //
+ // A 2 dimensional array like [[yl1, yl2, ...], [yu1, yu2, ...]] where
+ // [yl1, yl2, ...] are y values of the lower line and
+ // [yu1, yu2, ...] are y values of the upper line.
+ // In this case there must be the same number of y data points as data points
+ // in the series and the bands will inherit the x values of the series.
+ //
+ // A 2 dimensional array like [[[xl1, yl1], [xl2, yl2], ...], [[xh1, yh1], [xh2, yh2], ...]]
+ // where [xl1, yl1] are x,y data points for the lower line and
+ // [xh1, yh1] are x,y data points for the high line.
+ // x values do not have to correspond to the x values of the series and can
+ // be of any arbitrary length.
+ //
+ // Can be of form [[yl1, yu1], [yl2, yu2], [yl3, yu3], ...] where
+ // there must be 3 or more arrays and there must be the same number of arrays
+ // as there are data points in the series. In this case,
+ // [yl1, yu1] specifies the lower and upper y values for the 1st
+ // data point and so on. The bands will inherit the x
+ // values from the series.
+ this.renderer.bandData = [];
+
+ // Group: bands
+ // Banding around line, e.g error bands or confidence intervals.
+ this.renderer.bands = {
+ // prop: show
+ // true to show the bands. If bandData or interval is
+ // supplied, show will be set to true by default.
+ show: false,
+ hiData: [],
+ lowData: [],
+ // prop: color
+ // color of lines at top and bottom of bands [default: series color].
+ color: this.color,
+ // prop: showLines
+ // True to show lines at top and bottom of bands [default: false].
+ showLines: false,
+ // prop: fill
+ // True to fill area between bands [default: true].
+ fill: true,
+ // prop: fillColor
+ // css color spec for filled area. [default: series color].
+ fillColor: null,
+ _min: null,
+ _max: null,
+ // prop: interval
+ // User specified interval above and below line for bands [default: '3%''].
+ // Can be a value like 3 or a string like '3%'
+ // or an upper/lower array like [1, -2] or ['2%', '-1.5%']
+ interval: '3%'
+ };
+
+
var lopts = {highlightMouseOver: options.highlightMouseOver, highlightMouseDown: options.highlightMouseDown, highlightColor: options.highlightColor};
delete (options.highlightMouseOver);
@@ -4117,26 +4964,60 @@
delete (options.highlightColor);
$.extend(true, this.renderer, options);
+
+ this.renderer.options = options;
+
+ // if we are given some band data, and bands aren't explicity set to false in options, turn them on.
+ if (this.renderer.bandData.length > 1 && (!options.bands || options.bands.show == null)) {
+ this.renderer.bands.show = true;
+ }
+
+ // if we are given an interval, and bands aren't explicity set to false in options, turn them on.
+ else if (options.bands && options.bands.show == null && options.bands.interval != null) {
+ this.renderer.bands.show = true;
+ }
+
+ // if plot is filled, turn off bands.
+ if (this.fill) {
+ this.renderer.bands.show = false;
+ }
+
+ if (this.renderer.bands.show) {
+ this.renderer.initBands.call(this, this.renderer.options, plot);
+ }
+
+
+ // smoothing is not compatible with stacked lines, disable
+ if (this._stack) {
+ this.renderer.smooth = false;
+ }
+
// set the shape renderer options
- var opts = {lineJoin:'round', lineCap:'round', fill:this.fill, isarc:false, strokeStyle:this.color, fillStyle:this.fillColor, lineWidth:this.lineWidth, closePath:this.fill};
+ var opts = {lineJoin:this.lineJoin, lineCap:this.lineCap, fill:this.fill, isarc:false, strokeStyle:this.color, fillStyle:this.fillColor, lineWidth:this.lineWidth, linePattern:this.linePattern, closePath:this.fill};
this.renderer.shapeRenderer.init(opts);
+
+ var shadow_offset = options.shadowOffset;
// set the shadow renderer options
- // scale the shadowOffset to the width of the line.
- if (this.lineWidth > 2.5) {
- var shadow_offset = this.shadowOffset* (1 + (Math.atan((this.lineWidth/2.5))/0.785398163 - 1)*0.6);
- // var shadow_offset = this.shadowOffset;
+ if (shadow_offset == null) {
+ // scale the shadowOffset to the width of the line.
+ if (this.lineWidth > 2.5) {
+ shadow_offset = 1.25 * (1 + (Math.atan((this.lineWidth/2.5))/0.785398163 - 1)*0.6);
+ // var shadow_offset = this.shadowOffset;
+ }
+ // for skinny lines, don't make such a big shadow.
+ else {
+ shadow_offset = 1.25 * Math.atan((this.lineWidth/2.5))/0.785398163;
+ }
}
- // for skinny lines, don't make such a big shadow.
- else {
- var shadow_offset = this.shadowOffset*Math.atan((this.lineWidth/2.5))/0.785398163;
- }
- var sopts = {lineJoin:'round', lineCap:'round', fill:this.fill, isarc:false, angle:this.shadowAngle, offset:shadow_offset, alpha:this.shadowAlpha, depth:this.shadowDepth, lineWidth:this.lineWidth, closePath:this.fill};
+
+ var sopts = {lineJoin:this.lineJoin, lineCap:this.lineCap, fill:this.fill, isarc:false, angle:this.shadowAngle, offset:shadow_offset, alpha:this.shadowAlpha, depth:this.shadowDepth, lineWidth:this.lineWidth, linePattern:this.linePattern, closePath:this.fill};
this.renderer.shadowRenderer.init(sopts);
this._areaPoints = [];
this._boundingBox = [[],[]];
- if (!this.isTrendline && this.fill) {
-
+ if (!this.isTrendline && this.fill || this.renderer.bands.show) {
+ // Group: Properties
+ //
// prop: highlightMouseOver
// True to highlight area on a filled plot when moused over.
// This must be false to enable highlightMouseDown to highlight when clicking on an area on a filled plot.
@@ -4156,12 +5037,17 @@
$.extend(true, this, {highlightMouseOver: lopts.highlightMouseOver, highlightMouseDown: lopts.highlightMouseDown, highlightColor: lopts.highlightColor});
if (!this.highlightColor) {
- this.highlightColor = $.jqplot.computeHighlightColors(this.fillColor);
+ var fc = (this.renderer.bands.show) ? this.renderer.bands.fillColor : this.fillColor;
+ this.highlightColor = $.jqplot.computeHighlightColors(fc);
}
- // turn off traditional highlighter
+ // turn off (disable) the highlighter plugin
if (this.highlighter) {
this.highlighter.show = false;
}
+ }
+
+ if (!this.isTrendline && plot) {
+ plot.plugins.lineRenderer = {};
plot.postInitHooks.addOnce(postInit);
plot.postDrawHooks.addOnce(postPlotDraw);
plot.eventListenerHooks.addOnce('jqplotMouseMove', handleMove);
@@ -4172,8 +5058,448 @@
}
};
+
+ $.jqplot.LineRenderer.prototype.initBands = function(options, plot) {
+ // use bandData if no data specified in bands option
+ //var bd = this.renderer.bandData;
+ var bd = options.bandData || [];
+ var bands = this.renderer.bands;
+ bands.hiData = [];
+ bands.lowData = [];
+ var data = this.data;
+ bands._max = null;
+ bands._min = null;
+ // If 2 arrays, and each array greater than 2 elements, assume it is hi and low data bands of y values.
+ if (bd.length == 2) {
+ // Do we have an array of x,y values?
+ // like [[[1,1], [2,4], [3,3]], [[1,3], [2,6], [3,5]]]
+ if ($.isArray(bd[0][0])) {
+ // since an arbitrary array of points, spin through all of them to determine max and min lines.
+
+ var p;
+ var bdminidx = 0, bdmaxidx = 0;
+ for (var i = 0, l = bd[0].length; i<l; i++) {
+ p = bd[0][i];
+ if ((p[1] != null && p[1] > bands._max) || bands._max == null) {
+ bands._max = p[1];
+ }
+ if ((p[1] != null && p[1] < bands._min) || bands._min == null) {
+ bands._min = p[1];
+ }
+ }
+ for (var i = 0, l = bd[1].length; i<l; i++) {
+ p = bd[1][i];
+ if ((p[1] != null && p[1] > bands._max) || bands._max == null) {
+ bands._max = p[1];
+ bdmaxidx = 1;
+ }
+ if ((p[1] != null && p[1] < bands._min) || bands._min == null) {
+ bands._min = p[1];
+ bdminidx = 1;
+ }
+ }
+
+ if (bdmaxidx === bdminidx) {
+ bands.show = false;
+ }
+
+ bands.hiData = bd[bdmaxidx];
+ bands.lowData = bd[bdminidx];
+ }
+ // else data is arrays of y values
+ // like [[1,4,3], [3,6,5]]
+ // must have same number of band data points as points in series
+ else if (bd[0].length === data.length && bd[1].length === data.length) {
+ var hi = (bd[0][0] > bd[1][0]) ? 0 : 1;
+ var low = (hi) ? 0 : 1;
+ for (var i=0, l=data.length; i < l; i++) {
+ bands.hiData.push([data[i][0], bd[hi][i]]);
+ bands.lowData.push([data[i][0], bd[low][i]]);
+ }
+ }
+
+ // we don't have proper data array, don't show bands.
+ else {
+ bands.show = false;
+ }
+ }
+
+ // if more than 2 arrays, have arrays of [ylow, yhi] values.
+ // note, can't distinguish case of [[ylow, yhi], [ylow, yhi]] from [[ylow, ylow], [yhi, yhi]]
+ // this is assumed to be of the latter form.
+ else if (bd.length > 2 && !$.isArray(bd[0][0])) {
+ var hi = (bd[0][0] > bd[0][1]) ? 0 : 1;
+ var low = (hi) ? 0 : 1;
+ for (var i=0, l=bd.length; i<l; i++) {
+ bands.hiData.push([data[i][0], bd[i][hi]]);
+ bands.lowData.push([data[i][0], bd[i][low]]);
+ }
+ }
+
+ // don't have proper data, auto calculate
+ else {
+ var intrv = bands.interval;
+ var a = null;
+ var b = null;
+ var afunc = null;
+ var bfunc = null;
+
+ if ($.isArray(intrv)) {
+ a = intrv[0];
+ b = intrv[1];
+ }
+ else {
+ a = intrv;
+ }
+
+ if (isNaN(a)) {
+ // we have a string
+ if (a.charAt(a.length - 1) === '%') {
+ afunc = 'multiply';
+ a = parseFloat(a)/100 + 1;
+ }
+ }
+
+ else {
+ a = parseFloat(a);
+ afunc = 'add';
+ }
+
+ if (b !== null && isNaN(b)) {
+ // we have a string
+ if (b.charAt(b.length - 1) === '%') {
+ bfunc = 'multiply';
+ b = parseFloat(b)/100 + 1;
+ }
+ }
+
+ else if (b !== null) {
+ b = parseFloat(b);
+ bfunc = 'add';
+ }
+
+ if (a !== null) {
+ if (b === null) {
+ b = -a;
+ bfunc = afunc;
+ if (bfunc === 'multiply') {
+ b += 2;
+ }
+ }
+
+ // make sure a always applies to hi band.
+ if (a < b) {
+ var temp = a;
+ a = b;
+ b = temp;
+ temp = afunc;
+ afunc = bfunc;
+ bfunc = temp;
+ }
+
+ for (var i=0, l = data.length; i < l; i++) {
+ switch (afunc) {
+ case 'add':
+ bands.hiData.push([data[i][0], data[i][1] + a]);
+ break;
+ case 'multiply':
+ bands.hiData.push([data[i][0], data[i][1] * a]);
+ break;
+ }
+ switch (bfunc) {
+ case 'add':
+ bands.lowData.push([data[i][0], data[i][1] + b]);
+ break;
+ case 'multiply':
+ bands.lowData.push([data[i][0], data[i][1] * b]);
+ break;
+ }
+ }
+ }
+
+ else {
+ bands.show = false;
+ }
+ }
+
+ var hd = bands.hiData;
+ var ld = bands.lowData;
+ for (var i = 0, l = hd.length; i<l; i++) {
+ if ((hd[i][1] != null && hd[i][1] > bands._max) || bands._max == null) {
+ bands._max = hd[i][1];
+ }
+ }
+ for (var i = 0, l = ld.length; i<l; i++) {
+ if ((ld[i][1] != null && ld[i][1] < bands._min) || bands._min == null) {
+ bands._min = ld[i][1];
+ }
+ }
+
+ // one last check for proper data
+ // these don't apply any more since allowing arbitrary x,y values
+ // if (bands.hiData.length != bands.lowData.length) {
+ // bands.show = false;
+ // }
+
+ // if (bands.hiData.length != this.data.length) {
+ // bands.show = false;
+ // }
+
+ if (bands.fillColor === null) {
+ var c = $.jqplot.getColorComponents(bands.color);
+ // now adjust alpha to differentiate fill
+ c[3] = c[3] * 0.5;
+ bands.fillColor = 'rgba(' + c[0] +', '+ c[1] +', '+ c[2] +', '+ c[3] + ')';
+ }
+ };
+
+ function getSteps (d, f) {
+ return (3.4182054+f) * Math.pow(d, -0.3534992);
+ }
+
+ function computeSteps (d1, d2) {
+ var s = Math.sqrt(Math.pow((d2[0]- d1[0]), 2) + Math.pow ((d2[1] - d1[1]), 2));
+ return 5.7648 * Math.log(s) + 7.4456;
+ }
+
+ function tanh (x) {
+ var a = (Math.exp(2*x) - 1) / (Math.exp(2*x) + 1);
+ return a;
+ }
+
+ //////////
+ // computeConstrainedSmoothedData
+ // An implementation of the constrained cubic spline interpolation
+ // method as presented in:
+ //
+ // Kruger, CJC, Constrained Cubic Spine Interpolation for Chemical Engineering Applications
+ // http://www.korf.co.uk/spline.pdf
+ //
+ // The implementation below borrows heavily from the sample Visual Basic
+ // implementation by CJC Kruger found in http://www.korf.co.uk/spline.xls
+ //
+ /////////
+
+ // called with scope of series
+ function computeConstrainedSmoothedData (gd) {
+ var smooth = this.renderer.smooth;
+ var dim = this.canvas.getWidth();
+ var xp = this._xaxis.series_p2u;
+ var yp = this._yaxis.series_p2u;
+ var steps =null;
+ var _steps = null;
+ var dist = gd.length/dim;
+ var _smoothedData = [];
+ var _smoothedPlotData = [];
+
+ if (!isNaN(parseFloat(smooth))) {
+ steps = parseFloat(smooth);
+ }
+ else {
+ steps = getSteps(dist, 0.5);
+ }
+
+ var yy = [];
+ var xx = [];
+
+ for (var i=0, l = gd.length; i<l; i++) {
+ yy.push(gd[i][1]);
+ xx.push(gd[i][0]);
+ }
+
+ function dxx(x1, x0) {
+ if (x1 - x0 == 0) {
+ return Math.pow(10,10);
+ }
+ else {
+ return x1 - x0;
+ }
+ }
+
+ var A, B, C, D;
+ // loop through each line segment. Have # points - 1 line segments. Nmber segments starting at 1.
+ var nmax = gd.length - 1;
+ for (var num = 1, gdl = gd.length; num<gdl; num++) {
+ var gxx = [];
+ var ggxx = [];
+ // point at each end of segment.
+ for (var j = 0; j < 2; j++) {
+ var i = num - 1 + j; // point number, 0 to # points.
+
+ if (i == 0 || i == nmax) {
+ gxx[j] = Math.pow(10, 10);
+ }
+ else if (yy[i+1] - yy[i] == 0 || yy[i] - yy[i-1] == 0) {
+ gxx[j] = 0;
+ }
+ else if (((xx[i+1] - xx[i]) / (yy[i+1] - yy[i]) + (xx[i] - xx[i-1]) / (yy[i] - yy[i-1])) == 0 ) {
+ gxx[j] = 0;
+ }
+ else if ( (yy[i+1] - yy[i]) * (yy[i] - yy[i-1]) < 0 ) {
+ gxx[j] = 0;
+ }
+
+ else {
+ gxx[j] = 2 / (dxx(xx[i + 1], xx[i]) / (yy[i + 1] - yy[i]) + dxx(xx[i], xx[i - 1]) / (yy[i] - yy[i - 1]));
+ }
+ }
+
+ // Reset first derivative (slope) at first and last point
+ if (num == 1) {
+ // First point has 0 2nd derivative
+ gxx[0] = 3 / 2 * (yy[1] - yy[0]) / dxx(xx[1], xx[0]) - gxx[1] / 2;
+ }
+ else if (num == nmax) {
+ // Last point has 0 2nd derivative
+ gxx[1] = 3 / 2 * (yy[nmax] - yy[nmax - 1]) / dxx(xx[nmax], xx[nmax - 1]) - gxx[0] / 2;
+ }
+
+ // Calc second derivative at points
+ ggxx[0] = -2 * (gxx[1] + 2 * gxx[0]) / dxx(xx[num], xx[num - 1]) + 6 * (yy[num] - yy[num - 1]) / Math.pow(dxx(xx[num], xx[num - 1]), 2);
+ ggxx[1] = 2 * (2 * gxx[1] + gxx[0]) / dxx(xx[num], xx[num - 1]) - 6 * (yy[num] - yy[num - 1]) / Math.pow(dxx(xx[num], xx[num - 1]), 2);
+
+ // Calc constants for cubic interpolation
+ D = 1 / 6 * (ggxx[1] - ggxx[0]) / dxx(xx[num], xx[num - 1]);
+ C = 1 / 2 * (xx[num] * ggxx[0] - xx[num - 1] * ggxx[1]) / dxx(xx[num], xx[num - 1]);
+ B = (yy[num] - yy[num - 1] - C * (Math.pow(xx[num], 2) - Math.pow(xx[num - 1], 2)) - D * (Math.pow(xx[num], 3) - Math.pow(xx[num - 1], 3))) / dxx(xx[num], xx[num - 1]);
+ A = yy[num - 1] - B * xx[num - 1] - C * Math.pow(xx[num - 1], 2) - D * Math.pow(xx[num - 1], 3);
+
+ var increment = (xx[num] - xx[num - 1]) / steps;
+ var temp, tempx;
+
+ for (var j = 0, l = steps; j < l; j++) {
+ temp = [];
+ tempx = xx[num - 1] + j * increment;
+ temp.push(tempx);
+ temp.push(A + B * tempx + C * Math.pow(tempx, 2) + D * Math.pow(tempx, 3));
+ _smoothedData.push(temp);
+ _smoothedPlotData.push([xp(temp[0]), yp(temp[1])]);
+ }
+ }
+
+ _smoothedData.push(gd[i]);
+ _smoothedPlotData.push([xp(gd[i][0]), yp(gd[i][1])]);
+
+ return [_smoothedData, _smoothedPlotData];
+ }
+
+ ///////
+ // computeHermiteSmoothedData
+ // A hermite spline smoothing of the plot data.
+ // This implementation is derived from the one posted
+ // by krypin on the jqplot-users mailing list:
+ //
+ // http://groups.google.com/group/jqplot-users/browse_thread/thread/748be6a445723cea?pli=1
+ //
+ // with a blog post:
+ //
+ // http://blog.statscollector.com/a-plugin-renderer-for-jqplot-to-draw-a-hermite-spline/
+ //
+ // and download of the original plugin:
+ //
+ // http://blog.statscollector.com/wp-content/uploads/2010/02/jqplot.hermiteSplineRenderer.js
+ //////////
+
+ // called with scope of series
+ function computeHermiteSmoothedData (gd) {
+ var smooth = this.renderer.smooth;
+ var tension = this.renderer.tension;
+ var dim = this.canvas.getWidth();
+ var xp = this._xaxis.series_p2u;
+ var yp = this._yaxis.series_p2u;
+ var steps =null;
+ var _steps = null;
+ var a = null;
+ var a1 = null;
+ var a2 = null;
+ var slope = null;
+ var slope2 = null;
+ var temp = null;
+ var t, s, h1, h2, h3, h4;
+ var TiX, TiY, Ti1X, Ti1Y;
+ var pX, pY, p;
+ var sd = [];
+ var spd = [];
+ var dist = gd.length/dim;
+ var min, max, stretch, scale, shift;
+ var _smoothedData = [];
+ var _smoothedPlotData = [];
+ if (!isNaN(parseFloat(smooth))) {
+ steps = parseFloat(smooth);
+ }
+ else {
+ steps = getSteps(dist, 0.5);
+ }
+ if (!isNaN(parseFloat(tension))) {
+ tension = parseFloat(tension);
+ }
+
+ for (var i=0, l = gd.length-1; i < l; i++) {
+
+ if (tension === null) {
+ slope = Math.abs((gd[i+1][1] - gd[i][1]) / (gd[i+1][0] - gd[i][0]));
+
+ min = 0.3;
+ max = 0.6;
+ stretch = (max - min)/2.0;
+ scale = 2.5;
+ shift = -1.4;
+
+ temp = slope/scale + shift;
+
+ a1 = stretch * tanh(temp) - stretch * tanh(shift) + min;
+
+ // if have both left and right line segments, will use minimum tension.
+ if (i > 0) {
+ slope2 = Math.abs((gd[i][1] - gd[i-1][1]) / (gd[i][0] - gd[i-1][0]));
+ }
+ temp = slope2/scale + shift;
+
+ a2 = stretch * tanh(temp) - stretch * tanh(shift) + min;
+
+ a = (a1 + a2)/2.0;
+
+ }
+ else {
+ a = tension;
+ }
+ for (t=0; t < steps; t++) {
+ s = t / steps;
+ h1 = (1 + 2*s)*Math.pow((1-s),2);
+ h2 = s*Math.pow((1-s),2);
+ h3 = Math.pow(s,2)*(3-2*s);
+ h4 = Math.pow(s,2)*(s-1);
+
+ if (gd[i-1]) {
+ TiX = a * (gd[i+1][0] - gd[i-1][0]);
+ TiY = a * (gd[i+1][1] - gd[i-1][1]);
+ } else {
+ TiX = a * (gd[i+1][0] - gd[i][0]);
+ TiY = a * (gd[i+1][1] - gd[i][1]);
+ }
+ if (gd[i+2]) {
+ Ti1X = a * (gd[i+2][0] - gd[i][0]);
+ Ti1Y = a * (gd[i+2][1] - gd[i][1]);
+ } else {
+ Ti1X = a * (gd[i+1][0] - gd[i][0]);
+ Ti1Y = a * (gd[i+1][1] - gd[i][1]);
+ }
+
+ pX = h1*gd[i][0] + h3*gd[i+1][0] + h2*TiX + h4*Ti1X;
+ pY = h1*gd[i][1] + h3*gd[i+1][1] + h2*TiY + h4*Ti1Y;
+ p = [pX, pY];
+
+ _smoothedData.push(p);
+ _smoothedPlotData.push([xp(pX), yp(pY)]);
+ }
+ }
+ _smoothedData.push(gd[l]);
+ _smoothedPlotData.push([xp(gd[l][0]), yp(gd[l][1])]);
+
+ return [_smoothedData, _smoothedPlotData];
+ }
- // Method: setGridData
+ // setGridData
// converts the user data values to grid coordinates and stores them
// in the gridData array.
// Called with scope of a series.
@@ -4185,16 +5511,26 @@
var pdata = this._prevPlotData;
this.gridData = [];
this._prevGridData = [];
- for (var i=0; i<this.data.length; i++) {
+ this.renderer._smoothedData = [];
+ this.renderer._smoothedPlotData = [];
+ this.renderer._hiBandGridData = [];
+ this.renderer._lowBandGridData = [];
+ this.renderer._hiBandSmoothedData = [];
+ this.renderer._lowBandSmoothedData = [];
+ var bands = this.renderer.bands;
+ var hasNull = false;
+ for (var i=0, l=data.length; i < l; i++) {
// if not a line series or if no nulls in data, push the converted point onto the array.
if (data[i][0] != null && data[i][1] != null) {
this.gridData.push([xp.call(this._xaxis, data[i][0]), yp.call(this._yaxis, data[i][1])]);
}
// else if there is a null, preserve it.
else if (data[i][0] == null) {
+ hasNull = true;
this.gridData.push([null, yp.call(this._yaxis, data[i][1])]);
}
else if (data[i][1] == null) {
+ hasNull = true;
this.gridData.push([xp.call(this._xaxis, data[i][0]), null]);
}
// if not a line series or if no nulls in data, push the converted point onto the array.
@@ -4209,9 +5545,59 @@
this._prevGridData.push([xp.call(this._xaxis, pdata[i][0]), null]);
}
}
+
+ // don't do smoothing or bands on broken lines.
+ if (hasNull) {
+ this.renderer.smooth = false;
+ if (this._type === 'line') {
+ bands.show = false;
+ }
+ }
+
+ if (this._type === 'line' && bands.show) {
+ for (var i=0, l=bands.hiData.length; i<l; i++) {
+ this.renderer._hiBandGridData.push([xp.call(this._xaxis, bands.hiData[i][0]), yp.call(this._yaxis, bands.hiData[i][1])]);
+ }
+ for (var i=0, l=bands.lowData.length; i<l; i++) {
+ this.renderer._lowBandGridData.push([xp.call(this._xaxis, bands.lowData[i][0]), yp.call(this._yaxis, bands.lowData[i][1])]);
+ }
+ }
+
+ // calculate smoothed data if enough points and no nulls
+ if (this._type === 'line' && this.renderer.smooth && this.gridData.length > 2) {
+ var ret;
+ if (this.renderer.constrainSmoothing) {
+ ret = computeConstrainedSmoothedData.call(this, this.gridData);
+ this.renderer._smoothedData = ret[0];
+ this.renderer._smoothedPlotData = ret[1];
+
+ if (bands.show) {
+ ret = computeConstrainedSmoothedData.call(this, this.renderer._hiBandGridData);
+ this.renderer._hiBandSmoothedData = ret[0];
+ ret = computeConstrainedSmoothedData.call(this, this.renderer._lowBandGridData);
+ this.renderer._lowBandSmoothedData = ret[0];
+ }
+
+ ret = null;
+ }
+ else {
+ ret = computeHermiteSmoothedData.call(this, this.gridData);
+ this.renderer._smoothedData = ret[0];
+ this.renderer._smoothedPlotData = ret[1];
+
+ if (bands.show) {
+ ret = computeHermiteSmoothedData.call(this, this.renderer._hiBandGridData);
+ this.renderer._hiBandSmoothedData = ret[0];
+ ret = computeHermiteSmoothedData.call(this, this.renderer._lowBandGridData);
+ this.renderer._lowBandSmoothedData = ret[0];
+ }
+
+ ret = null;
+ }
+ }
};
- // Method: makeGridData
+ // makeGridData
// converts any arbitrary data values to grid coordinates and
// returns them. This method exists so that plugins can use a series'
// linerenderer to generate grid data points without overwriting the
@@ -4223,6 +5609,14 @@
var yp = this._yaxis.series_u2p;
var gd = [];
var pgd = [];
+ this.renderer._smoothedData = [];
+ this.renderer._smoothedPlotData = [];
+ this.renderer._hiBandGridData = [];
+ this.renderer._lowBandGridData = [];
+ this.renderer._hiBandSmoothedData = [];
+ this.renderer._lowBandSmoothedData = [];
+ var bands = this.renderer.bands;
+ var hasNull = false;
for (var i=0; i<data.length; i++) {
// if not a line series or if no nulls in data, push the converted point onto the array.
if (data[i][0] != null && data[i][1] != null) {
@@ -4230,20 +5624,72 @@
}
// else if there is a null, preserve it.
else if (data[i][0] == null) {
+ hasNull = true;
gd.push([null, yp.call(this._yaxis, data[i][1])]);
}
else if (data[i][1] == null) {
+ hasNull = true;
gd.push([xp.call(this._xaxis, data[i][0]), null]);
}
}
+
+ // don't do smoothing or bands on broken lines.
+ if (hasNull) {
+ this.renderer.smooth = false;
+ if (this._type === 'line') {
+ bands.show = false;
+ }
+ }
+
+ if (this._type === 'line' && bands.show) {
+ for (var i=0, l=bands.hiData.length; i<l; i++) {
+ this.renderer._hiBandGridData.push([xp.call(this._xaxis, bands.hiData[i][0]), yp.call(this._yaxis, bands.hiData[i][1])]);
+ }
+ for (var i=0, l=bands.lowData.length; i<l; i++) {
+ this.renderer._lowBandGridData.push([xp.call(this._xaxis, bands.lowData[i][0]), yp.call(this._yaxis, bands.lowData[i][1])]);
+ }
+ }
+
+ if (this._type === 'line' && this.renderer.smooth && gd.length > 2) {
+ var ret;
+ if (this.renderer.constrainSmoothing) {
+ ret = computeConstrainedSmoothedData.call(this, gd);
+ this.renderer._smoothedData = ret[0];
+ this.renderer._smoothedPlotData = ret[1];
+
+ if (bands.show) {
+ ret = computeConstrainedSmoothedData.call(this, this.renderer._hiBandGridData);
+ this.renderer._hiBandSmoothedData = ret[0];
+ ret = computeConstrainedSmoothedData.call(this, this.renderer._lowBandGridData);
+ this.renderer._lowBandSmoothedData = ret[0];
+ }
+
+ ret = null;
+ }
+ else {
+ ret = computeHermiteSmoothedData.call(this, gd);
+ this.renderer._smoothedData = ret[0];
+ this.renderer._smoothedPlotData = ret[1];
+
+ if (bands.show) {
+ ret = computeHermiteSmoothedData.call(this, this.renderer._hiBandGridData);
+ this.renderer._hiBandSmoothedData = ret[0];
+ ret = computeHermiteSmoothedData.call(this, this.renderer._lowBandGridData);
+ this.renderer._lowBandSmoothedData = ret[0];
+ }
+
+ ret = null;
+ }
+ }
return gd;
};
// called within scope of series.
- $.jqplot.LineRenderer.prototype.draw = function(ctx, gd, options) {
+ $.jqplot.LineRenderer.prototype.draw = function(ctx, gd, options, plot) {
var i;
- var opts = (options != undefined) ? options : {};
+ // get a copy of the options, so we don't modify the original object.
+ var opts = $.extend(true, {}, options);
var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow;
var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine;
var fill = (opts.fill != undefined) ? opts.fill : this.fill;
@@ -4254,10 +5700,9 @@
if (showLine) {
// if we fill, we'll have to add points to close the curve.
if (fill) {
- if (this.fillToZero) {
+ if (this.fillToZero) {
// have to break line up into shapes at axis crossings
- var negativeColors = new $.jqplot.ColorGenerator(this.negativeSeriesColors);
- var negativeColor = negativeColors.get(this.index);
+ var negativeColor = this.negativeColor;
if (! this.useNegativeColors) {
negativeColor = opts.fillStyle;
}
@@ -4272,9 +5717,12 @@
if (this.index == 0 || !this._stack) {
var tempgd = [];
+ var pd = (this.renderer.smooth) ? this.renderer._smoothedPlotData : this._plotData;
this._areaPoints = [];
var pyzero = this._yaxis.series_u2p(this.fillToValue);
var pxzero = this._xaxis.series_u2p(this.fillToValue);
+
+ opts.closePath = true;
if (this.fillAxis == 'y') {
tempgd.push([gd[0][0], pyzero]);
@@ -4284,8 +5732,8 @@
tempgd.push(gd[i]);
this._areaPoints.push(gd[i]);
// do we have an axis crossing?
- if (this._plotData[i][1] * this._plotData[i+1][1] < 0) {
- if (this._plotData[i][1] < 0) {
+ if (pd[i][1] * pd[i+1][1] < 0) {
+ if (pd[i][1] < 0) {
isnegative = true;
opts.fillStyle = negativeColor;
}
@@ -4307,7 +5755,7 @@
// this._areaPoints = [[xintercept, pyzero]];
}
}
- if (this._plotData[gd.length-1][1] < 0) {
+ if (pd[gd.length-1][1] < 0) {
isnegative = true;
opts.fillStyle = negativeColor;
}
@@ -4320,7 +5768,7 @@
tempgd.push([gd[gd.length-1][0], pyzero]);
this._areaPoints.push([gd[gd.length-1][0], pyzero]);
}
- // now draw this shape and shadow.
+ // now draw the last area.
if (shadow) {
this.renderer.shadowRenderer.draw(ctx, tempgd, opts);
}
@@ -4361,7 +5809,7 @@
var gridymin = ctx.canvas.height;
// IE doesn't return new length on unshift
gd.unshift([gd[0][0], gridymin]);
- len = gd.length;
+ var len = gd.length;
gd.push([gd[len - 1][0], gridymin]);
}
// if stacked, fill to line below
@@ -4389,6 +5837,9 @@
// }
// now draw the markers
if (this.markerRenderer.show) {
+ if (this.renderer.smooth) {
+ fasgd = this.gridData;
+ }
for (i=0; i<fasgd.length; i++) {
this.markerRenderer.draw(fasgd[i][0], fasgd[i][1], ctx, opts.markerOptions);
}
@@ -4396,6 +5847,32 @@
}
}
else {
+
+ if (this.renderer.bands.show) {
+ var bdat;
+ var bopts = $.extend(true, {}, opts);
+ if (this.renderer.bands.showLines) {
+ bdat = (this.renderer.smooth) ? this.renderer._hiBandSmoothedData : this.renderer._hiBandGridData;
+ this.renderer.shapeRenderer.draw(ctx, bdat, opts);
+ bdat = (this.renderer.smooth) ? this.renderer._lowBandSmoothedData : this.renderer._lowBandGridData;
+ this.renderer.shapeRenderer.draw(ctx, bdat, bopts);
+ }
+
+ if (this.renderer.bands.fill) {
+ if (this.renderer.smooth) {
+ bdat = this.renderer._hiBandSmoothedData.concat(this.renderer._lowBandSmoothedData.reverse());
+ }
+ else {
+ bdat = this.renderer._hiBandGridData.concat(this.renderer._lowBandGridData.reverse());
+ }
+ this._areaPoints = bdat;
+ bopts.closePath = true;
+ bopts.fill = true;
+ bopts.fillStyle = this.renderer.bands.fillColor;
+ this.renderer.shapeRenderer.draw(ctx, bdat, bopts);
+ }
+ }
+
if (shadow) {
this.renderer.shadowRenderer.draw(ctx, gd, opts);
}
@@ -4420,10 +5897,19 @@
ymin = p[1];
}
}
+
+ if (this.type === 'line' && this.renderer.bands.show) {
+ ymax = this._yaxis.series_u2p(this.renderer.bands._min);
+ ymin = this._yaxis.series_u2p(this.renderer.bands._max);
+ }
+
this._boundingBox = [[xmin, ymax], [xmax, ymin]];
// now draw the markers
if (this.markerRenderer.show && !fill) {
+ if (this.renderer.smooth) {
+ gd = this.gridData;
+ }
for (i=0; i<gd.length; i++) {
if (gd[i][0] != null && gd[i][1] != null) {
this.markerRenderer.draw(gd[i][0], gd[i][1], ctx, opts.markerOptions);
@@ -4442,7 +5928,7 @@
// called with scope of plot.
// make sure to not leave anything highlighted.
function postInit(target, data, options) {
- for (i=0; i<this.series.length; i++) {
+ for (var i=0; i<this.series.length; i++) {
if (this.series[i].renderer.constructor == $.jqplot.LineRenderer) {
// don't allow mouseover and mousedown at same time.
if (this.series[i].highlightMouseOver) {
@@ -4450,18 +5936,24 @@
}
}
}
- this.target.bind('mouseout', {plot:this}, function (ev) { unhighlight(ev.data.plot); });
}
// called within context of plot
// create a canvas which we can draw on.
// insert it before the eventCanvas, so eventCanvas will still capture events.
function postPlotDraw() {
- this.plugins.lineRenderer = {highlightedSeriesIndex:null};
+ // Memory Leaks patch
+ if (this.plugins.lineRenderer && this.plugins.lineRenderer.highlightCanvas) {
+ this.plugins.lineRenderer.highlightCanvas.resetCanvas();
+ this.plugins.lineRenderer.highlightCanvas = null;
+ }
+
+ this.plugins.lineRenderer.highlightedSeriesIndex = null;
this.plugins.lineRenderer.highlightCanvas = new $.jqplot.GenericCanvas();
- this.eventCanvas._elem.before(this.plugins.lineRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-lineRenderer-highlight-canvas', this._plotDimensions));
- var hctx = this.plugins.lineRenderer.highlightCanvas.setContext();
+ this.eventCanvas._elem.before(this.plugins.lineRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-lineRenderer-highlight-canvas', this._plotDimensions, this));
+ this.plugins.lineRenderer.highlightCanvas.setContext();
+ this.eventCanvas._elem.bind('mouseleave', {plot:this}, function (ev) { unhighlight(ev.data.plot); });
}
function highlight (plot, sidx, pidx, points) {
@@ -4471,7 +5963,12 @@
s._highlightedPoint = pidx;
plot.plugins.lineRenderer.highlightedSeriesIndex = sidx;
var opts = {fillStyle: s.highlightColor};
+ if (s.type === 'line' && s.renderer.bands.show) {
+ opts.fill = true;
+ opts.closePath = true;
+ }
s.renderer.shapeRenderer.draw(canvas._ctx, points, opts);
+ canvas = null;
}
function unhighlight (plot) {
@@ -4482,6 +5979,7 @@
}
plot.plugins.lineRenderer.highlightedSeriesIndex = null;
plot.target.trigger('jqplotDataUnhighlight');
+ canvas = null;
}
@@ -4494,6 +5992,7 @@
plot.target.trigger(evt1, ins);
if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.lineRenderer.highlightedSeriesIndex)) {
var evt = jQuery.Event('jqplotDataHighlight');
+ evt.which = ev.which;
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
plot.target.trigger(evt, ins);
@@ -4510,6 +6009,7 @@
var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
if (plot.series[ins[0]].highlightMouseDown && !(ins[0] == plot.plugins.lineRenderer.highlightedSeriesIndex)) {
var evt = jQuery.Event('jqplotDataHighlight');
+ evt.which = ev.which;
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
plot.target.trigger(evt, ins);
@@ -4532,6 +6032,7 @@
if (neighbor) {
var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
var evt = jQuery.Event('jqplotDataClick');
+ evt.which = ev.which;
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
plot.target.trigger(evt, ins);
@@ -4546,6 +6047,7 @@
unhighlight(plot);
}
var evt = jQuery.Event('jqplotDataRightClick');
+ evt.which = ev.which;
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
plot.target.trigger(evt, ins);
@@ -4555,48 +6057,90 @@
// class: $.jqplot.LinearAxisRenderer
// The default jqPlot axis renderer, creating a numeric axis.
- // The renderer has no additional options beyond the <Axis> object.
$.jqplot.LinearAxisRenderer = function() {
};
// called with scope of axis object.
$.jqplot.LinearAxisRenderer.prototype.init = function(options){
+ // prop: breakPoints
+ // EXPERIMENTAL!! Use at your own risk!
+ // Works only with linear axes and the default tick renderer.
+ // Array of [start, stop] points to create a broken axis.
+ // Broken axes have a "jump" in them, which is an immediate
+ // transition from a smaller value to a larger value.
+ // Currently, axis ticks MUST be manually assigned if using breakPoints
+ // by using the axis ticks array option.
+ this.breakPoints = null;
+ // prop: breakTickLabel
+ // Label to use at the axis break if breakPoints are specified.
+ this.breakTickLabel = "≈";
+ // prop: drawBaseline
+ // True to draw the axis baseline.
+ this.drawBaseline = true;
+ // prop: baselineWidth
+ // width of the baseline in pixels.
+ this.baselineWidth = null;
+ // prop: baselineColor
+ // CSS color spec for the baseline.
+ this.baselineColor = null;
+ // prop: forceTickAt0
+ // This will ensure that there is always a tick mark at 0.
+ // If data range is strictly positive or negative,
+ // this will force 0 to be inside the axis bounds unless
+ // the appropriate axis pad (pad, padMin or padMax) is set
+ // to 0, then this will force an axis min or max value at 0.
+ // This has know effect when any of the following options
+ // are set: autoscale, min, max, numberTicks or tickInterval.
+ this.forceTickAt0 = false;
+ // prop: forceTickAt100
+ // This will ensure that there is always a tick mark at 100.
+ // If data range is strictly above or below 100,
+ // this will force 100 to be inside the axis bounds unless
+ // the appropriate axis pad (pad, padMin or padMax) is set
+ // to 0, then this will force an axis min or max value at 100.
+ // This has know effect when any of the following options
+ // are set: autoscale, min, max, numberTicks or tickInterval.
+ this.forceTickAt100 = false;
+ // prop: tickInset
+ // Controls the amount to inset the first and last ticks from
+ // the edges of the grid, in multiples of the tick interval.
+ // 0 is no inset, 0.5 is one half a tick interval, 1 is a full
+ // tick interval, etc.
+ this.tickInset = 0;
+ // prop: minorTicks
+ // Number of ticks to add between "major" ticks.
+ // Major ticks are ticks supplied by user or auto computed.
+ // Minor ticks cannot be created by user.
+ this.minorTicks = 0;
+ // prop: alignTicks
+ // true to align tick marks across opposed axes
+ // such as from the y2axis to yaxis.
+ this.alignTicks = false;
+ this._autoFormatString = '';
+ this._overrideFormatString = false;
+ this._scalefact = 1.0;
$.extend(true, this, options);
- var db = this._dataBounds;
- // Go through all the series attached to this axis and find
- // the min/max bounds for this axis.
- for (var i=0; i<this._series.length; i++) {
- var s = this._series[i];
- var d = s._plotData;
-
- for (var j=0; j<d.length; j++) {
- if (this.name == 'xaxis' || this.name == 'x2axis') {
- if ((d[j][0] != null && d[j][0] < db.min) || db.min == null) {
- db.min = d[j][0];
- }
- if ((d[j][0] != null && d[j][0] > db.max) || db.max == null) {
- db.max = d[j][0];
- }
- }
- else {
- if ((d[j][1] != null && d[j][1] < db.min) || db.min == null) {
- db.min = d[j][1];
- }
- if ((d[j][1] != null && d[j][1] > db.max) || db.max == null) {
- db.max = d[j][1];
- }
- }
+ if (this.breakPoints) {
+ if (!$.isArray(this.breakPoints)) {
+ this.breakPoints = null;
}
+ else if (this.breakPoints.length < 2 || this.breakPoints[1] <= this.breakPoints[0]) {
+ this.breakPoints = null;
+ }
}
+ if (this.numberTicks != null && this.numberTicks < 2) {
+ this.numberTicks = 2;
+ }
+ this.resetDataBounds();
};
// called with scope of axis
- $.jqplot.LinearAxisRenderer.prototype.draw = function(ctx) {
+ $.jqplot.LinearAxisRenderer.prototype.draw = function(ctx, plot) {
if (this.show) {
// populate the axis label and value properties.
// createTicks is a method on the renderer, but
// call it within the scope of the axis.
- this.renderer.createTicks.call(this);
+ this.renderer.createTicks.call(this, plot);
// fill a div with axes labels in the right direction.
// Need to pregenerate each axis to get it's bounds and
// position it and the labels correctly on the plot.
@@ -4604,10 +6148,16 @@
var temp;
// Added for theming.
if (this._elem) {
- this._elem.empty();
+ // Memory Leaks patch
+ //this._elem.empty();
+ this._elem.emptyForce();
+ this._elem = null;
}
- this._elem = $('<div class="jqplot-axis jqplot-'+this.name+'" style="position:absolute;"></div>');
+ this._elem = $(document.createElement('div'));
+ this._elem.addClass('jqplot-axis jqplot-'+this.name);
+ this._elem.css('position', 'absolute');
+
if (this.name == 'xaxis' || this.name == 'x2axis') {
this._elem.width(this._plotDimensions.width);
@@ -4620,28 +6170,36 @@
this.labelOptions.axis = this.name;
this._label = new this.labelRenderer(this.labelOptions);
if (this._label.show) {
- var elem = this._label.draw(ctx);
+ var elem = this._label.draw(ctx, plot);
elem.appendTo(this._elem);
+ elem = null;
}
var t = this._ticks;
+ var tick;
for (var i=0; i<t.length; i++) {
- var tick = t[i];
- if (tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) {
- var elem = tick.draw(ctx);
- elem.appendTo(this._elem);
+ tick = t[i];
+ if (tick.show && tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) {
+ this._elem.append(tick.draw(ctx, plot));
}
}
+ tick = null;
+ t = null;
}
return this._elem;
};
// called with scope of an axis
$.jqplot.LinearAxisRenderer.prototype.reset = function() {
- this.min = this._min;
- this.max = this._max;
- this.tickInterval = this._tickInterval;
- this.numberTicks = this._numberTicks;
+ this.min = this._options.min;
+ this.max = this._options.max;
+ this.tickInterval = this._options.tickInterval;
+ this.numberTicks = this._options.numberTicks;
+ this._autoFormatString = '';
+ if (this._overrideFormatString && this.tickOptions && this.tickOptions.formatString) {
+ this.tickOptions.formatString = '';
+ }
+
// this._ticks = this.__ticks;
};
@@ -4654,9 +6212,10 @@
var lshow = (this._label == null) ? false : this._label.show;
if (this.show) {
var t = this._ticks;
+ var tick;
for (var i=0; i<t.length; i++) {
- var tick = t[i];
- if (tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) {
+ tick = t[i];
+ if (!tick._breakTick && tick.show && tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) {
if (this.name == 'xaxis' || this.name == 'x2axis') {
temp = tick._elem.outerHeight(true);
}
@@ -4668,6 +6227,8 @@
}
}
}
+ tick = null;
+ t = null;
if (lshow) {
w = this._label._elem.outerWidth(true);
@@ -4699,14 +6260,15 @@
};
// called with scope of axis
- $.jqplot.LinearAxisRenderer.prototype.createTicks = function() {
+ $.jqplot.LinearAxisRenderer.prototype.createTicks = function(plot) {
// we're are operating on an axis here
var ticks = this._ticks;
var userTicks = this.ticks;
var name = this.name;
// databounds were set on axis initialization.
var db = this._dataBounds;
- var dim, interval;
+ var dim = (this.name.charAt(0) === 'x') ? this._plotDimensions.width : this._plotDimensions.height;
+ var interval;
var min, max;
var pos1, pos2;
var tt, i;
@@ -4715,6 +6277,9 @@
var userMax = this.max;
var userNT = this.numberTicks;
var userTI = this.tickInterval;
+
+ var threshold = 30;
+ this._scalefact = (Math.max(dim, threshold+1) - threshold)/300.0;
// if we already have ticks, use them.
// ticks must be in order of increasing value.
@@ -4724,15 +6289,51 @@
for (i=0; i<userTicks.length; i++){
var ut = userTicks[i];
var t = new this.tickRenderer(this.tickOptions);
- if (ut.constructor == Array) {
+ if ($.isArray(ut)) {
t.value = ut[0];
- t.label = ut[1];
+ if (this.breakPoints) {
+ if (ut[0] == this.breakPoints[0]) {
+ t.label = this.breakTickLabel;
+ t._breakTick = true;
+ t.showGridline = false;
+ t.showMark = false;
+ }
+ else if (ut[0] > this.breakPoints[0] && ut[0] <= this.breakPoints[1]) {
+ t.show = false;
+ t.showGridline = false;
+ t.label = ut[1];
+ }
+ else {
+ t.label = ut[1];
+ }
+ }
+ else {
+ t.label = ut[1];
+ }
t.setTick(ut[0], this.name);
this._ticks.push(t);
}
+
+ else if ($.isPlainObject(ut)) {
+ $.extend(true, t, ut);
+ t.axis = this.name;
+ this._ticks.push(t);
+ }
else {
t.value = ut;
+ if (this.breakPoints) {
+ if (ut == this.breakPoints[0]) {
+ t.label = this.breakTickLabel;
+ t._breakTick = true;
+ t.showGridline = false;
+ t.showMark = false;
+ }
+ else if (ut > this.breakPoints[0] && ut <= this.breakPoints[1]) {
+ t.show = false;
+ t.showGridline = false;
+ }
+ }
t.setTick(ut, this.name);
this._ticks.push(t);
}
@@ -4751,290 +6352,464 @@
else {
dim = this._plotDimensions.height;
}
-
- // if min, max and number of ticks specified, user can't specify interval.
- if (!this.autoscale && this.min != null && this.max != null && this.numberTicks != null) {
- this.tickInterval = null;
+
+ var _numberTicks = this.numberTicks;
+
+ // if aligning this axis, use number of ticks from previous axis.
+ // Do I need to reset somehow if alignTicks is changed and then graph is replotted??
+ if (this.alignTicks) {
+ if (this.name === 'x2axis' && plot.axes.xaxis.show) {
+ _numberTicks = plot.axes.xaxis.numberTicks;
+ }
+ else if (this.name.charAt(0) === 'y' && this.name !== 'yaxis' && this.name !== 'yMidAxis' && plot.axes.yaxis.show) {
+ _numberTicks = plot.axes.yaxis.numberTicks;
+ }
}
-
- // if max, min, and interval specified and interval won't fit, ignore interval.
- // if (this.min != null && this.max != null && this.tickInterval != null) {
- // if (parseInt((this.max-this.min)/this.tickInterval, 10) != (this.max-this.min)/this.tickInterval) {
- // this.tickInterval = null;
- // }
- // }
min = ((this.min != null) ? this.min : db.min);
max = ((this.max != null) ? this.max : db.max);
-
- // if min and max are same, space them out a bit
- if (min == max) {
- var adj = 0.05;
- if (min > 0) {
- adj = Math.max(Math.log(min)/Math.LN10, 0.05);
- }
- min -= adj;
- max += adj;
- }
var range = max - min;
var rmin, rmax;
var temp;
-
- // autoscale. Can't autoscale if min or max is supplied.
- // Will use numberTicks and tickInterval if supplied. Ticks
- // across multiple axes may not line up depending on how
- // bars are to be plotted.
- if (this.autoscale && this.min == null && this.max == null) {
- var rrange, ti, margin;
- var forceMinZero = false;
- var forceZeroLine = false;
- var intervals = {min:null, max:null, average:null, stddev:null};
- // if any series are bars, or if any are fill to zero, and if this
- // is the axis to fill toward, check to see if we can start axis at zero.
- for (var i=0; i<this._series.length; i++) {
- var s = this._series[i];
- var faname = (s.fillAxis == 'x') ? s._xaxis.name : s._yaxis.name;
- // check to see if this is the fill axis
- if (this.name == faname) {
- var vals = s._plotValues[s.fillAxis];
- var vmin = vals[0];
- var vmax = vals[0];
- for (var j=1; j<vals.length; j++) {
- if (vals[j] < vmin) {
- vmin = vals[j];
+
+ if (this.tickOptions == null || !this.tickOptions.formatString) {
+ this._overrideFormatString = true;
+ }
+
+ // Doing complete autoscaling
+ if (this.min == null || this.max == null && this.tickInterval == null && !this.autoscale) {
+ // Check if user must have tick at 0 or 100 and ensure they are in range.
+ // The autoscaling algorithm will always place ticks at 0 and 100 if they are in range.
+ if (this.forceTickAt0) {
+ if (min > 0) {
+ min = 0;
+ }
+ if (max < 0) {
+ max = 0;
+ }
+ }
+
+ if (this.forceTickAt100) {
+ if (min > 100) {
+ min = 100;
+ }
+ if (max < 100) {
+ max = 100;
+ }
+ }
+
+ var keepMin = false,
+ keepMax = false;
+
+ if (this.min != null) {
+ keepMin = true;
+ }
+
+ else if (this.max != null) {
+ keepMax = true;
+ }
+
+ // var threshold = 30;
+ // var tdim = Math.max(dim, threshold+1);
+ // this._scalefact = (tdim-threshold)/300.0;
+ var ret = $.jqplot.LinearTickGenerator(min, max, this._scalefact, _numberTicks, keepMin, keepMax);
+ // calculate a padded max and min, points should be less than these
+ // so that they aren't too close to the edges of the plot.
+ // User can adjust how much padding is allowed with pad, padMin and PadMax options.
+ // If min or max is set, don't pad that end of axis.
+ var tumin = (this.min != null) ? min : min + range*(this.padMin - 1);
+ var tumax = (this.max != null) ? max : max - range*(this.padMax - 1);
+
+ // if they're equal, we shouldn't have to do anything, right?
+ // if (min <=tumin || max >= tumax) {
+ if (min <tumin || max > tumax) {
+ tumin = (this.min != null) ? min : min - range*(this.padMin - 1);
+ tumax = (this.max != null) ? max : max + range*(this.padMax - 1);
+ ret = $.jqplot.LinearTickGenerator(tumin, tumax, this._scalefact, _numberTicks, keepMin, keepMax);
+ }
+
+ this.min = ret[0];
+ this.max = ret[1];
+ // if numberTicks specified, it should return the same.
+ this.numberTicks = ret[2];
+ this._autoFormatString = ret[3];
+ this.tickInterval = ret[4];
+ }
+
+ // User has specified some axis scale related option, can use auto algorithm
+ else {
+
+ // if min and max are same, space them out a bit
+ if (min == max) {
+ var adj = 0.05;
+ if (min > 0) {
+ adj = Math.max(Math.log(min)/Math.LN10, 0.05);
+ }
+ min -= adj;
+ max += adj;
+ }
+
+ // autoscale. Can't autoscale if min or max is supplied.
+ // Will use numberTicks and tickInterval if supplied. Ticks
+ // across multiple axes may not line up depending on how
+ // bars are to be plotted.
+ if (this.autoscale && this.min == null && this.max == null) {
+ var rrange, ti, margin;
+ var forceMinZero = false;
+ var forceZeroLine = false;
+ var intervals = {min:null, max:null, average:null, stddev:null};
+ // if any series are bars, or if any are fill to zero, and if this
+ // is the axis to fill toward, check to see if we can start axis at zero.
+ for (var i=0; i<this._series.length; i++) {
+ var s = this._series[i];
+ var faname = (s.fillAxis == 'x') ? s._xaxis.name : s._yaxis.name;
+ // check to see if this is the fill axis
+ if (this.name == faname) {
+ var vals = s._plotValues[s.fillAxis];
+ var vmin = vals[0];
+ var vmax = vals[0];
+ for (var j=1; j<vals.length; j++) {
+ if (vals[j] < vmin) {
+ vmin = vals[j];
+ }
+ else if (vals[j] > vmax) {
+ vmax = vals[j];
+ }
}
- else if (vals[j] > vmax) {
- vmax = vals[j];
+ var dp = (vmax - vmin) / vmax;
+ // is this sries a bar?
+ if (s.renderer.constructor == $.jqplot.BarRenderer) {
+ // if no negative values and could also check range.
+ if (vmin >= 0 && (s.fillToZero || dp > 0.1)) {
+ forceMinZero = true;
+ }
+ else {
+ forceMinZero = false;
+ if (s.fill && s.fillToZero && vmin < 0 && vmax > 0) {
+ forceZeroLine = true;
+ }
+ else {
+ forceZeroLine = false;
+ }
+ }
}
- }
- var dp = (vmax - vmin) / vmax;
- // is this sries a bar?
- if (s.renderer.constructor == $.jqplot.BarRenderer) {
- // if no negative values and could also check range.
- if (vmin >= 0 && (s.fillToZero || dp > 0.1)) {
- forceMinZero = true;
- }
- else {
- forceMinZero = false;
- if (s.fill && s.fillToZero && vmin < 0 && vmax > 0) {
+
+ // if not a bar and filling, use appropriate method.
+ else if (s.fill) {
+ if (vmin >= 0 && (s.fillToZero || dp > 0.1)) {
+ forceMinZero = true;
+ }
+ else if (vmin < 0 && vmax > 0 && s.fillToZero) {
+ forceMinZero = false;
forceZeroLine = true;
}
else {
+ forceMinZero = false;
forceZeroLine = false;
}
}
+
+ // if not a bar and not filling, only change existing state
+ // if it doesn't make sense
+ else if (vmin < 0) {
+ forceMinZero = false;
+ }
}
-
- // if not a bar and filling, use appropriate method.
- else if (s.fill) {
- if (vmin >= 0 && (s.fillToZero || dp > 0.1)) {
- forceMinZero = true;
+ }
+
+ // check if we need make axis min at 0.
+ if (forceMinZero) {
+ // compute number of ticks
+ this.numberTicks = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing);
+ this.min = 0;
+ userMin = 0;
+ // what order is this range?
+ // what tick interval does that give us?
+ ti = max/(this.numberTicks-1);
+ temp = Math.pow(10, Math.abs(Math.floor(Math.log(ti)/Math.LN10)));
+ if (ti/temp == parseInt(ti/temp, 10)) {
+ ti += temp;
+ }
+ this.tickInterval = Math.ceil(ti/temp) * temp;
+ this.max = this.tickInterval * (this.numberTicks - 1);
+ }
+
+ // check if we need to make sure there is a tick at 0.
+ else if (forceZeroLine) {
+ // compute number of ticks
+ this.numberTicks = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing);
+ var ntmin = Math.ceil(Math.abs(min)/range*(this.numberTicks-1));
+ var ntmax = this.numberTicks - 1 - ntmin;
+ ti = Math.max(Math.abs(min/ntmin), Math.abs(max/ntmax));
+ temp = Math.pow(10, Math.abs(Math.floor(Math.log(ti)/Math.LN10)));
+ this.tickInterval = Math.ceil(ti/temp) * temp;
+ this.max = this.tickInterval * ntmax;
+ this.min = -this.tickInterval * ntmin;
+ }
+
+ // if nothing else, do autoscaling which will try to line up ticks across axes.
+ else {
+ if (this.numberTicks == null){
+ if (this.tickInterval) {
+ this.numberTicks = 3 + Math.ceil(range / this.tickInterval);
}
- else if (vmin < 0 && vmax > 0 && s.fillToZero) {
- forceMinZero = false;
- forceZeroLine = true;
+ else {
+ this.numberTicks = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing);
}
+ }
+
+ if (this.tickInterval == null) {
+ // get a tick interval
+ ti = range/(this.numberTicks - 1);
+
+ if (ti < 1) {
+ temp = Math.pow(10, Math.abs(Math.floor(Math.log(ti)/Math.LN10)));
+ }
else {
- forceMinZero = false;
- forceZeroLine = false;
+ temp = 1;
}
+ this.tickInterval = Math.ceil(ti*temp*this.pad)/temp;
}
+ else {
+ temp = 1 / this.tickInterval;
+ }
- // if not a bar and not filling, only change existing state
- // if it doesn't make sense
- else if (vmin < 0) {
- forceMinZero = false;
+ // try to compute a nicer, more even tick interval
+ // temp = Math.pow(10, Math.floor(Math.log(ti)/Math.LN10));
+ // this.tickInterval = Math.ceil(ti/temp) * temp;
+ rrange = this.tickInterval * (this.numberTicks - 1);
+ margin = (rrange - range)/2;
+
+ if (this.min == null) {
+ this.min = Math.floor(temp*(min-margin))/temp;
}
+ if (this.max == null) {
+ this.max = this.min + rrange;
+ }
}
- }
-
- // check if we need make axis min at 0.
- if (forceMinZero) {
- // compute number of ticks
- this.numberTicks = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing);
- this.min = 0;
- userMin = 0;
- // what order is this range?
- // what tick interval does that give us?
- ti = max/(this.numberTicks-1);
- temp = Math.pow(10, Math.abs(Math.floor(Math.log(ti)/Math.LN10)));
- if (ti/temp == parseInt(ti/temp, 10)) {
- ti += temp;
+
+ // Compute a somewhat decent format string if it is needed.
+ // get precision of interval and determine a format string.
+ var sf = $.jqplot.getSignificantFigures(this.tickInterval);
+
+ var fstr;
+
+ // if we have only a whole number, use integer formatting
+ if (sf.digitsLeft >= sf.significantDigits) {
+ fstr = '%d';
}
- this.tickInterval = Math.ceil(ti/temp) * temp;
- this.max = this.tickInterval * (this.numberTicks - 1);
+
+ else {
+ var temp = Math.max(0, 5 - sf.digitsLeft);
+ temp = Math.min(temp, sf.digitsRight);
+ fstr = '%.'+ temp + 'f';
+ }
+
+ this._autoFormatString = fstr;
}
- // check if we need to make sure there is a tick at 0.
- else if (forceZeroLine) {
- // compute number of ticks
- this.numberTicks = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing);
- var ntmin = Math.ceil(Math.abs(min)/range*(this.numberTicks-1));
- var ntmax = this.numberTicks - 1 - ntmin;
- ti = Math.max(Math.abs(min/ntmin), Math.abs(max/ntmax));
- temp = Math.pow(10, Math.abs(Math.floor(Math.log(ti)/Math.LN10)));
- this.tickInterval = Math.ceil(ti/temp) * temp;
- this.max = this.tickInterval * ntmax;
- this.min = -this.tickInterval * ntmin;
- }
-
- // if nothing else, do autoscaling which will try to line up ticks across axes.
- else {
+ // Use the default algorithm which pads each axis to make the chart
+ // centered nicely on the grid.
+ else {
+
+ rmin = (this.min != null) ? this.min : min - range*(this.padMin - 1);
+ rmax = (this.max != null) ? this.max : max + range*(this.padMax - 1);
+ range = rmax - rmin;
+
if (this.numberTicks == null){
- if (this.tickInterval) {
- this.numberTicks = 3 + Math.ceil(range / this.tickInterval);
+ // if tickInterval is specified by user, we will ignore computed maximum.
+ // max will be equal or greater to fit even # of ticks.
+ if (this.tickInterval != null) {
+ this.numberTicks = Math.ceil((rmax - rmin)/this.tickInterval)+1;
}
+ else if (dim > 100) {
+ this.numberTicks = parseInt(3+(dim-100)/75, 10);
+ }
else {
- this.numberTicks = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing);
+ this.numberTicks = 2;
}
}
-
+
if (this.tickInterval == null) {
- // get a tick interval
- ti = range/(this.numberTicks - 1);
-
- if (ti < 1) {
- temp = Math.pow(10, Math.abs(Math.floor(Math.log(ti)/Math.LN10)));
- }
- else {
- temp = 1;
- }
- this.tickInterval = Math.ceil(ti*temp*this.pad)/temp;
+ this.tickInterval = range / (this.numberTicks-1);
}
- else {
- temp = 1 / this.tickInterval;
- }
- // try to compute a nicer, more even tick interval
- // temp = Math.pow(10, Math.floor(Math.log(ti)/Math.LN10));
- // this.tickInterval = Math.ceil(ti/temp) * temp;
- rrange = this.tickInterval * (this.numberTicks - 1);
- margin = (rrange - range)/2;
-
+ if (this.max == null) {
+ rmax = rmin + this.tickInterval*(this.numberTicks - 1);
+ }
if (this.min == null) {
- this.min = Math.floor(temp*(min-margin))/temp;
+ rmin = rmax - this.tickInterval*(this.numberTicks - 1);
}
- if (this.max == null) {
- this.max = this.min + rrange;
+
+ // get precision of interval and determine a format string.
+ var sf = $.jqplot.getSignificantFigures(this.tickInterval);
+
+ var fstr;
+
+ // if we have only a whole number, use integer formatting
+ if (sf.digitsLeft >= sf.significantDigits) {
+ fstr = '%d';
}
- }
- }
-
- // Use the default algorithm which pads each axis to make the chart
- // centered nicely on the grid.
- else {
- rmin = (this.min != null) ? this.min : min - range*(this.padMin - 1);
- rmax = (this.max != null) ? this.max : max + range*(this.padMax - 1);
- this.min = rmin;
- this.max = rmax;
- range = this.max - this.min;
-
- if (this.numberTicks == null){
- // if tickInterval is specified by user, we will ignore computed maximum.
- // max will be equal or greater to fit even # of ticks.
- if (this.tickInterval != null) {
- this.numberTicks = Math.ceil((this.max - this.min)/this.tickInterval)+1;
- this.max = this.min + this.tickInterval*(this.numberTicks-1);
- }
- else if (dim > 100) {
- this.numberTicks = parseInt(3+(dim-100)/75, 10);
- }
+
else {
- this.numberTicks = 2;
+ var temp = Math.max(0, 5 - sf.digitsLeft);
+ temp = Math.min(temp, sf.digitsRight);
+ fstr = '%.'+ temp + 'f';
}
+
+
+ this._autoFormatString = fstr;
+
+ this.min = rmin;
+ this.max = rmax;
}
-
- if (this.tickInterval == null) {
- this.tickInterval = range / (this.numberTicks-1);
- }
- }
-
- if (this.renderer.constructor == $.jqplot.LinearAxisRenderer) {
- // fix for misleading tick display with small range and low precision.
- range = this.max - this.min;
- // figure out precision
- var temptick = new this.tickRenderer(this.tickOptions);
- // use the tick formatString or, the default.
- var fs = temptick.formatString || $.jqplot.config.defaultTickFormatString;
- var fs = fs.match($.jqplot.sprintf.regex)[0];
- var precision = 0;
- if (fs) {
- if (fs.search(/[fFeEgGpP]/) > -1) {
- var m = fs.match(/\%\.(\d{0,})?[eEfFgGpP]/);
- if (m) precision = parseInt(m[1], 10);
- else precision = 6;
- }
- else if (fs.search(/[di]/) > -1) {
- precision = 0;
- }
- // fact will be <= 1;
- var fact = Math.pow(10, -precision);
- if (this.tickInterval < fact) {
- // need to correct underrange
- if (userNT == null && userTI == null) {
- this.tickInterval = fact;
- if (userMax == null && userMin == null) {
- // this.min = Math.floor((this._dataBounds.min - this.tickInterval)/fact) * fact;
- this.min = Math.floor(this._dataBounds.min/fact) * fact;
- if (this.min == this._dataBounds.min) {
- this.min = this._dataBounds.min - this.tickInterval;
- }
- // this.max = Math.ceil((this._dataBounds.max + this.tickInterval)/fact) * fact;
- this.max = Math.ceil(this._dataBounds.max/fact) * fact;
- if (this.max == this._dataBounds.max) {
- this.max = this._dataBounds.max + this.tickInterval;
- }
- var n = (this.max - this.min)/this.tickInterval;
- n = n.toFixed(11);
- n = Math.ceil(n);
- this.numberTicks = n + 1;
+
+ if (this.renderer.constructor == $.jqplot.LinearAxisRenderer && this._autoFormatString == '') {
+ // fix for misleading tick display with small range and low precision.
+ range = this.max - this.min;
+ // figure out precision
+ var temptick = new this.tickRenderer(this.tickOptions);
+ // use the tick formatString or, the default.
+ var fs = temptick.formatString || $.jqplot.config.defaultTickFormatString;
+ var fs = fs.match($.jqplot.sprintf.regex)[0];
+ var precision = 0;
+ if (fs) {
+ if (fs.search(/[fFeEgGpP]/) > -1) {
+ var m = fs.match(/\%\.(\d{0,})?[eEfFgGpP]/);
+ if (m) {
+ precision = parseInt(m[1], 10);
}
- else if (userMax == null) {
- // add one tick for top of range.
- var n = (this._dataBounds.max - this.min) / this.tickInterval;
- n = n.toFixed(11);
- this.numberTicks = Math.ceil(n) + 2;
- this.max = this.min + this.tickInterval * (this.numberTicks-1);
- }
- else if (userMin == null) {
- // add one tick for bottom of range.
- var n = (this.max - this._dataBounds.min) / this.tickInterval;
- n = n.toFixed(11);
- this.numberTicks = Math.ceil(n) + 2;
- this.min = this.max - this.tickInterval * (this.numberTicks-1);
- }
else {
- // calculate a number of ticks so max is within axis scale
- this.numberTicks = Math.ceil((userMax - userMin)/this.tickInterval) + 1;
- // if user's min and max don't fit evenly in ticks, adjust.
- // This takes care of cases such as user min set to 0, max set to 3.5 but tick
- // format string set to %d (integer ticks)
- this.min = Math.floor(userMin*Math.pow(10, precision))/Math.pow(10, precision);
- this.max = Math.ceil(userMax*Math.pow(10, precision))/Math.pow(10, precision);
- // this.max = this.min + this.tickInterval*(this.numberTicks-1);
- this.numberTicks = Math.ceil((this.max - this.min)/this.tickInterval) + 1;
+ precision = 6;
}
}
+ else if (fs.search(/[di]/) > -1) {
+ precision = 0;
+ }
+ // fact will be <= 1;
+ var fact = Math.pow(10, -precision);
+ if (this.tickInterval < fact) {
+ // need to correct underrange
+ if (userNT == null && userTI == null) {
+ this.tickInterval = fact;
+ if (userMax == null && userMin == null) {
+ // this.min = Math.floor((this._dataBounds.min - this.tickInterval)/fact) * fact;
+ this.min = Math.floor(this._dataBounds.min/fact) * fact;
+ if (this.min == this._dataBounds.min) {
+ this.min = this._dataBounds.min - this.tickInterval;
+ }
+ // this.max = Math.ceil((this._dataBounds.max + this.tickInterval)/fact) * fact;
+ this.max = Math.ceil(this._dataBounds.max/fact) * fact;
+ if (this.max == this._dataBounds.max) {
+ this.max = this._dataBounds.max + this.tickInterval;
+ }
+ var n = (this.max - this.min)/this.tickInterval;
+ n = n.toFixed(11);
+ n = Math.ceil(n);
+ this.numberTicks = n + 1;
+ }
+ else if (userMax == null) {
+ // add one tick for top of range.
+ var n = (this._dataBounds.max - this.min) / this.tickInterval;
+ n = n.toFixed(11);
+ this.numberTicks = Math.ceil(n) + 2;
+ this.max = this.min + this.tickInterval * (this.numberTicks-1);
+ }
+ else if (userMin == null) {
+ // add one tick for bottom of range.
+ var n = (this.max - this._dataBounds.min) / this.tickInterval;
+ n = n.toFixed(11);
+ this.numberTicks = Math.ceil(n) + 2;
+ this.min = this.max - this.tickInterval * (this.numberTicks-1);
+ }
+ else {
+ // calculate a number of ticks so max is within axis scale
+ this.numberTicks = Math.ceil((userMax - userMin)/this.tickInterval) + 1;
+ // if user's min and max don't fit evenly in ticks, adjust.
+ // This takes care of cases such as user min set to 0, max set to 3.5 but tick
+ // format string set to %d (integer ticks)
+ this.min = Math.floor(userMin*Math.pow(10, precision))/Math.pow(10, precision);
+ this.max = Math.ceil(userMax*Math.pow(10, precision))/Math.pow(10, precision);
+ // this.max = this.min + this.tickInterval*(this.numberTicks-1);
+ this.numberTicks = Math.ceil((this.max - this.min)/this.tickInterval) + 1;
+ }
+ }
+ }
}
}
+
}
-
+ if (this._overrideFormatString && this._autoFormatString != '') {
+ this.tickOptions = this.tickOptions || {};
+ this.tickOptions.formatString = this._autoFormatString;
+ }
+ var t, to;
for (var i=0; i<this.numberTicks; i++){
tt = this.min + i * this.tickInterval;
- var t = new this.tickRenderer(this.tickOptions);
+ t = new this.tickRenderer(this.tickOptions);
// var t = new $.jqplot.AxisTickRenderer(this.tickOptions);
t.setTick(tt, this.name);
this._ticks.push(t);
+
+ if (i < this.numberTicks - 1) {
+ for (var j=0; j<this.minorTicks; j++) {
+ tt += this.tickInterval/(this.minorTicks+1);
+ to = $.extend(true, {}, this.tickOptions, {name:this.name, value:tt, label:'', isMinorTick:true});
+ t = new this.tickRenderer(to);
+ this._ticks.push(t);
+ }
+ }
+ t = null;
}
}
+
+ if (this.tickInset) {
+ this.min = this.min - this.tickInset * this.tickInterval;
+ this.max = this.max + this.tickInset * this.tickInterval;
+ }
+
+ ticks = null;
};
+ // Used to reset just the values of the ticks and then repack, which will
+ // recalculate the positioning functions. It is assuemd that the
+ // number of ticks is the same and the values of the new array are at the
+ // proper interval.
+ // This method needs to be called with the scope of an axis object, like:
+ //
+ // > plot.axes.yaxis.renderer.resetTickValues.call(plot.axes.yaxis, yarr);
+ //
+ $.jqplot.LinearAxisRenderer.prototype.resetTickValues = function(opts) {
+ if ($.isArray(opts) && opts.length == this._ticks.length) {
+ var t;
+ for (var i=0; i<opts.length; i++) {
+ t = this._ticks[i];
+ t.value = opts[i];
+ t.label = t.formatter(t.formatString, opts[i]);
+ t.label = t.prefix + t.label;
+ t._elem.html(t.label);
+ }
+ t = null;
+ this.min = $.jqplot.arrayMin(opts);
+ this.max = $.jqplot.arrayMax(opts);
+ this.pack();
+ }
+ // Not implemented yet.
+ // else if ($.isPlainObject(opts)) {
+ //
+ // }
+ };
+
// called with scope of axis
$.jqplot.LinearAxisRenderer.prototype.pack = function(pos, offsets) {
+ // Add defaults for repacking from resetTickValues function.
+ pos = pos || {};
+ offsets = offsets || this._offsets;
+
var ticks = this._ticks;
var max = this.max;
var min = this.min;
@@ -5052,35 +6827,90 @@
var unitlength = max - min;
// point to unit and unit to point conversions references to Plot DOM element top left corner.
- this.p2u = function(p){
- return (p - offmin) * unitlength / pixellength + min;
- };
+ if (this.breakPoints) {
+ unitlength = unitlength - this.breakPoints[1] + this.breakPoints[0];
+
+ this.p2u = function(p){
+ return (p - offmin) * unitlength / pixellength + min;
+ };
- this.u2p = function(u){
- return (u - min) * pixellength / unitlength + offmin;
- };
+ this.u2p = function(u){
+ if (u > this.breakPoints[0] && u < this.breakPoints[1]){
+ u = this.breakPoints[0];
+ }
+ if (u <= this.breakPoints[0]) {
+ return (u - min) * pixellength / unitlength + offmin;
+ }
+ else {
+ return (u - this.breakPoints[1] + this.breakPoints[0] - min) * pixellength / unitlength + offmin;
+ }
+ };
- if (this.name == 'xaxis' || this.name == 'x2axis'){
- this.series_u2p = function(u){
- return (u - min) * pixellength / unitlength;
- };
- this.series_p2u = function(p){
- return p * unitlength / pixellength + min;
- };
+ if (this.name.charAt(0) == 'x'){
+ this.series_u2p = function(u){
+ if (u > this.breakPoints[0] && u < this.breakPoints[1]){
+ u = this.breakPoints[0];
+ }
+ if (u <= this.breakPoints[0]) {
+ return (u - min) * pixellength / unitlength;
+ }
+ else {
+ return (u - this.breakPoints[1] + this.breakPoints[0] - min) * pixellength / unitlength;
+ }
+ };
+ this.series_p2u = function(p){
+ return p * unitlength / pixellength + min;
+ };
+ }
+
+ else {
+ this.series_u2p = function(u){
+ if (u > this.breakPoints[0] && u < this.breakPoints[1]){
+ u = this.breakPoints[0];
+ }
+ if (u >= this.breakPoints[1]) {
+ return (u - max) * pixellength / unitlength;
+ }
+ else {
+ return (u + this.breakPoints[1] - this.breakPoints[0] - max) * pixellength / unitlength;
+ }
+ };
+ this.series_p2u = function(p){
+ return p * unitlength / pixellength + max;
+ };
+ }
}
-
else {
- this.series_u2p = function(u){
- return (u - max) * pixellength / unitlength;
+ this.p2u = function(p){
+ return (p - offmin) * unitlength / pixellength + min;
};
- this.series_p2u = function(p){
- return p * unitlength / pixellength + max;
+
+ this.u2p = function(u){
+ return (u - min) * pixellength / unitlength + offmin;
};
+
+ if (this.name == 'xaxis' || this.name == 'x2axis'){
+ this.series_u2p = function(u){
+ return (u - min) * pixellength / unitlength;
+ };
+ this.series_p2u = function(p){
+ return p * unitlength / pixellength + min;
+ };
+ }
+
+ else {
+ this.series_u2p = function(u){
+ return (u - max) * pixellength / unitlength;
+ };
+ this.series_p2u = function(p){
+ return p * unitlength / pixellength + max;
+ };
+ }
}
if (this.show) {
if (this.name == 'xaxis' || this.name == 'x2axis') {
- for (i=0; i<ticks.length; i++) {
+ for (var i=0; i<ticks.length; i++) {
var t = ticks[i];
if (t.show && t.showLabel) {
var shim;
@@ -5134,7 +6964,7 @@
}
}
else {
- for (i=0; i<ticks.length; i++) {
+ for (var i=0; i<ticks.length; i++) {
var t = ticks[i];
if (t.show && t.showLabel) {
var shim;
@@ -5196,9 +7026,373 @@
}
}
}
+
+ ticks = null;
};
+ /**
+ * The following code was generaously given to me a while back by Scott Prahl.
+ * He did a good job at computing axes min, max and number of ticks for the
+ * case where the user has not set any scale related parameters (tickInterval,
+ * numberTicks, min or max). I had ignored this use case for a long time,
+ * focusing on the more difficult case where user has set some option controlling
+ * tick generation. Anyway, about time I got this into jqPlot.
+ * Thanks Scott!!
+ */
+
+ /**
+ * Copyright (c) 2010 Scott Prahl
+ * The next three routines are currently available for use in all personal
+ * or commercial projects under both the MIT and GPL version 2.0 licenses.
+ * This means that you can choose the license that best suits your project
+ * and use it accordingly.
+ */
+
+ // A good format string depends on the interval. If the interval is greater
+ // than 1 then there is no need to show any decimal digits. If it is < 1.0, then
+ // use the magnitude of the interval to determine the number of digits to show.
+ function bestFormatString (interval)
+ {
+ var fstr;
+ interval = Math.abs(interval);
+ if (interval >= 10) {
+ fstr = '%d';
+ }
+
+ else if (interval > 1) {
+ if (interval === parseInt(interval, 10)) {
+ fstr = '%d';
+ }
+ else {
+ fstr = '%.1f';
+ }
+ }
+
+ else {
+ var expv = -Math.floor(Math.log(interval)/Math.LN10);
+ fstr = '%.' + expv + 'f';
+ }
+
+ return fstr;
+ }
+
+ var _factors = [0.1, 0.2, 0.3, 0.4, 0.5, 0.8, 1, 2, 3, 4, 5];
+
+ var _getLowerFactor = function(f) {
+ var i = _factors.indexOf(f);
+ if (i > 0) {
+ return _factors[i-1];
+ }
+ else {
+ return _factors[_factors.length - 1] / 100;
+ }
+ };
+
+ var _getHigherFactor = function(f) {
+ var i = _factors.indexOf(f);
+ if (i < _factors.length-1) {
+ return _factors[i+1];
+ }
+ else {
+ return _factors[0] * 100;
+ }
+ };
+
+ // Given a fixed minimum and maximum and a target number ot ticks
+ // figure out the best interval and
+ // return min, max, number ticks, format string and tick interval
+ function bestConstrainedInterval(min, max, nttarget) {
+ // run through possible number to ticks and see which interval is best
+ var low = Math.floor(nttarget/2);
+ var hi = Math.ceil(nttarget*1.5);
+ var badness = Number.MAX_VALUE;
+ var r = (max - min);
+ var temp;
+ var sd;
+ var bestNT;
+ var gsf = $.jqplot.getSignificantFigures;
+ var fsd;
+ var fs;
+ var currentNT;
+ var bestPrec;
+
+ for (var i=0, l=hi-low+1; i<l; i++) {
+ currentNT = low + i;
+ temp = r/(currentNT-1);
+ sd = gsf(temp);
+
+ temp = Math.abs(nttarget - currentNT) + sd.digitsRight;
+ if (temp < badness) {
+ badness = temp;
+ bestNT = currentNT;
+ bestPrec = sd.digitsRight;
+ }
+ else if (temp === badness) {
+ // let nicer ticks trump number ot ticks
+ if (sd.digitsRight < bestPrec) {
+ bestNT = currentNT;
+ bestPrec = sd.digitsRight;
+ }
+ }
+
+ }
+
+ fsd = Math.max(bestPrec, Math.max(gsf(min).digitsRight, gsf(max).digitsRight));
+ if (fsd === 0) {
+ fs = '%d';
+ }
+ else {
+ fs = '%.' + fsd + 'f';
+ }
+ temp = r / (bestNT - 1);
+ // min, max, number ticks, format string, tick interval
+ return [min, max, bestNT, fs, temp];
+ }
+
+ // This will return an interval of form 2 * 10^n, 5 * 10^n or 10 * 10^n
+ // it is based soley on the range and number of ticks. So if user specifies
+ // number of ticks, use this.
+ function bestInterval(range, numberTicks) {
+ numberTicks = numberTicks || 7;
+ var minimum = range / (numberTicks - 1);
+ var magnitude = Math.pow(10, Math.floor(Math.log(minimum) / Math.LN10));
+ var residual = minimum / magnitude;
+ var interval;
+ // "nicest" ranges are 1, 2, 5 or powers of these.
+ // for magnitudes below 1, only allow these.
+ if (magnitude < 1) {
+ if (residual > 5) {
+ interval = 10 * magnitude;
+ }
+ else if (residual > 2) {
+ interval = 5 * magnitude;
+ }
+ else if (residual > 1) {
+ interval = 2 * magnitude;
+ }
+ else {
+ interval = magnitude;
+ }
+ }
+ // for large ranges (whole integers), allow intervals like 3, 4 or powers of these.
+ // this helps a lot with poor choices for number of ticks.
+ else {
+ if (residual > 5) {
+ interval = 10 * magnitude;
+ }
+ else if (residual > 4) {
+ interval = 5 * magnitude;
+ }
+ else if (residual > 3) {
+ interval = 4 * magnitude;
+ }
+ else if (residual > 2) {
+ interval = 3 * magnitude;
+ }
+ else if (residual > 1) {
+ interval = 2 * magnitude;
+ }
+ else {
+ interval = magnitude;
+ }
+ }
+
+ return interval;
+ }
+
+ // This will return an interval of form 2 * 10^n, 5 * 10^n or 10 * 10^n
+ // it is based soley on the range of data, number of ticks must be computed later.
+ function bestLinearInterval(range, scalefact) {
+ scalefact = scalefact || 1;
+ var expv = Math.floor(Math.log(range)/Math.LN10);
+ var magnitude = Math.pow(10, expv);
+ // 0 < f < 10
+ var f = range / magnitude;
+ var fact;
+ // for large plots, scalefact will decrease f and increase number of ticks.
+ // for small plots, scalefact will increase f and decrease number of ticks.
+ f = f/scalefact;
+
+ // for large plots, smaller interval, more ticks.
+ if (f<=0.38) {
+ fact = 0.1;
+ }
+ else if (f<=1.6) {
+ fact = 0.2;
+ }
+ else if (f<=4.0) {
+ fact = 0.5;
+ }
+ else if (f<=8.0) {
+ fact = 1.0;
+ }
+ // for very small plots, larger interval, less ticks in number ticks
+ else if (f<=16.0) {
+ fact = 2;
+ }
+ else {
+ fact = 5;
+ }
+
+ return fact*magnitude;
+ }
+
+ function bestLinearComponents(range, scalefact) {
+ var expv = Math.floor(Math.log(range)/Math.LN10);
+ var magnitude = Math.pow(10, expv);
+ // 0 < f < 10
+ var f = range / magnitude;
+ var interval;
+ var fact;
+ // for large plots, scalefact will decrease f and increase number of ticks.
+ // for small plots, scalefact will increase f and decrease number of ticks.
+ f = f/scalefact;
+
+ // for large plots, smaller interval, more ticks.
+ if (f<=0.38) {
+ fact = 0.1;
+ }
+ else if (f<=1.6) {
+ fact = 0.2;
+ }
+ else if (f<=4.0) {
+ fact = 0.5;
+ }
+ else if (f<=8.0) {
+ fact = 1.0;
+ }
+ // for very small plots, larger interval, less ticks in number ticks
+ else if (f<=16.0) {
+ fact = 2;
+ }
+ // else if (f<=20.0) {
+ // fact = 3;
+ // }
+ // else if (f<=24.0) {
+ // fact = 4;
+ // }
+ else {
+ fact = 5;
+ }
+
+ interval = fact * magnitude;
+
+ return [interval, fact, magnitude];
+ }
+
+ // Given the min and max for a dataset, return suitable endpoints
+ // for the graphing, a good number for the number of ticks, and a
+ // format string so that extraneous digits are not displayed.
+ // returned is an array containing [min, max, nTicks, format]
+ $.jqplot.LinearTickGenerator = function(axis_min, axis_max, scalefact, numberTicks, keepMin, keepMax) {
+ // Set to preserve EITHER min OR max.
+ // If min is preserved, max must be free.
+ keepMin = (keepMin === null) ? false : keepMin;
+ keepMax = (keepMax === null || keepMin) ? false : keepMax;
+ // if endpoints are equal try to include zero otherwise include one
+ if (axis_min === axis_max) {
+ axis_max = (axis_max) ? 0 : 1;
+ }
+
+ scalefact = scalefact || 1.0;
+
+ // make sure range is positive
+ if (axis_max < axis_min) {
+ var a = axis_max;
+ axis_max = axis_min;
+ axis_min = a;
+ }
+
+ var r = [];
+ var ss = bestLinearInterval(axis_max - axis_min, scalefact);
+
+ var gsf = $.jqplot.getSignificantFigures;
+
+ if (numberTicks == null) {
+
+ // Figure out the axis min, max and number of ticks
+ // the min and max will be some multiple of the tick interval,
+ // 1*10^n, 2*10^n or 5*10^n. This gaurantees that, if the
+ // axis min is negative, 0 will be a tick.
+ if (!keepMin && !keepMax) {
+ r[0] = Math.floor(axis_min / ss) * ss; // min
+ r[1] = Math.ceil(axis_max / ss) * ss; // max
+ r[2] = Math.round((r[1]-r[0])/ss+1.0); // number of ticks
+ r[3] = bestFormatString(ss); // format string
+ r[4] = ss; // tick Interval
+ }
+
+ else if (keepMin) {
+ r[0] = axis_min; // min
+ r[2] = Math.ceil((axis_max - axis_min) / ss + 1.0); // number of ticks
+ r[1] = axis_min + (r[2] - 1) * ss; // max
+ var digitsMin = gsf(axis_min).digitsRight;
+ var digitsSS = gsf(ss).digitsRight;
+ if (digitsMin < digitsSS) {
+ r[3] = bestFormatString(ss); // format string
+ }
+ else {
+ r[3] = '%.' + digitsMin + 'f';
+ }
+ r[4] = ss; // tick Interval
+ }
+
+ else if (keepMax) {
+ r[1] = axis_max; // max
+ r[2] = Math.ceil((axis_max - axis_min) / ss + 1.0); // number of ticks
+ r[0] = axis_max - (r[2] - 1) * ss; // min
+ var digitsMax = gsf(axis_max).digitsRight;
+ var digitsSS = gsf(ss).digitsRight;
+ if (digitsMax < digitsSS) {
+ r[3] = bestFormatString(ss); // format string
+ }
+ else {
+ r[3] = '%.' + digitsMax + 'f';
+ }
+ r[4] = ss; // tick Interval
+ }
+ }
+
+ else {
+ var tempr = [];
+
+ // Figure out the axis min, max and number of ticks
+ // the min and max will be some multiple of the tick interval,
+ // 1*10^n, 2*10^n or 5*10^n. This gaurantees that, if the
+ // axis min is negative, 0 will be a tick.
+ tempr[0] = Math.floor(axis_min / ss) * ss; // min
+ tempr[1] = Math.ceil(axis_max / ss) * ss; // max
+ tempr[2] = Math.round((tempr[1]-tempr[0])/ss+1.0); // number of ticks
+ tempr[3] = bestFormatString(ss); // format string
+ tempr[4] = ss; // tick Interval
+
+ // first, see if we happen to get the right number of ticks
+ if (tempr[2] === numberTicks) {
+ r = tempr;
+ }
+
+ else {
+
+ var newti = bestInterval(tempr[1] - tempr[0], numberTicks);
+
+ r[0] = tempr[0]; // min
+ r[2] = numberTicks; // number of ticks
+ r[4] = newti; // tick interval
+ r[3] = bestFormatString(newti); // format string
+ r[1] = r[0] + (r[2] - 1) * r[4]; // max
+ }
+ }
+
+ return r;
+ };
+
+ $.jqplot.LinearTickGenerator.bestLinearInterval = bestLinearInterval;
+ $.jqplot.LinearTickGenerator.bestInterval = bestInterval;
+ $.jqplot.LinearTickGenerator.bestLinearComponents = bestLinearComponents;
+ $.jqplot.LinearTickGenerator.bestConstrainedInterval = bestConstrainedInterval;
+
+
// class: $.jqplot.MarkerRenderer
// The default jqPlot marker renderer, rendering the points on the line.
$.jqplot.MarkerRenderer = function(options){
@@ -5276,8 +7470,6 @@
this.shadowRenderer.draw(ctx, points);
}
this.shapeRenderer.draw(ctx, points, options);
-
- // ctx.restore();
};
$.jqplot.MarkerRenderer.prototype.drawPlus = function(x, y, ctx, fill, options) {
@@ -5293,8 +7485,6 @@
}
this.shapeRenderer.draw(ctx, points1, opts);
this.shapeRenderer.draw(ctx, points2, opts);
-
- // ctx.restore();
};
$.jqplot.MarkerRenderer.prototype.drawX = function(x, y, ctx, fill, options) {
@@ -5310,8 +7500,6 @@
}
this.shapeRenderer.draw(ctx, points1, opts);
this.shapeRenderer.draw(ctx, points2, opts);
-
- // ctx.restore();
};
$.jqplot.MarkerRenderer.prototype.drawDash = function(x, y, ctx, fill, options) {
@@ -5323,10 +7511,16 @@
this.shadowRenderer.draw(ctx, points);
}
this.shapeRenderer.draw(ctx, points, options);
-
- // ctx.restore();
};
+ $.jqplot.MarkerRenderer.prototype.drawLine = function(p1, p2, ctx, fill, options) {
+ var points = [p1, p2];
+ if (this.shadow) {
+ this.shadowRenderer.draw(ctx, points);
+ }
+ this.shapeRenderer.draw(ctx, points, options);
+ };
+
$.jqplot.MarkerRenderer.prototype.drawSquare = function(x, y, ctx, fill, options) {
var stretch = 1.0;
var dx = this.size/2/stretch;
@@ -5336,8 +7530,6 @@
this.shadowRenderer.draw(ctx, points);
}
this.shapeRenderer.draw(ctx, points, options);
-
- // ctx.restore();
};
$.jqplot.MarkerRenderer.prototype.drawCircle = function(x, y, ctx, fill, options) {
@@ -5348,8 +7540,6 @@
this.shadowRenderer.draw(ctx, points);
}
this.shapeRenderer.draw(ctx, points, options);
-
- // ctx.restore();
};
$.jqplot.MarkerRenderer.prototype.draw = function(x, y, ctx, options) {
@@ -5391,6 +7581,9 @@
case 'dash':
this.drawDash(x,y,ctx, true, options);
break;
+ case 'line':
+ this.drawLine(x, y, ctx, false, options);
+ break;
default:
this.drawDiamond(x,y,ctx, false, options);
break;
@@ -5451,33 +7644,41 @@
ctx.save();
var opts = (options != null) ? options : {};
var fill = (opts.fill != null) ? opts.fill : this.fill;
+ var fillRect = (opts.fillRect != null) ? opts.fillRect : this.fillRect;
var closePath = (opts.closePath != null) ? opts.closePath : this.closePath;
var offset = (opts.offset != null) ? opts.offset : this.offset;
var alpha = (opts.alpha != null) ? opts.alpha : this.alpha;
var depth = (opts.depth != null) ? opts.depth : this.depth;
var isarc = (opts.isarc != null) ? opts.isarc : this.isarc;
+ var linePattern = (opts.linePattern != null) ? opts.linePattern : this.linePattern;
ctx.lineWidth = (opts.lineWidth != null) ? opts.lineWidth : this.lineWidth;
ctx.lineJoin = (opts.lineJoin != null) ? opts.lineJoin : this.lineJoin;
ctx.lineCap = (opts.lineCap != null) ? opts.lineCap : this.lineCap;
ctx.strokeStyle = opts.strokeStyle || this.strokeStyle || 'rgba(0,0,0,'+alpha+')';
ctx.fillStyle = opts.fillStyle || this.fillStyle || 'rgba(0,0,0,'+alpha+')';
for (var j=0; j<depth; j++) {
+ var ctxPattern = $.jqplot.LinePattern(ctx, linePattern);
ctx.translate(Math.cos(this.angle*Math.PI/180)*offset, Math.sin(this.angle*Math.PI/180)*offset);
- ctx.beginPath();
+ ctxPattern.beginPath();
if (isarc) {
ctx.arc(points[0], points[1], points[2], points[3], points[4], true);
}
- else {
+ else if (fillRect) {
+ if (fillRect) {
+ ctx.fillRect(points[0], points[1], points[2], points[3]);
+ }
+ }
+ else if (points && points.length){
var move = true;
for (var i=0; i<points.length; i++) {
// skip to the first non-null point and move to it.
if (points[i][0] != null && points[i][1] != null) {
if (move) {
- ctx.moveTo(points[i][0], points[i][1]);
+ ctxPattern.moveTo(points[i][0], points[i][1]);
move = false;
}
else {
- ctx.lineTo(points[i][0], points[i][1]);
+ ctxPattern.lineTo(points[i][0], points[i][1]);
}
}
else {
@@ -5487,7 +7688,7 @@
}
if (closePath) {
- ctx.closePath();
+ ctxPattern.closePath();
}
if (fill) {
ctx.fill();
@@ -5507,6 +7708,12 @@
$.jqplot.ShapeRenderer = function(options){
this.lineWidth = 1.5;
+ // prop: linePattern
+ // line pattern 'dashed', 'dotted', 'solid', some combination
+ // of '-' and '.' characters such as '.-.' or a numerical array like
+ // [draw, skip, draw, skip, ...] such as [1, 10] to draw a dotted line,
+ // [1, 10, 20, 10] to draw a dot-dash line, and so on.
+ this.linePattern = 'solid';
// prop: lineJoin
// How line segments of the shadow are joined.
this.lineJoin = 'miter';
@@ -5561,8 +7768,10 @@
var strokeRect = (opts.strokeRect != null) ? opts.strokeRect : this.strokeRect;
var clearRect = (opts.clearRect != null) ? opts.clearRect : this.clearRect;
var isarc = (opts.isarc != null) ? opts.isarc : this.isarc;
+ var linePattern = (opts.linePattern != null) ? opts.linePattern : this.linePattern;
+ var ctxPattern = $.jqplot.LinePattern(ctx, linePattern);
ctx.lineWidth = opts.lineWidth || this.lineWidth;
- ctx.lineJoin = opts.lineJoing || this.lineJoin;
+ ctx.lineJoin = opts.lineJoin || this.lineJoin;
ctx.lineCap = opts.lineCap || this.lineCap;
ctx.strokeStyle = (opts.strokeStyle || opts.color) || this.strokeStyle;
ctx.fillStyle = opts.fillStyle || this.fillStyle;
@@ -5596,17 +7805,17 @@
return;
}
}
- else {
+ else if (points && points.length){
var move = true;
for (var i=0; i<points.length; i++) {
// skip to the first non-null point and move to it.
if (points[i][0] != null && points[i][1] != null) {
if (move) {
- ctx.moveTo(points[i][0], points[i][1]);
+ ctxPattern.moveTo(points[i][0], points[i][1]);
move = false;
}
else {
- ctx.lineTo(points[i][0], points[i][1]);
+ ctxPattern.lineTo(points[i][0], points[i][1]);
}
}
else {
@@ -5614,7 +7823,7 @@
}
}
if (closePath) {
- ctx.closePath();
+ ctxPattern.closePath();
}
if (fill) {
ctx.fill();
@@ -5637,50 +7846,111 @@
};
$.jqplot.TableLegendRenderer.prototype.addrow = function (label, color, pad, reverse) {
- var rs = (pad) ? this.rowSpacing : '0';
+ var rs = (pad) ? this.rowSpacing+'px' : '0px';
+ var tr;
+ var td;
+ var elem;
+ var div0;
+ var div1;
+ elem = document.createElement('tr');
+ tr = $(elem);
+ tr.addClass('jqplot-table-legend');
+ elem = null;
+
if (reverse){
- var tr = $('<tr class="jqplot-table-legend"></tr>').prependTo(this._elem);
+ tr.prependTo(this._elem);
}
+
else{
- var tr = $('<tr class="jqplot-table-legend"></tr>').appendTo(this._elem);
+ tr.appendTo(this._elem);
}
+
if (this.showSwatches) {
- $('<td class="jqplot-table-legend" style="text-align:center;padding-top:'+rs+';">'+
- '<div><div class="jqplot-table-legend-swatch" style="background-color:'+color+';border-color:'+color+';"></div>'+
- '</div></td>').appendTo(tr);
+ td = $(document.createElement('td'));
+ td.addClass('jqplot-table-legend jqplot-table-legend-swatch');
+ td.css({textAlign: 'center', paddingTop: rs});
+
+ div0 = $(document.createElement('div'));
+ div0.addClass('jqplot-table-legend-swatch-outline');
+ div1 = $(document.createElement('div'));
+ div1.addClass('jqplot-table-legend-swatch');
+ div1.css({backgroundColor: color, borderColor: color});
+
+ tr.append(td.append(div0.append(div1)));
+
+ // $('<td class="jqplot-table-legend" style="text-align:center;padding-top:'+rs+';">'+
+ // '<div><div class="jqplot-table-legend-swatch" style="background-color:'+color+';border-color:'+color+';"></div>'+
+ // '</div></td>').appendTo(tr);
}
if (this.showLabels) {
- var elem = $('<td class="jqplot-table-legend" style="padding-top:'+rs+';"></td>');
- elem.appendTo(tr);
+ td = $(document.createElement('td'));
+ td.addClass('jqplot-table-legend jqplot-table-legend-label');
+ td.css('paddingTop', rs);
+ tr.append(td);
+
+ // elem = $('<td class="jqplot-table-legend" style="padding-top:'+rs+';"></td>');
+ // elem.appendTo(tr);
if (this.escapeHtml) {
- elem.text(label);
+ td.text(label);
}
else {
- elem.html(label);
+ td.html(label);
}
}
+ td = null;
+ div0 = null;
+ div1 = null;
+ tr = null;
+ elem = null;
};
// called with scope of legend
$.jqplot.TableLegendRenderer.prototype.draw = function() {
- var legend = this;
+ if (this._elem) {
+ this._elem.emptyForce();
+ this._elem = null;
+ }
+
if (this.show) {
var series = this._series;
// make a table. one line label per row.
- var ss = 'position:absolute;';
- ss += (this.background) ? 'background:'+this.background+';' : '';
- ss += (this.border) ? 'border:'+this.border+';' : '';
- ss += (this.fontSize) ? 'font-size:'+this.fontSize+';' : '';
- ss += (this.fontFamily) ? 'font-family:'+this.fontFamily+';' : '';
- ss += (this.textColor) ? 'color:'+this.textColor+';' : '';
- ss += (this.marginTop != null) ? 'margin-top:'+this.marginTop+';' : '';
- ss += (this.marginBottom != null) ? 'margin-bottom:'+this.marginBottom+';' : '';
- ss += (this.marginLeft != null) ? 'margin-left:'+this.marginLeft+';' : '';
- ss += (this.marginRight != null) ? 'margin-right:'+this.marginRight+';' : '';
- this._elem = $('<table class="jqplot-table-legend" style="'+ss+'"></table>');
+ var elem = document.createElement('table');
+ this._elem = $(elem);
+ this._elem.addClass('jqplot-table-legend');
+
+ var ss = {position:'absolute'};
+ if (this.background) {
+ ss['background'] = this.background;
+ }
+ if (this.border) {
+ ss['border'] = this.border;
+ }
+ if (this.fontSize) {
+ ss['fontSize'] = this.fontSize;
+ }
+ if (this.fontFamily) {
+ ss['fontFamily'] = this.fontFamily;
+ }
+ if (this.textColor) {
+ ss['textColor'] = this.textColor;
+ }
+ if (this.marginTop != null) {
+ ss['marginTop'] = this.marginTop;
+ }
+ if (this.marginBottom != null) {
+ ss['marginBottom'] = this.marginBottom;
+ }
+ if (this.marginLeft != null) {
+ ss['marginLeft'] = this.marginLeft;
+ }
+ if (this.marginRight != null) {
+ ss['marginRight'] = this.marginRight;
+ }
+
var pad = false,
- reverse = false;
+ reverse = false,
+ s;
for (var i = 0; i< series.length; i++) {
s = series[i];
if (s._stack || s.renderer.constructor == $.jqplot.BezierCurveRenderer){
@@ -5707,6 +7977,7 @@
pad = true;
}
}
+ lt = null;
}
}
}
@@ -5896,6 +8167,7 @@
* > series: [{
* > color: "#4bb2c5",
* > lineWidth: 2.5,
+ * > linePattern: "solid",
* > shadow: true,
* > fillColor: "#4bb2c5",
* > showMarker: true,
@@ -6043,7 +8315,7 @@
$.jqplot.ThemeEngine.prototype.init = function() {
// get the Default theme from the current plot settings.
var th = new $.jqplot.Theme({_name:'Default'});
- var n, i;
+ var n, i, nn;
for (n in th.target) {
if (n == "textColor") {
@@ -6245,7 +8517,7 @@
}
}
- for (axname in plot.axes) {
+ for (var axname in plot.axes) {
var axis = plot.axes[axname];
if (axis.show) {
var thaxis = th.axes[axname] || {};
@@ -6262,7 +8534,7 @@
redrawPlot = true;
}
if (axis._ticks && axis._ticks[0]) {
- for (nn in thax.ticks) {
+ for (var nn in thax.ticks) {
// val = null;
// if (th.axesStyles.ticks && th.axesStyles.ticks[nn] != null) {
// val = th.axesStyles.ticks[nn];
@@ -6279,7 +8551,7 @@
}
}
if (axis._label && axis._label.show) {
- for (nn in thax.label) {
+ for (var nn in thax.label) {
// val = null;
// if (th.axesStyles.label && th.axesStyles.label[nn] != null) {
// val = th.axesStyles.label[nn];
@@ -6335,8 +8607,8 @@
plot.series[i].renderer.shapeRenderer.strokeStyle = val;
plot.series[i][n] = val;
}
- else if (n == 'lineWidth') {
- plot.series[i].renderer.shapeRenderer.lineWidth = val;
+ else if ((n == 'lineWidth') || (n == 'linePattern')) {
+ plot.series[i].renderer.shapeRenderer[n] = val;
plot.series[i][n] = val;
}
else if (n == 'markerOptions') {
@@ -6477,50 +8749,50 @@
// Use the jQuery 1.3.2 extend function since behaviour in jQuery 1.4 seems problematic
$.jqplot.extend = function() {
- // copy reference to target object
- var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
+ // copy reference to target object
+ var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
- // Handle a deep copy situation
- if ( typeof target === "boolean" ) {
- deep = target;
- target = arguments[1] || {};
- // skip the boolean and the target
- i = 2;
- }
+ // Handle a deep copy situation
+ if ( typeof target === "boolean" ) {
+ deep = target;
+ target = arguments[1] || {};
+ // skip the boolean and the target
+ i = 2;
+ }
- // Handle case when target is a string or something (possible in deep copy)
- if ( typeof target !== "object" && !toString.call(target) === "[object Function]" ) {
- target = {};
- }
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target !== "object" && !toString.call(target) === "[object Function]" ) {
+ target = {};
+ }
- for ( ; i < length; i++ ){
- // Only deal with non-null/undefined values
- if ( (options = arguments[ i ]) != null ) {
- // Extend the base object
- for ( var name in options ) {
- var src = target[ name ], copy = options[ name ];
+ for ( ; i < length; i++ ){
+ // Only deal with non-null/undefined values
+ if ( (options = arguments[ i ]) != null ) {
+ // Extend the base object
+ for ( var name in options ) {
+ var src = target[ name ], copy = options[ name ];
- // Prevent never-ending loop
- if ( target === copy ) {
- continue;
- }
+ // Prevent never-ending loop
+ if ( target === copy ) {
+ continue;
+ }
- // Recurse if we're merging object values
- if ( deep && copy && typeof copy === "object" && !copy.nodeType ) {
- target[ name ] = $.jqplot.extend( deep,
- // Never move original objects, clone them
- src || ( copy.length != null ? [ ] : { } )
- , copy );
+ // Recurse if we're merging object values
+ if ( deep && copy && typeof copy === "object" && !copy.nodeType ) {
+ target[ name ] = $.jqplot.extend( deep,
+ // Never move original objects, clone them
+ src || ( copy.length != null ? [ ] : { } )
+ , copy );
}
- // Don't bring in undefined values
- else if ( copy !== undefined ) {
- target[ name ] = copy;
- }
- }
- }
+ // Don't bring in undefined values
+ else if ( copy !== undefined ) {
+ target[ name ] = copy;
+ }
+ }
+ }
}
- // Return the modified object
- return target;
+ // Return the modified object
+ return target;
};
/**
@@ -6663,6 +8935,7 @@
var LineSeriesProperties = function() {
this.color=null;
this.lineWidth=null;
+ this.linePattern=null;
this.shadow=null;
this.fillColor=null;
this.showMarker=null;
@@ -6739,6 +9012,1762 @@
};
+
+
+ $.fn.jqplotChildText = function() {
+ return $(this).contents().filter(function() {
+ return this.nodeType == 3; // Node.TEXT_NODE not defined in I7
+ }).text();
+ };
+
+ // Returns font style as abbreviation for "font" property.
+ $.fn.jqplotGetComputedFontStyle = function() {
+ var css = window.getComputedStyle ? window.getComputedStyle(this[0], "") : this[0].currentStyle;
+ var attrs = css['font-style'] ? ['font-style', 'font-weight', 'font-size', 'font-family'] : ['fontStyle', 'fontWeight', 'fontSize', 'fontFamily'];
+ var style = [];
+
+ for (var i=0 ; i < attrs.length; ++i) {
+ var attr = String(css[attrs[i]]);
+
+ if (attr && attr != 'normal') {
+ style.push(attr);
+ }
+ }
+ return style.join(' ');
+ };
+
+ /**
+ * Namespace: $.fn
+ * jQuery namespace to attach functions to jQuery elements.
+ *
+ */
+
+ $.fn.jqplotToImageCanvas = function(options) {
+
+ options = options || {};
+ var x_offset = (options.x_offset == null) ? 0 : options.x_offset;
+ var y_offset = (options.y_offset == null) ? 0 : options.y_offset;
+ var backgroundColor = (options.backgroundColor == null) ? 'rgb(255,255,255)' : options.backgroundColor;
+
+ if ($(this).width() == 0 || $(this).height() == 0) {
+ return null;
+ }
+
+ // excanvas and hence IE < 9 do not support toDataURL and cannot export images.
+ if ($.jqplot.use_excanvas) {
+ return null;
+ }
+
+ var newCanvas = document.createElement("canvas");
+ var h = $(this).outerHeight(true);
+ var w = $(this).outerWidth(true);
+ var offs = $(this).offset();
+ var plotleft = offs.left;
+ var plottop = offs.top;
+ var transx = 0, transy = 0;
+
+ // have to check if any elements are hanging outside of plot area before rendering,
+ // since changing width of canvas will erase canvas.
+
+ var clses = ['jqplot-table-legend', 'jqplot-xaxis-tick', 'jqplot-x2axis-tick', 'jqplot-yaxis-tick', 'jqplot-y2axis-tick', 'jqplot-y3axis-tick',
+ 'jqplot-y4axis-tick', 'jqplot-y5axis-tick', 'jqplot-y6axis-tick', 'jqplot-y7axis-tick', 'jqplot-y8axis-tick', 'jqplot-y9axis-tick',
+ 'jqplot-xaxis-label', 'jqplot-x2axis-label', 'jqplot-yaxis-label', 'jqplot-y2axis-label', 'jqplot-y3axis-label', 'jqplot-y4axis-label',
+ 'jqplot-y5axis-label', 'jqplot-y6axis-label', 'jqplot-y7axis-label', 'jqplot-y8axis-label', 'jqplot-y9axis-label' ];
+
+ var temptop, templeft, tempbottom, tempright;
+
+ for (var i = 0; i < clses.length; i++) {
+ $(this).find('.'+clses[i]).each(function() {
+ temptop = $(this).offset().top - plottop;
+ templeft = $(this).offset().left - plotleft;
+ tempright = templeft + $(this).outerWidth(true) + transx;
+ tempbottom = temptop + $(this).outerHeight(true) + transy;
+ if (templeft < -transx) {
+ w = w - transx - templeft;
+ transx = -templeft;
+ }
+ if (temptop < -transy) {
+ h = h - transy - temptop;
+ transy = - temptop;
+ }
+ if (tempright > w) {
+ w = tempright;
+ }
+ if (tempbottom > h) {
+ h = tempbottom;
+ }
+ });
+ }
+
+ newCanvas.width = w + Number(x_offset);
+ newCanvas.height = h + Number(y_offset);
+
+ var newContext = newCanvas.getContext("2d");
+
+ newContext.save();
+ newContext.fillStyle = backgroundColor;
+ newContext.fillRect(0,0, newCanvas.width, newCanvas.height);
+ newContext.restore();
+
+ newContext.translate(transx, transy);
+ newContext.textAlign = 'left';
+ newContext.textBaseline = 'top';
+
+ function getLineheight(el) {
+ var lineheight = parseInt($(el).css('line-height'), 10);
+
+ if (isNaN(lineheight)) {
+ lineheight = parseInt($(el).css('font-size'), 10) * 1.2;
+ }
+ return lineheight;
+ }
+
+ function writeWrappedText (el, context, text, left, top, canvasWidth) {
+ var lineheight = getLineheight(el);
+ var tagwidth = $(el).innerWidth();
+ var tagheight = $(el).innerHeight();
+ var words = text.split(/\s+/);
+ var wl = words.length;
+ var w = '';
+ var breaks = [];
+ var temptop = top;
+ var templeft = left;
+
+ for (var i=0; i<wl; i++) {
+ w += words[i];
+ if (context.measureText(w).width > tagwidth) {
+ breaks.push(i);
+ w = '';
+ i--;
+ }
+ }
+ if (breaks.length === 0) {
+ // center text if necessary
+ if ($(el).css('textAlign') === 'center') {
+ templeft = left + (canvasWidth - context.measureText(w).width)/2 - transx;
+ }
+ context.fillText(text, templeft, top);
+ }
+ else {
+ w = words.slice(0, breaks[0]).join(' ');
+ // center text if necessary
+ if ($(el).css('textAlign') === 'center') {
+ templeft = left + (canvasWidth - context.measureText(w).width)/2 - transx;
+ }
+ context.fillText(w, templeft, temptop);
+ temptop += lineheight;
+ for (var i=1, l=breaks.length; i<l; i++) {
+ w = words.slice(breaks[i-1], breaks[i]).join(' ');
+ // center text if necessary
+ if ($(el).css('textAlign') === 'center') {
+ templeft = left + (canvasWidth - context.measureText(w).width)/2 - transx;
+ }
+ context.fillText(w, templeft, temptop);
+ temptop += lineheight;
+ }
+ w = words.slice(breaks[i-1], words.length).join(' ');
+ // center text if necessary
+ if ($(el).css('textAlign') === 'center') {
+ templeft = left + (canvasWidth - context.measureText(w).width)/2 - transx;
+ }
+ context.fillText(w, templeft, temptop);
+ }
+
+ }
+
+ function _jqpToImage(el, x_offset, y_offset) {
+ var tagname = el.tagName.toLowerCase();
+ var p = $(el).position();
+ var css = window.getComputedStyle ? window.getComputedStyle(el, "") : el.currentStyle; // for IE < 9
+ var left = x_offset + p.left + parseInt(css.marginLeft, 10) + parseInt(css.borderLeftWidth, 10) + parseInt(css.paddingLeft, 10);
+ var top = y_offset + p.top + parseInt(css.marginTop, 10) + parseInt(css.borderTopWidth, 10)+ parseInt(css.paddingTop, 10);
+ var w = newCanvas.width;
+ // var left = x_offset + p.left + $(el).css('marginLeft') + $(el).css('borderLeftWidth')
+
+ // somehow in here, for divs within divs, the width of the inner div should be used instead of the canvas.
+
+ if ((tagname == 'div' || tagname == 'span') && !$(el).hasClass('jqplot-highlighter-tooltip')) {
+ $(el).children().each(function() {
+ _jqpToImage(this, left, top);
+ });
+ var text = $(el).jqplotChildText();
+
+ if (text) {
+ newContext.font = $(el).jqplotGetComputedFontStyle();
+ newContext.fillStyle = $(el).css('color');
+
+ writeWrappedText(el, newContext, text, left, top, w);
+ }
+ }
+
+ // handle the standard table legend
+
+ else if (tagname === 'table' && $(el).hasClass('jqplot-table-legend')) {
+ newContext.strokeStyle = $(el).css('border-top-color');
+ newContext.fillStyle = $(el).css('background-color');
+ newContext.fillRect(left, top, $(el).innerWidth(), $(el).innerHeight());
+ if (parseInt($(el).css('border-top-width'), 10) > 0) {
+ newContext.strokeRect(left, top, $(el).innerWidth(), $(el).innerHeight());
+ }
+
+ // find all the swatches
+ $(el).find('div.jqplot-table-legend-swatch-outline').each(function() {
+ // get the first div and stroke it
+ var elem = $(this);
+ newContext.strokeStyle = elem.css('border-top-color');
+ var l = left + elem.position().left;
+ var t = top + elem.position().top;
+ newContext.strokeRect(l, t, elem.innerWidth(), elem.innerHeight());
+
+ // now fill the swatch
+
+ l += parseInt(elem.css('padding-left'), 10);
+ t += parseInt(elem.css('padding-top'), 10);
+ var h = elem.innerHeight() - 2 * parseInt(elem.css('padding-top'), 10);
+ var w = elem.innerWidth() - 2 * parseInt(elem.css('padding-left'), 10);
+
+ var swatch = elem.children('div.jqplot-table-legend-swatch');
+ newContext.fillStyle = swatch.css('background-color');
+ newContext.fillRect(l, t, w, h);
+ });
+
+ // now add text
+
+ $(el).find('td.jqplot-table-legend-label').each(function(){
+ var elem = $(this);
+ var l = left + elem.position().left;
+ var t = top + elem.position().top + parseInt(elem.css('padding-top'), 10);
+ newContext.font = elem.jqplotGetComputedFontStyle();
+ newContext.fillStyle = elem.css('color');
+ writeWrappedText(elem, newContext, elem.text(), l, t, w);
+ });
+
+ var elem = null;
+ }
+
+ else if (tagname == 'canvas') {
+ newContext.drawImage(el, left, top);
+ }
+ }
+ $(this).children().each(function() {
+ _jqpToImage(this, x_offset, y_offset);
+ });
+ return newCanvas;
+ };
+
+ // return the raw image data string.
+ // Should work on canvas supporting browsers.
+ $.fn.jqplotToImageStr = function(options) {
+ var imgCanvas = $(this).jqplotToImageCanvas(options);
+ if (imgCanvas) {
+ return imgCanvas.toDataURL("image/png");
+ }
+ else {
+ return null;
+ }
+ };
+
+ // return a DOM <img> element and return it.
+ // Should work on canvas supporting browsers.
+ $.fn.jqplotToImageElem = function(options) {
+ var elem = document.createElement("img");
+ var str = $(this).jqplotToImageStr(options);
+ elem.src = str;
+ return elem;
+ };
+
+ // return a string for an <img> element and return it.
+ // Should work on canvas supporting browsers.
+ $.fn.jqplotToImageElemStr = function(options) {
+ var str = '<img src='+$(this).jqplotToImageStr(options)+' />';
+ return str;
+ };
+
+ // Not gauranteed to work, even on canvas supporting browsers due to
+ // limitations with location.href and browser support.
+ $.fn.jqplotSaveImage = function() {
+ var imgData = $(this).jqplotToImageStr({});
+ if (imgData) {
+ window.location.href = imgData.replace("image/png", "image/octet-stream");
+ }
+
+ };
+
+ // Not gauranteed to work, even on canvas supporting browsers due to
+ // limitations with window.open and arbitrary data.
+ $.fn.jqplotViewImage = function() {
+ var imgStr = $(this).jqplotToImageElemStr({});
+ var imgData = $(this).jqplotToImageStr({});
+ if (imgStr) {
+ var w = window.open('');
+ w.document.open("image/png");
+ w.document.write(imgStr);
+ w.document.close();
+ w = null;
+ }
+ };
+
+
+
+
+ /**
+ * @description
+ * <p>Object with extended date parsing and formatting capabilities.
+ * This library borrows many concepts and ideas from the Date Instance
+ * Methods by Ken Snyder along with some parts of Ken's actual code.</p>
+ *
+ * <p>jsDate takes a different approach by not extending the built-in
+ * Date Object, improving date parsing, allowing for multiple formatting
+ * syntaxes and multiple and more easily expandable localization.</p>
+ *
+ * @author Chris Leonello
+ * @date #date#
+ * @version #VERSION#
+ * @copyright (c) 2010-2013 Chris Leonello
+ * jsDate is currently available for use in all personal or commercial projects
+ * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * choose the license that best suits your project and use it accordingly.
+ *
+ * <p>Ken's origianl Date Instance Methods and copyright notice:</p>
+ * <pre>
+ * Ken Snyder (ken d snyder at gmail dot com)
+ * 2008-09-10
+ * version 2.0.2 (http://kendsnyder.com/sandbox/date/)
+ * Creative Commons Attribution License 3.0 (http://creativecommons.org/licenses/by/3.0/)
+ * </pre>
+ *
+ * @class
+ * @name jsDate
+ * @param {String | Number | Array | Date Object | Options Object} arguments Optional arguments, either a parsable date/time string,
+ * a JavaScript timestamp, an array of numbers of form [year, month, day, hours, minutes, seconds, milliseconds],
+ * a Date object, or an options object of form {syntax: "perl", date:some Date} where all options are optional.
+ */
+
+ var jsDate = function () {
+
+ this.syntax = jsDate.config.syntax;
+ this._type = "jsDate";
+ this.proxy = new Date();
+ this.options = {};
+ this.locale = jsDate.regional.getLocale();
+ this.formatString = '';
+ this.defaultCentury = jsDate.config.defaultCentury;
+
+ switch ( arguments.length ) {
+ case 0:
+ break;
+ case 1:
+ // other objects either won't have a _type property or,
+ // if they do, it shouldn't be set to "jsDate", so
+ // assume it is an options argument.
+ if (get_type(arguments[0]) == "[object Object]" && arguments[0]._type != "jsDate") {
+ var opts = this.options = arguments[0];
+ this.syntax = opts.syntax || this.syntax;
+ this.defaultCentury = opts.defaultCentury || this.defaultCentury;
+ this.proxy = jsDate.createDate(opts.date);
+ }
+ else {
+ this.proxy = jsDate.createDate(arguments[0]);
+ }
+ break;
+ default:
+ var a = [];
+ for ( var i=0; i<arguments.length; i++ ) {
+ a.push(arguments[i]);
+ }
+ // this should be the current date/time?
+ this.proxy = new Date();
+ this.proxy.setFullYear.apply( this.proxy, a.slice(0,3) );
+ if ( a.slice(3).length ) {
+ this.proxy.setHours.apply( this.proxy, a.slice(3) );
+ }
+ break;
+ }
+ };
+
+ /**
+ * @namespace Configuration options that will be used as defaults for all instances on the page.
+ * @property {String} defaultLocale The default locale to use [en].
+ * @property {String} syntax The default syntax to use [perl].
+ * @property {Number} defaultCentury The default centry for 2 digit dates.
+ */
+ jsDate.config = {
+ defaultLocale: 'en',
+ syntax: 'perl',
+ defaultCentury: 1900
+ };
+
+ /**
+ * Add an arbitrary amount to the currently stored date
+ *
+ * @param {Number} number
+ * @param {String} unit
+ * @returns {jsDate}
+ */
+
+ jsDate.prototype.add = function(number, unit) {
+ var factor = multipliers[unit] || multipliers.day;
+ if (typeof factor == 'number') {
+ this.proxy.setTime(this.proxy.getTime() + (factor * number));
+ } else {
+ factor.add(this, number);
+ }
+ return this;
+ };
+
+ /**
+ * Create a new jqplot.date object with the same date
+ *
+ * @returns {jsDate}
+ */
+
+ jsDate.prototype.clone = function() {
+ return new jsDate(this.proxy.getTime());
+ };
+
+ /**
+ * Get the UTC TimeZone Offset of this date in milliseconds.
+ *
+ * @returns {Number}
+ */
+
+ jsDate.prototype.getUtcOffset = function() {
+ return this.proxy.getTimezoneOffset() * 60000;
+ };
+
+ /**
+ * Find the difference between this jsDate and another date.
+ *
+ * @param {String| Number| Array| jsDate Object| Date Object} dateObj
+ * @param {String} unit
+ * @param {Boolean} allowDecimal
+ * @returns {Number} Number of units difference between dates.
+ */
+
+ jsDate.prototype.diff = function(dateObj, unit, allowDecimal) {
+ // ensure we have a Date object
+ dateObj = new jsDate(dateObj);
+ if (dateObj === null) {
+ return null;
+ }
+ // get the multiplying factor integer or factor function
+ var factor = multipliers[unit] || multipliers.day;
+ if (typeof factor == 'number') {
+ // multiply
+ var unitDiff = (this.proxy.getTime() - dateObj.proxy.getTime()) / factor;
+ } else {
+ // run function
+ var unitDiff = factor.diff(this.proxy, dateObj.proxy);
+ }
+ // if decimals are not allowed, round toward zero
+ return (allowDecimal ? unitDiff : Math[unitDiff > 0 ? 'floor' : 'ceil'](unitDiff));
+ };
+
+ /**
+ * Get the abbreviated name of the current week day
+ *
+ * @returns {String}
+ */
+
+ jsDate.prototype.getAbbrDayName = function() {
+ return jsDate.regional[this.locale]["dayNamesShort"][this.proxy.getDay()];
+ };
+
+ /**
+ * Get the abbreviated name of the current month
+ *
+ * @returns {String}
+ */
+
+ jsDate.prototype.getAbbrMonthName = function() {
+ return jsDate.regional[this.locale]["monthNamesShort"][this.proxy.getMonth()];
+ };
+
+ /**
+ * Get UPPER CASE AM or PM for the current time
+ *
+ * @returns {String}
+ */
+
+ jsDate.prototype.getAMPM = function() {
+ return this.proxy.getHours() >= 12 ? 'PM' : 'AM';
+ };
+
+ /**
+ * Get lower case am or pm for the current time
+ *
+ * @returns {String}
+ */
+
+ jsDate.prototype.getAmPm = function() {
+ return this.proxy.getHours() >= 12 ? 'pm' : 'am';
+ };
+
+ /**
+ * Get the century (19 for 20th Century)
+ *
+ * @returns {Integer} Century (19 for 20th century).
+ */
+ jsDate.prototype.getCentury = function() {
+ return parseInt(this.proxy.getFullYear()/100, 10);
+ };
+
+ /**
+ * Implements Date functionality
+ */
+ jsDate.prototype.getDate = function() {
+ return this.proxy.getDate();
+ };
+
+ /**
+ * Implements Date functionality
+ */
+ jsDate.prototype.getDay = function() {
+ return this.proxy.getDay();
+ };
+
+ /**
+ * Get the Day of week 1 (Monday) thru 7 (Sunday)
+ *
+ * @returns {Integer} Day of week 1 (Monday) thru 7 (Sunday)
+ */
+ jsDate.prototype.getDayOfWeek = function() {
+ var dow = this.proxy.getDay();
+ return dow===0?7:dow;
+ };
+
+ /**
+ * Get the day of the year
+ *
+ * @returns {Integer} 1 - 366, day of the year
+ */
+ jsDate.prototype.getDayOfYear = function() {
+ var d = this.proxy;
+ var ms = d - new Date('' + d.getFullYear() + '/1/1 GMT');
+ ms += d.getTimezoneOffset()*60000;
+ d = null;
+ return parseInt(ms/60000/60/24, 10)+1;
+ };
+
+ /**
+ * Get the name of the current week day
+ *
+ * @returns {String}
+ */
+
+ jsDate.prototype.getDayName = function() {
+ return jsDate.regional[this.locale]["dayNames"][this.proxy.getDay()];
+ };
+
+ /**
+ * Get the week number of the given year, starting with the first Sunday as the first week
+ * @returns {Integer} Week number (13 for the 13th full week of the year).
+ */
+ jsDate.prototype.getFullWeekOfYear = function() {
+ var d = this.proxy;
+ var doy = this.getDayOfYear();
+ var rdow = 6-d.getDay();
+ var woy = parseInt((doy+rdow)/7, 10);
+ return woy;
+ };
+
+ /**
+ * Implements Date functionality
+ */
+ jsDate.prototype.getFullYear = function() {
+ return this.proxy.getFullYear();
+ };
+
+ /**
+ * Get the GMT offset in hours and minutes (e.g. +06:30)
+ *
+ * @returns {String}
+ */
+
+ jsDate.prototype.getGmtOffset = function() {
+ // divide the minutes offset by 60
+ var hours = this.proxy.getTimezoneOffset() / 60;
+ // decide if we are ahead of or behind GMT
+ var prefix = hours < 0 ? '+' : '-';
+ // remove the negative sign if any
+ hours = Math.abs(hours);
+ // add the +/- to the padded number of hours to : to the padded minutes
+ return prefix + addZeros(Math.floor(hours), 2) + ':' + addZeros((hours % 1) * 60, 2);
+ };
+
+ /**
+ * Implements Date functionality
+ */
+ jsDate.prototype.getHours = function() {
+ return this.proxy.getHours();
+ };
+
+ /**
+ * Get the current hour on a 12-hour scheme
+ *
+ * @returns {Integer}
+ */
+
+ jsDate.prototype.getHours12 = function() {
+ var hours = this.proxy.getHours();
+ return hours > 12 ? hours - 12 : (hours == 0 ? 12 : hours);
+ };
+
+
+ jsDate.prototype.getIsoWeek = function() {
+ var d = this.proxy;
+ var woy = d.getWeekOfYear();
+ var dow1_1 = (new Date('' + d.getFullYear() + '/1/1')).getDay();
+ // First week is 01 and not 00 as in the case of %U and %W,
+ // so we add 1 to the final result except if day 1 of the year
+ // is a Monday (then %W returns 01).
+ // We also need to subtract 1 if the day 1 of the year is
+ // Friday-Sunday, so the resulting equation becomes:
+ var idow = woy + (dow1_1 > 4 || dow1_1 <= 1 ? 0 : 1);
+ if(idow == 53 && (new Date('' + d.getFullYear() + '/12/31')).getDay() < 4)
+ {
+ idow = 1;
+ }
+ else if(idow === 0)
+ {
+ d = new jsDate(new Date('' + (d.getFullYear()-1) + '/12/31'));
+ idow = d.getIsoWeek();
+ }
+ d = null;
+ return idow;
+ };
+
+ /**
+ * Implements Date functionality
+ */
+ jsDate.prototype.getMilliseconds = function() {
+ return this.proxy.getMilliseconds();
+ };
+
+ /**
+ * Implements Date functionality
+ */
+ jsDate.prototype.getMinutes = function() {
+ return this.proxy.getMinutes();
+ };
+
+ /**
+ * Implements Date functionality
+ */
+ jsDate.prototype.getMonth = function() {
+ return this.proxy.getMonth();
+ };
+
+ /**
+ * Get the name of the current month
+ *
+ * @returns {String}
+ */
+
+ jsDate.prototype.getMonthName = function() {
+ return jsDate.regional[this.locale]["monthNames"][this.proxy.getMonth()];
+ };
+
+ /**
+ * Get the number of the current month, 1-12
+ *
+ * @returns {Integer}
+ */
+
+ jsDate.prototype.getMonthNumber = function() {
+ return this.proxy.getMonth() + 1;
+ };
+
+ /**
+ * Implements Date functionality
+ */
+ jsDate.prototype.getSeconds = function() {
+ return this.proxy.getSeconds();
+ };
+
+ /**
+ * Return a proper two-digit year integer
+ *
+ * @returns {Integer}
+ */
+
+ jsDate.prototype.getShortYear = function() {
+ return this.proxy.getYear() % 100;
+ };
+
+ /**
+ * Implements Date functionality
+ */
+ jsDate.prototype.getTime = function() {
+ return this.proxy.getTime();
+ };
+
+ /**
+ * Get the timezone abbreviation
+ *
+ * @returns {String} Abbreviation for the timezone
+ */
+ jsDate.prototype.getTimezoneAbbr = function() {
+ return this.proxy.toString().replace(/^.*\(([^)]+)\)$/, '$1');
+ };
+
+ /**
+ * Get the browser-reported name for the current timezone (e.g. MDT, Mountain Daylight Time)
+ *
+ * @returns {String}
+ */
+ jsDate.prototype.getTimezoneName = function() {
+ var match = /(?:\((.+)\)$| ([A-Z]{3}) )/.exec(this.toString());
+ return match[1] || match[2] || 'GMT' + this.getGmtOffset();
+ };
+
+ /**
+ * Implements Date functionality
+ */
+ jsDate.prototype.getTimezoneOffset = function() {
+ return this.proxy.getTimezoneOffset();
+ };
+
+
+ /**
+ * Get the week number of the given year, starting with the first Monday as the first week
+ * @returns {Integer} Week number (13 for the 13th week of the year).
+ */
+ jsDate.prototype.getWeekOfYear = function() {
+ var doy = this.getDayOfYear();
+ var rdow = 7 - this.getDayOfWeek();
+ var woy = parseInt((doy+rdow)/7, 10);
+ return woy;
+ };
+
+ /**
+ * Get the current date as a Unix timestamp
+ *
+ * @returns {Integer}
+ */
+
+ jsDate.prototype.getUnix = function() {
+ return Math.round(this.proxy.getTime() / 1000, 0);
+ };
+
+ /**
+ * Implements Date functionality
+ */
+ jsDate.prototype.getYear = function() {
+ return this.proxy.getYear();
+ };
+
+ /**
+ * Return a date one day ahead (or any other unit)
+ *
+ * @param {String} unit Optional, year | month | day | week | hour | minute | second | millisecond
+ * @returns {jsDate}
+ */
+
+ jsDate.prototype.next = function(unit) {
+ unit = unit || 'day';
+ return this.clone().add(1, unit);
+ };
+
+ /**
+ * Set the jsDate instance to a new date.
+ *
+ * @param {String | Number | Array | Date Object | jsDate Object | Options Object} arguments Optional arguments,
+ * either a parsable date/time string,
+ * a JavaScript timestamp, an array of numbers of form [year, month, day, hours, minutes, seconds, milliseconds],
+ * a Date object, jsDate Object or an options object of form {syntax: "perl", date:some Date} where all options are optional.
+ */
+ jsDate.prototype.set = function() {
+ switch ( arguments.length ) {
+ case 0:
+ this.proxy = new Date();
+ break;
+ case 1:
+ // other objects either won't have a _type property or,
+ // if they do, it shouldn't be set to "jsDate", so
+ // assume it is an options argument.
+ if (get_type(arguments[0]) == "[object Object]" && arguments[0]._type != "jsDate") {
+ var opts = this.options = arguments[0];
+ this.syntax = opts.syntax || this.syntax;
+ this.defaultCentury = opts.defaultCentury || this.defaultCentury;
+ this.proxy = jsDate.createDate(opts.date);
+ }
+ else {
+ this.proxy = jsDate.createDate(arguments[0]);
+ }
+ break;
+ default:
+ var a = [];
+ for ( var i=0; i<arguments.length; i++ ) {
+ a.push(arguments[i]);
+ }
+ // this should be the current date/time
+ this.proxy = new Date();
+ this.proxy.setFullYear.apply( this.proxy, a.slice(0,3) );
+ if ( a.slice(3).length ) {
+ this.proxy.setHours.apply( this.proxy, a.slice(3) );
+ }
+ break;
+ }
+ return this;
+ };
+
+ /**
+ * Sets the day of the month for a specified date according to local time.
+ * @param {Integer} dayValue An integer from 1 to 31, representing the day of the month.
+ */
+ jsDate.prototype.setDate = function(n) {
+ this.proxy.setDate(n);
+ return this;
+ };
+
+ /**
+ * Sets the full year for a specified date according to local time.
+ * @param {Integer} yearValue The numeric value of the year, for example, 1995.
+ * @param {Integer} monthValue Optional, between 0 and 11 representing the months January through December.
+ * @param {Integer} dayValue Optional, between 1 and 31 representing the day of the month. If you specify the dayValue parameter, you must also specify the monthValue.
+ */
+ jsDate.prototype.setFullYear = function() {
+ this.proxy.setFullYear.apply(this.proxy, arguments);
+ return this;
+ };
+
+ /**
+ * Sets the hours for a specified date according to local time.
+ *
+ * @param {Integer} hoursValue An integer between 0 and 23, representing the hour.
+ * @param {Integer} minutesValue Optional, An integer between 0 and 59, representing the minutes.
+ * @param {Integer} secondsValue Optional, An integer between 0 and 59, representing the seconds.
+ * If you specify the secondsValue parameter, you must also specify the minutesValue.
+ * @param {Integer} msValue Optional, A number between 0 and 999, representing the milliseconds.
+ * If you specify the msValue parameter, you must also specify the minutesValue and secondsValue.
+ */
+ jsDate.prototype.setHours = function() {
+ this.proxy.setHours.apply(this.proxy, arguments);
+ return this;
+ };
+
+ /**
+ * Implements Date functionality
+ */
+ jsDate.prototype.setMilliseconds = function(n) {
+ this.proxy.setMilliseconds(n);
+ return this;
+ };
+
+ /**
+ * Implements Date functionality
+ */
+ jsDate.prototype.setMinutes = function() {
+ this.proxy.setMinutes.apply(this.proxy, arguments);
+ return this;
+ };
+
+ /**
+ * Implements Date functionality
+ */
+ jsDate.prototype.setMonth = function() {
+ this.proxy.setMonth.apply(this.proxy, arguments);
+ return this;
+ };
+
+ /**
+ * Implements Date functionality
+ */
+ jsDate.prototype.setSeconds = function() {
+ this.proxy.setSeconds.apply(this.proxy, arguments);
+ return this;
+ };
+
+ /**
+ * Implements Date functionality
+ */
+ jsDate.prototype.setTime = function(n) {
+ this.proxy.setTime(n);
+ return this;
+ };
+
+ /**
+ * Implements Date functionality
+ */
+ jsDate.prototype.setYear = function() {
+ this.proxy.setYear.apply(this.proxy, arguments);
+ return this;
+ };
+
+ /**
+ * Provide a formatted string representation of this date.
+ *
+ * @param {String} formatString A format string.
+ * See: {@link jsDate.formats}.
+ * @returns {String} Date String.
+ */
+
+ jsDate.prototype.strftime = function(formatString) {
+ formatString = formatString || this.formatString || jsDate.regional[this.locale]['formatString'];
+ return jsDate.strftime(this, formatString, this.syntax);
+ };
+
+ /**
+ * Return a String representation of this jsDate object.
+ * @returns {String} Date string.
+ */
+
+ jsDate.prototype.toString = function() {
+ return this.proxy.toString();
+ };
+
+ /**
+ * Convert the current date to an 8-digit integer (%Y%m%d)
+ *
+ * @returns {Integer}
+ */
+
+ jsDate.prototype.toYmdInt = function() {
+ return (this.proxy.getFullYear() * 10000) + (this.getMonthNumber() * 100) + this.proxy.getDate();
+ };
+
+ /**
+ * @namespace Holds localizations for month/day names.
+ * <p>jsDate attempts to detect locale when loaded and defaults to 'en'.
+ * If a localization is detected which is not available, jsDate defaults to 'en'.
+ * Additional localizations can be added after jsDate loads. After adding a localization,
+ * call the jsDate.regional.getLocale() method. Currently, en, fr and de are defined.</p>
+ *
+ * <p>Localizations must be an object and have the following properties defined: monthNames, monthNamesShort, dayNames, dayNamesShort and Localizations are added like:</p>
+ * <pre class="code">
+ * jsDate.regional['en'] = {
+ * monthNames : 'January February March April May June July August September October November December'.split(' '),
+ * monthNamesShort : 'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split(' '),
+ * dayNames : 'Sunday Monday Tuesday Wednesday Thursday Friday Saturday'.split(' '),
+ * dayNamesShort : 'Sun Mon Tue Wed Thu Fri Sat'.split(' ')
+ * };
+ * </pre>
+ * <p>After adding localizations, call <code>jsDate.regional.getLocale();</code> to update the locale setting with the
+ * new localizations.</p>
+ */
+
+ jsDate.regional = {
+ 'en': {
+ monthNames: ['January','February','March','April','May','June','July','August','September','October','November','December'],
+ monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun','Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
+ dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
+ dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
+ formatString: '%Y-%m-%d %H:%M:%S'
+ },
+
+ 'fr': {
+ monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin','Juillet','Août','Septembre','Octobre','Novembre','Décembre'],
+ monthNamesShort: ['Jan','Fév','Mar','Avr','Mai','Jun','Jul','Aoû','Sep','Oct','Nov','Déc'],
+ dayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'],
+ dayNamesShort: ['Dim','Lun','Mar','Mer','Jeu','Ven','Sam'],
+ formatString: '%Y-%m-%d %H:%M:%S'
+ },
+
+ 'de': {
+ monthNames: ['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'],
+ monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez'],
+ dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'],
+ dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'],
+ formatString: '%Y-%m-%d %H:%M:%S'
+ },
+
+ 'es': {
+ monthNames: ['Enero','Febrero','Marzo','Abril','Mayo','Junio', 'Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'],
+ monthNamesShort: ['Ene','Feb','Mar','Abr','May','Jun', 'Jul','Ago','Sep','Oct','Nov','Dic'],
+ dayNames: ['Domingo','Lunes','Martes','Miércoles','Jueves','Viernes','Sábado'],
+ dayNamesShort: ['Dom','Lun','Mar','Mié','Juv','Vie','Sáb'],
+ formatString: '%Y-%m-%d %H:%M:%S'
+ },
+
+ 'ru': {
+ monthNames: ['ЯнваÑÑ','ФевÑалÑ','ÐаÑÑ','ÐпÑелÑ','Ðай','ÐÑнÑ','ÐÑлÑ','ÐвгÑÑÑ','СенÑÑбÑÑ','ÐкÑÑбÑÑ','ÐоÑбÑÑ','ÐекабÑÑ'],
+ monthNamesShort: ['Янв','Фев','ÐаÑ','ÐпÑ','Ðай','ÐÑн','ÐÑл','Ðвг','Сен','ÐкÑ','ÐоÑ','Ðек'],
+ dayNames: ['воÑкÑеÑенÑе','понеделÑник','вÑоÑник','ÑÑеда','ÑеÑвеÑг','пÑÑниÑа','ÑÑббоÑа'],
+ dayNamesShort: ['вÑк','пнд','вÑÑ','ÑÑд','ÑÑв','пÑн','ÑбÑ'],
+ formatString: '%Y-%m-%d %H:%M:%S'
+ },
+
+ 'ar': {
+ monthNames: ['ÙØ§ÙÙÙ Ø§ÙØ«Ø§ÙÙ', 'شباط', 'آذار', 'ÙÙØ³Ø§Ù', 'آذار', 'ØØ²ÙراÙ','تÙ
ÙØ²', 'آب', 'Ø£ÙÙÙÙ', 'تشرÙÙ Ø§ÙØ£ÙÙ', 'تشرÙÙ Ø§ÙØ«Ø§ÙÙ', 'ÙØ§ÙÙÙ Ø§ÙØ£ÙÙ'],
+ monthNamesShort: ['1','2','3','4','5','6','7','8','9','10','11','12'],
+ dayNames: ['Ø§ÙØ³Ø¨Øª', 'Ø§ÙØ£ØØ¯', 'Ø§ÙØ§Ø«ÙÙÙ', 'Ø§ÙØ«Ùاثاء', 'Ø§ÙØ£Ø±Ø¨Ø¹Ø§Ø¡', 'Ø§ÙØ®Ù
ÙØ³', 'Ø§ÙØ¬Ù
عة'],
+ dayNamesShort: ['سبت', 'Ø£ØØ¯', 'اثÙÙÙ', 'Ø«ÙØ§Ø«Ø§Ø¡', 'أربعاء', 'Ø®Ù
ÙØ³', 'جÙ
عة'],
+ formatString: '%Y-%m-%d %H:%M:%S'
+ },
+
+ 'pt': {
+ monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho','Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'],
+ monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez'],
+ dayNames: ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sábado'],
+ dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'],
+ formatString: '%Y-%m-%d %H:%M:%S'
+ },
+
+ 'pt-BR': {
+ monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho', 'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'],
+ monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez'],
+ dayNames: ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sábado'],
+ dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'],
+ formatString: '%Y-%m-%d %H:%M:%S'
+ },
+
+ 'pl': {
+ monthNames: ['StyczeÅ','Luty','Marzec','KwiecieÅ','Maj','Czerwiec','Lipiec','SierpieÅ','WrzesieÅ','Październik','Listopad','GrudzieÅ'],
+ monthNamesShort: ['Sty', 'Lut', 'Mar', 'Kwi', 'Maj', 'Cze','Lip', 'Sie', 'Wrz', 'Paź', 'Lis', 'Gru'],
+ dayNames: ['Niedziela', 'PoniedziaÅek', 'Wtorek', 'Åroda', 'Czwartek', 'PiÄ
tek', 'Sobota'],
+ dayNamesShort: ['Ni', 'Pn', 'Wt', 'År', 'Cz', 'Pt', 'Sb'],
+ formatString: '%Y-%m-%d %H:%M:%S'
+ },
+
+ };
+
+ // Set english variants to 'en'
+ jsDate.regional['en-US'] = jsDate.regional['en-GB'] = jsDate.regional['en'];
+
+ /**
+ * Try to determine the users locale based on the lang attribute of the html page. Defaults to 'en'
+ * if it cannot figure out a locale of if the locale does not have a localization defined.
+ * @returns {String} locale
+ */
+
+ jsDate.regional.getLocale = function () {
+ var l = jsDate.config.defaultLocale;
+
+ if ( document && document.getElementsByTagName('html') && document.getElementsByTagName('html')[0].lang ) {
+ l = document.getElementsByTagName('html')[0].lang;
+ if (!jsDate.regional.hasOwnProperty(l)) {
+ l = jsDate.config.defaultLocale;
+ }
+ }
+
+ return l;
+ };
+
+ // ms in day
+ var day = 24 * 60 * 60 * 1000;
+
+ // padd a number with zeros
+ var addZeros = function(num, digits) {
+ num = String(num);
+ var i = digits - num.length;
+ var s = String(Math.pow(10, i)).slice(1);
+ return s.concat(num);
+ };
+
+ // representations used for calculating differences between dates.
+ // This borrows heavily from Ken Snyder's work.
+ var multipliers = {
+ millisecond: 1,
+ second: 1000,
+ minute: 60 * 1000,
+ hour: 60 * 60 * 1000,
+ day: day,
+ week: 7 * day,
+ month: {
+ // add a number of months
+ add: function(d, number) {
+ // add any years needed (increments of 12)
+ multipliers.year.add(d, Math[number > 0 ? 'floor' : 'ceil'](number / 12));
+ // ensure that we properly wrap betwen December and January
+ // 11 % 12 = 11
+ // 12 % 12 = 0
+ var prevMonth = d.getMonth() + (number % 12);
+ if (prevMonth == 12) {
+ prevMonth = 0;
+ d.setYear(d.getFullYear() + 1);
+ } else if (prevMonth == -1) {
+ prevMonth = 11;
+ d.setYear(d.getFullYear() - 1);
+ }
+ d.setMonth(prevMonth);
+ },
+ // get the number of months between two Date objects (decimal to the nearest day)
+ diff: function(d1, d2) {
+ // get the number of years
+ var diffYears = d1.getFullYear() - d2.getFullYear();
+ // get the number of remaining months
+ var diffMonths = d1.getMonth() - d2.getMonth() + (diffYears * 12);
+ // get the number of remaining days
+ var diffDays = d1.getDate() - d2.getDate();
+ // return the month difference with the days difference as a decimal
+ return diffMonths + (diffDays / 30);
+ }
+ },
+ year: {
+ // add a number of years
+ add: function(d, number) {
+ d.setYear(d.getFullYear() + Math[number > 0 ? 'floor' : 'ceil'](number));
+ },
+ // get the number of years between two Date objects (decimal to the nearest day)
+ diff: function(d1, d2) {
+ return multipliers.month.diff(d1, d2) / 12;
+ }
+ }
+ };
+ //
+ // Alias each multiplier with an 's' to allow 'year' and 'years' for example.
+ // This comes from Ken Snyders work.
+ //
+ for (var unit in multipliers) {
+ if (unit.substring(unit.length - 1) != 's') { // IE will iterate newly added properties :|
+ multipliers[unit + 's'] = multipliers[unit];
+ }
+ }
+
+ //
+ // take a jsDate instance and a format code and return the formatted value.
+ // This is a somewhat modified version of Ken Snyder's method.
+ //
+ var format = function(d, code, syntax) {
+ // if shorcut codes are used, recursively expand those.
+ if (jsDate.formats[syntax]["shortcuts"][code]) {
+ return jsDate.strftime(d, jsDate.formats[syntax]["shortcuts"][code], syntax);
+ } else {
+ // get the format code function and addZeros() argument
+ var getter = (jsDate.formats[syntax]["codes"][code] || '').split('.');
+ var nbr = d['get' + getter[0]] ? d['get' + getter[0]]() : '';
+ if (getter[1]) {
+ nbr = addZeros(nbr, getter[1]);
+ }
+ return nbr;
+ }
+ };
+
+ /**
+ * @static
+ * Static function for convert a date to a string according to a given format. Also acts as namespace for strftime format codes.
+ * <p>strftime formatting can be accomplished without creating a jsDate object by calling jsDate.strftime():</p>
+ * <pre class="code">
+ * var formattedDate = jsDate.strftime('Feb 8, 2006 8:48:32', '%Y-%m-%d %H:%M:%S');
+ * </pre>
+ * @param {String | Number | Array | jsDate Object | Date Object} date A parsable date string, JavaScript time stamp, Array of form [year, month, day, hours, minutes, seconds, milliseconds], jsDate Object or Date object.
+ * @param {String} formatString String with embedded date formatting codes.
+ * See: {@link jsDate.formats}.
+ * @param {String} syntax Optional syntax to use [default perl].
+ * @param {String} locale Optional locale to use.
+ * @returns {String} Formatted representation of the date.
+ */
+ //
+ // Logic as implemented here is very similar to Ken Snyder's Date Instance Methods.
+ //
+ jsDate.strftime = function(d, formatString, syntax, locale) {
+ var syn = 'perl';
+ var loc = jsDate.regional.getLocale();
+
+ // check if syntax and locale are available or reversed
+ if (syntax && jsDate.formats.hasOwnProperty(syntax)) {
+ syn = syntax;
+ }
+ else if (syntax && jsDate.regional.hasOwnProperty(syntax)) {
+ loc = syntax;
+ }
+
+ if (locale && jsDate.formats.hasOwnProperty(locale)) {
+ syn = locale;
+ }
+ else if (locale && jsDate.regional.hasOwnProperty(locale)) {
+ loc = locale;
+ }
+
+ if (get_type(d) != "[object Object]" || d._type != "jsDate") {
+ d = new jsDate(d);
+ d.locale = loc;
+ }
+ if (!formatString) {
+ formatString = d.formatString || jsDate.regional[loc]['formatString'];
+ }
+ // default the format string to year-month-day
+ var source = formatString || '%Y-%m-%d',
+ result = '',
+ match;
+ // replace each format code
+ while (source.length > 0) {
+ if (match = source.match(jsDate.formats[syn].codes.matcher)) {
+ result += source.slice(0, match.index);
+ result += (match[1] || '') + format(d, match[2], syn);
+ source = source.slice(match.index + match[0].length);
+ } else {
+ result += source;
+ source = '';
+ }
+ }
+ return result;
+ };
+
+ /**
+ * @namespace
+ * Namespace to hold format codes and format shortcuts. "perl" and "php" format codes
+ * and shortcuts are defined by default. Additional codes and shortcuts can be
+ * added like:
+ *
+ * <pre class="code">
+ * jsDate.formats["perl"] = {
+ * "codes": {
+ * matcher: /someregex/,
+ * Y: "fullYear", // name of "get" method without the "get",
+ * ..., // more codes
+ * },
+ * "shortcuts": {
+ * F: '%Y-%m-%d',
+ * ..., // more shortcuts
+ * }
+ * };
+ * </pre>
+ *
+ * <p>Additionally, ISO and SQL shortcuts are defined and can be accesses via:
+ * <code>jsDate.formats.ISO</code> and <code>jsDate.formats.SQL</code>
+ */
+
+ jsDate.formats = {
+ ISO:'%Y-%m-%dT%H:%M:%S.%N%G',
+ SQL:'%Y-%m-%d %H:%M:%S'
+ };
+
+ /**
+ * Perl format codes and shortcuts for strftime.
+ *
+ * A hash (object) of codes where each code must be an array where the first member is
+ * the name of a Date.prototype or jsDate.prototype function to call
+ * and optionally a second member indicating the number to pass to addZeros()
+ *
+ * <p>The following format codes are defined:</p>
+ *
+ * <pre class="code">
+ * Code Result Description
+ * == Years ==
+ * %Y 2008 Four-digit year
+ * %y 08 Two-digit year
+ *
+ * == Months ==
+ * %m 09 Two-digit month
+ * %#m 9 One or two-digit month
+ * %B September Full month name
+ * %b Sep Abbreviated month name
+ *
+ * == Days ==
+ * %d 05 Two-digit day of month
+ * %#d 5 One or two-digit day of month
+ * %e 5 One or two-digit day of month
+ * %A Sunday Full name of the day of the week
+ * %a Sun Abbreviated name of the day of the week
+ * %w 0 Number of the day of the week (0 = Sunday, 6 = Saturday)
+ *
+ * == Hours ==
+ * %H 23 Hours in 24-hour format (two digits)
+ * %#H 3 Hours in 24-hour integer format (one or two digits)
+ * %I 11 Hours in 12-hour format (two digits)
+ * %#I 3 Hours in 12-hour integer format (one or two digits)
+ * %p PM AM or PM
+ *
+ * == Minutes ==
+ * %M 09 Minutes (two digits)
+ * %#M 9 Minutes (one or two digits)
+ *
+ * == Seconds ==
+ * %S 02 Seconds (two digits)
+ * %#S 2 Seconds (one or two digits)
+ * %s 1206567625723 Unix timestamp (Seconds past 1970-01-01 00:00:00)
+ *
+ * == Milliseconds ==
+ * %N 008 Milliseconds (three digits)
+ * %#N 8 Milliseconds (one to three digits)
+ *
+ * == Timezone ==
+ * %O 360 difference in minutes between local time and GMT
+ * %Z Mountain Standard Time Name of timezone as reported by browser
+ * %G 06:00 Hours and minutes between GMT
+ *
+ * == Shortcuts ==
+ * %F 2008-03-26 %Y-%m-%d
+ * %T 05:06:30 %H:%M:%S
+ * %X 05:06:30 %H:%M:%S
+ * %x 03/26/08 %m/%d/%y
+ * %D 03/26/08 %m/%d/%y
+ * %#c Wed Mar 26 15:31:00 2008 %a %b %e %H:%M:%S %Y
+ * %v 3-Sep-2008 %e-%b-%Y
+ * %R 15:31 %H:%M
+ * %r 03:31:00 PM %I:%M:%S %p
+ *
+ * == Characters ==
+ * %n \n Newline
+ * %t \t Tab
+ * %% % Percent Symbol
+ * </pre>
+ *
+ * <p>Formatting shortcuts that will be translated into their longer version.
+ * Be sure that format shortcuts do not refer to themselves: this will cause an infinite loop.</p>
+ *
+ * <p>Format codes and format shortcuts can be redefined after the jsDate
+ * module is imported.</p>
+ *
+ * <p>Note that if you redefine the whole hash (object), you must supply a "matcher"
+ * regex for the parser. The default matcher is:</p>
+ *
+ * <code>/()%(#?(%|[a-z]))/i</code>
+ *
+ * <p>which corresponds to the Perl syntax used by default.</p>
+ *
+ * <p>By customizing the matcher and format codes, nearly any strftime functionality is possible.</p>
+ */
+
+ jsDate.formats.perl = {
+ codes: {
+ //
+ // 2-part regex matcher for format codes
+ //
+ // first match must be the character before the code (to account for escaping)
+ // second match must be the format code character(s)
+ //
+ matcher: /()%(#?(%|[a-z]))/i,
+ // year
+ Y: 'FullYear',
+ y: 'ShortYear.2',
+ // month
+ m: 'MonthNumber.2',
+ '#m': 'MonthNumber',
+ B: 'MonthName',
+ b: 'AbbrMonthName',
+ // day
+ d: 'Date.2',
+ '#d': 'Date',
+ e: 'Date',
+ A: 'DayName',
+ a: 'AbbrDayName',
+ w: 'Day',
+ // hours
+ H: 'Hours.2',
+ '#H': 'Hours',
+ I: 'Hours12.2',
+ '#I': 'Hours12',
+ p: 'AMPM',
+ // minutes
+ M: 'Minutes.2',
+ '#M': 'Minutes',
+ // seconds
+ S: 'Seconds.2',
+ '#S': 'Seconds',
+ s: 'Unix',
+ // milliseconds
+ N: 'Milliseconds.3',
+ '#N': 'Milliseconds',
+ // timezone
+ O: 'TimezoneOffset',
+ Z: 'TimezoneName',
+ G: 'GmtOffset'
+ },
+
+ shortcuts: {
+ // date
+ F: '%Y-%m-%d',
+ // time
+ T: '%H:%M:%S',
+ X: '%H:%M:%S',
+ // local format date
+ x: '%m/%d/%y',
+ D: '%m/%d/%y',
+ // local format extended
+ '#c': '%a %b %e %H:%M:%S %Y',
+ // local format short
+ v: '%e-%b-%Y',
+ R: '%H:%M',
+ r: '%I:%M:%S %p',
+ // tab and newline
+ t: '\t',
+ n: '\n',
+ '%': '%'
+ }
+ };
+
+ /**
+ * PHP format codes and shortcuts for strftime.
+ *
+ * A hash (object) of codes where each code must be an array where the first member is
+ * the name of a Date.prototype or jsDate.prototype function to call
+ * and optionally a second member indicating the number to pass to addZeros()
+ *
+ * <p>The following format codes are defined:</p>
+ *
+ * <pre class="code">
+ * Code Result Description
+ * === Days ===
+ * %a Sun through Sat An abbreviated textual representation of the day
+ * %A Sunday - Saturday A full textual representation of the day
+ * %d 01 to 31 Two-digit day of the month (with leading zeros)
+ * %e 1 to 31 Day of the month, with a space preceding single digits.
+ * %j 001 to 366 Day of the year, 3 digits with leading zeros
+ * %u 1 - 7 (Mon - Sun) ISO-8601 numeric representation of the day of the week
+ * %w 0 - 6 (Sun - Sat) Numeric representation of the day of the week
+ *
+ * === Week ===
+ * %U 13 Full Week number, starting with the first Sunday as the first week
+ * %V 01 through 53 ISO-8601:1988 week number, starting with the first week of the year
+ * with at least 4 weekdays, with Monday being the start of the week
+ * %W 46 A numeric representation of the week of the year,
+ * starting with the first Monday as the first week
+ * === Month ===
+ * %b Jan through Dec Abbreviated month name, based on the locale
+ * %B January - December Full month name, based on the locale
+ * %h Jan through Dec Abbreviated month name, based on the locale (an alias of %b)
+ * %m 01 - 12 (Jan - Dec) Two digit representation of the month
+ *
+ * === Year ===
+ * %C 19 Two digit century (year/100, truncated to an integer)
+ * %y 09 for 2009 Two digit year
+ * %Y 2038 Four digit year
+ *
+ * === Time ===
+ * %H 00 through 23 Two digit representation of the hour in 24-hour format
+ * %I 01 through 12 Two digit representation of the hour in 12-hour format
+ * %l 1 through 12 Hour in 12-hour format, with a space preceeding single digits
+ * %M 00 through 59 Two digit representation of the minute
+ * %p AM/PM UPPER-CASE 'AM' or 'PM' based on the given time
+ * %P am/pm lower-case 'am' or 'pm' based on the given time
+ * %r 09:34:17 PM Same as %I:%M:%S %p
+ * %R 00:35 Same as %H:%M
+ * %S 00 through 59 Two digit representation of the second
+ * %T 21:34:17 Same as %H:%M:%S
+ * %X 03:59:16 Preferred time representation based on locale, without the date
+ * %z -0500 or EST Either the time zone offset from UTC or the abbreviation
+ * %Z -0500 or EST The time zone offset/abbreviation option NOT given by %z
+ *
+ * === Time and Date ===
+ * %D 02/05/09 Same as %m/%d/%y
+ * %F 2009-02-05 Same as %Y-%m-%d (commonly used in database datestamps)
+ * %s 305815200 Unix Epoch Time timestamp (same as the time() function)
+ * %x 02/05/09 Preferred date representation, without the time
+ *
+ * === Miscellaneous ===
+ * %n --- A newline character (\n)
+ * %t --- A Tab character (\t)
+ * %% --- A literal percentage character (%)
+ * </pre>
+ */
+
+ jsDate.formats.php = {
+ codes: {
+ //
+ // 2-part regex matcher for format codes
+ //
+ // first match must be the character before the code (to account for escaping)
+ // second match must be the format code character(s)
+ //
+ matcher: /()%((%|[a-z]))/i,
+ // day
+ a: 'AbbrDayName',
+ A: 'DayName',
+ d: 'Date.2',
+ e: 'Date',
+ j: 'DayOfYear.3',
+ u: 'DayOfWeek',
+ w: 'Day',
+ // week
+ U: 'FullWeekOfYear.2',
+ V: 'IsoWeek.2',
+ W: 'WeekOfYear.2',
+ // month
+ b: 'AbbrMonthName',
+ B: 'MonthName',
+ m: 'MonthNumber.2',
+ h: 'AbbrMonthName',
+ // year
+ C: 'Century.2',
+ y: 'ShortYear.2',
+ Y: 'FullYear',
+ // time
+ H: 'Hours.2',
+ I: 'Hours12.2',
+ l: 'Hours12',
+ p: 'AMPM',
+ P: 'AmPm',
+ M: 'Minutes.2',
+ S: 'Seconds.2',
+ s: 'Unix',
+ O: 'TimezoneOffset',
+ z: 'GmtOffset',
+ Z: 'TimezoneAbbr'
+ },
+
+ shortcuts: {
+ D: '%m/%d/%y',
+ F: '%Y-%m-%d',
+ T: '%H:%M:%S',
+ X: '%H:%M:%S',
+ x: '%m/%d/%y',
+ R: '%H:%M',
+ r: '%I:%M:%S %p',
+ t: '\t',
+ n: '\n',
+ '%': '%'
+ }
+ };
+ //
+ // Conceptually, the logic implemented here is similar to Ken Snyder's Date Instance Methods.
+ // I use his idea of a set of parsers which can be regular expressions or functions,
+ // iterating through those, and then seeing if Date.parse() will create a date.
+ // The parser expressions and functions are a little different and some bugs have been
+ // worked out. Also, a lot of "pre-parsing" is done to fix implementation
+ // variations of Date.parse() between browsers.
+ //
+ jsDate.createDate = function(date) {
+ // if passing in multiple arguments, try Date constructor
+ if (date == null) {
+ return new Date();
+ }
+ // If the passed value is already a date object, return it
+ if (date instanceof Date) {
+ return date;
+ }
+ // if (typeof date == 'number') return new Date(date * 1000);
+ // If the passed value is an integer, interpret it as a javascript timestamp
+ if (typeof date == 'number') {
+ return new Date(date);
+ }
+
+ // Before passing strings into Date.parse(), have to normalize them for certain conditions.
+ // If strings are not formatted staccording to the EcmaScript spec, results from Date parse will be implementation dependent.
+ //
+ // For example:
+ // * FF and Opera assume 2 digit dates are pre y2k, Chome assumes <50 is pre y2k, 50+ is 21st century.
+ // * Chrome will correctly parse '1984-1-25' into localtime, FF and Opera will not parse.
+ // * Both FF, Chrome and Opera will parse '1984/1/25' into localtime.
+
+ // remove leading and trailing spaces
+ var parsable = String(date).replace(/^\s*(.+)\s*$/g, '$1');
+
+ // replace dahses (-) with slashes (/) in dates like n[nnn]/n[n]/n[nnn]
+ parsable = parsable.replace(/^([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,4})/, "$1/$2/$3");
+
+ /////////
+ // Need to check for '15-Dec-09' also.
+ // FF will not parse, but Chrome will.
+ // Chrome will set date to 2009 as well.
+ /////////
+
+ // first check for 'dd-mmm-yyyy' or 'dd/mmm/yyyy' like '15-Dec-2010'
+ parsable = parsable.replace(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{4})/i, "$1 $2 $3");
+
+ // Now check for 'dd-mmm-yy' or 'dd/mmm/yy' and normalize years to default century.
+ var match = parsable.match(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{2})\D*/i);
+ if (match && match.length > 3) {
+ var m3 = parseFloat(match[3]);
+ var ny = jsDate.config.defaultCentury + m3;
+ ny = String(ny);
+
+ // now replace 2 digit year with 4 digit year
+ parsable = parsable.replace(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{2})\D*/i, match[1] +' '+ match[2] +' '+ ny);
+
+ }
+
+ // Check for '1/19/70 8:14PM'
+ // where starts with mm/dd/yy or yy/mm/dd and have something after
+ // Check if 1st postiion is greater than 31, assume it is year.
+ // Assme all 2 digit years are 1900's.
+ // Finally, change them into US style mm/dd/yyyy representations.
+ match = parsable.match(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})[^0-9]/);
+
+ function h1(parsable, match) {
+ var m1 = parseFloat(match[1]);
+ var m2 = parseFloat(match[2]);
+ var m3 = parseFloat(match[3]);
+ var cent = jsDate.config.defaultCentury;
+ var ny, nd, nm, str;
+
+ if (m1 > 31) { // first number is a year
+ nd = m3;
+ nm = m2;
+ ny = cent + m1;
+ }
+
+ else { // last number is the year
+ nd = m2;
+ nm = m1;
+ ny = cent + m3;
+ }
+
+ str = nm+'/'+nd+'/'+ny;
+
+ // now replace 2 digit year with 4 digit year
+ return parsable.replace(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})/, str);
+
+ }
+
+ if (match && match.length > 3) {
+ parsable = h1(parsable, match);
+ }
+
+ // Now check for '1/19/70' with nothing after and do as above
+ var match = parsable.match(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})$/);
+
+ if (match && match.length > 3) {
+ parsable = h1(parsable, match);
+ }
+
+
+ var i = 0;
+ var length = jsDate.matchers.length;
+ var pattern,
+ ms,
+ current = parsable,
+ obj;
+ while (i < length) {
+ ms = Date.parse(current);
+ if (!isNaN(ms)) {
+ return new Date(ms);
+ }
+ pattern = jsDate.matchers[i];
+ if (typeof pattern == 'function') {
+ obj = pattern.call(jsDate, current);
+ if (obj instanceof Date) {
+ return obj;
+ }
+ } else {
+ current = parsable.replace(pattern[0], pattern[1]);
+ }
+ i++;
+ }
+ return NaN;
+ };
+
+
+ /**
+ * @static
+ * Handy static utility function to return the number of days in a given month.
+ * @param {Integer} year Year
+ * @param {Integer} month Month (1-12)
+ * @returns {Integer} Number of days in the month.
+ */
+ //
+ // handy utility method Borrowed right from Ken Snyder's Date Instance Mehtods.
+ //
+ jsDate.daysInMonth = function(year, month) {
+ if (month == 2) {
+ return new Date(year, 1, 29).getDate() == 29 ? 29 : 28;
+ }
+ return [undefined,31,undefined,31,30,31,30,31,31,30,31,30,31][month];
+ };
+
+
+ //
+ // An Array of regular expressions or functions that will attempt to match the date string.
+ // Functions are called with scope of a jsDate instance.
+ //
+ jsDate.matchers = [
+ // convert dd.mmm.yyyy to mm/dd/yyyy (world date to US date).
+ [/(3[01]|[0-2]\d)\s*\.\s*(1[0-2]|0\d)\s*\.\s*([1-9]\d{3})/, '$2/$1/$3'],
+ // convert yyyy-mm-dd to mm/dd/yyyy (ISO date to US date).
+ [/([1-9]\d{3})\s*-\s*(1[0-2]|0\d)\s*-\s*(3[01]|[0-2]\d)/, '$2/$3/$1'],
+ // Handle 12 hour or 24 hour time with milliseconds am/pm and optional date part.
+ function(str) {
+ var match = str.match(/^(?:(.+)\s+)?([012]?\d)(?:\s*\:\s*(\d\d))?(?:\s*\:\s*(\d\d(\.\d*)?))?\s*(am|pm)?\s*$/i);
+ // opt. date hour opt. minute opt. second opt. msec opt. am or pm
+ if (match) {
+ if (match[1]) {
+ var d = this.createDate(match[1]);
+ if (isNaN(d)) {
+ return;
+ }
+ } else {
+ var d = new Date();
+ d.setMilliseconds(0);
+ }
+ var hour = parseFloat(match[2]);
+ if (match[6]) {
+ hour = match[6].toLowerCase() == 'am' ? (hour == 12 ? 0 : hour) : (hour == 12 ? 12 : hour + 12);
+ }
+ d.setHours(hour, parseInt(match[3] || 0, 10), parseInt(match[4] || 0, 10), ((parseFloat(match[5] || 0)) || 0)*1000);
+ return d;
+ }
+ else {
+ return str;
+ }
+ },
+ // Handle ISO timestamp with time zone.
+ function(str) {
+ var match = str.match(/^(?:(.+))[T|\s+]([012]\d)(?:\:(\d\d))(?:\:(\d\d))(?:\.\d+)([\+\-]\d\d\:\d\d)$/i);
+ if (match) {
+ if (match[1]) {
+ var d = this.createDate(match[1]);
+ if (isNaN(d)) {
+ return;
+ }
+ } else {
+ var d = new Date();
+ d.setMilliseconds(0);
+ }
+ var hour = parseFloat(match[2]);
+ d.setHours(hour, parseInt(match[3], 10), parseInt(match[4], 10), parseFloat(match[5])*1000);
+ return d;
+ }
+ else {
+ return str;
+ }
+ },
+ // Try to match ambiguous strings like 12/8/22.
+ // Use FF date assumption that 2 digit years are 20th century (i.e. 1900's).
+ // This may be redundant with pre processing of date already performed.
+ function(str) {
+ var match = str.match(/^([0-3]?\d)\s*[-\/.\s]{1}\s*([a-zA-Z]{3,9})\s*[-\/.\s]{1}\s*([0-3]?\d)$/);
+ if (match) {
+ var d = new Date();
+ var cent = jsDate.config.defaultCentury;
+ var m1 = parseFloat(match[1]);
+ var m3 = parseFloat(match[3]);
+ var ny, nd, nm;
+ if (m1 > 31) { // first number is a year
+ nd = m3;
+ ny = cent + m1;
+ }
+
+ else { // last number is the year
+ nd = m1;
+ ny = cent + m3;
+ }
+
+ var nm = inArray(match[2], jsDate.regional[jsDate.regional.getLocale()]["monthNamesShort"]);
+
+ if (nm == -1) {
+ nm = inArray(match[2], jsDate.regional[jsDate.regional.getLocale()]["monthNames"]);
+ }
+
+ d.setFullYear(ny, nm, nd);
+ d.setHours(0,0,0,0);
+ return d;
+ }
+
+ else {
+ return str;
+ }
+ }
+ ];
+
+ //
+ // I think John Reisig published this method on his blog, ejohn.
+ //
+ function inArray( elem, array ) {
+ if ( array.indexOf ) {
+ return array.indexOf( elem );
+ }
+
+ for ( var i = 0, length = array.length; i < length; i++ ) {
+ if ( array[ i ] === elem ) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ //
+ // Thanks to Kangax, Christian Sciberras and Stack Overflow for this method.
+ //
+ function get_type(thing){
+ if(thing===null) return "[object Null]"; // special case
+ return Object.prototype.toString.call(thing);
+ }
+
+ $.jsDate = jsDate;
+
/**
* JavaScript printf/sprintf functions.
@@ -6795,6 +10824,12 @@
* Format: '%.4g', Input: 12.0, Output: 12.00
* Format: '%.4p', Input: 4.321e-5, Output: 4.321e-5
* Format: '%.4g', Input: 4.321e-5, Output: 4.3210e-5
+ *
+ * Example:
+ * >>> $.jqplot.sprintf('%.2f, %d', 23.3452, 43.23)
+ * "23.35, 43"
+ * >>> $.jqplot.sprintf("no value: %n, decimal with thousands separator: %'d", 23.3452, 433524)
+ * "no value: , decimal with thousands separator: 433,524"
*/
$.jqplot.sprintf = function() {
function pad(str, len, chr, leftJustify) {
@@ -6803,6 +10838,14 @@
}
+ function thousand_separate(value) {
+ var value_str = new String(value);
+ for (var i=10; i>0; i--) {
+ if (value_str == (value_str = value_str.replace(/^(\d+)(\d{3})/, "$1"+$.jqplot.sprintf.thousandsSeparator+"$2"))) break;
+ }
+ return value_str;
+ }
+
function justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace) {
var diff = minWidth - value.length;
if (diff > 0) {
@@ -6838,14 +10881,15 @@
if (substring == '%%') { return '%'; }
// parse flags
- var leftJustify = false, positivePrefix = '', zeroPad = false, prefixBaseX = false, htmlSpace = false;
- for (var j = 0; flags && j < flags.length; j++) switch (flags.charAt(j)) {
+ var leftJustify = false, positivePrefix = '', zeroPad = false, prefixBaseX = false, htmlSpace = false, thousandSeparation = false;
+ for (var j = 0; flags && j < flags.length; j++) switch (flags.charAt(j)) {
case ' ': positivePrefix = ' '; break;
case '+': positivePrefix = '+'; break;
case '-': leftJustify = true; break;
case '0': zeroPad = true; break;
case '#': prefixBaseX = true; break;
case '&': htmlSpace = true; break;
+ case '\'': thousandSeparation = true; break;
}
// parameters may be null, undefined, empty-string or real valued
@@ -6909,7 +10953,9 @@
return '';
}
var prefix = number < 0 ? '-' : positivePrefix;
- value = prefix + pad(String(Math.abs(number)), precision, '0', false);
+ var number_str = thousandSeparation ? thousand_separate(String(Math.abs(number))): String(Math.abs(number));
+ value = prefix + pad(number_str, precision, '0', false);
+ //value = prefix + pad(String(Math.abs(number)), precision, '0', false);
return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace);
}
case 'd': {
@@ -6918,7 +10964,8 @@
return '';
}
var prefix = number < 0 ? '-' : positivePrefix;
- value = prefix + pad(String(Math.abs(number)), precision, '0', false);
+ var number_str = thousandSeparation ? thousand_separate(String(Math.abs(number))): String(Math.abs(number));
+ value = prefix + pad(number_str, precision, '0', false);
return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace);
}
case 'e':
@@ -6935,8 +10982,16 @@
var prefix = number < 0 ? '-' : positivePrefix;
var method = ['toExponential', 'toFixed', 'toPrecision']['efg'.indexOf(type.toLowerCase())];
var textTransform = ['toString', 'toUpperCase']['eEfFgG'.indexOf(type) % 2];
- value = prefix + Math.abs(number)[method](precision);
- return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace)[textTransform]();
+ var number_str = Math.abs(number)[method](precision);
+ number_str = thousandSeparation ? thousand_separate(number_str): number_str;
+ value = prefix + number_str;
+ var justified = justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace)[textTransform]();
+
+ if ($.jqplot.sprintf.decimalMark !== '.' && $.jqplot.sprintf.decimalMark !== $.jqplot.sprintf.thousandsSeparator) {
+ return justified.replace(/\./, $.jqplot.sprintf.decimalMark);
+ } else {
+ return justified;
+ }
}
case 'p':
case 'P':
@@ -6977,7 +11032,357 @@
}
});
};
+
+ $.jqplot.sprintf.thousandsSeparator = ',';
+ // Specifies the decimal mark for floating point values. By default a period '.'
+ // is used. If you change this value to for example a comma be sure to also
+ // change the thousands separator or else this won't work since a simple String
+ // replace is used (replacing all periods with the mark specified here).
+ $.jqplot.sprintf.decimalMark = '.';
- $.jqplot.sprintf.regex = /%%|%(\d+\$)?([-+#0& ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([nAscboxXuidfegpEGP])/g;
+ $.jqplot.sprintf.regex = /%%|%(\d+\$)?([-+#0&\' ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([nAscboxXuidfegpEGP])/g;
-})(jQuery);
\ No newline at end of file
+ $.jqplot.getSignificantFigures = function(number) {
+ var parts = String(Number(Math.abs(number)).toExponential()).split(/e|E/);
+ // total significant digits
+ var sd = (parts[0].indexOf('.') != -1) ? parts[0].length - 1 : parts[0].length;
+ var zeros = (parts[1] < 0) ? -parts[1] - 1 : 0;
+ // exponent
+ var expn = parseInt(parts[1], 10);
+ // digits to the left of the decimal place
+ var dleft = (expn + 1 > 0) ? expn + 1 : 0;
+ // digits to the right of the decimal place
+ var dright = (sd <= dleft) ? 0 : sd - expn - 1;
+ return {significantDigits: sd, digitsLeft: dleft, digitsRight: dright, zeros: zeros, exponent: expn} ;
+ };
+
+ $.jqplot.getPrecision = function(number) {
+ return $.jqplot.getSignificantFigures(number).digitsRight;
+ };
+
+
+
+
+ var backCompat = $.uiBackCompat !== false;
+
+ $.jqplot.effects = {
+ effect: {}
+ };
+
+ // prefix used for storing data on .data()
+ var dataSpace = "jqplot.storage.";
+
+ /******************************************************************************/
+ /*********************************** EFFECTS **********************************/
+ /******************************************************************************/
+
+ $.extend( $.jqplot.effects, {
+ version: "1.9pre",
+
+ // Saves a set of properties in a data storage
+ save: function( element, set ) {
+ for( var i=0; i < set.length; i++ ) {
+ if ( set[ i ] !== null ) {
+ element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
+ }
+ }
+ },
+
+ // Restores a set of previously saved properties from a data storage
+ restore: function( element, set ) {
+ for( var i=0; i < set.length; i++ ) {
+ if ( set[ i ] !== null ) {
+ element.css( set[ i ], element.data( dataSpace + set[ i ] ) );
+ }
+ }
+ },
+
+ setMode: function( el, mode ) {
+ if (mode === "toggle") {
+ mode = el.is( ":hidden" ) ? "show" : "hide";
+ }
+ return mode;
+ },
+
+ // Wraps the element around a wrapper that copies position properties
+ createWrapper: function( element ) {
+
+ // if the element is already wrapped, return it
+ if ( element.parent().is( ".ui-effects-wrapper" )) {
+ return element.parent();
+ }
+
+ // wrap the element
+ var props = {
+ width: element.outerWidth(true),
+ height: element.outerHeight(true),
+ "float": element.css( "float" )
+ },
+ wrapper = $( "<div></div>" )
+ .addClass( "ui-effects-wrapper" )
+ .css({
+ fontSize: "100%",
+ background: "transparent",
+ border: "none",
+ margin: 0,
+ padding: 0
+ }),
+ // Store the size in case width/height are defined in % - Fixes #5245
+ size = {
+ width: element.width(),
+ height: element.height()
+ },
+ active = document.activeElement;
+
+ element.wrap( wrapper );
+
+ // Fixes #7595 - Elements lose focus when wrapped.
+ if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
+ $( active ).focus();
+ }
+
+ wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element
+
+ // transfer positioning properties to the wrapper
+ if ( element.css( "position" ) === "static" ) {
+ wrapper.css({ position: "relative" });
+ element.css({ position: "relative" });
+ } else {
+ $.extend( props, {
+ position: element.css( "position" ),
+ zIndex: element.css( "z-index" )
+ });
+ $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
+ props[ pos ] = element.css( pos );
+ if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
+ props[ pos ] = "auto";
+ }
+ });
+ element.css({
+ position: "relative",
+ top: 0,
+ left: 0,
+ right: "auto",
+ bottom: "auto"
+ });
+ }
+ element.css(size);
+
+ return wrapper.css( props ).show();
+ },
+
+ removeWrapper: function( element ) {
+ var active = document.activeElement;
+
+ if ( element.parent().is( ".ui-effects-wrapper" ) ) {
+ element.parent().replaceWith( element );
+
+ // Fixes #7595 - Elements lose focus when wrapped.
+ if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
+ $( active ).focus();
+ }
+ }
+
+
+ return element;
+ }
+ });
+
+ // return an effect options object for the given parameters:
+ function _normalizeArguments( effect, options, speed, callback ) {
+
+ // short path for passing an effect options object:
+ if ( $.isPlainObject( effect ) ) {
+ return effect;
+ }
+
+ // convert to an object
+ effect = { effect: effect };
+
+ // catch (effect)
+ if ( options === undefined ) {
+ options = {};
+ }
+
+ // catch (effect, callback)
+ if ( $.isFunction( options ) ) {
+ callback = options;
+ speed = null;
+ options = {};
+ }
+
+ // catch (effect, speed, ?)
+ if ( $.type( options ) === "number" || $.fx.speeds[ options ]) {
+ callback = speed;
+ speed = options;
+ options = {};
+ }
+
+ // catch (effect, options, callback)
+ if ( $.isFunction( speed ) ) {
+ callback = speed;
+ speed = null;
+ }
+
+ // add options to effect
+ if ( options ) {
+ $.extend( effect, options );
+ }
+
+ speed = speed || options.duration;
+ effect.duration = $.fx.off ? 0 : typeof speed === "number"
+ ? speed : speed in $.fx.speeds ? $.fx.speeds[ speed ] : $.fx.speeds._default;
+
+ effect.complete = callback || options.complete;
+
+ return effect;
+ }
+
+ function standardSpeed( speed ) {
+ // valid standard speeds
+ if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
+ return true;
+ }
+
+ // invalid strings - treat as "normal" speed
+ if ( typeof speed === "string" && !$.jqplot.effects.effect[ speed ] ) {
+ // TODO: remove in 2.0 (#7115)
+ if ( backCompat && $.jqplot.effects[ speed ] ) {
+ return false;
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ $.fn.extend({
+ jqplotEffect: function( effect, options, speed, callback ) {
+ var args = _normalizeArguments.apply( this, arguments ),
+ mode = args.mode,
+ queue = args.queue,
+ effectMethod = $.jqplot.effects.effect[ args.effect ],
+
+ // DEPRECATED: remove in 2.0 (#7115)
+ oldEffectMethod = !effectMethod && backCompat && $.jqplot.effects[ args.effect ];
+
+ if ( $.fx.off || !( effectMethod || oldEffectMethod ) ) {
+ // delegate to the original method (e.g., .show()) if possible
+ if ( mode ) {
+ return this[ mode ]( args.duration, args.complete );
+ } else {
+ return this.each( function() {
+ if ( args.complete ) {
+ args.complete.call( this );
+ }
+ });
+ }
+ }
+
+ function run( next ) {
+ var elem = $( this ),
+ complete = args.complete,
+ mode = args.mode;
+
+ function done() {
+ if ( $.isFunction( complete ) ) {
+ complete.call( elem[0] );
+ }
+ if ( $.isFunction( next ) ) {
+ next();
+ }
+ }
+
+ // if the element is hiddden and mode is hide,
+ // or element is visible and mode is show
+ if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
+ done();
+ } else {
+ effectMethod.call( elem[0], args, done );
+ }
+ }
+
+ // TODO: remove this check in 2.0, effectMethod will always be true
+ if ( effectMethod ) {
+ return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
+ } else {
+ // DEPRECATED: remove in 2.0 (#7115)
+ return oldEffectMethod.call(this, {
+ options: args,
+ duration: args.duration,
+ callback: args.complete,
+ mode: args.mode
+ });
+ }
+ }
+ });
+
+
+
+
+ var rvertical = /up|down|vertical/,
+ rpositivemotion = /up|left|vertical|horizontal/;
+
+ $.jqplot.effects.effect.blind = function( o, done ) {
+ // Create element
+ var el = $( this ),
+ props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
+ mode = $.jqplot.effects.setMode( el, o.mode || "hide" ),
+ direction = o.direction || "up",
+ vertical = rvertical.test( direction ),
+ ref = vertical ? "height" : "width",
+ ref2 = vertical ? "top" : "left",
+ motion = rpositivemotion.test( direction ),
+ animation = {},
+ show = mode === "show",
+ wrapper, distance, top;
+
+ // // if already wrapped, the wrapper's properties are my property. #6245
+ if ( el.parent().is( ".ui-effects-wrapper" ) ) {
+ $.jqplot.effects.save( el.parent(), props );
+ } else {
+ $.jqplot.effects.save( el, props );
+ }
+ el.show();
+ top = parseInt(el.css('top'), 10);
+ wrapper = $.jqplot.effects.createWrapper( el ).css({
+ overflow: "hidden"
+ });
+
+ distance = vertical ? wrapper[ ref ]() + top : wrapper[ ref ]();
+
+ animation[ ref ] = show ? String(distance) : '0';
+ if ( !motion ) {
+ el
+ .css( vertical ? "bottom" : "right", 0 )
+ .css( vertical ? "top" : "left", "" )
+ .css({ position: "absolute" });
+ animation[ ref2 ] = show ? '0' : String(distance);
+ }
+
+ // // start at 0 if we are showing
+ if ( show ) {
+ wrapper.css( ref, 0 );
+ if ( ! motion ) {
+ wrapper.css( ref2, distance );
+ }
+ }
+
+ // // Animate
+ wrapper.animate( animation, {
+ duration: o.duration,
+ easing: o.easing,
+ queue: false,
+ complete: function() {
+ if ( mode === "hide" ) {
+ el.hide();
+ }
+ $.jqplot.effects.restore( el, props );
+ $.jqplot.effects.removeWrapper( el );
+ done();
+ }
+ });
+
+ };
+
+})(jQuery);
Added: gnucash/trunk/src/report/jqplot/jquery.jqplot.min.css
===================================================================
--- gnucash/trunk/src/report/jqplot/jquery.jqplot.min.css (rev 0)
+++ gnucash/trunk/src/report/jqplot/jquery.jqplot.min.css 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1 @@
+.jqplot-target{position:relative;color:#666;font-family:"Trebuchet MS",Arial,Helvetica,sans-serif;font-size:1em;}.jqplot-axis{font-size:.75em;}.jqplot-xaxis{margin-top:10px;}.jqplot-x2axis{margin-bottom:10px;}.jqplot-yaxis{margin-right:10px;}.jqplot-y2axis,.jqplot-y3axis,.jqplot-y4axis,.jqplot-y5axis,.jqplot-y6axis,.jqplot-y7axis,.jqplot-y8axis,.jqplot-y9axis,.jqplot-yMidAxis{margin-left:10px;margin-right:10px;}.jqplot-axis-tick,.jqplot-xaxis-tick,.jqplot-yaxis-tick,.jqplot-x2axis-tick,.jqplot-y2axis-tick,.jqplot-y3axis-tick,.jqplot-y4axis-tick,.jqplot-y5axis-tick,.jqplot-y6axis-tick,.jqplot-y7axis-tick,.jqplot-y8axis-tick,.jqplot-y9axis-tick,.jqplot-yMidAxis-tick{position:absolute;white-space:pre;}.jqplot-xaxis-tick{top:0;left:15px;vertical-align:top;}.jqplot-x2axis-tick{bottom:0;left:15px;vertical-align:bottom;}.jqplot-yaxis-tick{right:0;top:15px;text-align:right;}.jqplot-yaxis-tick.jqplot-breakTick{right:-20px;margin-right:0;padding:1px 5px 1px 5px;z-index:2;font-size:1.5em;}.jqplot-y2axis-tick,.jqplot-y3axis-tick,.jqplot-y4axis-tick,.jqplot-y5axis-tick,.jqplot-y6axis-tick,.jqplot-y7axis-tick,.jqplot-y8axis-tick,.jqplot-y9axis-tick{left:0;top:15px;text-align:left;}.jqplot-yMidAxis-tick{text-align:center;white-space:nowrap;}.jqplot-xaxis-label{margin-top:10px;font-size:11pt;position:absolute;}.jqplot-x2axis-label{margin-bottom:10px;font-size:11pt;position:absolute;}.jqplot-yaxis-label{margin-right:10px;font-size:11pt;position:absolute;}.jqplot-yMidAxis-label{font-size:11pt;position:absolute;}.jqplot-y2axis-label,.jqplot-y3axis-label,.jqplot-y4axis-label,.jqplot-y5axis-label,.jqplot-y6axis-label,.jqplot-y7axis-label,.jqplot-y8axis-label,.jqplot-y9axis-label{font-size:11pt;margin-left:10px;position:absolute;}.jqplot-meterGauge-tick{font-size:.75em;color:#999;}.jqplot-meterGauge-label{font-size:1em;color:#999;}table.jqplot-table-legend{margin-top:12px;margin-bottom:12px;margin-left:12px;margin-right:12px;}table.jqplot-table-legend,table.jqplot-cursor-legend{background-color:rgba(255,255,255,0.6);border:1!
px solid #ccc;position:absolute;font-size:.75em;}td.jqplot-table-legend{vertical-align:middle;}td.jqplot-seriesToggle:hover,td.jqplot-seriesToggle:active{cursor:pointer;}.jqplot-table-legend .jqplot-series-hidden{text-decoration:line-through;}div.jqplot-table-legend-swatch-outline{border:1px solid #ccc;padding:1px;}div.jqplot-table-legend-swatch{width:0;height:0;border-top-width:5px;border-bottom-width:5px;border-left-width:6px;border-right-width:6px;border-top-style:solid;border-bottom-style:solid;border-left-style:solid;border-right-style:solid;}.jqplot-title{top:0;left:0;padding-bottom:.5em;font-size:1.2em;}table.jqplot-cursor-tooltip{border:1px solid #ccc;font-size:.75em;}.jqplot-cursor-tooltip{border:1px solid #ccc;font-size:.75em;white-space:nowrap;background:rgba(208,208,208,0.5);padding:1px;}.jqplot-highlighter-tooltip,.jqplot-canvasOverlay-tooltip{border:1px solid #ccc;font-size:.75em;white-space:nowrap;background:rgba(208,208,208,0.5);padding:1px;}.jqplot-point-label{font-size:.75em;z-index:2;}td.jqplot-cursor-legend-swatch{vertical-align:middle;text-align:center;}div.jqplot-cursor-legend-swatch{width:1.2em;height:.7em;}.jqplot-error{text-align:center;}.jqplot-error-message{position:relative;top:46%;display:inline-block;}div.jqplot-bubble-label{font-size:.8em;padding-left:2px;padding-right:2px;color:rgb(20%,20%,20%);}div.jqplot-bubble-label.jqplot-bubble-label-highlight{background:rgba(90%,90%,90%,0.7);}div.jqplot-noData-container{text-align:center;background-color:rgba(96%,96%,96%,0.3);}
\ No newline at end of file
Added: gnucash/trunk/src/report/jqplot/jquery.jqplot.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/jquery.jqplot.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/jquery.jqplot.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(L){var u;L.fn.emptyForce=function(){for(var ah=0,ai;(ai=L(this)[ah])!=null;ah++){if(ai.nodeType===1){L.cleanData(ai.getElementsByTagName("*"))}if(L.jqplot.use_excanvas){ai.outerHTML=""}else{while(ai.firstChild){ai.removeChild(ai.firstChild)}}ai=null}return L(this)};L.fn.removeChildForce=function(ah){while(ah.firstChild){this.removeChildForce(ah.firstChild);ah.removeChild(ah.firstChild)}};L.fn.jqplot=function(){var ah=[];var aj=[];for(var ak=0,ai=arguments.length;ak<ai;ak++){if(L.isArray(arguments[ak])){ah.push(arguments[ak])}else{if(L.isPlainObject(arguments[ak])){aj.push(arguments[ak])}}}return this.each(function(an){var at,ar,aq=L(this),am=ah.length,al=aj.length,ap,ao;if(an<am){ap=ah[an]}else{ap=am?ah[am-1]:null}if(an<al){ao=aj[an]}else{ao=al?aj[al-1]:null}at=aq.attr("id");if(at===u){at="jqplot_target_"+L.jqplot.targetCounter++;aq.attr("id",at)}ar=L.jqplot(at,ap,ao);aq.data("jqplot",ar)})};L.jqplot=function(an,ak,ai){var aj=null,ah=null;if(arguments.length===3){aj=ak;ah=ai}else{if(arguments.length===2){if(L.isArray(ak)){aj=ak}else{if(L.isPlainObject(ak)){ah=ak}}}}if(aj===null&&ah!==null&&ah.data){aj=ah.data}var am=new R();L("#"+an).removeClass("jqplot-error");if(L.jqplot.config.catchErrors){try{am.init(an,aj,ah);am.draw();am.themeEngine.init.call(am);return am}catch(al){var ao=L.jqplot.config.errorMessage||al.message;L("#"+an).append('<div class="jqplot-error-message">'+ao+"</div>");L("#"+an).addClass("jqplot-error");document.getElementById(an).style.background=L.jqplot.config.errorBackground;document.getElementById(an).style.border=L.jqplot.config.errorBorder;document.getElementById(an).style.fontFamily=L.jqplot.config.errorFontFamily;document.getElementById(an).style.fontSize=L.jqplot.config.errorFontSize;document.getElementById(an).style.fontStyle=L.jqplot.config.errorFontStyle;document.getElementById(an).style.fontWeight=L.jqplot.config.errorFontWeight}}else{am.init(an,aj,ah);am.draw();am.themeEngine.init.call(am);return am}};L.jqplot.version="1.0.6";L.jqplot.revision="1138";L.jqplot.!
targetCounter=1;L.jqplot.CanvasManager=function(){if(typeof L.jqplot.CanvasManager.canvases=="undefined"){L.jqplot.CanvasManager.canvases=[];L.jqplot.CanvasManager.free=[]}var ah=[];this.getCanvas=function(){var ak;var aj=true;if(!L.jqplot.use_excanvas){for(var al=0,ai=L.jqplot.CanvasManager.canvases.length;al<ai;al++){if(L.jqplot.CanvasManager.free[al]===true){aj=false;ak=L.jqplot.CanvasManager.canvases[al];L.jqplot.CanvasManager.free[al]=false;ah.push(al);break}}}if(aj){ak=document.createElement("canvas");ah.push(L.jqplot.CanvasManager.canvases.length);L.jqplot.CanvasManager.canvases.push(ak);L.jqplot.CanvasManager.free.push(false)}return ak};this.initCanvas=function(ai){if(L.jqplot.use_excanvas){return window.G_vmlCanvasManager.initElement(ai)}return ai};this.freeAllCanvases=function(){for(var aj=0,ai=ah.length;aj<ai;aj++){this.freeCanvas(ah[aj])}ah=[]};this.freeCanvas=function(ai){if(L.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==u){window.G_vmlCanvasManager.uninitElement(L.jqplot.CanvasManager.canvases[ai]);L.jqplot.CanvasManager.canvases[ai]=null}else{var aj=L.jqplot.CanvasManager.canvases[ai];aj.getContext("2d").clearRect(0,0,aj.width,aj.height);L(aj).unbind().removeAttr("class").removeAttr("style");L(aj).css({left:"",top:"",position:""});aj.width=0;aj.height=0;L.jqplot.CanvasManager.free[ai]=true}}};L.jqplot.log=function(){if(window.console){window.console.log.apply(window.console,arguments)}};L.jqplot.config={addDomReference:false,enablePlugins:false,defaultHeight:300,defaultWidth:400,UTCAdjust:false,timezoneOffset:new Date(new Date().getTimezoneOffset()*60000),errorMessage:"",errorBackground:"",errorBorder:"",errorFontFamily:"",errorFontSize:"",errorFontStyle:"",errorFontWeight:"",catchErrors:false,defaultTickFormatString:"%.1f",defaultColors:["#4bb2c5","#EAA228","#c5b47f","#579575","#839557","#958c12","#953579","#4b5de4","#d8b83f","#ff5800","#0085cc","#c747a3","#cddf54","#FBD178","#26B4E3","#bd70c7"],defaultNegativeColors:["#498991","#C08840","#9F9274","#546D61","#646C4A","#6F6621","!
#6E3F5F","#4F64B0","#A89050","#C45923","#187399","#945381","#959E5C","#C7AF7B","#478396","#907294"],dashLength:4,gapLength:4,dotGapLength:2.5,srcLocation:"jqplot/src/",pluginLocation:"jqplot/src/plugins/"};L.jqplot.arrayMax=function(ah){return Math.max.apply(Math,ah)};L.jqplot.arrayMin=function(ah){return Math.min.apply(Math,ah)};L.jqplot.enablePlugins=L.jqplot.config.enablePlugins;L.jqplot.support_canvas=function(){if(typeof L.jqplot.support_canvas.result=="undefined"){L.jqplot.support_canvas.result=!!document.createElement("canvas").getContext}return L.jqplot.support_canvas.result};L.jqplot.support_canvas_text=function(){if(typeof L.jqplot.support_canvas_text.result=="undefined"){if(window.G_vmlCanvasManager!==u&&window.G_vmlCanvasManager._version>887){L.jqplot.support_canvas_text.result=true}else{L.jqplot.support_canvas_text.result=!!(document.createElement("canvas").getContext&&typeof document.createElement("canvas").getContext("2d").fillText=="function")}}return L.jqplot.support_canvas_text.result};L.jqplot.use_excanvas=((!L.support.boxModel||!L.support.objectAll||!$support.leadingWhitespace)&&!L.jqplot.support_canvas())?true:false;L.jqplot.preInitHooks=[];L.jqplot.postInitHooks=[];L.jqplot.preParseOptionsHooks=[];L.jqplot.postParseOptionsHooks=[];L.jqplot.preDrawHooks=[];L.jqplot.postDrawHooks=[];L.jqplot.preDrawSeriesHooks=[];L.jqplot.postDrawSeriesHooks=[];L.jqplot.preDrawLegendHooks=[];L.jqplot.addLegendRowHooks=[];L.jqplot.preSeriesInitHooks=[];L.jqplot.postSeriesInitHooks=[];L.jqplot.preParseSeriesOptionsHooks=[];L.jqplot.postParseSeriesOptionsHooks=[];L.jqplot.eventListenerHooks=[];L.jqplot.preDrawSeriesShadowHooks=[];L.jqplot.postDrawSeriesShadowHooks=[];L.jqplot.ElemContainer=function(){this._elem;this._plotWidth;this._plotHeight;this._plotDimensions={height:null,width:null}};L.jqplot.ElemContainer.prototype.createElement=function(ak,am,ai,aj,an){this._offsets=am;var ah=ai||"jqplot";var al=document.createElement(ak);this._elem=L(al);this._elem.addClass(ah);this._elem.css(aj);this._elem.attr(an);al=!
null;return this._elem};L.jqplot.ElemContainer.prototype.getWidth=function(){if(this._elem){return this._elem.outerWidth(true)}else{return null}};L.jqplot.ElemContainer.prototype.getHeight=function(){if(this._elem){return this._elem.outerHeight(true)}else{return null}};L.jqplot.ElemContainer.prototype.getPosition=function(){if(this._elem){return this._elem.position()}else{return{top:null,left:null,bottom:null,right:null}}};L.jqplot.ElemContainer.prototype.getTop=function(){return this.getPosition().top};L.jqplot.ElemContainer.prototype.getLeft=function(){return this.getPosition().left};L.jqplot.ElemContainer.prototype.getBottom=function(){return this._elem.css("bottom")};L.jqplot.ElemContainer.prototype.getRight=function(){return this._elem.css("right")};function w(ah){L.jqplot.ElemContainer.call(this);this.name=ah;this._series=[];this.show=false;this.tickRenderer=L.jqplot.AxisTickRenderer;this.tickOptions={};this.labelRenderer=L.jqplot.AxisLabelRenderer;this.labelOptions={};this.label=null;this.showLabel=true;this.min=null;this.max=null;this.autoscale=false;this.pad=1.2;this.padMax=null;this.padMin=null;this.ticks=[];this.numberTicks;this.tickInterval;this.renderer=L.jqplot.LinearAxisRenderer;this.rendererOptions={};this.showTicks=true;this.showTickMarks=true;this.showMinorTicks=true;this.drawMajorGridlines=true;this.drawMinorGridlines=false;this.drawMajorTickMarks=true;this.drawMinorTickMarks=true;this.useSeriesColor=false;this.borderWidth=null;this.borderColor=null;this.scaleToHiddenSeries=false;this._dataBounds={min:null,max:null};this._intervalStats=[];this._offsets={min:null,max:null};this._ticks=[];this._label=null;this.syncTicks=null;this.tickSpacing=75;this._min=null;this._max=null;this._tickInterval=null;this._numberTicks=null;this.__ticks=null;this._options={}}w.prototype=new L.jqplot.ElemContainer();w.prototype.constructor=w;w.prototype.init=function(){if(L.isFunction(this.renderer)){this.renderer=new this.renderer()}this.tickOptions.axis=this.name;if(this.tickOptions.showMark==null){this.tickOptions!
.showMark=this.showTicks}if(this.tickOptions.showMark==null){this.tickOptions.showMark=this.showTickMarks}if(this.tickOptions.showLabel==null){this.tickOptions.showLabel=this.showTicks}if(this.label==null||this.label==""){this.showLabel=false}else{this.labelOptions.label=this.label}if(this.showLabel==false){this.labelOptions.show=false}if(this.pad==0){this.pad=1}if(this.padMax==0){this.padMax=1}if(this.padMin==0){this.padMin=1}if(this.padMax==null){this.padMax=(this.pad-1)/2+1}if(this.padMin==null){this.padMin=(this.pad-1)/2+1}this.pad=this.padMax+this.padMin-1;if(this.min!=null||this.max!=null){this.autoscale=false}if(this.syncTicks==null&&this.name.indexOf("y")>-1){this.syncTicks=true}else{if(this.syncTicks==null){this.syncTicks=false}}this.renderer.init.call(this,this.rendererOptions)};w.prototype.draw=function(ah,ai){if(this.__ticks){this.__ticks=null}return this.renderer.draw.call(this,ah,ai)};w.prototype.set=function(){this.renderer.set.call(this)};w.prototype.pack=function(ai,ah){if(this.show){this.renderer.pack.call(this,ai,ah)}if(this._min==null){this._min=this.min;this._max=this.max;this._tickInterval=this.tickInterval;this._numberTicks=this.numberTicks;this.__ticks=this._ticks}};w.prototype.reset=function(){this.renderer.reset.call(this)};w.prototype.resetScale=function(ah){L.extend(true,this,{min:null,max:null,numberTicks:null,tickInterval:null,_ticks:[],ticks:[]},ah);this.resetDataBounds()};w.prototype.resetDataBounds=function(){var ao=this._dataBounds;ao.min=null;ao.max=null;var ai,ap,am;var aj=(this.show)?true:false;for(var al=0;al<this._series.length;al++){ap=this._series[al];if(ap.show||this.scaleToHiddenSeries){am=ap._plotData;if(ap._type==="line"&&ap.renderer.bands.show&&this.name.charAt(0)!=="x"){am=[[0,ap.renderer.bands._min],[1,ap.renderer.bands._max]]}var ah=1,an=1;if(ap._type!=null&&ap._type=="ohlc"){ah=3;an=2}for(var ak=0,ai=am.length;ak<ai;ak++){if(this.name=="xaxis"||this.name=="x2axis"){if((am[ak][0]!=null&&am[ak][0]<ao.min)||ao.min==null){ao.min=am[ak][0]}if((am[ak][0]!=null&&am[ak][!
0]>ao.max)||ao.max==null){ao.max=am[ak][0]}}else{if((am[ak][ah]!=null&&am[ak][ah]<ao.min)||ao.min==null){ao.min=am[ak][ah]}if((am[ak][an]!=null&&am[ak][an]>ao.max)||ao.max==null){ao.max=am[ak][an]}}}if(aj&&ap.renderer.constructor!==L.jqplot.BarRenderer){aj=false}else{if(aj&&this._options.hasOwnProperty("forceTickAt0")&&this._options.forceTickAt0==false){aj=false}else{if(aj&&ap.renderer.constructor===L.jqplot.BarRenderer){if(ap.barDirection=="vertical"&&this.name!="xaxis"&&this.name!="x2axis"){if(this._options.pad!=null||this._options.padMin!=null){aj=false}}else{if(ap.barDirection=="horizontal"&&(this.name=="xaxis"||this.name=="x2axis")){if(this._options.pad!=null||this._options.padMin!=null){aj=false}}}}}}}}if(aj&&this.renderer.constructor===L.jqplot.LinearAxisRenderer&&ao.min>=0){this.padMin=1;this.forceTickAt0=true}};function q(ah){L.jqplot.ElemContainer.call(this);this.show=false;this.location="ne";this.labels=[];this.showLabels=true;this.showSwatches=true;this.placement="insideGrid";this.xoffset=0;this.yoffset=0;this.border;this.background;this.textColor;this.fontFamily;this.fontSize;this.rowSpacing="0.5em";this.renderer=L.jqplot.TableLegendRenderer;this.rendererOptions={};this.preDraw=false;this.marginTop=null;this.marginRight=null;this.marginBottom=null;this.marginLeft=null;this.escapeHtml=false;this._series=[];L.extend(true,this,ah)}q.prototype=new L.jqplot.ElemContainer();q.prototype.constructor=q;q.prototype.setOptions=function(ah){L.extend(true,this,ah);if(this.placement=="inside"){this.placement="insideGrid"}if(this.xoffset>0){if(this.placement=="insideGrid"){switch(this.location){case"nw":case"w":case"sw":if(this.marginLeft==null){this.marginLeft=this.xoffset+"px"}this.marginRight="0px";break;case"ne":case"e":case"se":default:if(this.marginRight==null){this.marginRight=this.xoffset+"px"}this.marginLeft="0px";break}}else{if(this.placement=="outside"){switch(this.location){case"nw":case"w":case"sw":if(this.marginRight==null){this.marginRight=this.xoffset+"px"}this.marginLeft="0px";break;case"ne":case"!
e":case"se":default:if(this.marginLeft==null){this.marginLeft=this.xoffset+"px"}this.marginRight="0px";break}}}this.xoffset=0}if(this.yoffset>0){if(this.placement=="outside"){switch(this.location){case"sw":case"s":case"se":if(this.marginTop==null){this.marginTop=this.yoffset+"px"}this.marginBottom="0px";break;case"ne":case"n":case"nw":default:if(this.marginBottom==null){this.marginBottom=this.yoffset+"px"}this.marginTop="0px";break}}else{if(this.placement=="insideGrid"){switch(this.location){case"sw":case"s":case"se":if(this.marginBottom==null){this.marginBottom=this.yoffset+"px"}this.marginTop="0px";break;case"ne":case"n":case"nw":default:if(this.marginTop==null){this.marginTop=this.yoffset+"px"}this.marginBottom="0px";break}}}this.yoffset=0}};q.prototype.init=function(){if(L.isFunction(this.renderer)){this.renderer=new this.renderer()}this.renderer.init.call(this,this.rendererOptions)};q.prototype.draw=function(ai,aj){for(var ah=0;ah<L.jqplot.preDrawLegendHooks.length;ah++){L.jqplot.preDrawLegendHooks[ah].call(this,ai)}return this.renderer.draw.call(this,ai,aj)};q.prototype.pack=function(ah){this.renderer.pack.call(this,ah)};function y(ah){L.jqplot.ElemContainer.call(this);this.text=ah;this.show=true;this.fontFamily;this.fontSize;this.textAlign;this.textColor;this.renderer=L.jqplot.DivTitleRenderer;this.rendererOptions={};this.escapeHtml=false}y.prototype=new L.jqplot.ElemContainer();y.prototype.constructor=y;y.prototype.init=function(){if(L.isFunction(this.renderer)){this.renderer=new this.renderer()}this.renderer.init.call(this,this.rendererOptions)};y.prototype.draw=function(ah){return this.renderer.draw.call(this,ah)};y.prototype.pack=function(){this.renderer.pack.call(this)};function S(ah){ah=ah||{};L.jqplot.ElemContainer.call(this);this.show=true;this.xaxis="xaxis";this._xaxis;this.yaxis="yaxis";this._yaxis;this.gridBorderWidth=2;this.renderer=L.jqplot.LineRenderer;this.rendererOptions={};this.data=[];this.gridData=[];this.label="";this.showLabel=true;this.color;this.negativeColor;this.lineWidth=2.5;this!
.lineJoin="round";this.lineCap="round";this.linePattern="solid";this.shadow=true;this.shadowAngle=45;this.shadowOffset=1.25;this.shadowDepth=3;this.shadowAlpha="0.1";this.breakOnNull=false;this.markerRenderer=L.jqplot.MarkerRenderer;this.markerOptions={};this.showLine=true;this.showMarker=true;this.index;this.fill=false;this.fillColor;this.fillAlpha;this.fillAndStroke=false;this.disableStack=false;this._stack=false;this.neighborThreshold=4;this.fillToZero=false;this.fillToValue=0;this.fillAxis="y";this.useNegativeColors=true;this._stackData=[];this._plotData=[];this._plotValues={x:[],y:[]};this._intervals={x:{},y:{}};this._prevPlotData=[];this._prevGridData=[];this._stackAxis="y";this._primaryAxis="_xaxis";this.canvas=new L.jqplot.GenericCanvas();this.shadowCanvas=new L.jqplot.GenericCanvas();this.plugins={};this._sumy=0;this._sumx=0;this._type=""}S.prototype=new L.jqplot.ElemContainer();S.prototype.constructor=S;S.prototype.init=function(ak,ao,am){this.index=ak;this.gridBorderWidth=ao;var an=this.data;var aj=[],al,ah;for(al=0,ah=an.length;al<ah;al++){if(!this.breakOnNull){if(an[al]==null||an[al][0]==null||an[al][1]==null){continue}else{aj.push(an[al])}}else{aj.push(an[al])}}this.data=aj;if(!this.color){this.color=am.colorGenerator.get(this.index)}if(!this.negativeColor){this.negativeColor=am.negativeColorGenerator.get(this.index)}if(!this.fillColor){this.fillColor=this.color}if(this.fillAlpha){var ai=L.jqplot.normalize2rgb(this.fillColor);var ai=L.jqplot.getColorComponents(ai);this.fillColor="rgba("+ai[0]+","+ai[1]+","+ai[2]+","+this.fillAlpha+")"}if(L.isFunction(this.renderer)){this.renderer=new this.renderer()}this.renderer.init.call(this,this.rendererOptions,am);this.markerRenderer=new this.markerRenderer();if(!this.markerOptions.color){this.markerOptions.color=this.color}if(this.markerOptions.show==null){this.markerOptions.show=this.showMarker}this.showMarker=this.markerOptions.show;this.markerRenderer.init(this.markerOptions)};S.prototype.draw=function(an,ak,am){var ai=(ak==u)?{}:ak;an=(an==u)?this.canvas.!
_ctx:an;var ah,al,aj;for(ah=0;ah<L.jqplot.preDrawSeriesHooks.length;ah++){L.jqplot.preDrawSeriesHooks[ah].call(this,an,ai)}if(this.show){this.renderer.setGridData.call(this,am);if(!ai.preventJqPlotSeriesDrawTrigger){L(an.canvas).trigger("jqplotSeriesDraw",[this.data,this.gridData])}al=[];if(ai.data){al=ai.data}else{if(!this._stack){al=this.data}else{al=this._plotData}}aj=ai.gridData||this.renderer.makeGridData.call(this,al,am);if(this._type==="line"&&this.renderer.smooth&&this.renderer._smoothedData.length){aj=this.renderer._smoothedData}this.renderer.draw.call(this,an,aj,ai,am)}for(ah=0;ah<L.jqplot.postDrawSeriesHooks.length;ah++){L.jqplot.postDrawSeriesHooks[ah].call(this,an,ai,am)}an=ak=am=ah=al=aj=null};S.prototype.drawShadow=function(an,ak,am){var ai=(ak==u)?{}:ak;an=(an==u)?this.shadowCanvas._ctx:an;var ah,al,aj;for(ah=0;ah<L.jqplot.preDrawSeriesShadowHooks.length;ah++){L.jqplot.preDrawSeriesShadowHooks[ah].call(this,an,ai)}if(this.shadow){this.renderer.setGridData.call(this,am);al=[];if(ai.data){al=ai.data}else{if(!this._stack){al=this.data}else{al=this._plotData}}aj=ai.gridData||this.renderer.makeGridData.call(this,al,am);this.renderer.drawShadow.call(this,an,aj,ai,am)}for(ah=0;ah<L.jqplot.postDrawSeriesShadowHooks.length;ah++){L.jqplot.postDrawSeriesShadowHooks[ah].call(this,an,ai)}an=ak=am=ah=al=aj=null};S.prototype.toggleDisplay=function(ai,ak){var ah,aj;if(ai.data.series){ah=ai.data.series}else{ah=this}if(ai.data.speed){aj=ai.data.speed}if(aj){if(ah.canvas._elem.is(":hidden")||!ah.show){ah.show=true;ah.canvas._elem.removeClass("jqplot-series-hidden");if(ah.shadowCanvas._elem){ah.shadowCanvas._elem.fadeIn(aj)}ah.canvas._elem.fadeIn(aj,ak);ah.canvas._elem.nextAll(".jqplot-point-label.jqplot-series-"+ah.index).fadeIn(aj)}else{ah.show=false;ah.canvas._elem.addClass("jqplot-series-hidden");if(ah.shadowCanvas._elem){ah.shadowCanvas._elem.fadeOut(aj)}ah.canvas._elem.fadeOut(aj,ak);ah.canvas._elem.nextAll(".jqplot-point-label.jqplot-series-"+ah.index).fadeOut(aj)}}else{if(ah.canvas._elem.is(":hidden")||!ah.s!
how){ah.show=true;ah.canvas._elem.removeClass("jqplot-series-hidden");if(ah.shadowCanvas._elem){ah.shadowCanvas._elem.show()}ah.canvas._elem.show(0,ak);ah.canvas._elem.nextAll(".jqplot-point-label.jqplot-series-"+ah.index).show()}else{ah.show=false;ah.canvas._elem.addClass("jqplot-series-hidden");if(ah.shadowCanvas._elem){ah.shadowCanvas._elem.hide()}ah.canvas._elem.hide(0,ak);ah.canvas._elem.nextAll(".jqplot-point-label.jqplot-series-"+ah.index).hide()}}};function M(){L.jqplot.ElemContainer.call(this);this.drawGridlines=true;this.gridLineColor="#cccccc";this.gridLineWidth=1;this.background="#fffdf6";this.borderColor="#999999";this.borderWidth=2;this.drawBorder=true;this.shadow=true;this.shadowAngle=45;this.shadowOffset=1.5;this.shadowWidth=3;this.shadowDepth=3;this.shadowColor=null;this.shadowAlpha="0.07";this._left;this._top;this._right;this._bottom;this._width;this._height;this._axes=[];this.renderer=L.jqplot.CanvasGridRenderer;this.rendererOptions={};this._offsets={top:null,bottom:null,left:null,right:null}}M.prototype=new L.jqplot.ElemContainer();M.prototype.constructor=M;M.prototype.init=function(){if(L.isFunction(this.renderer)){this.renderer=new this.renderer()}this.renderer.init.call(this,this.rendererOptions)};M.prototype.createElement=function(ah,ai){this._offsets=ah;return this.renderer.createElement.call(this,ai)};M.prototype.draw=function(){this.renderer.draw.call(this)};L.jqplot.GenericCanvas=function(){L.jqplot.ElemContainer.call(this);this._ctx};L.jqplot.GenericCanvas.prototype=new L.jqplot.ElemContainer();L.jqplot.GenericCanvas.prototype.constructor=L.jqplot.GenericCanvas;L.jqplot.GenericCanvas.prototype.createElement=function(al,aj,ai,am){this._offsets=al;var ah="jqplot";if(aj!=u){ah=aj}var ak;ak=am.canvasManager.getCanvas();if(ai!=null){this._plotDimensions=ai}ak.width=this._plotDimensions.width-this._offsets.left-this._offsets.right;ak.height=this._plotDimensions.height-this._offsets.top-this._offsets.bottom;this._elem=L(ak);this._elem.css({position:"absolute",left:this._offsets.left,top:thi!
s._offsets.top});this._elem.addClass(ah);ak=am.canvasManager.initCanvas(ak);ak=null;return this._elem};L.jqplot.GenericCanvas.prototype.setContext=function(){this._ctx=this._elem.get(0).getContext("2d");return this._ctx};L.jqplot.GenericCanvas.prototype.resetCanvas=function(){if(this._elem){if(L.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==u){window.G_vmlCanvasManager.uninitElement(this._elem.get(0))}this._elem.emptyForce()}this._ctx=null};L.jqplot.HooksManager=function(){this.hooks=[];this.args=[]};L.jqplot.HooksManager.prototype.addOnce=function(ak,ai){ai=ai||[];var al=false;for(var aj=0,ah=this.hooks.length;aj<ah;aj++){if(this.hooks[aj]==ak){al=true}}if(!al){this.hooks.push(ak);this.args.push(ai)}};L.jqplot.HooksManager.prototype.add=function(ai,ah){ah=ah||[];this.hooks.push(ai);this.args.push(ah)};L.jqplot.EventListenerManager=function(){this.hooks=[]};L.jqplot.EventListenerManager.prototype.addOnce=function(al,ak){var am=false,aj,ai;for(var ai=0,ah=this.hooks.length;ai<ah;ai++){aj=this.hooks[ai];if(aj[0]==al&&aj[1]==ak){am=true}}if(!am){this.hooks.push([al,ak])}};L.jqplot.EventListenerManager.prototype.add=function(ai,ah){this.hooks.push([ai,ah])};var U=["yMidAxis","xaxis","yaxis","x2axis","y2axis","y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis"];function R(){this.animate=false;this.animateReplot=false;this.axes={xaxis:new w("xaxis"),yaxis:new w("yaxis"),x2axis:new w("x2axis"),y2axis:new w("y2axis"),y3axis:new w("y3axis"),y4axis:new w("y4axis"),y5axis:new w("y5axis"),y6axis:new w("y6axis"),y7axis:new w("y7axis"),y8axis:new w("y8axis"),y9axis:new w("y9axis"),yMidAxis:new w("yMidAxis")};this.baseCanvas=new L.jqplot.GenericCanvas();this.captureRightClick=false;this.data=[];this.dataRenderer;this.dataRendererOptions;this.defaults={axesDefaults:{},axes:{xaxis:{},yaxis:{},x2axis:{},y2axis:{},y3axis:{},y4axis:{},y5axis:{},y6axis:{},y7axis:{},y8axis:{},y9axis:{},yMidAxis:{}},seriesDefaults:{},series:[]};this.defaultAxisStart=1;this.drawIfHidden=false;this.eventCanvas=new L.jqplot.Ge!
nericCanvas();this.fillBetween={series1:null,series2:null,color:null,baseSeries:0,fill:true};this.fontFamily;this.fontSize;this.grid=new M();this.legend=new q();this.negativeSeriesColors=L.jqplot.config.defaultNegativeColors;this.noDataIndicator={show:false,indicator:"Loading Data...",axes:{xaxis:{min:0,max:10,tickInterval:2,show:true},yaxis:{min:0,max:12,tickInterval:3,show:true}}};this.options={};this.previousSeriesStack=[];this.plugins={};this.series=[];this.seriesStack=[];this.seriesColors=L.jqplot.config.defaultColors;this.sortData=true;this.stackSeries=false;this.syncXTicks=true;this.syncYTicks=true;this.target=null;this.targetId=null;this.textColor;this.title=new y();this._drawCount=0;this._sumy=0;this._sumx=0;this._stackData=[];this._plotData=[];this._width=null;this._height=null;this._plotDimensions={height:null,width:null};this._gridPadding={top:null,right:null,bottom:null,left:null};this._defaultGridPadding={top:10,right:10,bottom:23,left:10};this._addDomReference=L.jqplot.config.addDomReference;this.preInitHooks=new L.jqplot.HooksManager();this.postInitHooks=new L.jqplot.HooksManager();this.preParseOptionsHooks=new L.jqplot.HooksManager();this.postParseOptionsHooks=new L.jqplot.HooksManager();this.preDrawHooks=new L.jqplot.HooksManager();this.postDrawHooks=new L.jqplot.HooksManager();this.preDrawSeriesHooks=new L.jqplot.HooksManager();this.postDrawSeriesHooks=new L.jqplot.HooksManager();this.preDrawLegendHooks=new L.jqplot.HooksManager();this.addLegendRowHooks=new L.jqplot.HooksManager();this.preSeriesInitHooks=new L.jqplot.HooksManager();this.postSeriesInitHooks=new L.jqplot.HooksManager();this.preParseSeriesOptionsHooks=new L.jqplot.HooksManager();this.postParseSeriesOptionsHooks=new L.jqplot.HooksManager();this.eventListenerHooks=new L.jqplot.EventListenerManager();this.preDrawSeriesShadowHooks=new L.jqplot.HooksManager();this.postDrawSeriesShadowHooks=new L.jqplot.HooksManager();this.colorGenerator=new L.jqplot.ColorGenerator();this.negativeColorGenerator=new L.jqplot.ColorGenerator();this.canvas!
Manager=new L.jqplot.CanvasManager();this.themeEngine=new L.jqplot.ThemeEngine();var aj=0;this.init=function(av,ar,ay){ay=ay||{};for(var at=0;at<L.jqplot.preInitHooks.length;at++){L.jqplot.preInitHooks[at].call(this,av,ar,ay)}for(var at=0;at<this.preInitHooks.hooks.length;at++){this.preInitHooks.hooks[at].call(this,av,ar,ay)}this.targetId="#"+av;this.target=L("#"+av);if(this._addDomReference){this.target.data("jqplot",this)}this.target.removeClass("jqplot-error");if(!this.target.get(0)){throw"No plot target specified"}if(this.target.css("position")=="static"){this.target.css("position","relative")}if(!this.target.hasClass("jqplot-target")){this.target.addClass("jqplot-target")}if(!this.target.height()){var au;if(ay&&ay.height){au=parseInt(ay.height,10)}else{if(this.target.attr("data-height")){au=parseInt(this.target.attr("data-height"),10)}else{au=parseInt(L.jqplot.config.defaultHeight,10)}}this._height=au;this.target.css("height",au+"px")}else{this._height=au=this.target.height()}if(!this.target.width()){var aw;if(ay&&ay.width){aw=parseInt(ay.width,10)}else{if(this.target.attr("data-width")){aw=parseInt(this.target.attr("data-width"),10)}else{aw=parseInt(L.jqplot.config.defaultWidth,10)}}this._width=aw;this.target.css("width",aw+"px")}else{this._width=aw=this.target.width()}for(var at=0,ap=U.length;at<ap;at++){this.axes[U[at]]=new w(U[at])}this._plotDimensions.height=this._height;this._plotDimensions.width=this._width;this.grid._plotDimensions=this._plotDimensions;this.title._plotDimensions=this._plotDimensions;this.baseCanvas._plotDimensions=this._plotDimensions;this.eventCanvas._plotDimensions=this._plotDimensions;this.legend._plotDimensions=this._plotDimensions;if(this._height<=0||this._width<=0||!this._height||!this._width){throw"Canvas dimension not set"}if(ay.dataRenderer&&L.isFunction(ay.dataRenderer)){if(ay.dataRendererOptions){this.dataRendererOptions=ay.dataRendererOptions}this.dataRenderer=ay.dataRenderer;ar=this.dataRenderer(ar,this,this.dataRendererOptions)}if(ay.noDataIndicator&&L.isPlainObject(ay!
.noDataIndicator)){L.extend(true,this.noDataIndicator,ay.noDataIndicator)}if(ar==null||L.isArray(ar)==false||ar.length==0||L.isArray(ar[0])==false||ar[0].length==0){if(this.noDataIndicator.show==false){throw"No Data"}else{for(var al in this.noDataIndicator.axes){for(var an in this.noDataIndicator.axes[al]){this.axes[al][an]=this.noDataIndicator.axes[al][an]}}this.postDrawHooks.add(function(){var aD=this.eventCanvas.getHeight();var aA=this.eventCanvas.getWidth();var az=L('<div class="jqplot-noData-container" style="position:absolute;"></div>');this.target.append(az);az.height(aD);az.width(aA);az.css("top",this.eventCanvas._offsets.top);az.css("left",this.eventCanvas._offsets.left);var aC=L('<div class="jqplot-noData-contents" style="text-align:center; position:relative; margin-left:auto; margin-right:auto;"></div>');az.append(aC);aC.html(this.noDataIndicator.indicator);var aB=aC.height();var ax=aC.width();aC.height(aB);aC.width(ax);aC.css("top",(aD-aB)/2+"px")})}}this.data=L.extend(true,[],ar);this.parseOptions(ay);if(this.textColor){this.target.css("color",this.textColor)}if(this.fontFamily){this.target.css("font-family",this.fontFamily)}if(this.fontSize){this.target.css("font-size",this.fontSize)}this.title.init();this.legend.init();this._sumy=0;this._sumx=0;this.computePlotData();for(var at=0;at<this.series.length;at++){this.seriesStack.push(at);this.previousSeriesStack.push(at);this.series[at].shadowCanvas._plotDimensions=this._plotDimensions;this.series[at].canvas._plotDimensions=this._plotDimensions;for(var aq=0;aq<L.jqplot.preSeriesInitHooks.length;aq++){L.jqplot.preSeriesInitHooks[aq].call(this.series[at],av,this.data,this.options.seriesDefaults,this.options.series[at],this)}for(var aq=0;aq<this.preSeriesInitHooks.hooks.length;aq++){this.preSeriesInitHooks.hooks[aq].call(this.series[at],av,this.data,this.options.seriesDefaults,this.options.series[at],this)}this.series[at]._plotDimensions=this._plotDimensions;this.series[at].init(at,this.grid.borderWidth,this);for(var aq=0;aq<L.jqplot.postSeriesInitHooks.l!
ength;aq++){L.jqplot.postSeriesInitHooks[aq].call(this.series[at],av,this.data,this.options.seriesDefaults,this.options.series[at],this)}for(var aq=0;aq<this.postSeriesInitHooks.hooks.length;aq++){this.postSeriesInitHooks.hooks[aq].call(this.series[at],av,this.data,this.options.seriesDefaults,this.options.series[at],this)}this._sumy+=this.series[at]._sumy;this._sumx+=this.series[at]._sumx}var am,ao;for(var at=0,ap=U.length;at<ap;at++){am=U[at];ao=this.axes[am];ao._plotDimensions=this._plotDimensions;ao.init();if(this.axes[am].borderColor==null){if(am.charAt(0)!=="x"&&ao.useSeriesColor===true&&ao.show){ao.borderColor=ao._series[0].color}else{ao.borderColor=this.grid.borderColor}}}if(this.sortData){ah(this.series)}this.grid.init();this.grid._axes=this.axes;this.legend._series=this.series;for(var at=0;at<L.jqplot.postInitHooks.length;at++){L.jqplot.postInitHooks[at].call(this,av,this.data,ay)}for(var at=0;at<this.postInitHooks.hooks.length;at++){this.postInitHooks.hooks[at].call(this,av,this.data,ay)}};this.resetAxesScale=function(aq,am){var ao=am||{};var ap=aq||this.axes;if(ap===true){ap=this.axes}if(L.isArray(ap)){for(var an=0;an<ap.length;an++){this.axes[ap[an]].resetScale(ao[ap[an]])}}else{if(typeof(ap)==="object"){for(var al in ap){this.axes[al].resetScale(ao[al])}}}};this.reInitialize=function(au,al){var ay=L.extend(true,{},this.options,al);var aw=this.targetId.substr(1);var ar=(au==null)?this.data:au;for(var av=0;av<L.jqplot.preInitHooks.length;av++){L.jqplot.preInitHooks[av].call(this,aw,ar,ay)}for(var av=0;av<this.preInitHooks.hooks.length;av++){this.preInitHooks.hooks[av].call(this,aw,ar,ay)}this._height=this.target.height();this._width=this.target.width();if(this._height<=0||this._width<=0||!this._height||!this._width){throw"Target dimension not set"}this._plotDimensions.height=this._height;this._plotDimensions.width=this._width;this.grid._plotDimensions=this._plotDimensions;this.title._plotDimensions=this._plotDimensions;this.baseCanvas._plotDimensions=this._plotDimensions;this.eventCanvas._plotDimensio!
ns=this._plotDimensions;this.legend._plotDimensions=this._plotDimensions;var am,ax,at,ao;for(var av=0,aq=U.length;av<aq;av++){am=U[av];ao=this.axes[am];ax=ao._ticks;for(var at=0,ap=ax.length;at<ap;at++){var an=ax[at]._elem;if(an){if(L.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==u){window.G_vmlCanvasManager.uninitElement(an.get(0))}an.emptyForce();an=null;ax._elem=null}}ax=null;delete ao.ticks;delete ao._ticks;this.axes[am]=new w(am);this.axes[am]._plotWidth=this._width;this.axes[am]._plotHeight=this._height}if(au){if(ay.dataRenderer&&L.isFunction(ay.dataRenderer)){if(ay.dataRendererOptions){this.dataRendererOptions=ay.dataRendererOptions}this.dataRenderer=ay.dataRenderer;au=this.dataRenderer(au,this,this.dataRendererOptions)}this.data=L.extend(true,[],au)}if(al){this.parseOptions(ay)}this.title._plotWidth=this._width;if(this.textColor){this.target.css("color",this.textColor)}if(this.fontFamily){this.target.css("font-family",this.fontFamily)}if(this.fontSize){this.target.css("font-size",this.fontSize)}this.title.init();this.legend.init();this._sumy=0;this._sumx=0;this.seriesStack=[];this.previousSeriesStack=[];this.computePlotData();for(var av=0,aq=this.series.length;av<aq;av++){this.seriesStack.push(av);this.previousSeriesStack.push(av);this.series[av].shadowCanvas._plotDimensions=this._plotDimensions;this.series[av].canvas._plotDimensions=this._plotDimensions;for(var at=0;at<L.jqplot.preSeriesInitHooks.length;at++){L.jqplot.preSeriesInitHooks[at].call(this.series[av],aw,this.data,this.options.seriesDefaults,this.options.series[av],this)}for(var at=0;at<this.preSeriesInitHooks.hooks.length;at++){this.preSeriesInitHooks.hooks[at].call(this.series[av],aw,this.data,this.options.seriesDefaults,this.options.series[av],this)}this.series[av]._plotDimensions=this._plotDimensions;this.series[av].init(av,this.grid.borderWidth,this);for(var at=0;at<L.jqplot.postSeriesInitHooks.length;at++){L.jqplot.postSeriesInitHooks[at].call(this.series[av],aw,this.data,this.options.seriesDefaults,this.options.series[a!
v],this)}for(var at=0;at<this.postSeriesInitHooks.hooks.length;at++){this.postSeriesInitHooks.hooks[at].call(this.series[av],aw,this.data,this.options.seriesDefaults,this.options.series[av],this)}this._sumy+=this.series[av]._sumy;this._sumx+=this.series[av]._sumx}for(var av=0,aq=U.length;av<aq;av++){am=U[av];ao=this.axes[am];ao._plotDimensions=this._plotDimensions;ao.init();if(ao.borderColor==null){if(am.charAt(0)!=="x"&&ao.useSeriesColor===true&&ao.show){ao.borderColor=ao._series[0].color}else{ao.borderColor=this.grid.borderColor}}}if(this.sortData){ah(this.series)}this.grid.init();this.grid._axes=this.axes;this.legend._series=this.series;for(var av=0,aq=L.jqplot.postInitHooks.length;av<aq;av++){L.jqplot.postInitHooks[av].call(this,aw,this.data,ay)}for(var av=0,aq=this.postInitHooks.hooks.length;av<aq;av++){this.postInitHooks.hooks[av].call(this,aw,this.data,ay)}};this.quickInit=function(){this._height=this.target.height();this._width=this.target.width();if(this._height<=0||this._width<=0||!this._height||!this._width){throw"Target dimension not set"}this._plotDimensions.height=this._height;this._plotDimensions.width=this._width;this.grid._plotDimensions=this._plotDimensions;this.title._plotDimensions=this._plotDimensions;this.baseCanvas._plotDimensions=this._plotDimensions;this.eventCanvas._plotDimensions=this._plotDimensions;this.legend._plotDimensions=this._plotDimensions;for(var aq in this.axes){this.axes[aq]._plotWidth=this._width;this.axes[aq]._plotHeight=this._height}this.title._plotWidth=this._width;if(this.textColor){this.target.css("color",this.textColor)}if(this.fontFamily){this.target.css("font-family",this.fontFamily)}if(this.fontSize){this.target.css("font-size",this.fontSize)}this._sumy=0;this._sumx=0;this.computePlotData();for(var ao=0;ao<this.series.length;ao++){if(this.series[ao]._type==="line"&&this.series[ao].renderer.bands.show){this.series[ao].renderer.initBands.call(this.series[ao],this.series[ao].renderer.options,this)}this.series[ao]._plotDimensions=this._plotDimensions;this.series[ao].c!
anvas._plotDimensions=this._plotDimensions;this._sumy+=this.series[ao]._sumy;this._sumx+=this.series[ao]._sumx}var am;for(var al=0;al<12;al++){am=U[al];var an=this.axes[am]._ticks;for(var ao=0;ao<an.length;ao++){var ap=an[ao]._elem;if(ap){if(L.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==u){window.G_vmlCanvasManager.uninitElement(ap.get(0))}ap.emptyForce();ap=null;an._elem=null}}an=null;this.axes[am]._plotDimensions=this._plotDimensions;this.axes[am]._ticks=[]}if(this.sortData){ah(this.series)}this.grid._axes=this.axes;this.legend._series=this.series};function ah(ap){var au,av,aw,al,at;for(var aq=0;aq<ap.length;aq++){var am;var ar=[ap[aq].data,ap[aq]._stackData,ap[aq]._plotData,ap[aq]._prevPlotData];for(var an=0;an<4;an++){am=true;au=ar[an];if(ap[aq]._stackAxis=="x"){for(var ao=0;ao<au.length;ao++){if(typeof(au[ao][1])!="number"){am=false;break}}if(am){au.sort(function(ay,ax){return ay[1]-ax[1]})}}else{for(var ao=0;ao<au.length;ao++){if(typeof(au[ao][0])!="number"){am=false;break}}if(am){au.sort(function(ay,ax){return ay[0]-ax[0]})}}}}}this.computePlotData=function(){this._plotData=[];this._stackData=[];var at,au,ao;for(au=0,ao=this.series.length;au<ao;au++){at=this.series[au];this._plotData.push([]);this._stackData.push([]);var am=at.data;this._plotData[au]=L.extend(true,[],am);this._stackData[au]=L.extend(true,[],am);at._plotData=this._plotData[au];at._stackData=this._stackData[au];var ax={x:[],y:[]};if(this.stackSeries&&!at.disableStack){at._stack=true;var av=(at._stackAxis==="x")?0:1;for(var ap=0,al=am.length;ap<al;ap++){var aw=am[ap][av];if(aw==null){aw=0}this._plotData[au][ap][av]=aw;this._stackData[au][ap][av]=aw;if(au>0){for(var aq=au;aq--;){var an=this._plotData[aq][ap][av];if(aw*an>=0){this._plotData[au][ap][av]+=an;this._stackData[au][ap][av]+=an;break}}}}}else{for(var ar=0;ar<at.data.length;ar++){ax.x.push(at.data[ar][0]);ax.y.push(at.data[ar][1])}this._stackData.push(at.data);this.series[au]._stackData=at.data;this._plotData.push(at.data);at._plotData=at.data;at._plotValues=ax}if(a!
u>0){at._prevPlotData=this.series[au-1]._plotData}at._sumy=0;at._sumx=0;for(ar=at.data.length-1;ar>-1;ar--){at._sumy+=at.data[ar][1];at._sumx+=at.data[ar][0]}}};this.populatePlotData=function(au,av){this._plotData=[];this._stackData=[];au._stackData=[];au._plotData=[];var ay={x:[],y:[]};if(this.stackSeries&&!au.disableStack){au._stack=true;var ax=(au._stackAxis==="x")?0:1;var az=L.extend(true,[],au.data);var aA=L.extend(true,[],au.data);var an,am,ao,aw,al;for(var ar=0;ar<av;ar++){var ap=this.series[ar].data;for(var aq=0;aq<ap.length;aq++){ao=ap[aq];an=(ao[0]!=null)?ao[0]:0;am=(ao[1]!=null)?ao[1]:0;az[aq][0]+=an;az[aq][1]+=am;aw=(ax)?am:an;if(au.data[aq][ax]*aw>=0){aA[aq][ax]+=aw}}}for(var at=0;at<aA.length;at++){ay.x.push(aA[at][0]);ay.y.push(aA[at][1])}this._plotData.push(aA);this._stackData.push(az);au._stackData=az;au._plotData=aA;au._plotValues=ay}else{for(var at=0;at<au.data.length;at++){ay.x.push(au.data[at][0]);ay.y.push(au.data[at][1])}this._stackData.push(au.data);this.series[av]._stackData=au.data;this._plotData.push(au.data);au._plotData=au.data;au._plotValues=ay}if(av>0){au._prevPlotData=this.series[av-1]._plotData}au._sumy=0;au._sumx=0;for(at=au.data.length-1;at>-1;at--){au._sumy+=au.data[at][1];au._sumx+=au.data[at][0]}};this.getNextSeriesColor=(function(am){var al=0;var an=am.seriesColors;return function(){if(al<an.length){return an[al++]}else{al=0;return an[al++]}}})(this);this.parseOptions=function(ay){for(var at=0;at<this.preParseOptionsHooks.hooks.length;at++){this.preParseOptionsHooks.hooks[at].call(this,ay)}for(var at=0;at<L.jqplot.preParseOptionsHooks.length;at++){L.jqplot.preParseOptionsHooks[at].call(this,ay)}this.options=L.extend(true,{},this.defaults,ay);var am=this.options;this.animate=am.animate;this.animateReplot=am.animateReplot;this.stackSeries=am.stackSeries;if(L.isPlainObject(am.fillBetween)){var ax=["series1","series2","color","baseSeries","fill"],au;for(var at=0,aq=ax.length;at<aq;at++){au=ax[at];if(am.fillBetween[au]!=null){this.fillBetween[au]=am.fillBetween[au]}}}if(am.serie!
sColors){this.seriesColors=am.seriesColors}if(am.negativeSeriesColors){this.negativeSeriesColors=am.negativeSeriesColors}if(am.captureRightClick){this.captureRightClick=am.captureRightClick}this.defaultAxisStart=(ay&&ay.defaultAxisStart!=null)?ay.defaultAxisStart:this.defaultAxisStart;this.colorGenerator.setColors(this.seriesColors);this.negativeColorGenerator.setColors(this.negativeSeriesColors);L.extend(true,this._gridPadding,am.gridPadding);this.sortData=(am.sortData!=null)?am.sortData:this.sortData;for(var at=0;at<12;at++){var an=U[at];var ap=this.axes[an];ap._options=L.extend(true,{},am.axesDefaults,am.axes[an]);L.extend(true,ap,am.axesDefaults,am.axes[an]);ap._plotWidth=this._width;ap._plotHeight=this._height}var aw=function(aD,aB,aE){var aA=[];var aC,az;aB=aB||"vertical";if(!L.isArray(aD[0])){for(aC=0,az=aD.length;aC<az;aC++){if(aB=="vertical"){aA.push([aE+aC,aD[aC]])}else{aA.push([aD[aC],aE+aC])}}}else{L.extend(true,aA,aD)}return aA};var av=0;this.series=[];for(var at=0;at<this.data.length;at++){var al=L.extend(true,{index:at},{seriesColors:this.seriesColors,negativeSeriesColors:this.negativeSeriesColors},this.options.seriesDefaults,this.options.series[at],{rendererOptions:{animation:{show:this.animate}}});var ax=new S(al);for(var ar=0;ar<L.jqplot.preParseSeriesOptionsHooks.length;ar++){L.jqplot.preParseSeriesOptionsHooks[ar].call(ax,this.options.seriesDefaults,this.options.series[at])}for(var ar=0;ar<this.preParseSeriesOptionsHooks.hooks.length;ar++){this.preParseSeriesOptionsHooks.hooks[ar].call(ax,this.options.seriesDefaults,this.options.series[at])}L.extend(true,ax,al);var ao="vertical";if(ax.renderer===L.jqplot.BarRenderer&&ax.rendererOptions&&ax.rendererOptions.barDirection=="horizontal"){ao="horizontal";ax._stackAxis="x";ax._primaryAxis="_yaxis"}ax.data=aw(this.data[at],ao,this.defaultAxisStart);switch(ax.xaxis){case"xaxis":ax._xaxis=this.axes.xaxis;break;case"x2axis":ax._xaxis=this.axes.x2axis;break;default:break}ax._yaxis=this.axes[ax.yaxis];ax._xaxis._series.push(ax);ax._yaxis._series.push(ax);!
if(ax.show){ax._xaxis.show=true;ax._yaxis.show=true}else{if(ax._xaxis.scaleToHiddenSeries){ax._xaxis.show=true}if(ax._yaxis.scaleToHiddenSeries){ax._yaxis.show=true}}if(!ax.label){ax.label="Series "+(at+1).toString()}this.series.push(ax);for(var ar=0;ar<L.jqplot.postParseSeriesOptionsHooks.length;ar++){L.jqplot.postParseSeriesOptionsHooks[ar].call(this.series[at],this.options.seriesDefaults,this.options.series[at])}for(var ar=0;ar<this.postParseSeriesOptionsHooks.hooks.length;ar++){this.postParseSeriesOptionsHooks.hooks[ar].call(this.series[at],this.options.seriesDefaults,this.options.series[at])}}L.extend(true,this.grid,this.options.grid);for(var at=0,aq=U.length;at<aq;at++){var an=U[at];var ap=this.axes[an];if(ap.borderWidth==null){ap.borderWidth=this.grid.borderWidth}}if(typeof this.options.title=="string"){this.title.text=this.options.title}else{if(typeof this.options.title=="object"){L.extend(true,this.title,this.options.title)}}this.title._plotWidth=this._width;this.legend.setOptions(this.options.legend);for(var at=0;at<L.jqplot.postParseOptionsHooks.length;at++){L.jqplot.postParseOptionsHooks[at].call(this,ay)}for(var at=0;at<this.postParseOptionsHooks.hooks.length;at++){this.postParseOptionsHooks.hooks[at].call(this,ay)}};this.destroy=function(){this.canvasManager.freeAllCanvases();if(this.eventCanvas&&this.eventCanvas._elem){this.eventCanvas._elem.unbind()}this.target.empty();this.target[0].innerHTML=""};this.replot=function(am){var an=am||{};var ap=an.data||null;var al=(an.clear===false)?false:true;var ao=an.resetAxes||false;delete an.data;delete an.clear;delete an.resetAxes;this.target.trigger("jqplotPreReplot");if(al){this.destroy()}if(ap||!L.isEmptyObject(an)){this.reInitialize(ap,an)}else{this.quickInit()}if(ao){this.resetAxesScale(ao,an.axes)}this.draw();this.target.trigger("jqplotPostReplot")};this.redraw=function(al){al=(al!=null)?al:true;this.target.trigger("jqplotPreRedraw");if(al){this.canvasManager.freeAllCanvases();this.eventCanvas._elem.unbind();this.target.empty()}for(var an in this.axes)!
{this.axes[an]._ticks=[]}this.computePlotData();this._sumy=0;this._sumx=0;for(var am=0,ao=this.series.length;am<ao;am++){this._sumy+=this.series[am]._sumy;this._sumx+=this.series[am]._sumx}this.draw();this.target.trigger("jqplotPostRedraw")};this.draw=function(){if(this.drawIfHidden||this.target.is(":visible")){this.target.trigger("jqplotPreDraw");var aH,aF,aE,ao;for(aH=0,aE=L.jqplot.preDrawHooks.length;aH<aE;aH++){L.jqplot.preDrawHooks[aH].call(this)}for(aH=0,aE=this.preDrawHooks.length;aH<aE;aH++){this.preDrawHooks.hooks[aH].apply(this,this.preDrawSeriesHooks.args[aH])}this.target.append(this.baseCanvas.createElement({left:0,right:0,top:0,bottom:0},"jqplot-base-canvas",null,this));this.baseCanvas.setContext();this.target.append(this.title.draw());this.title.pack({top:0,left:0});var aL=this.legend.draw({},this);var al={top:0,left:0,bottom:0,right:0};if(this.legend.placement=="outsideGrid"){this.target.append(aL);switch(this.legend.location){case"n":al.top+=this.legend.getHeight();break;case"s":al.bottom+=this.legend.getHeight();break;case"ne":case"e":case"se":al.right+=this.legend.getWidth();break;case"nw":case"w":case"sw":al.left+=this.legend.getWidth();break;default:al.right+=this.legend.getWidth();break}aL=aL.detach()}var ar=this.axes;var aM;for(aH=0;aH<12;aH++){aM=U[aH];this.target.append(ar[aM].draw(this.baseCanvas._ctx,this));ar[aM].set()}if(ar.yaxis.show){al.left+=ar.yaxis.getWidth()}var aG=["y2axis","y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis"];var az=[0,0,0,0,0,0,0,0];var aC=0;var aB;for(aB=0;aB<8;aB++){if(ar[aG[aB]].show){aC+=ar[aG[aB]].getWidth();az[aB]=aC}}al.right+=aC;if(ar.x2axis.show){al.top+=ar.x2axis.getHeight()}if(this.title.show){al.top+=this.title.getHeight()}if(ar.xaxis.show){al.bottom+=ar.xaxis.getHeight()}if(this.options.gridDimensions&&L.isPlainObject(this.options.gridDimensions)){var at=parseInt(this.options.gridDimensions.width,10)||0;var aI=parseInt(this.options.gridDimensions.height,10)||0;var an=(this._width-al.left-al.right-at)/2;var aK=(this._height-al.top-al.bot!
tom-aI)/2;if(aK>=0&&an>=0){al.top+=aK;al.bottom+=aK;al.left+=an;al.right+=an}}var am=["top","bottom","left","right"];for(var aB in am){if(this._gridPadding[am[aB]]==null&&al[am[aB]]>0){this._gridPadding[am[aB]]=al[am[aB]]}else{if(this._gridPadding[am[aB]]==null){this._gridPadding[am[aB]]=this._defaultGridPadding[am[aB]]}}}var aA=this._gridPadding;if(this.legend.placement==="outsideGrid"){aA={top:this.title.getHeight(),left:0,right:0,bottom:0};if(this.legend.location==="s"){aA.left=this._gridPadding.left;aA.right=this._gridPadding.right}}ar.xaxis.pack({position:"absolute",bottom:this._gridPadding.bottom-ar.xaxis.getHeight(),left:0,width:this._width},{min:this._gridPadding.left,max:this._width-this._gridPadding.right});ar.yaxis.pack({position:"absolute",top:0,left:this._gridPadding.left-ar.yaxis.getWidth(),height:this._height},{min:this._height-this._gridPadding.bottom,max:this._gridPadding.top});ar.x2axis.pack({position:"absolute",top:this._gridPadding.top-ar.x2axis.getHeight(),left:0,width:this._width},{min:this._gridPadding.left,max:this._width-this._gridPadding.right});for(aH=8;aH>0;aH--){ar[aG[aH-1]].pack({position:"absolute",top:0,right:this._gridPadding.right-az[aH-1]},{min:this._height-this._gridPadding.bottom,max:this._gridPadding.top})}var au=(this._width-this._gridPadding.left-this._gridPadding.right)/2+this._gridPadding.left-ar.yMidAxis.getWidth()/2;ar.yMidAxis.pack({position:"absolute",top:0,left:au,zIndex:9,textAlign:"center"},{min:this._height-this._gridPadding.bottom,max:this._gridPadding.top});this.target.append(this.grid.createElement(this._gridPadding,this));this.grid.draw();var aq=this.series;var aJ=aq.length;for(aH=0,aE=aJ;aH<aE;aH++){aF=this.seriesStack[aH];this.target.append(aq[aF].shadowCanvas.createElement(this._gridPadding,"jqplot-series-shadowCanvas",null,this));aq[aF].shadowCanvas.setContext();aq[aF].shadowCanvas._elem.data("seriesIndex",aF)}for(aH=0,aE=aJ;aH<aE;aH++){aF=this.seriesStack[aH];this.target.append(aq[aF].canvas.createElement(this._gridPadding,"jqplot-series-canvas",null,thi!
s));aq[aF].canvas.setContext();aq[aF].canvas._elem.data("seriesIndex",aF)}this.target.append(this.eventCanvas.createElement(this._gridPadding,"jqplot-event-canvas",null,this));this.eventCanvas.setContext();this.eventCanvas._ctx.fillStyle="rgba(0,0,0,0)";this.eventCanvas._ctx.fillRect(0,0,this.eventCanvas._ctx.canvas.width,this.eventCanvas._ctx.canvas.height);this.bindCustomEvents();if(this.legend.preDraw){this.eventCanvas._elem.before(aL);this.legend.pack(aA);if(this.legend._elem){this.drawSeries({legendInfo:{location:this.legend.location,placement:this.legend.placement,width:this.legend.getWidth(),height:this.legend.getHeight(),xoffset:this.legend.xoffset,yoffset:this.legend.yoffset}})}else{this.drawSeries()}}else{this.drawSeries();if(aJ){L(aq[aJ-1].canvas._elem).after(aL)}this.legend.pack(aA)}for(var aH=0,aE=L.jqplot.eventListenerHooks.length;aH<aE;aH++){this.eventCanvas._elem.bind(L.jqplot.eventListenerHooks[aH][0],{plot:this},L.jqplot.eventListenerHooks[aH][1])}for(var aH=0,aE=this.eventListenerHooks.hooks.length;aH<aE;aH++){this.eventCanvas._elem.bind(this.eventListenerHooks.hooks[aH][0],{plot:this},this.eventListenerHooks.hooks[aH][1])}var ay=this.fillBetween;if(ay.fill&&ay.series1!==ay.series2&&ay.series1<aJ&&ay.series2<aJ&&aq[ay.series1]._type==="line"&&aq[ay.series2]._type==="line"){this.doFillBetweenLines()}for(var aH=0,aE=L.jqplot.postDrawHooks.length;aH<aE;aH++){L.jqplot.postDrawHooks[aH].call(this)}for(var aH=0,aE=this.postDrawHooks.hooks.length;aH<aE;aH++){this.postDrawHooks.hooks[aH].apply(this,this.postDrawHooks.args[aH])}if(this.target.is(":visible")){this._drawCount+=1}var av,aw,aD,ap;for(aH=0,aE=aJ;aH<aE;aH++){av=aq[aH];aw=av.renderer;aD=".jqplot-point-label.jqplot-series-"+aH;if(aw.animation&&aw.animation._supported&&aw.animation.show&&(this._drawCount<2||this.animateReplot)){ap=this.target.find(aD);ap.stop(true,true).hide();av.canvas._elem.stop(true,true).hide();av.shadowCanvas._elem.stop(true,true).hide();av.canvas._elem.jqplotEffect("blind",{mode:"show",direction:aw.animation.direction},aw!
.animation.speed);av.shadowCanvas._elem.jqplotEffect("blind",{mode:"show",direction:aw.animation.direction},aw.animation.speed);ap.fadeIn(aw.animation.speed*0.8)}}ap=null;this.target.trigger("jqplotPostDraw",[this])}};R.prototype.doFillBetweenLines=function(){var an=this.fillBetween;var ax=an.series1;var av=an.series2;var aw=(ax<av)?ax:av;var au=(av>ax)?av:ax;var ar=this.series[aw];var aq=this.series[au];if(aq.renderer.smooth){var ap=aq.renderer._smoothedData.slice(0).reverse()}else{var ap=aq.gridData.slice(0).reverse()}if(ar.renderer.smooth){var at=ar.renderer._smoothedData.concat(ap)}else{var at=ar.gridData.concat(ap)}var ao=(an.color!==null)?an.color:this.series[ax].fillColor;var ay=(an.baseSeries!==null)?an.baseSeries:aw;var am=this.series[ay].renderer.shapeRenderer;var al={fillStyle:ao,fill:true,closePath:true};am.draw(ar.shadowCanvas._ctx,at,al)};this.bindCustomEvents=function(){this.eventCanvas._elem.bind("click",{plot:this},this.onClick);this.eventCanvas._elem.bind("dblclick",{plot:this},this.onDblClick);this.eventCanvas._elem.bind("mousedown",{plot:this},this.onMouseDown);this.eventCanvas._elem.bind("mousemove",{plot:this},this.onMouseMove);this.eventCanvas._elem.bind("mouseenter",{plot:this},this.onMouseEnter);this.eventCanvas._elem.bind("mouseleave",{plot:this},this.onMouseLeave);if(this.captureRightClick){this.eventCanvas._elem.bind("mouseup",{plot:this},this.onRightClick);this.eventCanvas._elem.get(0).oncontextmenu=function(){return false}}else{this.eventCanvas._elem.bind("mouseup",{plot:this},this.onMouseUp)}};function ai(av){var au=av.data.plot;var ap=au.eventCanvas._elem.offset();var at={x:av.pageX-ap.left,y:av.pageY-ap.top};var aq={xaxis:null,yaxis:null,x2axis:null,y2axis:null,y3axis:null,y4axis:null,y5axis:null,y6axis:null,y7axis:null,y8axis:null,y9axis:null,yMidAxis:null};var ar=["xaxis","yaxis","x2axis","y2axis","y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis","yMidAxis"];var al=au.axes;var am,ao;for(am=11;am>0;am--){ao=ar[am-1];if(al[ao].show){aq[ao]=al[ao].series_p2u(at[ao.cha!
rAt(0)])}}return{offsets:ap,gridPos:at,dataPos:aq}}function ak(al,am){var aq=am.series;var aW,aU,aT,aO,aP,aJ,aI,aw,au,az,aA,aK;var aS,aX,aQ,ar,aH,aM,aV;var an,aN;for(aT=am.seriesStack.length-1;aT>=0;aT--){aW=am.seriesStack[aT];aO=aq[aW];aV=aO._highlightThreshold;switch(aO.renderer.constructor){case L.jqplot.BarRenderer:aJ=al.x;aI=al.y;for(aU=0;aU<aO._barPoints.length;aU++){aH=aO._barPoints[aU];aQ=aO.gridData[aU];if(aJ>aH[0][0]&&aJ<aH[2][0]&&aI>aH[2][1]&&aI<aH[0][1]){return{seriesIndex:aO.index,pointIndex:aU,gridData:aQ,data:aO.data[aU],points:aO._barPoints[aU]}}}break;case L.jqplot.PyramidRenderer:aJ=al.x;aI=al.y;for(aU=0;aU<aO._barPoints.length;aU++){aH=aO._barPoints[aU];aQ=aO.gridData[aU];if(aJ>aH[0][0]+aV[0][0]&&aJ<aH[2][0]+aV[2][0]&&aI>aH[2][1]&&aI<aH[0][1]){return{seriesIndex:aO.index,pointIndex:aU,gridData:aQ,data:aO.data[aU],points:aO._barPoints[aU]}}}break;case L.jqplot.DonutRenderer:az=aO.startAngle/180*Math.PI;aJ=al.x-aO._center[0];aI=al.y-aO._center[1];aP=Math.sqrt(Math.pow(aJ,2)+Math.pow(aI,2));if(aJ>0&&-aI>=0){aw=2*Math.PI-Math.atan(-aI/aJ)}else{if(aJ>0&&-aI<0){aw=-Math.atan(-aI/aJ)}else{if(aJ<0){aw=Math.PI-Math.atan(-aI/aJ)}else{if(aJ==0&&-aI>0){aw=3*Math.PI/2}else{if(aJ==0&&-aI<0){aw=Math.PI/2}else{if(aJ==0&&aI==0){aw=0}}}}}}if(az){aw-=az;if(aw<0){aw+=2*Math.PI}else{if(aw>2*Math.PI){aw-=2*Math.PI}}}au=aO.sliceMargin/180*Math.PI;if(aP<aO._radius&&aP>aO._innerRadius){for(aU=0;aU<aO.gridData.length;aU++){aA=(aU>0)?aO.gridData[aU-1][1]+au:au;aK=aO.gridData[aU][1];if(aw>aA&&aw<aK){return{seriesIndex:aO.index,pointIndex:aU,gridData:aO.gridData[aU],data:aO.data[aU]}}}}break;case L.jqplot.PieRenderer:az=aO.startAngle/180*Math.PI;aJ=al.x-aO._center[0];aI=al.y-aO._center[1];aP=Math.sqrt(Math.pow(aJ,2)+Math.pow(aI,2));if(aJ>0&&-aI>=0){aw=2*Math.PI-Math.atan(-aI/aJ)}else{if(aJ>0&&-aI<0){aw=-Math.atan(-aI/aJ)}else{if(aJ<0){aw=Math.PI-Math.atan(-aI/aJ)}else{if(aJ==0&&-aI>0){aw=3*Math.PI/2}else{if(aJ==0&&-aI<0){aw=Math.PI/2}else{if(aJ==0&&aI==0){aw=0}}}}}}if(az){aw-=az;if(aw<0){aw+=2*Math.PI}else{if(aw>2*Math.PI!
){aw-=2*Math.PI}}}au=aO.sliceMargin/180*Math.PI;if(aP<aO._radius){for(aU=0;aU<aO.gridData.length;aU++){aA=(aU>0)?aO.gridData[aU-1][1]+au:au;aK=aO.gridData[aU][1];if(aw>aA&&aw<aK){return{seriesIndex:aO.index,pointIndex:aU,gridData:aO.gridData[aU],data:aO.data[aU]}}}}break;case L.jqplot.BubbleRenderer:aJ=al.x;aI=al.y;var aF=null;if(aO.show){for(var aU=0;aU<aO.gridData.length;aU++){aQ=aO.gridData[aU];aX=Math.sqrt((aJ-aQ[0])*(aJ-aQ[0])+(aI-aQ[1])*(aI-aQ[1]));if(aX<=aQ[2]&&(aX<=aS||aS==null)){aS=aX;aF={seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}if(aF!=null){return aF}}break;case L.jqplot.FunnelRenderer:aJ=al.x;aI=al.y;var aL=aO._vertices,ap=aL[0],ao=aL[aL.length-1],at,aE,ay;function aR(a0,a2,a1){var aZ=(a2[1]-a1[1])/(a2[0]-a1[0]);var aY=a2[1]-aZ*a2[0];var a3=a0+a2[1];return[(a3-aY)/aZ,a3]}at=aR(aI,ap[0],ao[3]);aE=aR(aI,ap[1],ao[2]);for(aU=0;aU<aL.length;aU++){ay=aL[aU];if(aI>=ay[0][1]&&aI<=ay[3][1]&&aJ>=at[0]&&aJ<=aE[0]){return{seriesIndex:aO.index,pointIndex:aU,gridData:null,data:aO.data[aU]}}}break;case L.jqplot.LineRenderer:aJ=al.x;aI=al.y;aP=aO.renderer;if(aO.show){if((aO.fill||(aO.renderer.bands.show&&aO.renderer.bands.fill))&&(!am.plugins.highlighter||!am.plugins.highlighter.show)){var ax=false;if(aJ>aO._boundingBox[0][0]&&aJ<aO._boundingBox[1][0]&&aI>aO._boundingBox[1][1]&&aI<aO._boundingBox[0][1]){var aD=aO._areaPoints.length;var aG;var aU=aD-1;for(var aG=0;aG<aD;aG++){var aC=[aO._areaPoints[aG][0],aO._areaPoints[aG][1]];var aB=[aO._areaPoints[aU][0],aO._areaPoints[aU][1]];if(aC[1]<aI&&aB[1]>=aI||aB[1]<aI&&aC[1]>=aI){if(aC[0]+(aI-aC[1])/(aB[1]-aC[1])*(aB[0]-aC[0])<aJ){ax=!ax}}aU=aG}}if(ax){return{seriesIndex:aW,pointIndex:null,gridData:aO.gridData,data:aO.data,points:aO._areaPoints}}break}else{aN=aO.markerRenderer.size/2+aO.neighborThreshold;an=(aN>0)?aN:0;for(var aU=0;aU<aO.gridData.length;aU++){aQ=aO.gridData[aU];if(aP.constructor==L.jqplot.OHLCRenderer){if(aP.candleStick){var av=aO._yaxis.series_u2p;if(aJ>=aQ[0]-aP._bodyWidth/2&&aJ<=aQ[0]+aP._bodyWidth/2&&aI>=av(aO.data[aU][2])&&aI<=av(aO.!
data[aU][3])){return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}else{if(!aP.hlc){var av=aO._yaxis.series_u2p;if(aJ>=aQ[0]-aP._tickLength&&aJ<=aQ[0]+aP._tickLength&&aI>=av(aO.data[aU][2])&&aI<=av(aO.data[aU][3])){return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}else{var av=aO._yaxis.series_u2p;if(aJ>=aQ[0]-aP._tickLength&&aJ<=aQ[0]+aP._tickLength&&aI>=av(aO.data[aU][1])&&aI<=av(aO.data[aU][2])){return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}}}else{if(aQ[0]!=null&&aQ[1]!=null){aX=Math.sqrt((aJ-aQ[0])*(aJ-aQ[0])+(aI-aQ[1])*(aI-aQ[1]));if(aX<=an&&(aX<=aS||aS==null)){aS=aX;return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}}}}}break;default:aJ=al.x;aI=al.y;aP=aO.renderer;if(aO.show){aN=aO.markerRenderer.size/2+aO.neighborThreshold;an=(aN>0)?aN:0;for(var aU=0;aU<aO.gridData.length;aU++){aQ=aO.gridData[aU];if(aP.constructor==L.jqplot.OHLCRenderer){if(aP.candleStick){var av=aO._yaxis.series_u2p;if(aJ>=aQ[0]-aP._bodyWidth/2&&aJ<=aQ[0]+aP._bodyWidth/2&&aI>=av(aO.data[aU][2])&&aI<=av(aO.data[aU][3])){return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}else{if(!aP.hlc){var av=aO._yaxis.series_u2p;if(aJ>=aQ[0]-aP._tickLength&&aJ<=aQ[0]+aP._tickLength&&aI>=av(aO.data[aU][2])&&aI<=av(aO.data[aU][3])){return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}else{var av=aO._yaxis.series_u2p;if(aJ>=aQ[0]-aP._tickLength&&aJ<=aQ[0]+aP._tickLength&&aI>=av(aO.data[aU][1])&&aI<=av(aO.data[aU][2])){return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}}}else{aX=Math.sqrt((aJ-aQ[0])*(aJ-aQ[0])+(aI-aQ[1])*(aI-aQ[1]));if(aX<=an&&(aX<=aS||aS==null)){aS=aX;return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}}}break}}return null}this.onClick=function(an){var am=ai(an);var ap=an.data.plot;var ao=ak(am.gridPos,ap);var al=L.Event("jqplotClick");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,ao,ap])};this.onDblClick=function(an){var am=ai(an);var ap=an.data.plot;var ao=ak(am.gridPos,ap);var al!
=L.Event("jqplotDblClick");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,ao,ap])};this.onMouseDown=function(an){var am=ai(an);var ap=an.data.plot;var ao=ak(am.gridPos,ap);var al=L.Event("jqplotMouseDown");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,ao,ap])};this.onMouseUp=function(an){var am=ai(an);var al=L.Event("jqplotMouseUp");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,null,an.data.plot])};this.onRightClick=function(an){var am=ai(an);var ap=an.data.plot;var ao=ak(am.gridPos,ap);if(ap.captureRightClick){if(an.which==3){var al=L.Event("jqplotRightClick");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,ao,ap])}else{var al=L.Event("jqplotMouseUp");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,ao,ap])}}};this.onMouseMove=function(an){var am=ai(an);var ap=an.data.plot;var ao=ak(am.gridPos,ap);var al=L.Event("jqplotMouseMove");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,ao,ap])};this.onMouseEnter=function(an){var am=ai(an);var ao=an.data.plot;var al=L.Event("jqplotMouseEnter");al.pageX=an.pageX;al.pageY=an.pageY;al.relatedTarget=an.relatedTarget;L(this).trigger(al,[am.gridPos,am.dataPos,null,ao])};this.onMouseLeave=function(an){var am=ai(an);var ao=an.data.plot;var al=L.Event("jqplotMouseLeave");al.pageX=an.pageX;al.pageY=an.pageY;al.relatedTarget=an.relatedTarget;L(this).trigger(al,[am.gridPos,am.dataPos,null,ao])};this.drawSeries=function(an,al){var ap,ao,am;al=(typeof(an)==="number"&&al==null)?an:al;an=(typeof(an)==="object")?an:{};if(al!=u){ao=this.series[al];am=ao.shadowCanvas._ctx;am.clearRect(0,0,am.canvas.width,am.canvas.height);ao.drawShadow(am,an,this);am=ao.canvas._ctx;am.clearRect(0,0,am.canvas.width,am.canvas.height);ao.draw(am,an,this);if(ao.renderer.constructor==L.jqplot.BezierCurveRenderer){if(al<this.series.length-1){this.drawSeries(al+1)}}}else{for(ap=0;ap<this.series.length;ap++){ao=this.series[ap];am=ao!
.shadowCanvas._ctx;am.clearRect(0,0,am.canvas.width,am.canvas.height);ao.drawShadow(am,an,this);am=ao.canvas._ctx;am.clearRect(0,0,am.canvas.width,am.canvas.height);ao.draw(am,an,this)}}an=al=ap=ao=am=null};this.moveSeriesToFront=function(am){am=parseInt(am,10);var ap=L.inArray(am,this.seriesStack);if(ap==-1){return}if(ap==this.seriesStack.length-1){this.previousSeriesStack=this.seriesStack.slice(0);return}var al=this.seriesStack[this.seriesStack.length-1];var ao=this.series[am].canvas._elem.detach();var an=this.series[am].shadowCanvas._elem.detach();this.series[al].shadowCanvas._elem.after(an);this.series[al].canvas._elem.after(ao);this.previousSeriesStack=this.seriesStack.slice(0);this.seriesStack.splice(ap,1);this.seriesStack.push(am)};this.moveSeriesToBack=function(am){am=parseInt(am,10);var ap=L.inArray(am,this.seriesStack);if(ap==0||ap==-1){return}var al=this.seriesStack[0];var ao=this.series[am].canvas._elem.detach();var an=this.series[am].shadowCanvas._elem.detach();this.series[al].shadowCanvas._elem.before(an);this.series[al].canvas._elem.before(ao);this.previousSeriesStack=this.seriesStack.slice(0);this.seriesStack.splice(ap,1);this.seriesStack.unshift(am)};this.restorePreviousSeriesOrder=function(){var ar,aq,ap,ao,an,al,am;if(this.seriesStack==this.previousSeriesStack){return}for(ar=1;ar<this.previousSeriesStack.length;ar++){al=this.previousSeriesStack[ar];am=this.previousSeriesStack[ar-1];ap=this.series[al].canvas._elem.detach();ao=this.series[al].shadowCanvas._elem.detach();this.series[am].shadowCanvas._elem.after(ao);this.series[am].canvas._elem.after(ap)}an=this.seriesStack.slice(0);this.seriesStack=this.previousSeriesStack.slice(0);this.previousSeriesStack=an};this.restoreOriginalSeriesOrder=function(){var ap,ao,al=[],an,am;for(ap=0;ap<this.series.length;ap++){al.push(ap)}if(this.seriesStack==al){return}this.previousSeriesStack=this.seriesStack.slice(0);this.seriesStack=al;for(ap=1;ap<this.seriesStack.length;ap++){an=this.series[ap].canvas._elem.detach();am=this.series[ap].shadowCanvas._elem.deta!
ch();this.series[ap-1].shadowCanvas._elem.after(am);this.series[ap-1].canvas._elem.after(an)}};this.activateTheme=function(al){this.themeEngine.activate(this,al)}}L.jqplot.computeHighlightColors=function(ai){var ak;if(L.isArray(ai)){ak=[];for(var am=0;am<ai.length;am++){var al=L.jqplot.getColorComponents(ai[am]);var ah=[al[0],al[1],al[2]];var an=ah[0]+ah[1]+ah[2];for(var aj=0;aj<3;aj++){ah[aj]=(an>660)?ah[aj]*0.85:0.73*ah[aj]+90;ah[aj]=parseInt(ah[aj],10);(ah[aj]>255)?255:ah[aj]}ah[3]=0.3+0.35*al[3];ak.push("rgba("+ah[0]+","+ah[1]+","+ah[2]+","+ah[3]+")")}}else{var al=L.jqplot.getColorComponents(ai);var ah=[al[0],al[1],al[2]];var an=ah[0]+ah[1]+ah[2];for(var aj=0;aj<3;aj++){ah[aj]=(an>660)?ah[aj]*0.85:0.73*ah[aj]+90;ah[aj]=parseInt(ah[aj],10);(ah[aj]>255)?255:ah[aj]}ah[3]=0.3+0.35*al[3];ak="rgba("+ah[0]+","+ah[1]+","+ah[2]+","+ah[3]+")"}return ak};L.jqplot.ColorGenerator=function(ai){ai=ai||L.jqplot.config.defaultColors;var ah=0;this.next=function(){if(ah<ai.length){return ai[ah++]}else{ah=0;return ai[ah++]}};this.previous=function(){if(ah>0){return ai[ah--]}else{ah=ai.length-1;return ai[ah]}};this.get=function(ak){var aj=ak-ai.length*Math.floor(ak/ai.length);return ai[aj]};this.setColors=function(aj){ai=aj};this.reset=function(){ah=0};this.getIndex=function(){return ah};this.setIndex=function(aj){ah=aj}};L.jqplot.hex2rgb=function(aj,ah){aj=aj.replace("#","");if(aj.length==3){aj=aj.charAt(0)+aj.charAt(0)+aj.charAt(1)+aj.charAt(1)+aj.charAt(2)+aj.charAt(2)}var ai;ai="rgba("+parseInt(aj.slice(0,2),16)+", "+parseInt(aj.slice(2,4),16)+", "+parseInt(aj.slice(4,6),16);if(ah){ai+=", "+ah}ai+=")";return ai};L.jqplot.rgb2hex=function(am){var aj=/rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *(?:, *[0-9.]*)?\)/;var ah=am.match(aj);var al="#";for(var ak=1;ak<4;ak++){var ai;if(ah[ak].search(/%/)!=-1){ai=parseInt(255*ah[ak]/100,10).toString(16);if(ai.length==1){ai="0"+ai}}else{ai=parseInt(ah[ak],10).toString(16);if(ai.length==1){ai="0"+ai}}al+=ai}return al};L.jqplot.normalize2rgb=fu!
nction(ai,ah){if(ai.search(/^ *rgba?\(/)!=-1){return ai}else{if(ai.search(/^ *#?[0-9a-fA-F]?[0-9a-fA-F]/)!=-1){return L.jqplot.hex2rgb(ai,ah)}else{throw"invalid color spec"}}};L.jqplot.getColorComponents=function(am){am=L.jqplot.colorKeywordMap[am]||am;var ak=L.jqplot.normalize2rgb(am);var aj=/rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *,? *([0-9.]* *)?\)/;var ah=ak.match(aj);var ai=[];for(var al=1;al<4;al++){if(ah[al].search(/%/)!=-1){ai[al-1]=parseInt(255*ah[al]/100,10)}else{ai[al-1]=parseInt(ah[al],10)}}ai[3]=parseFloat(ah[4])?parseFloat(ah[4]):1;return ai};L.jqplot.colorKeywordMap={aliceblue:"rgb(240, 248, 255)",antiquewhite:"rgb(250, 235, 215)",aqua:"rgb( 0, 255, 255)",aquamarine:"rgb(127, 255, 212)",azure:"rgb(240, 255, 255)",beige:"rgb(245, 245, 220)",bisque:"rgb(255, 228, 196)",black:"rgb( 0, 0, 0)",blanchedalmond:"rgb(255, 235, 205)",blue:"rgb( 0, 0, 255)",blueviolet:"rgb(138, 43, 226)",brown:"rgb(165, 42, 42)",burlywood:"rgb(222, 184, 135)",cadetblue:"rgb( 95, 158, 160)",chartreuse:"rgb(127, 255, 0)",chocolate:"rgb(210, 105, 30)",coral:"rgb(255, 127, 80)",cornflowerblue:"rgb(100, 149, 237)",cornsilk:"rgb(255, 248, 220)",crimson:"rgb(220, 20, 60)",cyan:"rgb( 0, 255, 255)",darkblue:"rgb( 0, 0, 139)",darkcyan:"rgb( 0, 139, 139)",darkgoldenrod:"rgb(184, 134, 11)",darkgray:"rgb(169, 169, 169)",darkgreen:"rgb( 0, 100, 0)",darkgrey:"rgb(169, 169, 169)",darkkhaki:"rgb(189, 183, 107)",darkmagenta:"rgb(139, 0, 139)",darkolivegreen:"rgb( 85, 107, 47)",darkorange:"rgb(255, 140, 0)",darkorchid:"rgb(153, 50, 204)",darkred:"rgb(139, 0, 0)",darksalmon:"rgb(233, 150, 122)",darkseagreen:"rgb(143, 188, 143)",darkslateblue:"rgb( 72, 61, 139)",darkslategray:"rgb( 47, 79, 79)",darkslategrey:"rgb( 47, 79, 79)",darkturquoise:"rgb( 0, 206, 209)",darkviolet:"rgb(148, 0, 211)",deeppink:"rgb(255, 20, 147)",deepskyblue:"rgb( 0, 191, 255)",dimgray:"rgb(105, 105, 105)",dimgrey:"rgb(105, 105, 105)",dodgerblue:"rgb( 30, 144, 255)",firebrick:"rgb(178, 34, 34)",floralwhite:"rgb(255, 250, 240!
)",forestgreen:"rgb( 34, 139, 34)",fuchsia:"rgb(255, 0, 255)",gainsboro:"rgb(220, 220, 220)",ghostwhite:"rgb(248, 248, 255)",gold:"rgb(255, 215, 0)",goldenrod:"rgb(218, 165, 32)",gray:"rgb(128, 128, 128)",grey:"rgb(128, 128, 128)",green:"rgb( 0, 128, 0)",greenyellow:"rgb(173, 255, 47)",honeydew:"rgb(240, 255, 240)",hotpink:"rgb(255, 105, 180)",indianred:"rgb(205, 92, 92)",indigo:"rgb( 75, 0, 130)",ivory:"rgb(255, 255, 240)",khaki:"rgb(240, 230, 140)",lavender:"rgb(230, 230, 250)",lavenderblush:"rgb(255, 240, 245)",lawngreen:"rgb(124, 252, 0)",lemonchiffon:"rgb(255, 250, 205)",lightblue:"rgb(173, 216, 230)",lightcoral:"rgb(240, 128, 128)",lightcyan:"rgb(224, 255, 255)",lightgoldenrodyellow:"rgb(250, 250, 210)",lightgray:"rgb(211, 211, 211)",lightgreen:"rgb(144, 238, 144)",lightgrey:"rgb(211, 211, 211)",lightpink:"rgb(255, 182, 193)",lightsalmon:"rgb(255, 160, 122)",lightseagreen:"rgb( 32, 178, 170)",lightskyblue:"rgb(135, 206, 250)",lightslategray:"rgb(119, 136, 153)",lightslategrey:"rgb(119, 136, 153)",lightsteelblue:"rgb(176, 196, 222)",lightyellow:"rgb(255, 255, 224)",lime:"rgb( 0, 255, 0)",limegreen:"rgb( 50, 205, 50)",linen:"rgb(250, 240, 230)",magenta:"rgb(255, 0, 255)",maroon:"rgb(128, 0, 0)",mediumaquamarine:"rgb(102, 205, 170)",mediumblue:"rgb( 0, 0, 205)",mediumorchid:"rgb(186, 85, 211)",mediumpurple:"rgb(147, 112, 219)",mediumseagreen:"rgb( 60, 179, 113)",mediumslateblue:"rgb(123, 104, 238)",mediumspringgreen:"rgb( 0, 250, 154)",mediumturquoise:"rgb( 72, 209, 204)",mediumvioletred:"rgb(199, 21, 133)",midnightblue:"rgb( 25, 25, 112)",mintcream:"rgb(245, 255, 250)",mistyrose:"rgb(255, 228, 225)",moccasin:"rgb(255, 228, 181)",navajowhite:"rgb(255, 222, 173)",navy:"rgb( 0, 0, 128)",oldlace:"rgb(253, 245, 230)",olive:"rgb(128, 128, 0)",olivedrab:"rgb(107, 142, 35)",orange:"rgb(255, 165, 0)",orangered:"rgb(255, 69, 0)",orchid:"rgb(218, 112, 214)",palegoldenrod:"rgb(238, 232, 170)",palegreen:"rgb(152, 251, 152)",paleturquoise:"rgb(175, 238, 238)",palevioletred:"rgb(219, 112, 147)",papayawhip:"rgb(255, 239, 21!
3)",peachpuff:"rgb(255, 218, 185)",peru:"rgb(205, 133, 63)",pink:"rgb(255, 192, 203)",plum:"rgb(221, 160, 221)",powderblue:"rgb(176, 224, 230)",purple:"rgb(128, 0, 128)",red:"rgb(255, 0, 0)",rosybrown:"rgb(188, 143, 143)",royalblue:"rgb( 65, 105, 225)",saddlebrown:"rgb(139, 69, 19)",salmon:"rgb(250, 128, 114)",sandybrown:"rgb(244, 164, 96)",seagreen:"rgb( 46, 139, 87)",seashell:"rgb(255, 245, 238)",sienna:"rgb(160, 82, 45)",silver:"rgb(192, 192, 192)",skyblue:"rgb(135, 206, 235)",slateblue:"rgb(106, 90, 205)",slategray:"rgb(112, 128, 144)",slategrey:"rgb(112, 128, 144)",snow:"rgb(255, 250, 250)",springgreen:"rgb( 0, 255, 127)",steelblue:"rgb( 70, 130, 180)",tan:"rgb(210, 180, 140)",teal:"rgb( 0, 128, 128)",thistle:"rgb(216, 191, 216)",tomato:"rgb(255, 99, 71)",turquoise:"rgb( 64, 224, 208)",violet:"rgb(238, 130, 238)",wheat:"rgb(245, 222, 179)",white:"rgb(255, 255, 255)",whitesmoke:"rgb(245, 245, 245)",yellow:"rgb(255, 255, 0)",yellowgreen:"rgb(154, 205, 50)"};L.jqplot.AxisLabelRenderer=function(ah){L.jqplot.ElemContainer.call(this);this.axis;this.show=true;this.label="";this.fontFamily=null;this.fontSize=null;this.textColor=null;this._elem;this.escapeHTML=false;L.extend(true,this,ah)};L.jqplot.AxisLabelRenderer.prototype=new L.jqplot.ElemContainer();L.jqplot.AxisLabelRenderer.prototype.constructor=L.jqplot.AxisLabelRenderer;L.jqplot.AxisLabelRenderer.prototype.init=function(ah){L.extend(true,this,ah)};L.jqplot.AxisLabelRenderer.prototype.draw=function(ah,ai){if(this._elem){this._elem.emptyForce();this._elem=null}this._elem=L('<div style="position:absolute;" class="jqplot-'+this.axis+'-label"></div>');if(Number(this.label)){this._elem.css("white-space","nowrap")}if(!this.escapeHTML){this._elem.html(this.label)}else{this._elem.text(this.label)}if(this.fontFamily){this._elem.css("font-family",this.fontFamily)}if(this.fontSize){this._elem.css("font-size",this.fontSize)}if(this.textColor){this._elem.css("color",this.textColor)}return this._elem};L.jqplot.AxisLabelRenderer.prototype.pack=function(){};L.jqplot.AxisTic!
kRenderer=function(ah){L.jqplot.ElemContainer.call(this);this.mark="outside";this.axis;this.showMark=true;this.showGridline=true;this.isMinorTick=false;this.size=4;this.markSize=6;this.show=true;this.showLabel=true;this.label=null;this.value=null;this._styles={};this.formatter=L.jqplot.DefaultTickFormatter;this.prefix="";this.suffix="";this.formatString="";this.fontFamily;this.fontSize;this.textColor;this.escapeHTML=false;this._elem;this._breakTick=false;L.extend(true,this,ah)};L.jqplot.AxisTickRenderer.prototype.init=function(ah){L.extend(true,this,ah)};L.jqplot.AxisTickRenderer.prototype=new L.jqplot.ElemContainer();L.jqplot.AxisTickRenderer.prototype.constructor=L.jqplot.AxisTickRenderer;L.jqplot.AxisTickRenderer.prototype.setTick=function(ah,aj,ai){this.value=ah;this.axis=aj;if(ai){this.isMinorTick=true}return this};L.jqplot.AxisTickRenderer.prototype.draw=function(){if(this.label===null){this.label=this.prefix+this.formatter(this.formatString,this.value)+this.suffix}var ai={position:"absolute"};if(Number(this.label)){ai.whitSpace="nowrap"}if(this._elem){this._elem.emptyForce();this._elem=null}this._elem=L(document.createElement("div"));this._elem.addClass("jqplot-"+this.axis+"-tick");if(!this.escapeHTML){this._elem.html(this.label)}else{this._elem.text(this.label)}this._elem.css(ai);for(var ah in this._styles){this._elem.css(ah,this._styles[ah])}if(this.fontFamily){this._elem.css("font-family",this.fontFamily)}if(this.fontSize){this._elem.css("font-size",this.fontSize)}if(this.textColor){this._elem.css("color",this.textColor)}if(this._breakTick){this._elem.addClass("jqplot-breakTick")}return this._elem};L.jqplot.DefaultTickFormatter=function(ah,ai){if(typeof ai=="number"){if(!ah){ah=L.jqplot.config.defaultTickFormatString}return L.jqplot.sprintf(ah,ai)}else{return String(ai)}};L.jqplot.PercentTickFormatter=function(ah,ai){if(typeof ai=="number"){ai=100*ai;if(!ah){ah=L.jqplot.config.defaultTickFormatString}return L.jqplot.sprintf(ah,ai)}else{return String(ai)}};L.jqplot.AxisTickRenderer.prototype.pack=functi!
on(){};L..jqplot.CanvasGridRenderer=function(){this.shadowRenderer=new L.jqplot.ShadowRenderer()};L.jqplot.CanvasGridRenderer.prototype.init=function(ai){this._ctx;L.extend(true,this,ai);var ah={lineJoin:"miter",lineCap:"round",fill:false,isarc:false,angle:this.shadowAngle,offset:this.shadowOffset,alpha:this.shadowAlpha,depth:this.shadowDepth,lineWidth:this.shadowWidth,closePath:false,strokeStyle:this.shadowColor};this.renderer.shadowRenderer.init(ah)};L.jqplot.CanvasGridRenderer.prototype.createElement=function(ak){var aj;if(this._elem){if(L.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==u){aj=this._elem.get(0);window.G_vmlCanvasManager.uninitElement(aj);aj=null}this._elem.emptyForce();this._elem=null}aj=ak.canvasManager.getCanvas();var ah=this._plotDimensions.width;var ai=this._plotDimensions.height;aj.width=ah;aj.height=ai;this._elem=L(aj);this._elem.addClass("jqplot-grid-canvas");this._elem.css({position:"absolute",left:0,top:0});aj=ak.canvasManager.initCanvas(aj);this._top=this._offsets.top;this._bottom=ai-this._offsets.bottom;this._left=this._offsets.left;this._right=ah-this._offsets.right;this._width=this._right-this._left;this._height=this._bottom-this._top;aj=null;return this._elem};L.jqplot.CanvasGridRenderer.prototype.draw=function(){this._ctx=this._elem.get(0).getContext("2d");var at=this._ctx;var aw=this._axes;at.save();at.clearRect(0,0,this._plotDimensions.width,this._plotDimensions.height);at.fillStyle=this.backgroundColor||this.background;at.fillRect(this._left,this._top,this._width,this._height);at.save();at.lineJoin="miter";at.lineCap="butt";at.lineWidth=this.gridLineWidth;at.strokeStyle=this.gridLineColor;var aA,az,ap,aq;var am=["xaxis","yaxis","x2axis","y2axis"];for(var ay=4;ay>0;ay--){var aD=am[ay-1];var ah=aw[aD];var aB=ah._ticks;var ar=aB.length;if(ah.show){if(ah.drawBaseline){var aC={};if(ah.baselineWidth!==null){aC.lineWidth=ah.baselineWidth}if(ah.baselineColor!==null){aC.strokeStyle=ah.baselineColor}switch(aD){case"xaxis":ao(this._left,this._bottom,this._right,this._botto!
m,aC);break;case"yaxis":ao(this._left,this._bottom,this._left,this._top,aC);break;case"x2axis":ao(this._left,this._bottom,this._right,this._bottom,aC);break;case"y2axis":ao(this._right,this._bottom,this._right,this._top,aC);break}}for(var au=ar;au>0;au--){var an=aB[au-1];if(an.show){var ak=Math.round(ah.u2p(an.value))+0.5;switch(aD){case"xaxis":if(an.showGridline&&this.drawGridlines&&((!an.isMinorTick&&ah.drawMajorGridlines)||(an.isMinorTick&&ah.drawMinorGridlines))){ao(ak,this._top,ak,this._bottom)}if(an.showMark&&an.mark&&((!an.isMinorTick&&ah.drawMajorTickMarks)||(an.isMinorTick&&ah.drawMinorTickMarks))){ap=an.markSize;aq=an.mark;var ak=Math.round(ah.u2p(an.value))+0.5;switch(aq){case"outside":aA=this._bottom;az=this._bottom+ap;break;case"inside":aA=this._bottom-ap;az=this._bottom;break;case"cross":aA=this._bottom-ap;az=this._bottom+ap;break;default:aA=this._bottom;az=this._bottom+ap;break}if(this.shadow){this.renderer.shadowRenderer.draw(at,[[ak,aA],[ak,az]],{lineCap:"butt",lineWidth:this.gridLineWidth,offset:this.gridLineWidth*0.75,depth:2,fill:false,closePath:false})}ao(ak,aA,ak,az)}break;case"yaxis":if(an.showGridline&&this.drawGridlines&&((!an.isMinorTick&&ah.drawMajorGridlines)||(an.isMinorTick&&ah.drawMinorGridlines))){ao(this._right,ak,this._left,ak)}if(an.showMark&&an.mark&&((!an.isMinorTick&&ah.drawMajorTickMarks)||(an.isMinorTick&&ah.drawMinorTickMarks))){ap=an.markSize;aq=an.mark;var ak=Math.round(ah.u2p(an.value))+0.5;switch(aq){case"outside":aA=this._left-ap;az=this._left;break;case"inside":aA=this._left;az=this._left+ap;break;case"cross":aA=this._left-ap;az=this._left+ap;break;default:aA=this._left-ap;az=this._left;break}if(this.shadow){this.renderer.shadowRenderer.draw(at,[[aA,ak],[az,ak]],{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}ao(aA,ak,az,ak,{strokeStyle:ah.borderColor})}break;case"x2axis":if(an.showGridline&&this.drawGridlines&&((!an.isMinorTick&&ah.drawMajorGridlines)||(an.isMinorTick&&ah.drawMinorGridlines))){ao(ak,this.!
_bottom,ak,this._top)}if(an.showMark&&an.mark&&((!an.isMinorTick&&ah.drawMajorTickMarks)||(an.isMinorTick&&ah.drawMinorTickMarks))){ap=an.markSize;aq=an.mark;var ak=Math.round(ah.u2p(an.value))+0.5;switch(aq){case"outside":aA=this._top-ap;az=this._top;break;case"inside":aA=this._top;az=this._top+ap;break;case"cross":aA=this._top-ap;az=this._top+ap;break;default:aA=this._top-ap;az=this._top;break}if(this.shadow){this.renderer.shadowRenderer.draw(at,[[ak,aA],[ak,az]],{lineCap:"butt",lineWidth:this.gridLineWidth,offset:this.gridLineWidth*0.75,depth:2,fill:false,closePath:false})}ao(ak,aA,ak,az)}break;case"y2axis":if(an.showGridline&&this.drawGridlines&&((!an.isMinorTick&&ah.drawMajorGridlines)||(an.isMinorTick&&ah.drawMinorGridlines))){ao(this._left,ak,this._right,ak)}if(an.showMark&&an.mark&&((!an.isMinorTick&&ah.drawMajorTickMarks)||(an.isMinorTick&&ah.drawMinorTickMarks))){ap=an.markSize;aq=an.mark;var ak=Math.round(ah.u2p(an.value))+0.5;switch(aq){case"outside":aA=this._right;az=this._right+ap;break;case"inside":aA=this._right-ap;az=this._right;break;case"cross":aA=this._right-ap;az=this._right+ap;break;default:aA=this._right;az=this._right+ap;break}if(this.shadow){this.renderer.shadowRenderer.draw(at,[[aA,ak],[az,ak]],{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}ao(aA,ak,az,ak,{strokeStyle:ah.borderColor})}break;default:break}}}an=null}ah=null;aB=null}am=["y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis","yMidAxis"];for(var ay=7;ay>0;ay--){var ah=aw[am[ay-1]];var aB=ah._ticks;if(ah.show){var ai=aB[ah.numberTicks-1];var al=aB[0];var aj=ah.getLeft();var av=[[aj,ai.getTop()+ai.getHeight()/2],[aj,al.getTop()+al.getHeight()/2+1]];if(this.shadow){this.renderer.shadowRenderer.draw(at,av,{lineCap:"butt",fill:false,closePath:false})}ao(av[0][0],av[0][1],av[1][0],av[1][1],{lineCap:"butt",strokeStyle:ah.borderColor,lineWidth:ah.borderWidth});for(var au=aB.length;au>0;au--){var an=aB[au-1];ap=an.markSize;aq=an.mark;var ak=Math.round(ah.u2p(an.val!
ue))+0.5;if(an.showMark&&an.mark){switch(aq){case"outside":aA=aj;az=aj+ap;break;case"inside":aA=aj-ap;az=aj;break;case"cross":aA=aj-ap;az=aj+ap;break;default:aA=aj;az=aj+ap;break}av=[[aA,ak],[az,ak]];if(this.shadow){this.renderer.shadowRenderer.draw(at,av,{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}ao(aA,ak,az,ak,{strokeStyle:ah.borderColor})}an=null}al=null}ah=null;aB=null}at.restore();function ao(aH,aG,aE,ax,aF){at.save();aF=aF||{};if(aF.lineWidth==null||aF.lineWidth!=0){L.extend(true,at,aF);at.beginPath();at.moveTo(aH,aG);at.lineTo(aE,ax);at.stroke();at.restore()}}if(this.shadow){var av=[[this._left,this._bottom],[this._right,this._bottom],[this._right,this._top]];this.renderer.shadowRenderer.draw(at,av)}if(this.borderWidth!=0&&this.drawBorder){ao(this._left,this._top,this._right,this._top,{lineCap:"round",strokeStyle:aw.x2axis.borderColor,lineWidth:aw.x2axis.borderWidth});ao(this._right,this._top,this._right,this._bottom,{lineCap:"round",strokeStyle:aw.y2axis.borderColor,lineWidth:aw.y2axis.borderWidth});ao(this._right,this._bottom,this._left,this._bottom,{lineCap:"round",strokeStyle:aw.xaxis.borderColor,lineWidth:aw.xaxis.borderWidth});ao(this._left,this._bottom,this._left,this._top,{lineCap:"round",strokeStyle:aw.yaxis.borderColor,lineWidth:aw.yaxis.borderWidth})}at.restore();at=null;aw=null};L.jqplot.DivTitleRenderer=function(){};L.jqplot.DivTitleRenderer.prototype.init=function(ah){L.extend(true,this,ah)};L.jqplot.DivTitleRenderer.prototype.draw=function(){if(this._elem){this._elem.emptyForce();this._elem=null}var ak=this.renderer;var aj=document.createElement("div");this._elem=L(aj);this._elem.addClass("jqplot-title");if(!this.text){this.show=false;this._elem.height(0);this._elem.width(0)}else{if(this.text){var ah;if(this.color){ah=this.color}else{if(this.textColor){ah=this.textColor}}var ai={position:"absolute",top:"0px",left:"0px"};if(this._plotWidth){ai.width=this._plotWidth+"px"}if(this.fontSize){ai.fontSize=this.fontSize}if(typeof thi!
s.textAlign==="string"){ai.textAlign=this.textAlign}else{ai.textAlign="center"}if(ah){ai.color=ah}if(this.paddingBottom){ai.paddingBottom=this.paddingBottom}if(this.fontFamily){ai.fontFamily=this.fontFamily}this._elem.css(ai);if(this.escapeHtml){this._elem.text(this.text)}else{this._elem.html(this.text)}}}aj=null;return this._elem};L.jqplot.DivTitleRenderer.prototype.pack=function(){};var r=0.1;L.jqplot.LinePattern=function(aw,aq){var ap={dotted:[r,L.jqplot.config.dotGapLength],dashed:[L.jqplot.config.dashLength,L.jqplot.config.gapLength],solid:null};if(typeof aq==="string"){if(aq[0]==="."||aq[0]==="-"){var ax=aq;aq=[];for(var ao=0,al=ax.length;ao<al;ao++){if(ax[ao]==="."){aq.push(r)}else{if(ax[ao]==="-"){aq.push(L.jqplot.config.dashLength)}else{continue}}aq.push(L.jqplot.config.gapLength)}}else{aq=ap[aq]}}if(!(aq&&aq.length)){return aw}var ak=0;var ar=aq[0];var au=0;var at=0;var an=0;var ah=0;var av=function(ay,az){aw.moveTo(ay,az);au=ay;at=az;an=ay;ah=az};var aj=function(ay,aE){var aC=aw.lineWidth;var aA=ay-au;var az=aE-at;var aB=Math.sqrt(aA*aA+az*az);if((aB>0)&&(aC>0)){aA/=aB;az/=aB;while(true){var aD=aC*ar;if(aD<aB){au+=aD*aA;at+=aD*az;if((ak&1)==0){aw.lineTo(au,at)}else{aw.moveTo(au,at)}aB-=aD;ak++;if(ak>=aq.length){ak=0}ar=aq[ak]}else{au=ay;at=aE;if((ak&1)==0){aw.lineTo(au,at)}else{aw.moveTo(au,at)}ar-=aB/aC;break}}}};var ai=function(){aw.beginPath()};var am=function(){aj(an,ah)};return{moveTo:av,lineTo:aj,beginPath:ai,closePath:am}};L.jqplot.LineRenderer=function(){this.shapeRenderer=new L.jqplot.ShapeRenderer();this.shadowRenderer=new L.jqplot.ShadowRenderer()};L.jqplot.LineRenderer.prototype.init=function(ai,an){ai=ai||{};this._type="line";this.renderer.animation={show:false,direction:"left",speed:2500,_supported:true};this.renderer.smooth=false;this.renderer.tension=null;this.renderer.constrainSmoothing=true;this.renderer._smoothedData=[];this.renderer._smoothedPlotData=[];this.renderer._hiBandGridData=[];this.renderer._lowBandGridData=[];this.renderer._hiBandSmoothedData=[];this.renderer._lowBandSmoo!
thedData=[];this.renderer.bandData=[];this.renderer.bands={show:false,hiData:[],lowData:[],color:this.color,showLines:false,fill:true,fillColor:null,_min:null,_max:null,interval:"3%"};var al={highlightMouseOver:ai.highlightMouseOver,highlightMouseDown:ai.highlightMouseDown,highlightColor:ai.highlightColor};delete (ai.highlightMouseOver);delete (ai.highlightMouseDown);delete (ai.highlightColor);L.extend(true,this.renderer,ai);this.renderer.options=ai;if(this.renderer.bandData.length>1&&(!ai.bands||ai.bands.show==null)){this.renderer.bands.show=true}else{if(ai.bands&&ai.bands.show==null&&ai.bands.interval!=null){this.renderer.bands.show=true}}if(this.fill){this.renderer.bands.show=false}if(this.renderer.bands.show){this.renderer.initBands.call(this,this.renderer.options,an)}if(this._stack){this.renderer.smooth=false}var am={lineJoin:this.lineJoin,lineCap:this.lineCap,fill:this.fill,isarc:false,strokeStyle:this.color,fillStyle:this.fillColor,lineWidth:this.lineWidth,linePattern:this.linePattern,closePath:this.fill};this.renderer.shapeRenderer.init(am);var aj=ai.shadowOffset;if(aj==null){if(this.lineWidth>2.5){aj=1.25*(1+(Math.atan((this.lineWidth/2.5))/0.785398163-1)*0.6)}else{aj=1.25*Math.atan((this.lineWidth/2.5))/0.785398163}}var ah={lineJoin:this.lineJoin,lineCap:this.lineCap,fill:this.fill,isarc:false,angle:this.shadowAngle,offset:aj,alpha:this.shadowAlpha,depth:this.shadowDepth,lineWidth:this.lineWidth,linePattern:this.linePattern,closePath:this.fill};this.renderer.shadowRenderer.init(ah);this._areaPoints=[];this._boundingBox=[[],[]];if(!this.isTrendline&&this.fill||this.renderer.bands.show){this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColor=null;if(al.highlightMouseDown&&al.highlightMouseOver==null){al.highlightMouseOver=false}L.extend(true,this,{highlightMouseOver:al.highlightMouseOver,highlightMouseDown:al.highlightMouseDown,highlightColor:al.highlightColor});if(!this.highlightColor){var ak=(this.renderer.bands.show)?this.renderer.bands.fillColor:this.fillColor;this.highlightCol!
or=L.jqplot.computeHighlightColors(ak)}if(this.highlighter){this.highlighter.show=false}}if(!this.isTrendline&&an){an.plugins.lineRenderer={};an.postInitHooks.addOnce(z);an.postDrawHooks.addOnce(af);an.eventListenerHooks.addOnce("jqplotMouseMove",h);an.eventListenerHooks.addOnce("jqplotMouseDown",e);an.eventListenerHooks.addOnce("jqplotMouseUp",ad);an.eventListenerHooks.addOnce("jqplotClick",g);an.eventListenerHooks.addOnce("jqplotRightClick",s)}};L.jqplot.LineRenderer.prototype.initBands=function(ak,av){var al=ak.bandData||[];var an=this.renderer.bands;an.hiData=[];an.lowData=[];var aB=this.data;an._max=null;an._min=null;if(al.length==2){if(L.isArray(al[0][0])){var ao;var ah=0,ar=0;for(var aw=0,at=al[0].length;aw<at;aw++){ao=al[0][aw];if((ao[1]!=null&&ao[1]>an._max)||an._max==null){an._max=ao[1]}if((ao[1]!=null&&ao[1]<an._min)||an._min==null){an._min=ao[1]}}for(var aw=0,at=al[1].length;aw<at;aw++){ao=al[1][aw];if((ao[1]!=null&&ao[1]>an._max)||an._max==null){an._max=ao[1];ar=1}if((ao[1]!=null&&ao[1]<an._min)||an._min==null){an._min=ao[1];ah=1}}if(ar===ah){an.show=false}an.hiData=al[ar];an.lowData=al[ah]}else{if(al[0].length===aB.length&&al[1].length===aB.length){var aj=(al[0][0]>al[1][0])?0:1;var aC=(aj)?0:1;for(var aw=0,at=aB.length;aw<at;aw++){an.hiData.push([aB[aw][0],al[aj][aw]]);an.lowData.push([aB[aw][0],al[aC][aw]])}}else{an.show=false}}}else{if(al.length>2&&!L.isArray(al[0][0])){var aj=(al[0][0]>al[0][1])?0:1;var aC=(aj)?0:1;for(var aw=0,at=al.length;aw<at;aw++){an.hiData.push([aB[aw][0],al[aw][aj]]);an.lowData.push([aB[aw][0],al[aw][aC]])}}else{var aq=an.interval;var aA=null;var az=null;var ai=null;var au=null;if(L.isArray(aq)){aA=aq[0];az=aq[1]}else{aA=aq}if(isNaN(aA)){if(aA.charAt(aA.length-1)==="%"){ai="multiply";aA=parseFloat(aA)/100+1}}else{aA=parseFloat(aA);ai="add"}if(az!==null&&isNaN(az)){if(az.charAt(az.length-1)==="%"){au="multiply";az=parseFloat(az)/100+1}}else{if(az!==null){az=parseFloat(az);au="add"}}if(aA!==null){if(az===null){az=-aA;au=ai;if(au==="multiply"){az+=2}}if(aA<az){var ax=aA;aA=!
az;az=ax;ax=ai;ai=au;au=ax}for(var aw=0,at=aB.length;aw<at;aw++){switch(ai){case"add":an.hiData.push([aB[aw][0],aB[aw][1]+aA]);break;case"multiply":an.hiData.push([aB[aw][0],aB[aw][1]*aA]);break}switch(au){case"add":an.lowData.push([aB[aw][0],aB[aw][1]+az]);break;case"multiply":an.lowData.push([aB[aw][0],aB[aw][1]*az]);break}}}else{an.show=false}}}var am=an.hiData;var ap=an.lowData;for(var aw=0,at=am.length;aw<at;aw++){if((am[aw][1]!=null&&am[aw][1]>an._max)||an._max==null){an._max=am[aw][1]}}for(var aw=0,at=ap.length;aw<at;aw++){if((ap[aw][1]!=null&&ap[aw][1]<an._min)||an._min==null){an._min=ap[aw][1]}}if(an.fillColor===null){var ay=L.jqplot.getColorComponents(an.color);ay[3]=ay[3]*0.5;an.fillColor="rgba("+ay[0]+", "+ay[1]+", "+ay[2]+", "+ay[3]+")"}};function K(ai,ah){return(3.4182054+ah)*Math.pow(ai,-0.3534992)}function n(aj,ai){var ah=Math.sqrt(Math.pow((ai[0]-aj[0]),2)+Math.pow((ai[1]-aj[1]),2));return 5.7648*Math.log(ah)+7.4456}function A(ah){var ai=(Math.exp(2*ah)-1)/(Math.exp(2*ah)+1);return ai}function J(aJ){var at=this.renderer.smooth;var aD=this.canvas.getWidth();var an=this._xaxis.series_p2u;var aG=this._yaxis.series_p2u;var aF=null;var am=null;var az=aJ.length/aD;var aj=[];var ay=[];if(!isNaN(parseFloat(at))){aF=parseFloat(at)}else{aF=K(az,0.5)}var aw=[];var ak=[];for(var aE=0,aA=aJ.length;aE<aA;aE++){aw.push(aJ[aE][1]);ak.push(aJ[aE][0])}function av(aK,aL){if(aK-aL==0){return Math.pow(10,10)}else{return aK-aL}}var ax,ar,aq,ap;var ah=aJ.length-1;for(var al=1,aB=aJ.length;al<aB;al++){var ai=[];var au=[];for(var aC=0;aC<2;aC++){var aE=al-1+aC;if(aE==0||aE==ah){ai[aC]=Math.pow(10,10)}else{if(aw[aE+1]-aw[aE]==0||aw[aE]-aw[aE-1]==0){ai[aC]=0}else{if(((ak[aE+1]-ak[aE])/(aw[aE+1]-aw[aE])+(ak[aE]-ak[aE-1])/(aw[aE]-aw[aE-1]))==0){ai[aC]=0}else{if((aw[aE+1]-aw[aE])*(aw[aE]-aw[aE-1])<0){ai[aC]=0}else{ai[aC]=2/(av(ak[aE+1],ak[aE])/(aw[aE+1]-aw[aE])+av(ak[aE],ak[aE-1])/(aw[aE]-aw[aE-1]))}}}}}if(al==1){ai[0]=3/2*(aw[1]-aw[0])/av(ak[1],ak[0])-ai[1]/2}else{if(al==ah){ai[1]=3/2*(aw[ah]-aw[ah-1])/av(ak[ah],ak[ah-1])-a!
i[0]/2}}au[0]=-2*(ai[1]+2*ai[0])/av(ak[al],ak[al-1])+6*(aw[al]-aw[al-1])/Math.pow(av(ak[al],ak[al-1]),2);au[1]=2*(2*ai[1]+ai[0])/av(ak[al],ak[al-1])-6*(aw[al]-aw[al-1])/Math.pow(av(ak[al],ak[al-1]),2);ap=1/6*(au[1]-au[0])/av(ak[al],ak[al-1]);aq=1/2*(ak[al]*au[0]-ak[al-1]*au[1])/av(ak[al],ak[al-1]);ar=(aw[al]-aw[al-1]-aq*(Math.pow(ak[al],2)-Math.pow(ak[al-1],2))-ap*(Math.pow(ak[al],3)-Math.pow(ak[al-1],3)))/av(ak[al],ak[al-1]);ax=aw[al-1]-ar*ak[al-1]-aq*Math.pow(ak[al-1],2)-ap*Math.pow(ak[al-1],3);var aI=(ak[al]-ak[al-1])/aF;var aH,ao;for(var aC=0,aA=aF;aC<aA;aC++){aH=[];ao=ak[al-1]+aC*aI;aH.push(ao);aH.push(ax+ar*ao+aq*Math.pow(ao,2)+ap*Math.pow(ao,3));aj.push(aH);ay.push([an(aH[0]),aG(aH[1])])}}aj.push(aJ[aE]);ay.push([an(aJ[aE][0]),aG(aJ[aE][1])]);return[aj,ay]}function F(ap){var ao=this.renderer.smooth;var aU=this.renderer.tension;var ah=this.canvas.getWidth();var aH=this._xaxis.series_p2u;var aq=this._yaxis.series_p2u;var aI=null;var aJ=null;var aT=null;var aO=null;var aM=null;var at=null;var aR=null;var am=null;var aK,aL,aD,aC,aA,ay;var ak,ai,av,au;var aB,az,aN;var aw=[];var aj=[];var al=ap.length/ah;var aS,ax,aF,aG,aE;var ar=[];var an=[];if(!isNaN(parseFloat(ao))){aI=parseFloat(ao)}else{aI=K(al,0.5)}if(!isNaN(parseFloat(aU))){aU=parseFloat(aU)}for(var aQ=0,aP=ap.length-1;aQ<aP;aQ++){if(aU===null){at=Math.abs((ap[aQ+1][1]-ap[aQ][1])/(ap[aQ+1][0]-ap[aQ][0]));aS=0.3;ax=0.6;aF=(ax-aS)/2;aG=2.5;aE=-1.4;am=at/aG+aE;aO=aF*A(am)-aF*A(aE)+aS;if(aQ>0){aR=Math.abs((ap[aQ][1]-ap[aQ-1][1])/(ap[aQ][0]-ap[aQ-1][0]))}am=aR/aG+aE;aM=aF*A(am)-aF*A(aE)+aS;aT=(aO+aM)/2}else{aT=aU}for(aK=0;aK<aI;aK++){aL=aK/aI;aD=(1+2*aL)*Math.pow((1-aL),2);aC=aL*Math.pow((1-aL),2);aA=Math.pow(aL,2)*(3-2*aL);ay=Math.pow(aL,2)*(aL-1);if(ap[aQ-1]){ak=aT*(ap[aQ+1][0]-ap[aQ-1][0]);ai=aT*(ap[aQ+1][1]-ap[aQ-1][1])}else{ak=aT*(ap[aQ+1][0]-ap[aQ][0]);ai=aT*(ap[aQ+1][1]-ap[aQ][1])}if(ap[aQ+2]){av=aT*(ap[aQ+2][0]-ap[aQ][0]);au=aT*(ap[aQ+2][1]-ap[aQ][1])}else{av=aT*(ap[aQ+1][0]-ap[aQ][0]);au=aT*(ap[aQ+1][1]-ap[aQ][1])}aB=aD*ap[aQ][0]+aA*ap[aQ+1][0]+aC*ak!
+ay*av;az=aD*ap[aQ][1]+aA*ap[aQ+1][1]+aC*ai+ay*au;aN=[aB,az];ar.push(aN);an.push([aH(aB),aq(az)])}}ar.push(ap[aP]);an.push([aH(ap[aP][0]),aq(ap[aP][1])]);return[ar,an]}L.jqplot.LineRenderer.prototype.setGridData=function(ap){var al=this._xaxis.series_u2p;var ah=this._yaxis.series_u2p;var am=this._plotData;var aq=this._prevPlotData;this.gridData=[];this._prevGridData=[];this.renderer._smoothedData=[];this.renderer._smoothedPlotData=[];this.renderer._hiBandGridData=[];this.renderer._lowBandGridData=[];this.renderer._hiBandSmoothedData=[];this.renderer._lowBandSmoothedData=[];var ak=this.renderer.bands;var ai=false;for(var an=0,aj=am.length;an<aj;an++){if(am[an][0]!=null&&am[an][1]!=null){this.gridData.push([al.call(this._xaxis,am[an][0]),ah.call(this._yaxis,am[an][1])])}else{if(am[an][0]==null){ai=true;this.gridData.push([null,ah.call(this._yaxis,am[an][1])])}else{if(am[an][1]==null){ai=true;this.gridData.push([al.call(this._xaxis,am[an][0]),null])}}}if(aq[an]!=null&&aq[an][0]!=null&&aq[an][1]!=null){this._prevGridData.push([al.call(this._xaxis,aq[an][0]),ah.call(this._yaxis,aq[an][1])])}else{if(aq[an]!=null&&aq[an][0]==null){this._prevGridData.push([null,ah.call(this._yaxis,aq[an][1])])}else{if(aq[an]!=null&&aq[an][0]!=null&&aq[an][1]==null){this._prevGridData.push([al.call(this._xaxis,aq[an][0]),null])}}}}if(ai){this.renderer.smooth=false;if(this._type==="line"){ak.show=false}}if(this._type==="line"&&ak.show){for(var an=0,aj=ak.hiData.length;an<aj;an++){this.renderer._hiBandGridData.push([al.call(this._xaxis,ak.hiData[an][0]),ah.call(this._yaxis,ak.hiData[an][1])])}for(var an=0,aj=ak.lowData.length;an<aj;an++){this.renderer._lowBandGridData.push([al.call(this._xaxis,ak.lowData[an][0]),ah.call(this._yaxis,ak.lowData[an][1])])}}if(this._type==="line"&&this.renderer.smooth&&this.gridData.length>2){var ao;if(this.renderer.constrainSmoothing){ao=J.call(this,this.gridData);this.renderer._smoothedData=ao[0];this.renderer._smoothedPlotData=ao[1];if(ak.show){ao=J.call(this,this.renderer._hiBandGridData);this.renderer._hi!
BandSmoothedData=ao[0];ao=J.call(this,this.renderer._lowBandGridData);this.renderer._lowBandSmoothedData=ao[0]}ao=null}else{ao=F.call(this,this.gridData);this.renderer._smoothedData=ao[0];this.renderer._smoothedPlotData=ao[1];if(ak.show){ao=F.call(this,this.renderer._hiBandGridData);this.renderer._hiBandSmoothedData=ao[0];ao=F.call(this,this.renderer._lowBandGridData);this.renderer._lowBandSmoothedData=ao[0]}ao=null}}};L.jqplot.LineRenderer.prototype.makeGridData=function(ao,aq){var am=this._xaxis.series_u2p;var ah=this._yaxis.series_u2p;var ar=[];var aj=[];this.renderer._smoothedData=[];this.renderer._smoothedPlotData=[];this.renderer._hiBandGridData=[];this.renderer._lowBandGridData=[];this.renderer._hiBandSmoothedData=[];this.renderer._lowBandSmoothedData=[];var al=this.renderer.bands;var ai=false;for(var an=0;an<ao.length;an++){if(ao[an][0]!=null&&ao[an][1]!=null){ar.push([am.call(this._xaxis,ao[an][0]),ah.call(this._yaxis,ao[an][1])])}else{if(ao[an][0]==null){ai=true;ar.push([null,ah.call(this._yaxis,ao[an][1])])}else{if(ao[an][1]==null){ai=true;ar.push([am.call(this._xaxis,ao[an][0]),null])}}}}if(ai){this.renderer.smooth=false;if(this._type==="line"){al.show=false}}if(this._type==="line"&&al.show){for(var an=0,ak=al.hiData.length;an<ak;an++){this.renderer._hiBandGridData.push([am.call(this._xaxis,al.hiData[an][0]),ah.call(this._yaxis,al.hiData[an][1])])}for(var an=0,ak=al.lowData.length;an<ak;an++){this.renderer._lowBandGridData.push([am.call(this._xaxis,al.lowData[an][0]),ah.call(this._yaxis,al.lowData[an][1])])}}if(this._type==="line"&&this.renderer.smooth&&ar.length>2){var ap;if(this.renderer.constrainSmoothing){ap=J.call(this,ar);this.renderer._smoothedData=ap[0];this.renderer._smoothedPlotData=ap[1];if(al.show){ap=J.call(this,this.renderer._hiBandGridData);this.renderer._hiBandSmoothedData=ap[0];ap=J.call(this,this.renderer._lowBandGridData);this.renderer._lowBandSmoothedData=ap[0]}ap=null}else{ap=F.call(this,ar);this.renderer._smoothedData=ap[0];this.renderer._smoothedPlotData=ap[1];if(al.show){ap=F.!
call(this,this.renderer._hiBandGridData);this.renderer._hiBandSmoothedData=ap[0];ap=F.call(this,this.renderer._lowBandGridData);this.renderer._lowBandSmoothedData=ap[0]}ap=null}}return ar};L.jqplot.LineRenderer.prototype.draw=function(ax,aI,ai,aB){var aC;var aq=L.extend(true,{},ai);var ak=(aq.shadow!=u)?aq.shadow:this.shadow;var aJ=(aq.showLine!=u)?aq.showLine:this.showLine;var aA=(aq.fill!=u)?aq.fill:this.fill;var ah=(aq.fillAndStroke!=u)?aq.fillAndStroke:this.fillAndStroke;var ar,ay,av,aE;ax.save();if(aI.length){if(aJ){if(aA){if(this.fillToZero){var aF=this.negativeColor;if(!this.useNegativeColors){aF=aq.fillStyle}var ao=false;var ap=aq.fillStyle;if(ah){var aH=aI.slice(0)}if(this.index==0||!this._stack){var aw=[];var aL=(this.renderer.smooth)?this.renderer._smoothedPlotData:this._plotData;this._areaPoints=[];var aG=this._yaxis.series_u2p(this.fillToValue);var aj=this._xaxis.series_u2p(this.fillToValue);aq.closePath=true;if(this.fillAxis=="y"){aw.push([aI[0][0],aG]);this._areaPoints.push([aI[0][0],aG]);for(var aC=0;aC<aI.length-1;aC++){aw.push(aI[aC]);this._areaPoints.push(aI[aC]);if(aL[aC][1]*aL[aC+1][1]<0){if(aL[aC][1]<0){ao=true;aq.fillStyle=aF}else{ao=false;aq.fillStyle=ap}var an=aI[aC][0]+(aI[aC+1][0]-aI[aC][0])*(aG-aI[aC][1])/(aI[aC+1][1]-aI[aC][1]);aw.push([an,aG]);this._areaPoints.push([an,aG]);if(ak){this.renderer.shadowRenderer.draw(ax,aw,aq)}this.renderer.shapeRenderer.draw(ax,aw,aq);aw=[[an,aG]]}}if(aL[aI.length-1][1]<0){ao=true;aq.fillStyle=aF}else{ao=false;aq.fillStyle=ap}aw.push(aI[aI.length-1]);this._areaPoints.push(aI[aI.length-1]);aw.push([aI[aI.length-1][0],aG]);this._areaPoints.push([aI[aI.length-1][0],aG])}if(ak){this.renderer.shadowRenderer.draw(ax,aw,aq)}this.renderer.shapeRenderer.draw(ax,aw,aq)}else{var au=this._prevGridData;for(var aC=au.length;aC>0;aC--){aI.push(au[aC-1])}if(ak){this.renderer.shadowRenderer.draw(ax,aI,aq)}this._areaPoints=aI;this.renderer.shapeRenderer.draw(ax,aI,aq)}}else{if(ah){var aH=aI.slice(0)}if(this.index==0||!this._stack){var al=ax.canvas.height;aI.unshift([aI!
[0][0],al]);var aD=aI.length;aI.push([aI[aD-1][0],al])}else{var au=this._prevGridData;for(var aC=au.length;aC>0;aC--){aI.push(au[aC-1])}}this._areaPoints=aI;if(ak){this.renderer.shadowRenderer.draw(ax,aI,aq)}this.renderer.shapeRenderer.draw(ax,aI,aq)}if(ah){var az=L.extend(true,{},aq,{fill:false,closePath:false});this.renderer.shapeRenderer.draw(ax,aH,az);if(this.markerRenderer.show){if(this.renderer.smooth){aH=this.gridData}for(aC=0;aC<aH.length;aC++){this.markerRenderer.draw(aH[aC][0],aH[aC][1],ax,aq.markerOptions)}}}}else{if(this.renderer.bands.show){var am;var aK=L.extend(true,{},aq);if(this.renderer.bands.showLines){am=(this.renderer.smooth)?this.renderer._hiBandSmoothedData:this.renderer._hiBandGridData;this.renderer.shapeRenderer.draw(ax,am,aq);am=(this.renderer.smooth)?this.renderer._lowBandSmoothedData:this.renderer._lowBandGridData;this.renderer.shapeRenderer.draw(ax,am,aK)}if(this.renderer.bands.fill){if(this.renderer.smooth){am=this.renderer._hiBandSmoothedData.concat(this.renderer._lowBandSmoothedData.reverse())}else{am=this.renderer._hiBandGridData.concat(this.renderer._lowBandGridData.reverse())}this._areaPoints=am;aK.closePath=true;aK.fill=true;aK.fillStyle=this.renderer.bands.fillColor;this.renderer.shapeRenderer.draw(ax,am,aK)}}if(ak){this.renderer.shadowRenderer.draw(ax,aI,aq)}this.renderer.shapeRenderer.draw(ax,aI,aq)}}var ar=av=ay=aE=null;for(aC=0;aC<this._areaPoints.length;aC++){var at=this._areaPoints[aC];if(ar>at[0]||ar==null){ar=at[0]}if(aE<at[1]||aE==null){aE=at[1]}if(av<at[0]||av==null){av=at[0]}if(ay>at[1]||ay==null){ay=at[1]}}if(this.type==="line"&&this.renderer.bands.show){aE=this._yaxis.series_u2p(this.renderer.bands._min);ay=this._yaxis.series_u2p(this.renderer.bands._max)}this._boundingBox=[[ar,aE],[av,ay]];if(this.markerRenderer.show&&!aA){if(this.renderer.smooth){aI=this.gridData}for(aC=0;aC<aI.length;aC++){if(aI[aC][0]!=null&&aI[aC][1]!=null){this.markerRenderer.draw(aI[aC][0],aI[aC][1],ax,aq.markerOptions)}}}}ax.restore()};L.jqplot.LineRenderer.prototype.drawShadow=function(a!
h,aj,ai){};function z(ak,aj,ah){for(var ai=0;ai<this.series.length;ai++){if(this.series[ai].renderer.constructor==L.jqplot.LineRenderer){if(this.series[ai].highlightMouseOver){this.series[ai].highlightMouseDown=false}}}}function af(){if(this.plugins.lineRenderer&&this.plugins.lineRenderer.highlightCanvas){this.plugins.lineRenderer.highlightCanvas.resetCanvas();this.plugins.lineRenderer.highlightCanvas=null}this.plugins.lineRenderer.highlightedSeriesIndex=null;this.plugins.lineRenderer.highlightCanvas=new L.jqplot.GenericCanvas();this.eventCanvas._elem.before(this.plugins.lineRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-lineRenderer-highlight-canvas",this._plotDimensions,this));this.plugins.lineRenderer.highlightCanvas.setContext();this.eventCanvas._elem.bind("mouseleave",{plot:this},function(ah){aa(ah.data.plot)})}function ac(an,am,ak,aj){var ai=an.series[am];var ah=an.plugins.lineRenderer.highlightCanvas;ah._ctx.clearRect(0,0,ah._ctx.canvas.width,ah._ctx.canvas.height);ai._highlightedPoint=ak;an.plugins.lineRenderer.highlightedSeriesIndex=am;var al={fillStyle:ai.highlightColor};if(ai.type==="line"&&ai.renderer.bands.show){al.fill=true;al.closePath=true}ai.renderer.shapeRenderer.draw(ah._ctx,aj,al);ah=null}function aa(aj){var ah=aj.plugins.lineRenderer.highlightCanvas;ah._ctx.clearRect(0,0,ah._ctx.canvas.width,ah._ctx.canvas.height);for(var ai=0;ai<aj.series.length;ai++){aj.series[ai]._highlightedPoint=null}aj.plugins.lineRenderer.highlightedSeriesIndex=null;aj.target.trigger("jqplotDataUnhighlight");ah=null}function h(al,ak,ao,an,am){if(an){var aj=[an.seriesIndex,an.pointIndex,an.data];var ai=jQuery.Event("jqplotDataMouseOver");ai.pageX=al.pageX;ai.pageY=al.pageY;am.target.trigger(ai,aj);if(am.series[aj[0]].highlightMouseOver&&!(aj[0]==am.plugins.lineRenderer.highlightedSeriesIndex)){var ah=jQuery.Event("jqplotDataHighlight");ah.which=al.which;ah.pageX=al.pageX;ah.pageY=al.pageY;am.target.trigger(ah,aj);ac(am,an.seriesIndex,an.pointIndex,an.points)}}else{if(an==null){aa(am)}}}function e(ak,a!
j,an,am,al){if(am){var ai=[am.seriesIndex,am.pointIndex,am.data];if(al.series[ai[0]].highlightMouseDown&&!(ai[0]==al.plugins.lineRenderer.highlightedSeriesIndex)){var ah=jQuery.Event("jqplotDataHighlight");ah.which=ak.which;ah.pageX=ak.pageX;ah.pageY=ak.pageY;al.target.trigger(ah,ai);ac(al,am.seriesIndex,am.pointIndex,am.points)}}else{if(am==null){aa(al)}}}function ad(aj,ai,am,al,ak){var ah=ak.plugins.lineRenderer.highlightedSeriesIndex;if(ah!=null&&ak.series[ah].highlightMouseDown){aa(ak)}}function g(ak,aj,an,am,al){if(am){var ai=[am.seriesIndex,am.pointIndex,am.data];var ah=jQuery.Event("jqplotDataClick");ah.which=ak.which;ah.pageX=ak.pageX;ah.pageY=ak.pageY;al.target.trigger(ah,ai)}}function s(al,ak,ao,an,am){if(an){var aj=[an.seriesIndex,an.pointIndex,an.data];var ah=am.plugins.lineRenderer.highlightedSeriesIndex;if(ah!=null&&am.series[ah].highlightMouseDown){aa(am)}var ai=jQuery.Event("jqplotDataRightClick");ai.which=al.which;ai.pageX=al.pageX;ai.pageY=al.pageY;am.target.trigger(ai,aj)}}L.jqplot.LinearAxisRenderer=function(){};L.jqplot.LinearAxisRenderer.prototype.init=function(ah){this.breakPoints=null;this.breakTickLabel="≈";this.drawBaseline=true;this.baselineWidth=null;this.baselineColor=null;this.forceTickAt0=false;this.forceTickAt100=false;this.tickInset=0;this.minorTicks=0;this.alignTicks=false;this._autoFormatString="";this._overrideFormatString=false;this._scalefact=1;L.extend(true,this,ah);if(this.breakPoints){if(!L.isArray(this.breakPoints)){this.breakPoints=null}else{if(this.breakPoints.length<2||this.breakPoints[1]<=this.breakPoints[0]){this.breakPoints=null}}}if(this.numberTicks!=null&&this.numberTicks<2){this.numberTicks=2}this.resetDataBounds()};L.jqplot.LinearAxisRenderer.prototype.draw=function(ah,ao){if(this.show){this.renderer.createTicks.call(this,ao);var an=0;var ai;if(this._elem){this._elem.emptyForce();this._elem=null}this._elem=L(document.createElement("div"));this._elem.addClass("jqplot-axis jqplot-"+this.name);this._elem.css("position","absolute");if(this.name=="xaxis"||this!
.name=="x2axis"){this._elem.width(this._plotDimensions.width)}else{this._elem.height(this._plotDimensions.height)}this.labelOptions.axis=this.name;this._label=new this.labelRenderer(this.labelOptions);if(this._label.show){var am=this._label.draw(ah,ao);am.appendTo(this._elem);am=null}var al=this._ticks;var ak;for(var aj=0;aj<al.length;aj++){ak=al[aj];if(ak.show&&ak.showLabel&&(!ak.isMinorTick||this.showMinorTicks)){this._elem.append(ak.draw(ah,ao))}}ak=null;al=null}return this._elem};L.jqplot.LinearAxisRenderer.prototype.reset=function(){this.min=this._options.min;this.max=this._options.max;this.tickInterval=this._options.tickInterval;this.numberTicks=this._options.numberTicks;this._autoFormatString="";if(this._overrideFormatString&&this.tickOptions&&this.tickOptions.formatString){this.tickOptions.formatString=""}};L.jqplot.LinearAxisRenderer.prototype.set=function(){var ao=0;var aj;var ai=0;var an=0;var ah=(this._label==null)?false:this._label.show;if(this.show){var am=this._ticks;var al;for(var ak=0;ak<am.length;ak++){al=am[ak];if(!al._breakTick&&al.show&&al.showLabel&&(!al.isMinorTick||this.showMinorTicks)){if(this.name=="xaxis"||this.name=="x2axis"){aj=al._elem.outerHeight(true)}else{aj=al._elem.outerWidth(true)}if(aj>ao){ao=aj}}}al=null;am=null;if(ah){ai=this._label._elem.outerWidth(true);an=this._label._elem.outerHeight(true)}if(this.name=="xaxis"){ao=ao+an;this._elem.css({height:ao+"px",left:"0px",bottom:"0px"})}else{if(this.name=="x2axis"){ao=ao+an;this._elem.css({height:ao+"px",left:"0px",top:"0px"})}else{if(this.name=="yaxis"){ao=ao+ai;this._elem.css({width:ao+"px",left:"0px",top:"0px"});if(ah&&this._label.constructor==L.jqplot.AxisLabelRenderer){this._label._elem.css("width",ai+"px")}}else{ao=ao+ai;this._elem.css({width:ao+"px",right:"0px",top:"0px"});if(ah&&this._label.constructor==L.jqplot.AxisLabelRenderer){this._label._elem.css("width",ai+"px")}}}}}};L.jqplot.LinearAxisRenderer.prototype.createTicks=function(aj){var aT=this._ticks;var aK=this.ticks;var az=this.name;var aB=this._dataBounds;var ah=(!
this.name.charAt(0)==="x")?this._plotDimensions.width:this._plotDimensions.height;var an;var a6,aI;var ap,ao;var a4,a0;var aH=this.min;var a5=this.max;var aW=this.numberTicks;var ba=this.tickInterval;var am=30;this._scalefact=(Math.max(ah,am+1)-am)/300;if(aK.length){for(a0=0;a0<aK.length;a0++){var aO=aK[a0];var aU=new this.tickRenderer(this.tickOptions);if(L.isArray(aO)){aU.value=aO[0];if(this.breakPoints){if(aO[0]==this.breakPoints[0]){aU.label=this.breakTickLabel;aU._breakTick=true;aU.showGridline=false;aU.showMark=false}else{if(aO[0]>this.breakPoints[0]&&aO[0]<=this.breakPoints[1]){aU.show=false;aU.showGridline=false;aU.label=aO[1]}else{aU.label=aO[1]}}}else{aU.label=aO[1]}aU.setTick(aO[0],this.name);this._ticks.push(aU)}else{if(L.isPlainObject(aO)){L.extend(true,aU,aO);aU.axis=this.name;this._ticks.push(aU)}else{aU.value=aO;if(this.breakPoints){if(aO==this.breakPoints[0]){aU.label=this.breakTickLabel;aU._breakTick=true;aU.showGridline=false;aU.showMark=false}else{if(aO>this.breakPoints[0]&&aO<=this.breakPoints[1]){aU.show=false;aU.showGridline=false}}}aU.setTick(aO,this.name);this._ticks.push(aU)}}}this.numberTicks=aK.length;this.min=this._ticks[0].value;this.max=this._ticks[this.numberTicks-1].value;this.tickInterval=(this.max-this.min)/(this.numberTicks-1)}else{if(az=="xaxis"||az=="x2axis"){ah=this._plotDimensions.width}else{ah=this._plotDimensions.height}var ax=this.numberTicks;if(this.alignTicks){if(this.name==="x2axis"&&aj.axes.xaxis.show){ax=aj.axes.xaxis.numberTicks}else{if(this.name.charAt(0)==="y"&&this.name!=="yaxis"&&this.name!=="yMidAxis"&&aj.axes.yaxis.show){ax=aj.axes.yaxis.numberTicks}}}a6=((this.min!=null)?this.min:aB.min);aI=((this.max!=null)?this.max:aB.max);var av=aI-a6;var aS,ay;var at;if(this.tickOptions==null||!this.tickOptions.formatString){this._overrideFormatString=true}if(this.min==null||this.max==null&&this.tickInterval==null&&!this.autoscale){if(this.forceTickAt0){if(a6>0){a6=0}if(aI<0){aI=0}}if(this.forceTickAt100){if(a6>100){a6=100}if(aI<100){aI=100}}var aE=false,a1=false;if(thi!
s.min!=null){aE=true}else{if(this.max!=null){a1=true}}var aP=L.jqplot.LinearTickGenerator(a6,aI,this._scalefact,ax,aE,a1);var aw=(this.min!=null)?a6:a6+av*(this.padMin-1);var aQ=(this.max!=null)?aI:aI-av*(this.padMax-1);if(a6<aw||aI>aQ){aw=(this.min!=null)?a6:a6-av*(this.padMin-1);aQ=(this.max!=null)?aI:aI+av*(this.padMax-1);aP=L.jqplot.LinearTickGenerator(aw,aQ,this._scalefact,ax,aE,a1)}this.min=aP[0];this.max=aP[1];this.numberTicks=aP[2];this._autoFormatString=aP[3];this.tickInterval=aP[4]}else{if(a6==aI){var ai=0.05;if(a6>0){ai=Math.max(Math.log(a6)/Math.LN10,0.05)}a6-=ai;aI+=ai}if(this.autoscale&&this.min==null&&this.max==null){var ak,al,ar;var aC=false;var aN=false;var aA={min:null,max:null,average:null,stddev:null};for(var a0=0;a0<this._series.length;a0++){var aV=this._series[a0];var aD=(aV.fillAxis=="x")?aV._xaxis.name:aV._yaxis.name;if(this.name==aD){var aR=aV._plotValues[aV.fillAxis];var aG=aR[0];var a2=aR[0];for(var aZ=1;aZ<aR.length;aZ++){if(aR[aZ]<aG){aG=aR[aZ]}else{if(aR[aZ]>a2){a2=aR[aZ]}}}var au=(a2-aG)/a2;if(aV.renderer.constructor==L.jqplot.BarRenderer){if(aG>=0&&(aV.fillToZero||au>0.1)){aC=true}else{aC=false;if(aV.fill&&aV.fillToZero&&aG<0&&a2>0){aN=true}else{aN=false}}}else{if(aV.fill){if(aG>=0&&(aV.fillToZero||au>0.1)){aC=true}else{if(aG<0&&a2>0&&aV.fillToZero){aC=false;aN=true}else{aC=false;aN=false}}}else{if(aG<0){aC=false}}}}}if(aC){this.numberTicks=2+Math.ceil((ah-(this.tickSpacing-1))/this.tickSpacing);this.min=0;aH=0;al=aI/(this.numberTicks-1);at=Math.pow(10,Math.abs(Math.floor(Math.log(al)/Math.LN10)));if(al/at==parseInt(al/at,10)){al+=at}this.tickInterval=Math.ceil(al/at)*at;this.max=this.tickInterval*(this.numberTicks-1)}else{if(aN){this.numberTicks=2+Math.ceil((ah-(this.tickSpacing-1))/this.tickSpacing);var aJ=Math.ceil(Math.abs(a6)/av*(this.numberTicks-1));var a9=this.numberTicks-1-aJ;al=Math.max(Math.abs(a6/aJ),Math.abs(aI/a9));at=Math.pow(10,Math.abs(Math.floor(Math.log(al)/Math.LN10)));this.tickInterval=Math.ceil(al/at)*at;this.max=this.tickInterval*a9;this.min=-this.tickInterva!
l*aJ}else{if(this.numberTicks==null){if(this.tickInterval){this.numberTicks=3+Math.ceil(av/this.tickInterval)}else{this.numberTicks=2+Math.ceil((ah-(this.tickSpacing-1))/this.tickSpacing)}}if(this.tickInterval==null){al=av/(this.numberTicks-1);if(al<1){at=Math.pow(10,Math.abs(Math.floor(Math.log(al)/Math.LN10)))}else{at=1}this.tickInterval=Math.ceil(al*at*this.pad)/at}else{at=1/this.tickInterval}ak=this.tickInterval*(this.numberTicks-1);ar=(ak-av)/2;if(this.min==null){this.min=Math.floor(at*(a6-ar))/at}if(this.max==null){this.max=this.min+ak}}}var aF=L.jqplot.getSignificantFigures(this.tickInterval);var aM;if(aF.digitsLeft>=aF.significantDigits){aM="%d"}else{var at=Math.max(0,5-aF.digitsLeft);at=Math.min(at,aF.digitsRight);aM="%."+at+"f"}this._autoFormatString=aM}else{aS=(this.min!=null)?this.min:a6-av*(this.padMin-1);ay=(this.max!=null)?this.max:aI+av*(this.padMax-1);av=ay-aS;if(this.numberTicks==null){if(this.tickInterval!=null){this.numberTicks=Math.ceil((ay-aS)/this.tickInterval)+1}else{if(ah>100){this.numberTicks=parseInt(3+(ah-100)/75,10)}else{this.numberTicks=2}}}if(this.tickInterval==null){this.tickInterval=av/(this.numberTicks-1)}if(this.max==null){ay=aS+this.tickInterval*(this.numberTicks-1)}if(this.min==null){aS=ay-this.tickInterval*(this.numberTicks-1)}var aF=L.jqplot.getSignificantFigures(this.tickInterval);var aM;if(aF.digitsLeft>=aF.significantDigits){aM="%d"}else{var at=Math.max(0,5-aF.digitsLeft);at=Math.min(at,aF.digitsRight);aM="%."+at+"f"}this._autoFormatString=aM;this.min=aS;this.max=ay}if(this.renderer.constructor==L.jqplot.LinearAxisRenderer&&this._autoFormatString==""){av=this.max-this.min;var a7=new this.tickRenderer(this.tickOptions);var aL=a7.formatString||L.jqplot.config.defaultTickFormatString;var aL=aL.match(L.jqplot.sprintf.regex)[0];var a3=0;if(aL){if(aL.search(/[fFeEgGpP]/)>-1){var aY=aL.match(/\%\.(\d{0,})?[eEfFgGpP]/);if(aY){a3=parseInt(aY[1],10)}else{a3=6}}else{if(aL.search(/[di]/)>-1){a3=0}}var aq=Math.pow(10,-a3);if(this.tickInterval<aq){if(aW==null&&ba==null){this.tickInter!
val=aq;if(a5==null&&aH==null){this.min=Math.floor(this._dataBounds.min/aq)*aq;if(this.min==this._dataBounds.min){this.min=this._dataBounds.min-this.tickInterval}this.max=Math.ceil(this._dataBounds.max/aq)*aq;if(this.max==this._dataBounds.max){this.max=this._dataBounds.max+this.tickInterval}var aX=(this.max-this.min)/this.tickInterval;aX=aX.toFixed(11);aX=Math.ceil(aX);this.numberTicks=aX+1}else{if(a5==null){var aX=(this._dataBounds.max-this.min)/this.tickInterval;aX=aX.toFixed(11);this.numberTicks=Math.ceil(aX)+2;this.max=this.min+this.tickInterval*(this.numberTicks-1)}else{if(aH==null){var aX=(this.max-this._dataBounds.min)/this.tickInterval;aX=aX.toFixed(11);this.numberTicks=Math.ceil(aX)+2;this.min=this.max-this.tickInterval*(this.numberTicks-1)}else{this.numberTicks=Math.ceil((a5-aH)/this.tickInterval)+1;this.min=Math.floor(aH*Math.pow(10,a3))/Math.pow(10,a3);this.max=Math.ceil(a5*Math.pow(10,a3))/Math.pow(10,a3);this.numberTicks=Math.ceil((this.max-this.min)/this.tickInterval)+1}}}}}}}}if(this._overrideFormatString&&this._autoFormatString!=""){this.tickOptions=this.tickOptions||{};this.tickOptions.formatString=this._autoFormatString}var aU,a8;for(var a0=0;a0<this.numberTicks;a0++){a4=this.min+a0*this.tickInterval;aU=new this.tickRenderer(this.tickOptions);aU.setTick(a4,this.name);this._ticks.push(aU);if(a0<this.numberTicks-1){for(var aZ=0;aZ<this.minorTicks;aZ++){a4+=this.tickInterval/(this.minorTicks+1);a8=L.extend(true,{},this.tickOptions,{name:this.name,value:a4,label:"",isMinorTick:true});aU=new this.tickRenderer(a8);this._ticks.push(aU)}}aU=null}}if(this.tickInset){this.min=this.min-this.tickInset*this.tickInterval;this.max=this.max+this.tickInset*this.tickInterval}aT=null};L.jqplot.LinearAxisRenderer.prototype.resetTickValues=function(aj){if(L.isArray(aj)&&aj.length==this._ticks.length){var ai;for(var ah=0;ah<aj.length;ah++){ai=this._ticks[ah];ai.value=aj[ah];ai.label=ai.formatter(ai.formatString,aj[ah]);ai.label=ai.prefix+ai.label;ai._elem.html(ai.label)}ai=null;this.min=L.jqplot.arrayMin(aj);this.ma!
x=L.jqplot.arrayMax(aj);this.pack()}};L.jqplot.LinearAxisRenderer.prototype.pack=function(aj,ai){aj=aj||{};ai=ai||this._offsets;var ay=this._ticks;var au=this.max;var at=this.min;var ao=ai.max;var am=ai.min;var aq=(this._label==null)?false:this._label.show;for(var ar in aj){this._elem.css(ar,aj[ar])}this._offsets=ai;var ak=ao-am;var al=au-at;if(this.breakPoints){al=al-this.breakPoints[1]+this.breakPoints[0];this.p2u=function(aA){return(aA-am)*al/ak+at};this.u2p=function(aA){if(aA>this.breakPoints[0]&&aA<this.breakPoints[1]){aA=this.breakPoints[0]}if(aA<=this.breakPoints[0]){return(aA-at)*ak/al+am}else{return(aA-this.breakPoints[1]+this.breakPoints[0]-at)*ak/al+am}};if(this.name.charAt(0)=="x"){this.series_u2p=function(aA){if(aA>this.breakPoints[0]&&aA<this.breakPoints[1]){aA=this.breakPoints[0]}if(aA<=this.breakPoints[0]){return(aA-at)*ak/al}else{return(aA-this.breakPoints[1]+this.breakPoints[0]-at)*ak/al}};this.series_p2u=function(aA){return aA*al/ak+at}}else{this.series_u2p=function(aA){if(aA>this.breakPoints[0]&&aA<this.breakPoints[1]){aA=this.breakPoints[0]}if(aA>=this.breakPoints[1]){return(aA-au)*ak/al}else{return(aA+this.breakPoints[1]-this.breakPoints[0]-au)*ak/al}};this.series_p2u=function(aA){return aA*al/ak+au}}}else{this.p2u=function(aA){return(aA-am)*al/ak+at};this.u2p=function(aA){return(aA-at)*ak/al+am};if(this.name=="xaxis"||this.name=="x2axis"){this.series_u2p=function(aA){return(aA-at)*ak/al};this.series_p2u=function(aA){return aA*al/ak+at}}else{this.series_u2p=function(aA){return(aA-au)*ak/al};this.series_p2u=function(aA){return aA*al/ak+au}}}if(this.show){if(this.name=="xaxis"||this.name=="x2axis"){for(var av=0;av<ay.length;av++){var ap=ay[av];if(ap.show&&ap.showLabel){var ah;if(ap.constructor==L.jqplot.CanvasAxisTickRenderer&&ap.angle){var ax=(this.name=="xaxis")?1:-1;switch(ap.labelPosition){case"auto":if(ax*ap.angle<0){ah=-ap.getWidth()+ap._textRenderer.height*Math.sin(-ap._textRenderer.angle)/2}else{ah=-ap._textRenderer.height*Math.sin(ap._textRenderer.angle)/2}break;case"end":ah=-ap.getW!
idth()+ap._textRenderer.height*Math.sin(-ap._textRenderer.angle)/2;break;case"start":ah=-ap._textRenderer.height*Math.sin(ap._textRenderer.angle)/2;break;case"middle":ah=-ap.getWidth()/2+ap._textRenderer.height*Math.sin(-ap._textRenderer.angle)/2;break;default:ah=-ap.getWidth()/2+ap._textRenderer.height*Math.sin(-ap._textRenderer.angle)/2;break}}else{ah=-ap.getWidth()/2}var az=this.u2p(ap.value)+ah+"px";ap._elem.css("left",az);ap.pack()}}if(aq){var an=this._label._elem.outerWidth(true);this._label._elem.css("left",am+ak/2-an/2+"px");if(this.name=="xaxis"){this._label._elem.css("bottom","0px")}else{this._label._elem.css("top","0px")}this._label.pack()}}else{for(var av=0;av<ay.length;av++){var ap=ay[av];if(ap.show&&ap.showLabel){var ah;if(ap.constructor==L.jqplot.CanvasAxisTickRenderer&&ap.angle){var ax=(this.name=="yaxis")?1:-1;switch(ap.labelPosition){case"auto":case"end":if(ax*ap.angle<0){ah=-ap._textRenderer.height*Math.cos(-ap._textRenderer.angle)/2}else{ah=-ap.getHeight()+ap._textRenderer.height*Math.cos(ap._textRenderer.angle)/2}break;case"start":if(ap.angle>0){ah=-ap._textRenderer.height*Math.cos(-ap._textRenderer.angle)/2}else{ah=-ap.getHeight()+ap._textRenderer.height*Math.cos(ap._textRenderer.angle)/2}break;case"middle":ah=-ap.getHeight()/2;break;default:ah=-ap.getHeight()/2;break}}else{ah=-ap.getHeight()/2}var az=this.u2p(ap.value)+ah+"px";ap._elem.css("top",az);ap.pack()}}if(aq){var aw=this._label._elem.outerHeight(true);this._label._elem.css("top",ao-ak/2-aw/2+"px");if(this.name=="yaxis"){this._label._elem.css("left","0px")}else{this._label._elem.css("right","0px")}this._label.pack()}}}ay=null};function i(ai){var ah;ai=Math.abs(ai);if(ai>=10){ah="%d"}else{if(ai>1){if(ai===parseInt(ai,10)){ah="%d"}else{ah="%.1f"}}else{var aj=-Math.floor(Math.log(ai)/Math.LN10);ah="%."+aj+"f"}}return ah}var b=[0.1,0.2,0.3,0.4,0.5,0.8,1,2,3,4,5];var c=function(ai){var ah=b.indexOf(ai);if(ah>0){return b[ah-1]}else{return b[b.length-1]/100}};var k=function(ai){var ah=b.indexOf(ai);if(ah<b.length-1){return b[ah+1]}else{ret!
urn b[0]*100}};function d(al,au,at){var aq=Math.floor(at/2);var ai=Math.ceil(at*1.5);var ak=Number.MAX_VALUE;var ah=(au-al);var ax;var ap;var ar;var ay=L.jqplot.getSignificantFigures;var aw;var an;var ao;var av;for(var am=0,aj=ai-aq+1;am<aj;am++){ao=aq+am;ax=ah/(ao-1);ap=ay(ax);ax=Math.abs(at-ao)+ap.digitsRight;if(ax<ak){ak=ax;ar=ao;av=ap.digitsRight}else{if(ax===ak){if(ap.digitsRight<av){ar=ao;av=ap.digitsRight}}}}aw=Math.max(av,Math.max(ay(al).digitsRight,ay(au).digitsRight));if(aw===0){an="%d"}else{an="%."+aw+"f"}ax=ah/(ar-1);return[al,au,ar,an,ax]}function W(ai,al){al=al||7;var ak=ai/(al-1);var aj=Math.pow(10,Math.floor(Math.log(ak)/Math.LN10));var am=ak/aj;var ah;if(aj<1){if(am>5){ah=10*aj}else{if(am>2){ah=5*aj}else{if(am>1){ah=2*aj}else{ah=aj}}}}else{if(am>5){ah=10*aj}else{if(am>4){ah=5*aj}else{if(am>3){ah=4*aj}else{if(am>2){ah=3*aj}else{if(am>1){ah=2*aj}else{ah=aj}}}}}}return ah}function Q(ai,ah){ah=ah||1;var ak=Math.floor(Math.log(ai)/Math.LN10);var am=Math.pow(10,ak);var al=ai/am;var aj;al=al/ah;if(al<=0.38){aj=0.1}else{if(al<=1.6){aj=0.2}else{if(al<=4){aj=0.5}else{if(al<=8){aj=1}else{if(al<=16){aj=2}else{aj=5}}}}}return aj*am}function x(aj,ai){var al=Math.floor(Math.log(aj)/Math.LN10);var an=Math.pow(10,al);var am=aj/an;var ah;var ak;am=am/ai;if(am<=0.38){ak=0.1}else{if(am<=1.6){ak=0.2}else{if(am<=4){ak=0.5}else{if(am<=8){ak=1}else{if(am<=16){ak=2}else{ak=5}}}}}ah=ak*an;return[ah,ak,an]}L.jqplot.LinearTickGenerator=function(an,aq,aj,ak,ao,ar){ao=(ao===null)?false:ao;ar=(ar===null||ao)?false:ar;if(an===aq){aq=(aq)?0:1}aj=aj||1;if(aq<an){var at=aq;aq=an;an=at}var ai=[];var aw=Q(aq-an,aj);var av=L.jqplot.getSignificantFigures;if(ak==null){if(!ao&&!ar){ai[0]=Math.floor(an/aw)*aw;ai[1]=Math.ceil(aq/aw)*aw;ai[2]=Math.round((ai[1]-ai[0])/aw+1);ai[3]=i(aw);ai[4]=aw}else{if(ao){ai[0]=an;ai[2]=Math.ceil((aq-an)/aw+1);ai[1]=an+(ai[2]-1)*aw;var au=av(an).digitsRight;var ap=av(aw).digitsRight;if(au<ap){ai[3]=i(aw)}else{ai[3]="%."+au+"f"}ai[4]=aw}else{if(ar){ai[1]=aq;ai[2]=Math.ceil((aq-an)/aw+1);ai[0]=aq-(ai[2]-1)*!
aw;var al=av(aq).digitsRight;var ap=av(aw).digitsRight;if(al<ap){ai[3]=i(aw)}else{ai[3]="%."+al+"f"}ai[4]=aw}}}}else{var am=[];am[0]=Math.floor(an/aw)*aw;am[1]=Math.ceil(aq/aw)*aw;am[2]=Math.round((am[1]-am[0])/aw+1);am[3]=i(aw);am[4]=aw;if(am[2]===ak){ai=am}else{var ah=W(am[1]-am[0],ak);ai[0]=am[0];ai[2]=ak;ai[4]=ah;ai[3]=i(ah);ai[1]=ai[0]+(ai[2]-1)*ai[4]}}return ai};L.jqplot.LinearTickGenerator.bestLinearInterval=Q;L.jqplot.LinearTickGenerator.bestInterval=W;L.jqplot.LinearTickGenerator.bestLinearComponents=x;L.jqplot.LinearTickGenerator.bestConstrainedInterval=d;L.jqplot.MarkerRenderer=function(ah){this.show=true;this.style="filledCircle";this.lineWidth=2;this.size=9;this.color="#666666";this.shadow=true;this.shadowAngle=45;this.shadowOffset=1;this.shadowDepth=3;this.shadowAlpha="0.07";this.shadowRenderer=new L.jqplot.ShadowRenderer();this.shapeRenderer=new L.jqplot.ShapeRenderer();L.extend(true,this,ah)};L.jqplot.MarkerRenderer.prototype.init=function(ah){L.extend(true,this,ah);var aj={angle:this.shadowAngle,offset:this.shadowOffset,alpha:this.shadowAlpha,lineWidth:this.lineWidth,depth:this.shadowDepth,closePath:true};if(this.style.indexOf("filled")!=-1){aj.fill=true}if(this.style.indexOf("ircle")!=-1){aj.isarc=true;aj.closePath=false}this.shadowRenderer.init(aj);var ai={fill:false,isarc:false,strokeStyle:this.color,fillStyle:this.color,lineWidth:this.lineWidth,closePath:true};if(this.style.indexOf("filled")!=-1){ai.fill=true}if(this.style.indexOf("ircle")!=-1){ai.isarc=true;ai.closePath=false}this.shapeRenderer.init(ai)};L.jqplot.MarkerRenderer.prototype.drawDiamond=function(aj,ai,am,al,ao){var ah=1.2;var ap=this.size/2/ah;var an=this.size/2*ah;var ak=[[aj-ap,ai],[aj,ai+an],[aj+ap,ai],[aj,ai-an]];if(this.shadow){this.shadowRenderer.draw(am,ak)}this.shapeRenderer.draw(am,ak,ao)};L.jqplot.MarkerRenderer.prototype.drawPlus=function(ak,aj,an,am,aq){var ai=1;var ar=this.size/2*ai;var ao=this.size/2*ai;var ap=[[ak,aj-ao],[ak,aj+ao]];var al=[[ak+ar,aj],[ak-ar,aj]];var ah=L.extend(true,{},this.options,{closePath:fa!
lse});if(this.shadow){this.shadowRenderer.draw(an,ap,{closePath:false});this.shadowRenderer.draw(an,al,{closePath:false})}this.shapeRenderer.draw(an,ap,ah);this.shapeRenderer.draw(an,al,ah)};L.jqplot.MarkerRenderer.prototype.drawX=function(ak,aj,an,am,aq){var ai=1;var ar=this.size/2*ai;var ao=this.size/2*ai;var ah=L.extend(true,{},this.options,{closePath:false});var ap=[[ak-ar,aj-ao],[ak+ar,aj+ao]];var al=[[ak-ar,aj+ao],[ak+ar,aj-ao]];if(this.shadow){this.shadowRenderer.draw(an,ap,{closePath:false});this.shadowRenderer.draw(an,al,{closePath:false})}this.shapeRenderer.draw(an,ap,ah);this.shapeRenderer.draw(an,al,ah)};L.jqplot.MarkerRenderer.prototype.drawDash=function(aj,ai,am,al,ao){var ah=1;var ap=this.size/2*ah;var an=this.size/2*ah;var ak=[[aj-ap,ai],[aj+ap,ai]];if(this.shadow){this.shadowRenderer.draw(am,ak)}this.shapeRenderer.draw(am,ak,ao)};L.jqplot.MarkerRenderer.prototype.drawLine=function(am,al,ah,ak,ai){var aj=[am,al];if(this.shadow){this.shadowRenderer.draw(ah,aj)}this.shapeRenderer.draw(ah,aj,ai)};L.jqplot.MarkerRenderer.prototype.drawSquare=function(aj,ai,am,al,ao){var ah=1;var ap=this.size/2/ah;var an=this.size/2*ah;var ak=[[aj-ap,ai-an],[aj-ap,ai+an],[aj+ap,ai+an],[aj+ap,ai-an]];if(this.shadow){this.shadowRenderer.draw(am,ak)}this.shapeRenderer.draw(am,ak,ao)};L.jqplot.MarkerRenderer.prototype.drawCircle=function(ai,ao,ak,an,al){var ah=this.size/2;var aj=2*Math.PI;var am=[ai,ao,ah,0,aj,true];if(this.shadow){this.shadowRenderer.draw(ak,am)}this.shapeRenderer.draw(ak,am,al)};L.jqplot.MarkerRenderer.prototype.draw=function(ah,ak,ai,aj){aj=aj||{};if(aj.show==null||aj.show!=false){if(aj.color&&!aj.fillStyle){aj.fillStyle=aj.color}if(aj.color&&!aj.strokeStyle){aj.strokeStyle=aj.color}switch(this.style){case"diamond":this.drawDiamond(ah,ak,ai,false,aj);break;case"filledDiamond":this.drawDiamond(ah,ak,ai,true,aj);break;case"circle":this.drawCircle(ah,ak,ai,false,aj);break;case"filledCircle":this.drawCircle(ah,ak,ai,true,aj);break;case"square":this.drawSquare(ah,ak,ai,false,aj);break;case"filledSquare":thi!
s.drawSquare(ah,ak,ai,true,aj);break;case"x":this.drawX(ah,ak,ai,true,aj);break;case"plus":this.drawPlus(ah,ak,ai,true,aj);break;case"dash":this.drawDash(ah,ak,ai,true,aj);break;case"line":this.drawLine(ah,ak,ai,false,aj);break;default:this.drawDiamond(ah,ak,ai,false,aj);break}}};L.jqplot.ShadowRenderer=function(ah){this.angle=45;this.offset=1;this.alpha=0.07;this.lineWidth=1.5;this.lineJoin="miter";this.lineCap="round";this.closePath=false;this.fill=false;this.depth=3;this.strokeStyle="rgba(0,0,0,0.1)";this.isarc=false;L.extend(true,this,ah)};L.jqplot.ShadowRenderer.prototype.init=function(ah){L.extend(true,this,ah)};L.jqplot.ShadowRenderer.prototype.draw=function(av,at,ax){av.save();var ah=(ax!=null)?ax:{};var au=(ah.fill!=null)?ah.fill:this.fill;var ap=(ah.fillRect!=null)?ah.fillRect:this.fillRect;var ao=(ah.closePath!=null)?ah.closePath:this.closePath;var al=(ah.offset!=null)?ah.offset:this.offset;var aj=(ah.alpha!=null)?ah.alpha:this.alpha;var an=(ah.depth!=null)?ah.depth:this.depth;var aw=(ah.isarc!=null)?ah.isarc:this.isarc;var aq=(ah.linePattern!=null)?ah.linePattern:this.linePattern;av.lineWidth=(ah.lineWidth!=null)?ah.lineWidth:this.lineWidth;av.lineJoin=(ah.lineJoin!=null)?ah.lineJoin:this.lineJoin;av.lineCap=(ah.lineCap!=null)?ah.lineCap:this.lineCap;av.strokeStyle=ah.strokeStyle||this.strokeStyle||"rgba(0,0,0,"+aj+")";av.fillStyle=ah.fillStyle||this.fillStyle||"rgba(0,0,0,"+aj+")";for(var ak=0;ak<an;ak++){var ar=L.jqplot.LinePattern(av,aq);av.translate(Math.cos(this.angle*Math.PI/180)*al,Math.sin(this.angle*Math.PI/180)*al);ar.beginPath();if(aw){av.arc(at[0],at[1],at[2],at[3],at[4],true)}else{if(ap){if(ap){av.fillRect(at[0],at[1],at[2],at[3])}}else{if(at&&at.length){var ai=true;for(var am=0;am<at.length;am++){if(at[am][0]!=null&&at[am][1]!=null){if(ai){ar.moveTo(at[am][0],at[am][1]);ai=false}else{ar.lineTo(at[am][0],at[am][1])}}else{ai=true}}}}}if(ao){ar.closePath()}if(au){av.fill()}else{av.stroke()}}av.restore()};L.jqplot.ShapeRenderer=function(ah){this.lineWidth=1.5;this.linePattern="solid";this.l!
ineJoin="miter";this.lineCap="round";this.closePath=false;this.fill=false;this.isarc=false;this.fillRect=false;this.strokeRect=false;this.clearRect=false;this.strokeStyle="#999999";this.fillStyle="#999999";L.extend(true,this,ah)};L.jqplot.ShapeRenderer.prototype.init=function(ah){L.extend(true,this,ah)};L.jqplot.ShapeRenderer.prototype.draw=function(at,aq,av){at.save();var ah=(av!=null)?av:{};var ar=(ah.fill!=null)?ah.fill:this.fill;var am=(ah.closePath!=null)?ah.closePath:this.closePath;var an=(ah.fillRect!=null)?ah.fillRect:this.fillRect;var ak=(ah.strokeRect!=null)?ah.strokeRect:this.strokeRect;var ai=(ah.clearRect!=null)?ah.clearRect:this.clearRect;var au=(ah.isarc!=null)?ah.isarc:this.isarc;var ao=(ah.linePattern!=null)?ah.linePattern:this.linePattern;var ap=L.jqplot.LinePattern(at,ao);at.lineWidth=ah.lineWidth||this.lineWidth;at.lineJoin=ah.lineJoin||this.lineJoin;at.lineCap=ah.lineCap||this.lineCap;at.strokeStyle=(ah.strokeStyle||ah.color)||this.strokeStyle;at.fillStyle=ah.fillStyle||this.fillStyle;at.beginPath();if(au){at.arc(aq[0],aq[1],aq[2],aq[3],aq[4],true);if(am){at.closePath()}if(ar){at.fill()}else{at.stroke()}at.restore();return}else{if(ai){at.clearRect(aq[0],aq[1],aq[2],aq[3]);at.restore();return}else{if(an||ak){if(an){at.fillRect(aq[0],aq[1],aq[2],aq[3])}if(ak){at.strokeRect(aq[0],aq[1],aq[2],aq[3]);at.restore();return}}else{if(aq&&aq.length){var aj=true;for(var al=0;al<aq.length;al++){if(aq[al][0]!=null&&aq[al][1]!=null){if(aj){ap.moveTo(aq[al][0],aq[al][1]);aj=false}else{ap.lineTo(aq[al][0],aq[al][1])}}else{aj=true}}if(am){ap.closePath()}if(ar){at.fill()}else{at.stroke()}}}}}at.restore()};L.jqplot.TableLegendRenderer=function(){};L.jqplot.TableLegendRenderer.prototype.init=function(ah){L.extend(true,this,ah)};L.jqplot.TableLegendRenderer.prototype.addrow=function(aq,ak,ah,ao){var al=(ah)?this.rowSpacing+"px":"0px";var ap;var aj;var ai;var an;var am;ai=document.createElement("tr");ap=L(ai);ap.addClass("jqplot-table-legend");ai=null;if(ao){ap.prependTo(this._elem)}else{ap.appendTo(this._elem)}if!
(this.showSwatches){aj=L(document.createElement("td"));aj.addClass("jqplot-table-legend jqplot-table-legend-swatch");aj.css({textAlign:"center",paddingTop:al});an=L(document.createElement("div"));an.addClass("jqplot-table-legend-swatch-outline");am=L(document.createElement("div"));am.addClass("jqplot-table-legend-swatch");am.css({backgroundColor:ak,borderColor:ak});ap.append(aj.append(an.append(am)))}if(this.showLabels){aj=L(document.createElement("td"));aj.addClass("jqplot-table-legend jqplot-table-legend-label");aj.css("paddingTop",al);ap.append(aj);if(this.escapeHtml){aj.text(aq)}else{aj.html(aq)}}aj=null;an=null;am=null;ap=null;ai=null};L.jqplot.TableLegendRenderer.prototype.draw=function(){if(this._elem){this._elem.emptyForce();this._elem=null}if(this.show){var am=this._series;var ai=document.createElement("table");this._elem=L(ai);this._elem.addClass("jqplot-table-legend");var ar={position:"absolute"};if(this.background){ar.background=this.background}if(this.border){ar.border=this.border}if(this.fontSize){ar.fontSize=this.fontSize}if(this.fontFamily){ar.fontFamily=this.fontFamily}if(this.textColor){ar.textColor=this.textColor}if(this.marginTop!=null){ar.marginTop=this.marginTop}if(this.marginBottom!=null){ar.marginBottom=this.marginBottom}if(this.marginLeft!=null){ar.marginLeft=this.marginLeft}if(this.marginRight!=null){ar.marginRight=this.marginRight}var ah=false,ao=false,aq;for(var an=0;an<am.length;an++){aq=am[an];if(aq._stack||aq.renderer.constructor==L.jqplot.BezierCurveRenderer){ao=true}if(aq.show&&aq.showLabel){var al=this.labels[an]||aq.label.toString();if(al){var aj=aq.color;if(ao&&an<am.length-1){ah=true}else{if(ao&&an==am.length-1){ah=false}}this.renderer.addrow.call(this,al,aj,ah,ao);ah=true}for(var ak=0;ak<L.jqplot.addLegendRowHooks.length;ak++){var ap=L.jqplot.addLegendRowHooks[ak].call(this,aq);if(ap){this.renderer.addrow.call(this,ap.label,ap.color,ah);ah=true}}al=null}}}return this._elem};L.jqplot.TableLegendRenderer.prototype.pack=function(aj){if(this.show){if(this.placement=="insideGrid"!
){switch(this.location){case"nw":var ai=aj.left;var ah=aj.top;this._elem.css("left",ai);this._elem.css("top",ah);break;case"n":var ai=(aj.left+(this._plotDimensions.width-aj.right))/2-this.getWidth()/2;var ah=aj.top;this._elem.css("left",ai);this._elem.css("top",ah);break;case"ne":var ai=aj.right;var ah=aj.top;this._elem.css({right:ai,top:ah});break;case"e":var ai=aj.right;var ah=(aj.top+(this._plotDimensions.height-aj.bottom))/2-this.getHeight()/2;this._elem.css({right:ai,top:ah});break;case"se":var ai=aj.right;var ah=aj.bottom;this._elem.css({right:ai,bottom:ah});break;case"s":var ai=(aj.left+(this._plotDimensions.width-aj.right))/2-this.getWidth()/2;var ah=aj.bottom;this._elem.css({left:ai,bottom:ah});break;case"sw":var ai=aj.left;var ah=aj.bottom;this._elem.css({left:ai,bottom:ah});break;case"w":var ai=aj.left;var ah=(aj.top+(this._plotDimensions.height-aj.bottom))/2-this.getHeight()/2;this._elem.css({left:ai,top:ah});break;default:var ai=aj.right;var ah=aj.bottom;this._elem.css({right:ai,bottom:ah});break}}else{if(this.placement=="outside"){switch(this.location){case"nw":var ai=this._plotDimensions.width-aj.left;var ah=aj.top;this._elem.css("right",ai);this._elem.css("top",ah);break;case"n":var ai=(aj.left+(this._plotDimensions.width-aj.right))/2-this.getWidth()/2;var ah=this._plotDimensions.height-aj.top;this._elem.css("left",ai);this._elem.css("bottom",ah);break;case"ne":var ai=this._plotDimensions.width-aj.right;var ah=aj.top;this._elem.css({left:ai,top:ah});break;case"e":var ai=this._plotDimensions.width-aj.right;var ah=(aj.top+(this._plotDimensions.height-aj.bottom))/2-this.getHeight()/2;this._elem.css({left:ai,top:ah});break;case"se":var ai=this._plotDimensions.width-aj.right;var ah=aj.bottom;this._elem.css({left:ai,bottom:ah});break;case"s":var ai=(aj.left+(this._plotDimensions.width-aj.right))/2-this.getWidth()/2;var ah=this._plotDimensions.height-aj.bottom;this._elem.css({left:ai,top:ah});break;case"sw":var ai=this._plotDimensions.width-aj.left;var ah=aj.bottom;this._elem.css({right:ai,bottom:ah});!
break;case"w":var ai=this._plotDimensions.width-aj.left;var ah=(aj.top+(this._plotDimensions.height-aj.bottom))/2-this.getHeight()/2;this._elem.css({right:ai,top:ah});break;default:var ai=aj.right;var ah=aj.bottom;this._elem.css({right:ai,bottom:ah});break}}else{switch(this.location){case"nw":this._elem.css({left:0,top:aj.top});break;case"n":var ai=(aj.left+(this._plotDimensions.width-aj.right))/2-this.getWidth()/2;this._elem.css({left:ai,top:aj.top});break;case"ne":this._elem.css({right:0,top:aj.top});break;case"e":var ah=(aj.top+(this._plotDimensions.height-aj.bottom))/2-this.getHeight()/2;this._elem.css({right:aj.right,top:ah});break;case"se":this._elem.css({right:aj.right,bottom:aj.bottom});break;case"s":var ai=(aj.left+(this._plotDimensions.width-aj.right))/2-this.getWidth()/2;this._elem.css({left:ai,bottom:aj.bottom});break;case"sw":this._elem.css({left:aj.left,bottom:aj.bottom});break;case"w":var ah=(aj.top+(this._plotDimensions.height-aj.bottom))/2-this.getHeight()/2;this._elem.css({left:aj.left,top:ah});break;default:this._elem.css({right:aj.right,bottom:aj.bottom});break}}}}};L.jqplot.ThemeEngine=function(){this.themes={};this.activeTheme=null};L.jqplot.ThemeEngine.prototype.init=function(){var ak=new L.jqplot.Theme({_name:"Default"});var an,ai,am;for(an in ak.target){if(an=="textColor"){ak.target[an]=this.target.css("color")}else{ak.target[an]=this.target.css(an)}}if(this.title.show&&this.title._elem){for(an in ak.title){if(an=="textColor"){ak.title[an]=this.title._elem.css("color")}else{ak.title[an]=this.title._elem.css(an)}}}for(an in ak.grid){ak.grid[an]=this.grid[an]}if(ak.grid.backgroundColor==null&&this.grid.background!=null){ak.grid.backgroundColor=this.grid.background}if(this.legend.show&&this.legend._elem){for(an in ak.legend){if(an=="textColor"){ak.legend[an]=this.legend._elem.css("color")}else{ak.legend[an]=this.legend._elem.css(an)}}}var aj;for(ai=0;ai<this.series.length;ai++){aj=this.series[ai];if(aj.renderer.constructor==L.jqplot.LineRenderer){ak.series.push(new p())}else{if(aj.renderer.!
constructor==L.jqplot.BarRenderer){ak.series.push(new T())}else{if(aj.renderer.constructor==L.jqplot.PieRenderer){ak.series.push(new f())}else{if(aj.renderer.constructor==L.jqplot.DonutRenderer){ak.series.push(new G())}else{if(aj.renderer.constructor==L.jqplot.FunnelRenderer){ak.series.push(new Z())}else{if(aj.renderer.constructor==L.jqplot.MeterGaugeRenderer){ak.series.push(new D())}else{ak.series.push({})}}}}}}for(an in ak.series[ai]){ak.series[ai][an]=aj[an]}}var ah,al;for(an in this.axes){al=this.axes[an];ah=ak.axes[an]=new P();ah.borderColor=al.borderColor;ah.borderWidth=al.borderWidth;if(al._ticks&&al._ticks[0]){for(am in ah.ticks){if(al._ticks[0].hasOwnProperty(am)){ah.ticks[am]=al._ticks[0][am]}else{if(al._ticks[0]._elem){ah.ticks[am]=al._ticks[0]._elem.css(am)}}}}if(al._label&&al._label.show){for(am in ah.label){if(al._label[am]){ah.label[am]=al._label[am]}else{if(al._label._elem){if(am=="textColor"){ah.label[am]=al._label._elem.css("color")}else{ah.label[am]=al._label._elem.css(am)}}}}}}this.themeEngine._add(ak);this.themeEngine.activeTheme=this.themeEngine.themes[ak._name]};L.jqplot.ThemeEngine.prototype.get=function(ah){if(!ah){return this.activeTheme}else{return this.themes[ah]}};function O(ai,ah){return ai-ah}L.jqplot.ThemeEngine.prototype.getThemeNames=function(){var ah=[];for(var ai in this.themes){ah.push(ai)}return ah.sort(O)};L.jqplot.ThemeEngine.prototype.getThemes=function(){var ai=[];var ah=[];for(var ak in this.themes){ai.push(ak)}ai.sort(O);for(var aj=0;aj<ai.length;aj++){ah.push(this.themes[ai[aj]])}return ah};L.jqplot.ThemeEngine.prototype.activate=function(av,aB){var ah=false;if(!aB&&this.activeTheme&&this.activeTheme._name){aB=this.activeTheme._name}if(!this.themes.hasOwnProperty(aB)){throw new Error("No theme of that name")}else{var am=this.themes[aB];this.activeTheme=am;var aA,at=false,ar=false;var ai=["xaxis","x2axis","yaxis","y2axis"];for(aw=0;aw<ai.length;aw++){var an=ai[aw];if(am.axesStyles.borderColor!=null){av.axes[an].borderColor=am.axesStyles.borderColor}if(am.axesStyles.bor!
derWidth!=null){av.axes[an].borderWidth=am.axesStyles.borderWidth}}for(var az in av.axes){var ak=av.axes[az];if(ak.show){var aq=am.axes[az]||{};var ao=am.axesStyles;var al=L.jqplot.extend(true,{},aq,ao);aA=(am.axesStyles.borderColor!=null)?am.axesStyles.borderColor:al.borderColor;if(al.borderColor!=null){ak.borderColor=al.borderColor;ah=true}aA=(am.axesStyles.borderWidth!=null)?am.axesStyles.borderWidth:al.borderWidth;if(al.borderWidth!=null){ak.borderWidth=al.borderWidth;ah=true}if(ak._ticks&&ak._ticks[0]){for(var aj in al.ticks){aA=al.ticks[aj];if(aA!=null){ak.tickOptions[aj]=aA;ak._ticks=[];ah=true}}}if(ak._label&&ak._label.show){for(var aj in al.label){aA=al.label[aj];if(aA!=null){ak.labelOptions[aj]=aA;ah=true}}}}}for(var au in am.grid){if(am.grid[au]!=null){av.grid[au]=am.grid[au]}}if(!ah){av.grid.draw()}if(av.legend.show){for(au in am.legend){if(am.legend[au]!=null){av.legend[au]=am.legend[au]}}}if(av.title.show){for(au in am.title){if(am.title[au]!=null){av.title[au]=am.title[au]}}}var aw;for(aw=0;aw<am.series.length;aw++){var ap={};var ay=false;for(au in am.series[aw]){aA=(am.seriesStyles[au]!=null)?am.seriesStyles[au]:am.series[aw][au];if(aA!=null){ap[au]=aA;if(au=="color"){av.series[aw].renderer.shapeRenderer.fillStyle=aA;av.series[aw].renderer.shapeRenderer.strokeStyle=aA;av.series[aw][au]=aA}else{if((au=="lineWidth")||(au=="linePattern")){av.series[aw].renderer.shapeRenderer[au]=aA;av.series[aw][au]=aA}else{if(au=="markerOptions"){V(av.series[aw].markerOptions,aA);V(av.series[aw].markerRenderer,aA)}else{av.series[aw][au]=aA}}}ah=true}}}if(ah){av.target.empty();av.draw()}for(au in am.target){if(am.target[au]!=null){av.target.css(au,am.target[au])}}}};L.jqplot.ThemeEngine.prototype._add=function(ai,ah){if(ah){ai._name=ah}if(!ai._name){ai._name=Date.parse(new Date())}if(!this.themes.hasOwnProperty(ai._name)){this.themes[ai._name]=ai}else{throw new Error("jqplot.ThemeEngine Error: Theme already in use")}};L.jqplot.ThemeEngine.prototype.remove=function(ah){if(ah=="Default"){return false}return delete thi!
s.themes[ah]};L.jqplot.ThemeEngine.prototype.newTheme=function(ah,aj){if(typeof(ah)=="object"){aj=aj||ah;ah=null}if(aj&&aj._name){ah=aj._name}else{ah=ah||Date.parse(new Date())}var ai=this.copy(this.themes.Default._name,ah);L.jqplot.extend(ai,aj);return ai};function B(aj){if(aj==null||typeof(aj)!="object"){return aj}var ah=new aj.constructor();for(var ai in aj){ah[ai]=B(aj[ai])}return ah}L.jqplot.clone=B;function V(aj,ai){if(ai==null||typeof(ai)!="object"){return}for(var ah in ai){if(ah=="highlightColors"){aj[ah]=B(ai[ah])}if(ai[ah]!=null&&typeof(ai[ah])=="object"){if(!aj.hasOwnProperty(ah)){aj[ah]={}}V(aj[ah],ai[ah])}else{aj[ah]=ai[ah]}}}L.jqplot.merge=V;L.jqplot.extend=function(){var am=arguments[0]||{},ak=1,al=arguments.length,ah=false,aj;if(typeof am==="boolean"){ah=am;am=arguments[1]||{};ak=2}if(typeof am!=="object"&&!toString.call(am)==="[object Function]"){am={}}for(;ak<al;ak++){if((aj=arguments[ak])!=null){for(var ai in aj){var an=am[ai],ao=aj[ai];if(am===ao){continue}if(ah&&ao&&typeof ao==="object"&&!ao.nodeType){am[ai]=L.jqplot.extend(ah,an||(ao.length!=null?[]:{}),ao)}else{if(ao!==u){am[ai]=ao}}}}}return am};L.jqplot.ThemeEngine.prototype.rename=function(ai,ah){if(ai=="Default"||ah=="Default"){throw new Error("jqplot.ThemeEngine Error: Cannot rename from/to Default")}if(this.themes.hasOwnProperty(ah)){throw new Error("jqplot.ThemeEngine Error: New name already in use.")}else{if(this.themes.hasOwnProperty(ai)){var aj=this.copy(ai,ah);this.remove(ai);return aj}}throw new Error("jqplot.ThemeEngine Error: Old name or new name invalid")};L.jqplot.ThemeEngine.prototype.copy=function(ah,aj,al){if(aj=="Default"){throw new Error("jqplot.ThemeEngine Error: Cannot copy over Default theme")}if(!this.themes.hasOwnProperty(ah)){var ai="jqplot.ThemeEngine Error: Source name invalid";throw new Error(ai)}if(this.themes.hasOwnProperty(aj)){var ai="jqplot.ThemeEngine Error: Target name invalid";throw new Error(ai)}else{var ak=B(this.themes[ah]);ak._name=aj;L.jqplot.extend(true,ak,al);this._add(ak);return ak}};L.jqplot.T!
heme=function(ah,ai){if(typeof(ah)=="object"){ai=ai||ah;ah=null}ah=ah||Date.parse(new Date());this._name=ah;this.target={backgroundColor:null};this.legend={textColor:null,fontFamily:null,fontSize:null,border:null,background:null};this.title={textColor:null,fontFamily:null,fontSize:null,textAlign:null};this.seriesStyles={};this.series=[];this.grid={drawGridlines:null,gridLineColor:null,gridLineWidth:null,backgroundColor:null,borderColor:null,borderWidth:null,shadow:null};this.axesStyles={label:{},ticks:{}};this.axes={};if(typeof(ai)=="string"){this._name=ai}else{if(typeof(ai)=="object"){L.jqplot.extend(true,this,ai)}}};var P=function(){this.borderColor=null;this.borderWidth=null;this.ticks=new o();this.label=new t()};var o=function(){this.show=null;this.showGridline=null;this.showLabel=null;this.showMark=null;this.size=null;this.textColor=null;this.whiteSpace=null;this.fontSize=null;this.fontFamily=null};var t=function(){this.textColor=null;this.whiteSpace=null;this.fontSize=null;this.fontFamily=null;this.fontWeight=null};var p=function(){this.color=null;this.lineWidth=null;this.linePattern=null;this.shadow=null;this.fillColor=null;this.showMarker=null;this.markerOptions=new I()};var I=function(){this.show=null;this.style=null;this.lineWidth=null;this.size=null;this.color=null;this.shadow=null};var T=function(){this.color=null;this.seriesColors=null;this.lineWidth=null;this.shadow=null;this.barPadding=null;this.barMargin=null;this.barWidth=null;this.highlightColors=null};var f=function(){this.seriesColors=null;this.padding=null;this.sliceMargin=null;this.fill=null;this.shadow=null;this.startAngle=null;this.lineWidth=null;this.highlightColors=null};var G=function(){this.seriesColors=null;this.padding=null;this.sliceMargin=null;this.fill=null;this.shadow=null;this.startAngle=null;this.lineWidth=null;this.innerDiameter=null;this.thickness=null;this.ringMargin=null;this.highlightColors=null};var Z=function(){this.color=null;this.lineWidth=null;this.shadow=null;this.padding=null;this.sectionMargin=null;this.seriesColo!
rs=null;this.highlightColors=null};var D=function(){this.padding=null;this.backgroundColor=null;this.ringColor=null;this.tickColor=null;this.ringWidth=null;this.intervalColors=null;this.intervalInnerRadius=null;this.intervalOuterRadius=null;this.hubRadius=null;this.needleThickness=null;this.needlePad=null};L.fn.jqplotChildText=function(){return L(this).contents().filter(function(){return this.nodeType==3}).text()};L.fn.jqplotGetComputedFontStyle=function(){var ak=window.getComputedStyle?window.getComputedStyle(this[0],""):this[0].currentStyle;var ai=ak["font-style"]?["font-style","font-weight","font-size","font-family"]:["fontStyle","fontWeight","fontSize","fontFamily"];var al=[];for(var aj=0;aj<ai.length;++aj){var ah=String(ak[ai[aj]]);if(ah&&ah!="normal"){al.push(ah)}}return al.join(" ")};L.fn.jqplotToImageCanvas=function(aj){aj=aj||{};var av=(aj.x_offset==null)?0:aj.x_offset;var ax=(aj.y_offset==null)?0:aj.y_offset;var al=(aj.backgroundColor==null)?"rgb(255,255,255)":aj.backgroundColor;if(L(this).width()==0||L(this).height()==0){return null}if(L.jqplot.use_excanvas){return null}var an=document.createElement("canvas");var aA=L(this).outerHeight(true);var at=L(this).outerWidth(true);var am=L(this).offset();var ao=am.left;var aq=am.top;var au=0,ar=0;var ay=["jqplot-table-legend","jqplot-xaxis-tick","jqplot-x2axis-tick","jqplot-yaxis-tick","jqplot-y2axis-tick","jqplot-y3axis-tick","jqplot-y4axis-tick","jqplot-y5axis-tick","jqplot-y6axis-tick","jqplot-y7axis-tick","jqplot-y8axis-tick","jqplot-y9axis-tick","jqplot-xaxis-label","jqplot-x2axis-label","jqplot-yaxis-label","jqplot-y2axis-label","jqplot-y3axis-label","jqplot-y4axis-label","jqplot-y5axis-label","jqplot-y6axis-label","jqplot-y7axis-label","jqplot-y8axis-label","jqplot-y9axis-label"];var ap,ah,ai,aB;for(var az=0;az<ay.length;az++){L(this).find("."+ay[az]).each(function(){ap=L(this).offset().top-aq;ah=L(this).offset().left-ao;aB=ah+L(this).outerWidth(true)+au;ai=ap+L(this).outerHeight(true)+ar;if(ah<-au){at=at-au-ah;au=-ah}if(ap<-ar){aA=aA-ar-ap;ar=-ap}if(a!
B>at){at=aB}if(ai>aA){aA=ai}})}an.width=at+Number(av);an.height=aA+Number(ax);var ak=an.getContext("2d");ak.save();ak.fillStyle=al;ak.fillRect(0,0,an.width,an.height);ak.restore();ak.translate(au,ar);ak.textAlign="left";ak.textBaseline="top";function aC(aE){var aF=parseInt(L(aE).css("line-height"),10);if(isNaN(aF)){aF=parseInt(L(aE).css("font-size"),10)*1.2}return aF}function aD(aF,aE,aS,aG,aO,aH){var aQ=aC(aF);var aK=L(aF).innerWidth();var aL=L(aF).innerHeight();var aN=aS.split(/\s+/);var aR=aN.length;var aP="";var aM=[];var aU=aO;var aT=aG;for(var aJ=0;aJ<aR;aJ++){aP+=aN[aJ];if(aE.measureText(aP).width>aK){aM.push(aJ);aP="";aJ--}}if(aM.length===0){if(L(aF).css("textAlign")==="center"){aT=aG+(aH-aE.measureText(aP).width)/2-au}aE.fillText(aS,aT,aO)}else{aP=aN.slice(0,aM[0]).join(" ");if(L(aF).css("textAlign")==="center"){aT=aG+(aH-aE.measureText(aP).width)/2-au}aE.fillText(aP,aT,aU);aU+=aQ;for(var aJ=1,aI=aM.length;aJ<aI;aJ++){aP=aN.slice(aM[aJ-1],aM[aJ]).join(" ");if(L(aF).css("textAlign")==="center"){aT=aG+(aH-aE.measureText(aP).width)/2-au}aE.fillText(aP,aT,aU);aU+=aQ}aP=aN.slice(aM[aJ-1],aN.length).join(" ");if(L(aF).css("textAlign")==="center"){aT=aG+(aH-aE.measureText(aP).width)/2-au}aE.fillText(aP,aT,aU)}}function aw(aG,aJ,aE){var aN=aG.tagName.toLowerCase();var aF=L(aG).position();var aK=window.getComputedStyle?window.getComputedStyle(aG,""):aG.currentStyle;var aI=aJ+aF.left+parseInt(aK.marginLeft,10)+parseInt(aK.borderLeftWidth,10)+parseInt(aK.paddingLeft,10);var aL=aE+aF.top+parseInt(aK.marginTop,10)+parseInt(aK.borderTopWidth,10)+parseInt(aK.paddingTop,10);var aM=an.width;if((aN=="div"||aN=="span")&&!L(aG).hasClass("jqplot-highlighter-tooltip")){L(aG).children().each(function(){aw(this,aI,aL)});var aO=L(aG).jqplotChildText();if(aO){ak.font=L(aG).jqplotGetComputedFontStyle();ak.fillStyle=L(aG).css("color");aD(aG,ak,aO,aI,aL,aM)}}else{if(aN==="table"&&L(aG).hasClass("jqplot-table-legend")){ak.strokeStyle=L(aG).css("border-top-color");ak.fillStyle=L(aG).css("background-color");ak.fillRect(aI,aL,L(aG).inn!
erWidth(),L(aG).innerHeight());if(parseInt(L(aG).css("border-top-width"),10)>0){ak.strokeRect(aI,aL,L(aG).innerWidth(),L(aG).innerHeight())}L(aG).find("div.jqplot-table-legend-swatch-outline").each(function(){var aU=L(this);ak.strokeStyle=aU.css("border-top-color");var aQ=aI+aU.position().left;var aR=aL+aU.position().top;ak.strokeRect(aQ,aR,aU.innerWidth(),aU.innerHeight());aQ+=parseInt(aU.css("padding-left"),10);aR+=parseInt(aU.css("padding-top"),10);var aT=aU.innerHeight()-2*parseInt(aU.css("padding-top"),10);var aP=aU.innerWidth()-2*parseInt(aU.css("padding-left"),10);var aS=aU.children("div.jqplot-table-legend-swatch");ak.fillStyle=aS.css("background-color");ak.fillRect(aQ,aR,aP,aT)});L(aG).find("td.jqplot-table-legend-label").each(function(){var aR=L(this);var aP=aI+aR.position().left;var aQ=aL+aR.position().top+parseInt(aR.css("padding-top"),10);ak.font=aR.jqplotGetComputedFontStyle();ak.fillStyle=aR.css("color");aD(aR,ak,aR.text(),aP,aQ,aM)});var aH=null}else{if(aN=="canvas"){ak.drawImage(aG,aI,aL)}}}}L(this).children().each(function(){aw(this,av,ax)});return an};L.fn.jqplotToImageStr=function(ai){var ah=L(this).jqplotToImageCanvas(ai);if(ah){return ah.toDataURL("image/png")}else{return null}};L.fn.jqplotToImageElem=function(ah){var ai=document.createElement("img");var aj=L(this).jqplotToImageStr(ah);ai.src=aj;return ai};L.fn.jqplotToImageElemStr=function(ah){var ai="<img src="+L(this).jqplotToImageStr(ah)+" />";return ai};L.fn.jqplotSaveImage=function(){var ah=L(this).jqplotToImageStr({});if(ah){window.location.href=ah.replace("image/png","image/octet-stream")}};L.fn.jqplotViewImage=function(){var ai=L(this).jqplotToImageElemStr({});var aj=L(this).jqplotToImageStr({});if(ai){var ah=window.open("");ah.document.open("image/png");ah.document.write(ai);ah.document.close();ah=null}};var ag=function(){this.syntax=ag.config.syntax;this._type="jsDate";this.proxy=new Date();this.options={};this.locale=ag.regional.getLocale();this.formatString="";this.defaultCentury=ag.config.defaultCentury;switch(arguments.length!
){case 0:break;case 1:if(l(arguments[0])=="[object Object]"&&arguments[0]._type!="jsDate"){var aj=this.options=arguments[0];this.syntax=aj.syntax||this.syntax;this.defaultCentury=aj.defaultCentury||this.defaultCentury;this.proxy=ag.createDate(aj.date)}else{this.proxy=ag.createDate(arguments[0])}break;default:var ah=[];for(var ai=0;ai<arguments.length;ai++){ah.push(arguments[ai])}this.proxy=new Date();this.proxy.setFullYear.apply(this.proxy,ah.slice(0,3));if(ah.slice(3).length){this.proxy.setHours.apply(this.proxy,ah.slice(3))}break}};ag.config={defaultLocale:"en",syntax:"perl",defaultCentury:1900};ag.prototype.add=function(aj,ai){var ah=E[ai]||E.day;if(typeof ah=="number"){this.proxy.setTime(this.proxy.getTime()+(ah*aj))}else{ah.add(this,aj)}return this};ag.prototype.clone=function(){return new ag(this.proxy.getTime())};ag.prototype.getUtcOffset=function(){return this.proxy.getTimezoneOffset()*60000};ag.prototype.diff=function(ai,al,ah){ai=new ag(ai);if(ai===null){return null}var aj=E[al]||E.day;if(typeof aj=="number"){var ak=(this.proxy.getTime()-ai.proxy.getTime())/aj}else{var ak=aj.diff(this.proxy,ai.proxy)}return(ah?ak:Math[ak>0?"floor":"ceil"](ak))};ag.prototype.getAbbrDayName=function(){return ag.regional[this.locale]["dayNamesShort"][this.proxy.getDay()]};ag.prototype.getAbbrMonthName=function(){return ag.regional[this.locale]["monthNamesShort"][this.proxy.getMonth()]};ag.prototype.getAMPM=function(){return this.proxy.getHours()>=12?"PM":"AM"};ag.prototype.getAmPm=function(){return this.proxy.getHours()>=12?"pm":"am"};ag.prototype.getCentury=function(){return parseInt(this.proxy.getFullYear()/100,10)};ag.prototype.getDate=function(){return this.proxy.getDate()};ag.prototype.getDay=function(){return this.proxy.getDay()};ag.prototype.getDayOfWeek=function(){var ah=this.proxy.getDay();return ah===0?7:ah};ag.prototype.getDayOfYear=function(){var ai=this.proxy;var ah=ai-new Date(""+ai.getFullYear()+"/1/1 GMT");ah+=ai.getTimezoneOffset()*60000;ai=null;return parseInt(ah/60000/60/24,10)+1};ag.prototype.getDayNam!
e=function(){return ag.regional[this.locale]["dayNames"][this.proxy.getDay()]};ag.prototype.getFullWeekOfYear=function(){var ak=this.proxy;var ah=this.getDayOfYear();var aj=6-ak.getDay();var ai=parseInt((ah+aj)/7,10);return ai};ag.prototype.getFullYear=function(){return this.proxy.getFullYear()};ag.prototype.getGmtOffset=function(){var ah=this.proxy.getTimezoneOffset()/60;var ai=ah<0?"+":"-";ah=Math.abs(ah);return ai+N(Math.floor(ah),2)+":"+N((ah%1)*60,2)};ag.prototype.getHours=function(){return this.proxy.getHours()};ag.prototype.getHours12=function(){var ah=this.proxy.getHours();return ah>12?ah-12:(ah==0?12:ah)};ag.prototype.getIsoWeek=function(){var ak=this.proxy;var aj=ak.getWeekOfYear();var ah=(new Date(""+ak.getFullYear()+"/1/1")).getDay();var ai=aj+(ah>4||ah<=1?0:1);if(ai==53&&(new Date(""+ak.getFullYear()+"/12/31")).getDay()<4){ai=1}else{if(ai===0){ak=new ag(new Date(""+(ak.getFullYear()-1)+"/12/31"));ai=ak.getIsoWeek()}}ak=null;return ai};ag.prototype.getMilliseconds=function(){return this.proxy.getMilliseconds()};ag.prototype.getMinutes=function(){return this.proxy.getMinutes()};ag.prototype.getMonth=function(){return this.proxy.getMonth()};ag.prototype.getMonthName=function(){return ag.regional[this.locale]["monthNames"][this.proxy.getMonth()]};ag.prototype.getMonthNumber=function(){return this.proxy.getMonth()+1};ag.prototype.getSeconds=function(){return this.proxy.getSeconds()};ag.prototype.getShortYear=function(){return this.proxy.getYear()%100};ag.prototype.getTime=function(){return this.proxy.getTime()};ag.prototype.getTimezoneAbbr=function(){return this.proxy.toString().replace(/^.*\(([^)]+)\)$/,"$1")};ag.prototype.getTimezoneName=function(){var ah=/(?:\((.+)\)$| ([A-Z]{3}) )/.exec(this.toString());return ah[1]||ah[2]||"GMT"+this.getGmtOffset()};ag.prototype.getTimezoneOffset=function(){return this.proxy.getTimezoneOffset()};ag.prototype.getWeekOfYear=function(){var ah=this.getDayOfYear();var aj=7-this.getDayOfWeek();var ai=parseInt((ah+aj)/7,10);return ai};ag.prototype.getUnix=function(){return!
Math.round(this.proxy.getTime()/1000,0)};ag.prototype.getYear=function(){return this.proxy.getYear()};ag.prototype.next=function(ah){ah=ah||"day";return this.clone().add(1,ah)};ag.prototype.set=function(){switch(arguments.length){case 0:this.proxy=new Date();break;case 1:if(l(arguments[0])=="[object Object]"&&arguments[0]._type!="jsDate"){var aj=this.options=arguments[0];this.syntax=aj.syntax||this.syntax;this.defaultCentury=aj.defaultCentury||this.defaultCentury;this.proxy=ag.createDate(aj.date)}else{this.proxy=ag.createDate(arguments[0])}break;default:var ah=[];for(var ai=0;ai<arguments.length;ai++){ah.push(arguments[ai])}this.proxy=new Date();this.proxy.setFullYear.apply(this.proxy,ah.slice(0,3));if(ah.slice(3).length){this.proxy.setHours.apply(this.proxy,ah.slice(3))}break}return this};ag.prototype.setDate=function(ah){this.proxy.setDate(ah);return this};ag.prototype.setFullYear=function(){this.proxy.setFullYear.apply(this.proxy,arguments);return this};ag.prototype.setHours=function(){this.proxy.setHours.apply(this.proxy,arguments);return this};ag.prototype.setMilliseconds=function(ah){this.proxy.setMilliseconds(ah);return this};ag.prototype.setMinutes=function(){this.proxy.setMinutes.apply(this.proxy,arguments);return this};ag.prototype.setMonth=function(){this.proxy.setMonth.apply(this.proxy,arguments);return this};ag.prototype.setSeconds=function(){this.proxy.setSeconds.apply(this.proxy,arguments);return this};ag.prototype.setTime=function(ah){this.proxy.setTime(ah);return this};ag.prototype.setYear=function(){this.proxy.setYear.apply(this.proxy,arguments);return this};ag.prototype.strftime=function(ah){ah=ah||this.formatString||ag.regional[this.locale]["formatString"];return ag.strftime(this,ah,this.syntax)};ag.prototype.toString=function(){return this.proxy.toString()};ag.prototype.toYmdInt=function(){return(this.proxy.getFullYear()*10000)+(this.getMonthNumber()*100)+this.proxy.getDate()};ag.regional={en:{monthNames:["January","February","March","April","May","June","July","August","September","October!
","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],formatString:"%Y-%m-%d %H:%M:%S"},fr:{monthNames:["Janvier","Février","Mars","Avril","Mai","Juin","Juillet","Août","Septembre","Octobre","Novembre","Décembre"],monthNamesShort:["Jan","Fév","Mar","Avr","Mai","Jun","Jul","Aoû","Sep","Oct","Nov","Déc"],dayNames:["Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"],dayNamesShort:["Dim","Lun","Mar","Mer","Jeu","Ven","Sam"],formatString:"%Y-%m-%d %H:%M:%S"},de:{monthNames:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],monthNamesShort:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],dayNames:["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],dayNamesShort:["So","Mo","Di","Mi","Do","Fr","Sa"],formatString:"%Y-%m-%d %H:%M:%S"},es:{monthNames:["Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"],monthNamesShort:["Ene","Feb","Mar","Abr","May","Jun","Jul","Ago","Sep","Oct","Nov","Dic"],dayNames:["Domingo","Lunes","Martes","Miércoles","Jueves","Viernes","Sábado"],dayNamesShort:["Dom","Lun","Mar","Mié","Juv","Vie","Sáb"],formatString:"%Y-%m-%d %H:%M:%S"},ru:{monthNames:["ЯнваÑÑ","ФевÑалÑ","ÐаÑÑ","Ð?пÑелÑ","Ðай","ÐÑнÑ","ÐÑлÑ","Ð?вгÑÑ?Ñ","СенÑÑ?бÑÑ","ÐкÑÑ?бÑÑ","Ð?оÑ?бÑÑ","ÐекабÑÑ"],monthNamesShort:["Янв","Фев","ÐаÑ","Ð?пÑ","Ðай","ÐÑн","ÐÑл","Ð?вг","Сен","ÐкÑ","Ð?оÑ?","Ðек"],dayNames:["воÑ?кÑеÑ?енÑе","понеделÑник","вÑоÑник","Ñ?Ñеда","ÑеÑвеÑг","пÑ?ÑниÑа","Ñ?ÑббоÑа"],dayNamesShort:["вÑ?к","пнд","вÑÑ","Ñ?Ñд","ÑÑв","пÑн","Ñ?бÑ"],formatString:"%Y-%m-%d %H:%!
M:%S"},ar:{monthNames:["ÙØ§ÙÙÙ Ø§ÙØ«Ø§ÙÙ","شباط","آذار","ÙÙØ³Ø§Ù","آذار","ØØ²ÙراÙ","تÙ
ÙØ²","آب","Ø£ÙÙÙÙ","تشرÙÙ Ø§ÙØ£ÙÙ","تشرÙÙ Ø§ÙØ«Ø§ÙÙ","ÙØ§ÙÙÙ Ø§ÙØ£ÙÙ"],monthNamesShort:["1","2","3","4","5","6","7","8","9","10","11","12"],dayNames:["Ø§ÙØ³Ø¨Øª","Ø§ÙØ£ØØ¯","Ø§ÙØ§Ø«ÙÙÙ","Ø§ÙØ«Ùاثاء","Ø§ÙØ£Ø±Ø¨Ø¹Ø§Ø¡","Ø§ÙØ®Ù
ÙØ³","Ø§ÙØ¬Ù
عة"],dayNamesShort:["سبت","Ø£ØØ¯","اثÙÙÙ","Ø«ÙØ§Ø«Ø§Ø¡","أربعاء","Ø®Ù
ÙØ³","جÙ
عة"],formatString:"%Y-%m-%d %H:%M:%S"},pt:{monthNames:["Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"],monthNamesShort:["Jan","Fev","Mar","Abr","Mai","Jun","Jul","Ago","Set","Out","Nov","Dez"],dayNames:["Domingo","Segunda-feira","Terça-feira","Quarta-feira","Quinta-feira","Sexta-feira","Sábado"],dayNamesShort:["Dom","Seg","Ter","Qua","Qui","Sex","Sáb"],formatString:"%Y-%m-%d %H:%M:%S"},"pt-BR":{monthNames:["Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"],monthNamesShort:["Jan","Fev","Mar","Abr","Mai","Jun","Jul","Ago","Set","Out","Nov","Dez"],dayNames:["Domingo","Segunda-feira","Terça-feira","Quarta-feira","Quinta-feira","Sexta-feira","Sábado"],dayNamesShort:["Dom","Seg","Ter","Qua","Qui","Sex","Sáb"],formatString:"%Y-%m-%d %H:%M:%S"},pl:{monthNames:["StyczeÅ","Luty","Marzec","KwiecieÅ","Maj","Czerwiec","Lipiec","SierpieÅ","WrzesieÅ","Październik","Listopad","GrudzieÅ"],monthNamesShort:["Sty","Lut","Mar","Kwi","Maj","Cze","Lip","Sie","Wrz","Paź","Lis","Gru"],dayNames:["Niedziela","PoniedziaÅek","Wtorek","Åroda","Czwartek","PiÄ
tek","Sobota"],dayNamesShort:["Ni","Pn","Wt","År","Cz","Pt","Sb"],formatString:"%Y-%m-%d %H:%M:%S"},};ag.regional["en-US"]=ag.regional["en-GB"]=ag.regional.en;ag.regional.getLocale=function(){var ah=ag.config.defaultLocale;if(document&&document.getElementsByTagName("html")&&document.getElementsByTagName("!
html")[0].lang){ah=document.getElementsByTagName("html")[0].lang;if(!ag.regional.hasOwnProperty(ah)){ah=ag.config.defaultLocale}}return ah};var C=24*60*60*1000;var N=function(ah,ak){ah=String(ah);var ai=ak-ah.length;var aj=String(Math.pow(10,ai)).slice(1);return aj.concat(ah)};var E={millisecond:1,second:1000,minute:60*1000,hour:60*60*1000,day:C,week:7*C,month:{add:function(aj,ah){E.year.add(aj,Math[ah>0?"floor":"ceil"](ah/12));var ai=aj.getMonth()+(ah%12);if(ai==12){ai=0;aj.setYear(aj.getFullYear()+1)}else{if(ai==-1){ai=11;aj.setYear(aj.getFullYear()-1)}}aj.setMonth(ai)},diff:function(al,aj){var ah=al.getFullYear()-aj.getFullYear();var ai=al.getMonth()-aj.getMonth()+(ah*12);var ak=al.getDate()-aj.getDate();return ai+(ak/30)}},year:{add:function(ai,ah){ai.setYear(ai.getFullYear()+Math[ah>0?"floor":"ceil"](ah))},diff:function(ai,ah){return E.month.diff(ai,ah)/12}}};for(var Y in E){if(Y.substring(Y.length-1)!="s"){E[Y+"s"]=E[Y]}}var H=function(al,ak,ai){if(ag.formats[ai]["shortcuts"][ak]){return ag.strftime(al,ag.formats[ai]["shortcuts"][ak],ai)}else{var ah=(ag.formats[ai]["codes"][ak]||"").split(".");var aj=al["get"+ah[0]]?al["get"+ah[0]]():"";if(ah[1]){aj=N(aj,ah[1])}return aj}};ag.strftime=function(an,ak,aj,ao){var ai="perl";var am=ag.regional.getLocale();if(aj&&ag.formats.hasOwnProperty(aj)){ai=aj}else{if(aj&&ag.regional.hasOwnProperty(aj)){am=aj}}if(ao&&ag.formats.hasOwnProperty(ao)){ai=ao}else{if(ao&&ag.regional.hasOwnProperty(ao)){am=ao}}if(l(an)!="[object Object]"||an._type!="jsDate"){an=new ag(an);an.locale=am}if(!ak){ak=an.formatString||ag.regional[am]["formatString"]}var ah=ak||"%Y-%m-%d",ap="",al;while(ah.length>0){if(al=ah.match(ag.formats[ai].codes.matcher)){ap+=ah.slice(0,al.index);ap+=(al[1]||"")+H(an,al[2],ai);ah=ah.slice(al.index+al[0].length)}else{ap+=ah;ah=""}}return ap};ag.formats={ISO:"%Y-%m-%dT%H:%M:%S.%N%G",SQL:"%Y-%m-%d %H:%M:%S"};ag.formats.perl={codes:{matcher:/()%(#?(%|[a-z]))/i,Y:"FullYear",y:"ShortYear.2",m:"MonthNumber.2","#m":"MonthNumber",B:"MonthName",b:"AbbrMonthName",d:"Date.2",!
"#d":"Date",e:"Date",A:"DayName",a:"AbbrDayName",w:"Day",H:"Hours.2","#H":"Hours",I:"Hours12.2","#I":"Hours12",p:"AMPM",M:"Minutes.2","#M":"Minutes",S:"Seconds.2","#S":"Seconds",s:"Unix",N:"Milliseconds.3","#N":"Milliseconds",O:"TimezoneOffset",Z:"TimezoneName",G:"GmtOffset"},shortcuts:{F:"%Y-%m-%d",T:"%H:%M:%S",X:"%H:%M:%S",x:"%m/%d/%y",D:"%m/%d/%y","#c":"%a %b %e %H:%M:%S %Y",v:"%e-%b-%Y",R:"%H:%M",r:"%I:%M:%S %p",t:"\t",n:"\n","%":"%"}};ag.formats.php={codes:{matcher:/()%((%|[a-z]))/i,a:"AbbrDayName",A:"DayName",d:"Date.2",e:"Date",j:"DayOfYear.3",u:"DayOfWeek",w:"Day",U:"FullWeekOfYear.2",V:"IsoWeek.2",W:"WeekOfYear.2",b:"AbbrMonthName",B:"MonthName",m:"MonthNumber.2",h:"AbbrMonthName",C:"Century.2",y:"ShortYear.2",Y:"FullYear",H:"Hours.2",I:"Hours12.2",l:"Hours12",p:"AMPM",P:"AmPm",M:"Minutes.2",S:"Seconds.2",s:"Unix",O:"TimezoneOffset",z:"GmtOffset",Z:"TimezoneAbbr"},shortcuts:{D:"%m/%d/%y",F:"%Y-%m-%d",T:"%H:%M:%S",X:"%H:%M:%S",x:"%m/%d/%y",R:"%H:%M",r:"%I:%M:%S %p",t:"\t",n:"\n","%":"%"}};ag.createDate=function(aj){if(aj==null){return new Date()}if(aj instanceof Date){return aj}if(typeof aj=="number"){return new Date(aj)}var ao=String(aj).replace(/^\s*(.+)\s*$/g,"$1");ao=ao.replace(/^([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,4})/,"$1/$2/$3");ao=ao.replace(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{4})/i,"$1 $2 $3");var an=ao.match(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{2})\D*/i);if(an&&an.length>3){var at=parseFloat(an[3]);var am=ag.config.defaultCentury+at;am=String(am);ao=ao.replace(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{2})\D*/i,an[1]+" "+an[2]+" "+am)}an=ao.match(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})[^0-9]/);function ar(ax,aw){var aC=parseFloat(aw[1]);var aB=parseFloat(aw[2]);var aA=parseFloat(aw[3]);var az=ag.config.defaultCentury;var av,au,aD,ay;if(aC>31){au=aA;aD=aB;av=az+aC}else{au=aB;aD=aC;av=az+aA}ay=aD+"/"+au+"/"+av;return ax.replace(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})/,ay)}if(an&&an.length>3){ao=ar(ao,an)}var an=ao.match(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2}!
)$/);if(an&&an.length>3){ao=ar(ao,an)}var al=0;var ai=ag.matchers.length;var aq,ah,ap=ao,ak;while(al<ai){ah=Date.parse(ap);if(!isNaN(ah)){return new Date(ah)}aq=ag.matchers[al];if(typeof aq=="function"){ak=aq.call(ag,ap);if(ak instanceof Date){return ak}}else{ap=ao.replace(aq[0],aq[1])}al++}return NaN};ag.daysInMonth=function(ah,ai){if(ai==2){return new Date(ah,1,29).getDate()==29?29:28}return[u,31,u,31,30,31,30,31,31,30,31,30,31][ai]};ag.matchers=[[/(3[01]|[0-2]\d)\s*\.\s*(1[0-2]|0\d)\s*\.\s*([1-9]\d{3})/,"$2/$1/$3"],[/([1-9]\d{3})\s*-\s*(1[0-2]|0\d)\s*-\s*(3[01]|[0-2]\d)/,"$2/$3/$1"],function(ak){var ai=ak.match(/^(?:(.+)\s+)?([012]?\d)(?:\s*\:\s*(\d\d))?(?:\s*\:\s*(\d\d(\.\d*)?))?\s*(am|pm)?\s*$/i);if(ai){if(ai[1]){var aj=this.createDate(ai[1]);if(isNaN(aj)){return}}else{var aj=new Date();aj.setMilliseconds(0)}var ah=parseFloat(ai[2]);if(ai[6]){ah=ai[6].toLowerCase()=="am"?(ah==12?0:ah):(ah==12?12:ah+12)}aj.setHours(ah,parseInt(ai[3]||0,10),parseInt(ai[4]||0,10),((parseFloat(ai[5]||0))||0)*1000);return aj}else{return ak}},function(ak){var ai=ak.match(/^(?:(.+))[T|\s+]([012]\d)(?:\:(\d\d))(?:\:(\d\d))(?:\.\d+)([\+\-]\d\d\:\d\d)$/i);if(ai){if(ai[1]){var aj=this.createDate(ai[1]);if(isNaN(aj)){return}}else{var aj=new Date();aj.setMilliseconds(0)}var ah=parseFloat(ai[2]);aj.setHours(ah,parseInt(ai[3],10),parseInt(ai[4],10),parseFloat(ai[5])*1000);return aj}else{return ak}},function(al){var aj=al.match(/^([0-3]?\d)\s*[-\/.\s]{1}\s*([a-zA-Z]{3,9})\s*[-\/.\s]{1}\s*([0-3]?\d)$/);if(aj){var ak=new Date();var am=ag.config.defaultCentury;var ao=parseFloat(aj[1]);var an=parseFloat(aj[3]);var ai,ah,ap;if(ao>31){ah=an;ai=am+ao}else{ah=ao;ai=am+an}var ap=ab(aj[2],ag.regional[ag.regional.getLocale()]["monthNamesShort"]);if(ap==-1){ap=ab(aj[2],ag.regional[ag.regional.getLocale()]["monthNames"])}ak.setFullYear(ai,ap,ah);ak.setHours(0,0,0,0);return ak}else{return al}}];function ab(aj,ak){if(ak.indexOf){return ak.indexOf(aj)}for(var ah=0,ai=ak.length;ah<ai;ah++){if(ak[ah]===aj){return ah}}return -1}function l(ah){if(ah===null){r!
eturn"[object Null]"}return Object.prototype.toString.call(ah)}L.jsDate=ag;L.jqplot.sprintf=function(){function an(au,ap,aq,at){var ar=(au.length>=ap)?"":Array(1+ap-au.length>>>0).join(aq);return at?au+ar:ar+au}function ak(ar){var aq=new String(ar);for(var ap=10;ap>0;ap--){if(aq==(aq=aq.replace(/^(\d+)(\d{3})/,"$1"+L.jqplot.sprintf.thousandsSeparator+"$2"))){break}}return aq}function aj(av,au,ax,ar,at,aq){var aw=ar-av.length;if(aw>0){var ap=" ";if(aq){ap=" "}if(ax||!at){av=an(av,ar,ap,ax)}else{av=av.slice(0,au.length)+an("",aw,"0",true)+av.slice(au.length)}}return av}function ao(ay,aq,aw,ar,ap,av,ax,au){var at=ay>>>0;aw=aw&&at&&{"2":"0b","8":"0","16":"0x"}[aq]||"";ay=aw+an(at.toString(aq),av||0,"0",false);return aj(ay,aw,ar,ap,ax,au)}function ah(au,av,ar,ap,at,aq){if(ap!=null){au=au.slice(0,ap)}return aj(au,"",av,ar,at,aq)}var ai=arguments,al=0,am=ai[al++];return am.replace(L.jqplot.sprintf.regex,function(aM,ax,ay,aB,aO,aJ,av){if(aM=="%%"){return"%"}var aD=false,az="",aA=false,aL=false,aw=false,au=false;for(var aI=0;ay&&aI<ay.length;aI++){switch(ay.charAt(aI)){case" ":az=" ";break;case"+":az="+";break;case"-":aD=true;break;case"0":aA=true;break;case"#":aL=true;break;case"&":aw=true;break;case"'":au=true;break}}if(!aB){aB=0}else{if(aB=="*"){aB=+ai[al++]}else{if(aB.charAt(0)=="*"){aB=+ai[aB.slice(1,-1)]}else{aB=+aB}}}if(aB<0){aB=-aB;aD=true}if(!isFinite(aB)){throw new Error("$.jqplot.sprintf: (minimum-)width must be finite")}if(!aJ){aJ="fFeE".indexOf(av)>-1?6:(av=="d")?0:void (0)}else{if(aJ=="*"){aJ=+ai[al++]}else{if(aJ.charAt(0)=="*"){aJ=+ai[aJ.slice(1,-1)]}else{aJ=+aJ}}}var aF=ax?ai[ax.slice(0,-1)]:ai[al++];switch(av){case"s":if(aF==null){return""}return ah(String(aF),aD,aB,aJ,aA,aw);case"c":return ah(String.fromCharCode(+aF),aD,aB,aJ,aA,aw);case"b":return ao(aF,2,aL,aD,aB,aJ,aA,aw);case"o":return ao(aF,8,aL,aD,aB,aJ,aA,aw);case"x":return ao(aF,16,aL,aD,aB,aJ,aA,aw);case"X":return ao(aF,16,aL,aD,aB,aJ,aA,aw).toUpperCase();case"u":return ao(aF,10,aL,aD,aB,aJ,aA,aw);case"i":var ar=parseInt(+aF,10);if(isNaN(ar!
)){return""}var aH=ar<0?"-":az;var aK=au?ak(String(Math.abs(ar))):String(Math.abs(ar));aF=aH+an(aK,aJ,"0",false);return aj(aF,aH,aD,aB,aA,aw);case"d":var ar=Math.round(+aF);if(isNaN(ar)){return""}var aH=ar<0?"-":az;var aK=au?ak(String(Math.abs(ar))):String(Math.abs(ar));aF=aH+an(aK,aJ,"0",false);return aj(aF,aH,aD,aB,aA,aw);case"e":case"E":case"f":case"F":case"g":case"G":var ar=+aF;if(isNaN(ar)){return""}var aH=ar<0?"-":az;var at=["toExponential","toFixed","toPrecision"]["efg".indexOf(av.toLowerCase())];var aN=["toString","toUpperCase"]["eEfFgG".indexOf(av)%2];var aK=Math.abs(ar)[at](aJ);aK=au?ak(aK):aK;aF=aH+aK;var aC=aj(aF,aH,aD,aB,aA,aw)[aN]();if(L.jqplot.sprintf.decimalMark!=="."&&L.jqplot.sprintf.decimalMark!==L.jqplot.sprintf.thousandsSeparator){return aC.replace(/\./,L.jqplot.sprintf.decimalMark)}else{return aC}case"p":case"P":var ar=+aF;if(isNaN(ar)){return""}var aH=ar<0?"-":az;var aE=String(Number(Math.abs(ar)).toExponential()).split(/e|E/);var aq=(aE[0].indexOf(".")!=-1)?aE[0].length-1:aE[0].length;var aG=(aE[1]<0)?-aE[1]-1:0;if(Math.abs(ar)<1){if(aq+aG<=aJ){aF=aH+Math.abs(ar).toPrecision(aq)}else{if(aq<=aJ-1){aF=aH+Math.abs(ar).toExponential(aq-1)}else{aF=aH+Math.abs(ar).toExponential(aJ-1)}}}else{var ap=(aq<=aJ)?aq:aJ;aF=aH+Math.abs(ar).toPrecision(ap)}var aN=["toString","toUpperCase"]["pP".indexOf(av)%2];return aj(aF,aH,aD,aB,aA,aw)[aN]();case"n":return"";default:return aM}})};L.jqplot.sprintf.thousandsSeparator=",";L.jqplot.sprintf.decimalMark=".";L.jqplot.sprintf.regex=/%%|%(\d+\$)?([-+#0&\' ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([nAscboxXuidfegpEGP])/g;L.jqplot.getSignificantFigures=function(al){var an=String(Number(Math.abs(al)).toExponential()).split(/e|E/);var am=(an[0].indexOf(".")!=-1)?an[0].length-1:an[0].length;var ai=(an[1]<0)?-an[1]-1:0;var ah=parseInt(an[1],10);var aj=(ah+1>0)?ah+1:0;var ak=(am<=aj)?0:am-ah-1;return{significantDigits:am,digitsLeft:aj,digitsRight:ak,zeros:ai,exponent:ah}};L.jqplot.getPrecision=function(ah){return L.jqplot.getSignificantFigures(ah).digitsRight};var X=L!
.uiBackCompat!==false;L.jqplot.effects={effect:{}};var m="jqplot.storage.";L.extend(L.jqplot.effects,{version:"1.9pre",save:function(ai,aj){for(var ah=0;ah<aj.length;ah++){if(aj[ah]!==null){ai.data(m+aj[ah],ai[0].style[aj[ah]])}}},restore:function(ai,aj){for(var ah=0;ah<aj.length;ah++){if(aj[ah]!==null){ai.css(aj[ah],ai.data(m+aj[ah]))}}},setMode:function(ah,ai){if(ai==="toggle"){ai=ah.is(":hidden")?"show":"hide"}return ai},createWrapper:function(ai){if(ai.parent().is(".ui-effects-wrapper")){return ai.parent()}var aj={width:ai.outerWidth(true),height:ai.outerHeight(true),"float":ai.css("float")},al=L("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),ah={width:ai.width(),height:ai.height()},ak=document.activeElement;ai.wrap(al);if(ai[0]===ak||L.contains(ai[0],ak)){L(ak).focus()}al=ai.parent();if(ai.css("position")==="static"){al.css({position:"relative"});ai.css({position:"relative"})}else{L.extend(aj,{position:ai.css("position"),zIndex:ai.css("z-index")});L.each(["top","left","bottom","right"],function(am,an){aj[an]=ai.css(an);if(isNaN(parseInt(aj[an],10))){aj[an]="auto"}});ai.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}ai.css(ah);return al.css(aj).show()},removeWrapper:function(ah){var ai=document.activeElement;if(ah.parent().is(".ui-effects-wrapper")){ah.parent().replaceWith(ah);if(ah[0]===ai||L.contains(ah[0],ai)){L(ai).focus()}}return ah}});function j(ai,ah,aj,ak){if(L.isPlainObject(ai)){return ai}ai={effect:ai};if(ah===u){ah={}}if(L.isFunction(ah)){ak=ah;aj=null;ah={}}if(L.type(ah)==="number"||L.fx.speeds[ah]){ak=aj;aj=ah;ah={}}if(L.isFunction(aj)){ak=aj;aj=null}if(ah){L.extend(ai,ah)}aj=aj||ah.duration;ai.duration=L.fx.off?0:typeof aj==="number"?aj:aj in L.fx.speeds?L.fx.speeds[aj]:L.fx.speeds._default;ai.complete=ak||ah.complete;return ai}function ae(ah){if(!ah||typeof ah==="number"||L.fx.speeds[ah]){return true}if(typeof ah==="string"&&!L.jqplot.effects.effect[ah]){if(X&&L.jqplot.effects[ah]){return false}!
return true}return false}L.fn.extend({jqplotEffect:function(ap,aq,ai,ao){var an=j.apply(this,arguments),ak=an.mode,al=an.queue,am=L.jqplot.effects.effect[an.effect],ah=!am&&X&&L.jqplot.effects[an.effect];if(L.fx.off||!(am||ah)){if(ak){return this[ak](an.duration,an.complete)}else{return this.each(function(){if(an.complete){an.complete.call(this)}})}}function aj(au){var av=L(this),at=an.complete,aw=an.mode;function ar(){if(L.isFunction(at)){at.call(av[0])}if(L.isFunction(au)){au()}}if(av.is(":hidden")?aw==="hide":aw==="show"){ar()}else{am.call(av[0],an,ar)}}if(am){return al===false?this.each(aj):this.queue(al||"fx",aj)}else{return ah.call(this,{options:an,duration:an.duration,callback:an.complete,mode:an.mode})}}});var a=/up|down|vertical/,v=/up|left|vertical|horizontal/;L.jqplot.effects.effect.blind=function(aj,ao){var ak=L(this),ar=["position","top","bottom","left","right","height","width"],ap=L.jqplot.effects.setMode(ak,aj.mode||"hide"),au=aj.direction||"up",am=a.test(au),al=am?"height":"width",aq=am?"top":"left",aw=v.test(au),an={},av=ap==="show",ai,ah,at;if(ak.parent().is(".ui-effects-wrapper")){L.jqplot.effects.save(ak.parent(),ar)}else{L.jqplot.effects.save(ak,ar)}ak.show();at=parseInt(ak.css("top"),10);ai=L.jqplot.effects.createWrapper(ak).css({overflow:"hidden"});ah=am?ai[al]()+at:ai[al]();an[al]=av?String(ah):"0";if(!aw){ak.css(am?"bottom":"right",0).css(am?"top":"left","").css({position:"absolute"});an[aq]=av?"0":String(ah)}if(av){ai.css(al,0);if(!aw){ai.css(aq,ah)}}ai.animate(an,{duration:aj.duration,easing:aj.easing,queue:false,complete:function(){if(ap==="hide"){ak.hide()}L.jqplot.effects.restore(ak,ar);L.jqplot.effects.removeWrapper(ak);ao()}})}})(jQuery);
\ No newline at end of file
Added: gnucash/trunk/src/report/jqplot/jquery.js
===================================================================
--- gnucash/trunk/src/report/jqplot/jquery.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/jquery.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,9597 @@
+/*!
+ * jQuery JavaScript Library v1.9.1
+ * http://jquery.com/
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ *
+ * Copyright 2005, 2012 jQuery Foundation, Inc. and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2013-2-4
+ */
+(function( window, undefined ) {
+
+// Can't do this because several apps including ASP.NET trace
+// the stack via arguments.caller.callee and Firefox dies if
+// you try to trace through "use strict" call chains. (#13335)
+// Support: Firefox 18+
+//"use strict";
+var
+ // The deferred used on DOM ready
+ readyList,
+
+ // A central reference to the root jQuery(document)
+ rootjQuery,
+
+ // Support: IE<9
+ // For `typeof node.method` instead of `node.method !== undefined`
+ core_strundefined = typeof undefined,
+
+ // Use the correct document accordingly with window argument (sandbox)
+ document = window.document,
+ location = window.location,
+
+ // Map over jQuery in case of overwrite
+ _jQuery = window.jQuery,
+
+ // Map over the $ in case of overwrite
+ _$ = window.$,
+
+ // [[Class]] -> type pairs
+ class2type = {},
+
+ // List of deleted data cache ids, so we can reuse them
+ core_deletedIds = [],
+
+ core_version = "1.9.1",
+
+ // Save a reference to some core methods
+ core_concat = core_deletedIds.concat,
+ core_push = core_deletedIds.push,
+ core_slice = core_deletedIds.slice,
+ core_indexOf = core_deletedIds.indexOf,
+ core_toString = class2type.toString,
+ core_hasOwn = class2type.hasOwnProperty,
+ core_trim = core_version.trim,
+
+ // Define a local copy of jQuery
+ jQuery = function( selector, context ) {
+ // The jQuery object is actually just the init constructor 'enhanced'
+ return new jQuery.fn.init( selector, context, rootjQuery );
+ },
+
+ // Used for matching numbers
+ core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,
+
+ // Used for splitting on whitespace
+ core_rnotwhite = /\S+/g,
+
+ // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)
+ rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
+
+ // A simple way to check for HTML strings
+ // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
+ // Strict HTML recognition (#11290: must start with <)
+ rquickExpr = /^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,
+
+ // Match a standalone tag
+ rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
+
+ // JSON RegExp
+ rvalidchars = /^[\],:{}\s]*$/,
+ rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
+ rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,
+ rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,
+
+ // Matches dashed string for camelizing
+ rmsPrefix = /^-ms-/,
+ rdashAlpha = /-([\da-z])/gi,
+
+ // Used by jQuery.camelCase as callback to replace()
+ fcamelCase = function( all, letter ) {
+ return letter.toUpperCase();
+ },
+
+ // The ready event handler
+ completed = function( event ) {
+
+ // readyState === "complete" is good enough for us to call the dom ready in oldIE
+ if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
+ detach();
+ jQuery.ready();
+ }
+ },
+ // Clean-up method for dom ready events
+ detach = function() {
+ if ( document.addEventListener ) {
+ document.removeEventListener( "DOMContentLoaded", completed, false );
+ window.removeEventListener( "load", completed, false );
+
+ } else {
+ document.detachEvent( "onreadystatechange", completed );
+ window.detachEvent( "onload", completed );
+ }
+ };
+
+jQuery.fn = jQuery.prototype = {
+ // The current version of jQuery being used
+ jquery: core_version,
+
+ constructor: jQuery,
+ init: function( selector, context, rootjQuery ) {
+ var match, elem;
+
+ // HANDLE: $(""), $(null), $(undefined), $(false)
+ if ( !selector ) {
+ return this;
+ }
+
+ // Handle HTML strings
+ if ( typeof selector === "string" ) {
+ if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
+ // Assume that strings that start and end with <> are HTML and skip the regex check
+ match = [ null, selector, null ];
+
+ } else {
+ match = rquickExpr.exec( selector );
+ }
+
+ // Match html or make sure no context is specified for #id
+ if ( match && (match[1] || !context) ) {
+
+ // HANDLE: $(html) -> $(array)
+ if ( match[1] ) {
+ context = context instanceof jQuery ? context[0] : context;
+
+ // scripts is true for back-compat
+ jQuery.merge( this, jQuery.parseHTML(
+ match[1],
+ context && context.nodeType ? context.ownerDocument || context : document,
+ true
+ ) );
+
+ // HANDLE: $(html, props)
+ if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
+ for ( match in context ) {
+ // Properties of context are called as methods if possible
+ if ( jQuery.isFunction( this[ match ] ) ) {
+ this[ match ]( context[ match ] );
+
+ // ...and otherwise set as attributes
+ } else {
+ this.attr( match, context[ match ] );
+ }
+ }
+ }
+
+ return this;
+
+ // HANDLE: $(#id)
+ } else {
+ elem = document.getElementById( match[2] );
+
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ if ( elem && elem.parentNode ) {
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( elem.id !== match[2] ) {
+ return rootjQuery.find( selector );
+ }
+
+ // Otherwise, we inject the element directly into the jQuery object
+ this.length = 1;
+ this[0] = elem;
+ }
+
+ this.context = document;
+ this.selector = selector;
+ return this;
+ }
+
+ // HANDLE: $(expr, $(...))
+ } else if ( !context || context.jquery ) {
+ return ( context || rootjQuery ).find( selector );
+
+ // HANDLE: $(expr, context)
+ // (which is just equivalent to: $(context).find(expr)
+ } else {
+ return this.constructor( context ).find( selector );
+ }
+
+ // HANDLE: $(DOMElement)
+ } else if ( selector.nodeType ) {
+ this.context = this[0] = selector;
+ this.length = 1;
+ return this;
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( jQuery.isFunction( selector ) ) {
+ return rootjQuery.ready( selector );
+ }
+
+ if ( selector.selector !== undefined ) {
+ this.selector = selector.selector;
+ this.context = selector.context;
+ }
+
+ return jQuery.makeArray( selector, this );
+ },
+
+ // Start with an empty selector
+ selector: "",
+
+ // The default length of a jQuery object is 0
+ length: 0,
+
+ // The number of elements contained in the matched element set
+ size: function() {
+ return this.length;
+ },
+
+ toArray: function() {
+ return core_slice.call( this );
+ },
+
+ // Get the Nth element in the matched element set OR
+ // Get the whole matched element set as a clean array
+ get: function( num ) {
+ return num == null ?
+
+ // Return a 'clean' array
+ this.toArray() :
+
+ // Return just the object
+ ( num < 0 ? this[ this.length + num ] : this[ num ] );
+ },
+
+ // Take an array of elements and push it onto the stack
+ // (returning the new matched element set)
+ pushStack: function( elems ) {
+
+ // Build a new jQuery matched element set
+ var ret = jQuery.merge( this.constructor(), elems );
+
+ // Add the old object onto the stack (as a reference)
+ ret.prevObject = this;
+ ret.context = this.context;
+
+ // Return the newly-formed element set
+ return ret;
+ },
+
+ // Execute a callback for every element in the matched set.
+ // (You can seed the arguments with an array of args, but this is
+ // only used internally.)
+ each: function( callback, args ) {
+ return jQuery.each( this, callback, args );
+ },
+
+ ready: function( fn ) {
+ // Add the callback
+ jQuery.ready.promise().done( fn );
+
+ return this;
+ },
+
+ slice: function() {
+ return this.pushStack( core_slice.apply( this, arguments ) );
+ },
+
+ first: function() {
+ return this.eq( 0 );
+ },
+
+ last: function() {
+ return this.eq( -1 );
+ },
+
+ eq: function( i ) {
+ var len = this.length,
+ j = +i + ( i < 0 ? len : 0 );
+ return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
+ },
+
+ map: function( callback ) {
+ return this.pushStack( jQuery.map(this, function( elem, i ) {
+ return callback.call( elem, i, elem );
+ }));
+ },
+
+ end: function() {
+ return this.prevObject || this.constructor(null);
+ },
+
+ // For internal use only.
+ // Behaves like an Array's method, not like a jQuery method.
+ push: core_push,
+ sort: [].sort,
+ splice: [].splice
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+jQuery.extend = jQuery.fn.extend = function() {
+ var src, copyIsArray, copy, name, options, clone,
+ target = arguments[0] || {},
+ i = 1,
+ length = arguments.length,
+ deep = false;
+
+ // Handle a deep copy situation
+ if ( typeof target === "boolean" ) {
+ deep = target;
+ target = arguments[1] || {};
+ // skip the boolean and the target
+ i = 2;
+ }
+
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+ target = {};
+ }
+
+ // extend jQuery itself if only one argument is passed
+ if ( length === i ) {
+ target = this;
+ --i;
+ }
+
+ for ( ; i < length; i++ ) {
+ // Only deal with non-null/undefined values
+ if ( (options = arguments[ i ]) != null ) {
+ // Extend the base object
+ for ( name in options ) {
+ src = target[ name ];
+ copy = options[ name ];
+
+ // Prevent never-ending loop
+ if ( target === copy ) {
+ continue;
+ }
+
+ // Recurse if we're merging plain objects or arrays
+ if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
+ if ( copyIsArray ) {
+ copyIsArray = false;
+ clone = src && jQuery.isArray(src) ? src : [];
+
+ } else {
+ clone = src && jQuery.isPlainObject(src) ? src : {};
+ }
+
+ // Never move original objects, clone them
+ target[ name ] = jQuery.extend( deep, clone, copy );
+
+ // Don't bring in undefined values
+ } else if ( copy !== undefined ) {
+ target[ name ] = copy;
+ }
+ }
+ }
+ }
+
+ // Return the modified object
+ return target;
+};
+
+jQuery.extend({
+ noConflict: function( deep ) {
+ if ( window.$ === jQuery ) {
+ window.$ = _$;
+ }
+
+ if ( deep && window.jQuery === jQuery ) {
+ window.jQuery = _jQuery;
+ }
+
+ return jQuery;
+ },
+
+ // Is the DOM ready to be used? Set to true once it occurs.
+ isReady: false,
+
+ // A counter to track how many items to wait for before
+ // the ready event fires. See #6781
+ readyWait: 1,
+
+ // Hold (or release) the ready event
+ holdReady: function( hold ) {
+ if ( hold ) {
+ jQuery.readyWait++;
+ } else {
+ jQuery.ready( true );
+ }
+ },
+
+ // Handle when the DOM is ready
+ ready: function( wait ) {
+
+ // Abort if there are pending holds or we're already ready
+ if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
+ return;
+ }
+
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+ if ( !document.body ) {
+ return setTimeout( jQuery.ready );
+ }
+
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If a normal DOM Ready event fired, decrement, and wait if need be
+ if ( wait !== true && --jQuery.readyWait > 0 ) {
+ return;
+ }
+
+ // If there are functions bound, to execute
+ readyList.resolveWith( document, [ jQuery ] );
+
+ // Trigger any bound ready events
+ if ( jQuery.fn.trigger ) {
+ jQuery( document ).trigger("ready").off("ready");
+ }
+ },
+
+ // See test/unit/core.js for details concerning isFunction.
+ // Since version 1.3, DOM methods and functions like alert
+ // aren't supported. They return false on IE (#2968).
+ isFunction: function( obj ) {
+ return jQuery.type(obj) === "function";
+ },
+
+ isArray: Array.isArray || function( obj ) {
+ return jQuery.type(obj) === "array";
+ },
+
+ isWindow: function( obj ) {
+ return obj != null && obj == obj.window;
+ },
+
+ isNumeric: function( obj ) {
+ return !isNaN( parseFloat(obj) ) && isFinite( obj );
+ },
+
+ type: function( obj ) {
+ if ( obj == null ) {
+ return String( obj );
+ }
+ return typeof obj === "object" || typeof obj === "function" ?
+ class2type[ core_toString.call(obj) ] || "object" :
+ typeof obj;
+ },
+
+ isPlainObject: function( obj ) {
+ // Must be an Object.
+ // Because of IE, we also have to check the presence of the constructor property.
+ // Make sure that DOM nodes and window objects don't pass through, as well
+ if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
+ return false;
+ }
+
+ try {
+ // Not own constructor property must be Object
+ if ( obj.constructor &&
+ !core_hasOwn.call(obj, "constructor") &&
+ !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
+ return false;
+ }
+ } catch ( e ) {
+ // IE8,9 Will throw exceptions on certain host objects #9897
+ return false;
+ }
+
+ // Own properties are enumerated firstly, so to speed up,
+ // if last one is own, then all properties are own.
+
+ var key;
+ for ( key in obj ) {}
+
+ return key === undefined || core_hasOwn.call( obj, key );
+ },
+
+ isEmptyObject: function( obj ) {
+ var name;
+ for ( name in obj ) {
+ return false;
+ }
+ return true;
+ },
+
+ error: function( msg ) {
+ throw new Error( msg );
+ },
+
+ // data: string of html
+ // context (optional): If specified, the fragment will be created in this context, defaults to document
+ // keepScripts (optional): If true, will include scripts passed in the html string
+ parseHTML: function( data, context, keepScripts ) {
+ if ( !data || typeof data !== "string" ) {
+ return null;
+ }
+ if ( typeof context === "boolean" ) {
+ keepScripts = context;
+ context = false;
+ }
+ context = context || document;
+
+ var parsed = rsingleTag.exec( data ),
+ scripts = !keepScripts && [];
+
+ // Single tag
+ if ( parsed ) {
+ return [ context.createElement( parsed[1] ) ];
+ }
+
+ parsed = jQuery.buildFragment( [ data ], context, scripts );
+ if ( scripts ) {
+ jQuery( scripts ).remove();
+ }
+ return jQuery.merge( [], parsed.childNodes );
+ },
+
+ parseJSON: function( data ) {
+ // Attempt to parse using the native JSON parser first
+ if ( window.JSON && window.JSON.parse ) {
+ return window.JSON.parse( data );
+ }
+
+ if ( data === null ) {
+ return data;
+ }
+
+ if ( typeof data === "string" ) {
+
+ // Make sure leading/trailing whitespace is removed (IE can't handle it)
+ data = jQuery.trim( data );
+
+ if ( data ) {
+ // Make sure the incoming data is actual JSON
+ // Logic borrowed from http://json.org/json2.js
+ if ( rvalidchars.test( data.replace( rvalidescape, "@" )
+ .replace( rvalidtokens, "]" )
+ .replace( rvalidbraces, "")) ) {
+
+ return ( new Function( "return " + data ) )();
+ }
+ }
+ }
+
+ jQuery.error( "Invalid JSON: " + data );
+ },
+
+ // Cross-browser xml parsing
+ parseXML: function( data ) {
+ var xml, tmp;
+ if ( !data || typeof data !== "string" ) {
+ return null;
+ }
+ try {
+ if ( window.DOMParser ) { // Standard
+ tmp = new DOMParser();
+ xml = tmp.parseFromString( data , "text/xml" );
+ } else { // IE
+ xml = new ActiveXObject( "Microsoft.XMLDOM" );
+ xml.async = "false";
+ xml.loadXML( data );
+ }
+ } catch( e ) {
+ xml = undefined;
+ }
+ if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
+ jQuery.error( "Invalid XML: " + data );
+ }
+ return xml;
+ },
+
+ noop: function() {},
+
+ // Evaluates a script in a global context
+ // Workarounds based on findings by Jim Driscoll
+ // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
+ globalEval: function( data ) {
+ if ( data && jQuery.trim( data ) ) {
+ // We use execScript on Internet Explorer
+ // We use an anonymous function so that context is window
+ // rather than jQuery in Firefox
+ ( window.execScript || function( data ) {
+ window[ "eval" ].call( window, data );
+ } )( data );
+ }
+ },
+
+ // Convert dashed to camelCase; used by the css and data modules
+ // Microsoft forgot to hump their vendor prefix (#9572)
+ camelCase: function( string ) {
+ return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
+ },
+
+ nodeName: function( elem, name ) {
+ return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
+ },
+
+ // args is for internal usage only
+ each: function( obj, callback, args ) {
+ var value,
+ i = 0,
+ length = obj.length,
+ isArray = isArraylike( obj );
+
+ if ( args ) {
+ if ( isArray ) {
+ for ( ; i < length; i++ ) {
+ value = callback.apply( obj[ i ], args );
+
+ if ( value === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( i in obj ) {
+ value = callback.apply( obj[ i ], args );
+
+ if ( value === false ) {
+ break;
+ }
+ }
+ }
+
+ // A special, fast, case for the most common use of each
+ } else {
+ if ( isArray ) {
+ for ( ; i < length; i++ ) {
+ value = callback.call( obj[ i ], i, obj[ i ] );
+
+ if ( value === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( i in obj ) {
+ value = callback.call( obj[ i ], i, obj[ i ] );
+
+ if ( value === false ) {
+ break;
+ }
+ }
+ }
+ }
+
+ return obj;
+ },
+
+ // Use native String.trim function wherever possible
+ trim: core_trim && !core_trim.call("\uFEFF\xA0") ?
+ function( text ) {
+ return text == null ?
+ "" :
+ core_trim.call( text );
+ } :
+
+ // Otherwise use our own trimming functionality
+ function( text ) {
+ return text == null ?
+ "" :
+ ( text + "" ).replace( rtrim, "" );
+ },
+
+ // results is for internal usage only
+ makeArray: function( arr, results ) {
+ var ret = results || [];
+
+ if ( arr != null ) {
+ if ( isArraylike( Object(arr) ) ) {
+ jQuery.merge( ret,
+ typeof arr === "string" ?
+ [ arr ] : arr
+ );
+ } else {
+ core_push.call( ret, arr );
+ }
+ }
+
+ return ret;
+ },
+
+ inArray: function( elem, arr, i ) {
+ var len;
+
+ if ( arr ) {
+ if ( core_indexOf ) {
+ return core_indexOf.call( arr, elem, i );
+ }
+
+ len = arr.length;
+ i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
+
+ for ( ; i < len; i++ ) {
+ // Skip accessing in sparse arrays
+ if ( i in arr && arr[ i ] === elem ) {
+ return i;
+ }
+ }
+ }
+
+ return -1;
+ },
+
+ merge: function( first, second ) {
+ var l = second.length,
+ i = first.length,
+ j = 0;
+
+ if ( typeof l === "number" ) {
+ for ( ; j < l; j++ ) {
+ first[ i++ ] = second[ j ];
+ }
+ } else {
+ while ( second[j] !== undefined ) {
+ first[ i++ ] = second[ j++ ];
+ }
+ }
+
+ first.length = i;
+
+ return first;
+ },
+
+ grep: function( elems, callback, inv ) {
+ var retVal,
+ ret = [],
+ i = 0,
+ length = elems.length;
+ inv = !!inv;
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( ; i < length; i++ ) {
+ retVal = !!callback( elems[ i ], i );
+ if ( inv !== retVal ) {
+ ret.push( elems[ i ] );
+ }
+ }
+
+ return ret;
+ },
+
+ // arg is for internal usage only
+ map: function( elems, callback, arg ) {
+ var value,
+ i = 0,
+ length = elems.length,
+ isArray = isArraylike( elems ),
+ ret = [];
+
+ // Go through the array, translating each of the items to their
+ if ( isArray ) {
+ for ( ; i < length; i++ ) {
+ value = callback( elems[ i ], i, arg );
+
+ if ( value != null ) {
+ ret[ ret.length ] = value;
+ }
+ }
+
+ // Go through every key on the object,
+ } else {
+ for ( i in elems ) {
+ value = callback( elems[ i ], i, arg );
+
+ if ( value != null ) {
+ ret[ ret.length ] = value;
+ }
+ }
+ }
+
+ // Flatten any nested arrays
+ return core_concat.apply( [], ret );
+ },
+
+ // A global GUID counter for objects
+ guid: 1,
+
+ // Bind a function to a context, optionally partially applying any
+ // arguments.
+ proxy: function( fn, context ) {
+ var args, proxy, tmp;
+
+ if ( typeof context === "string" ) {
+ tmp = fn[ context ];
+ context = fn;
+ fn = tmp;
+ }
+
+ // Quick check to determine if target is callable, in the spec
+ // this throws a TypeError, but we will just return undefined.
+ if ( !jQuery.isFunction( fn ) ) {
+ return undefined;
+ }
+
+ // Simulated bind
+ args = core_slice.call( arguments, 2 );
+ proxy = function() {
+ return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) );
+ };
+
+ // Set the guid of unique handler to the same of original handler, so it can be removed
+ proxy.guid = fn.guid = fn.guid || jQuery.guid++;
+
+ return proxy;
+ },
+
+ // Multifunctional method to get and set values of a collection
+ // The value/s can optionally be executed if it's a function
+ access: function( elems, fn, key, value, chainable, emptyGet, raw ) {
+ var i = 0,
+ length = elems.length,
+ bulk = key == null;
+
+ // Sets many values
+ if ( jQuery.type( key ) === "object" ) {
+ chainable = true;
+ for ( i in key ) {
+ jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
+ }
+
+ // Sets one value
+ } else if ( value !== undefined ) {
+ chainable = true;
+
+ if ( !jQuery.isFunction( value ) ) {
+ raw = true;
+ }
+
+ if ( bulk ) {
+ // Bulk operations run against the entire set
+ if ( raw ) {
+ fn.call( elems, value );
+ fn = null;
+
+ // ...except when executing function values
+ } else {
+ bulk = fn;
+ fn = function( elem, key, value ) {
+ return bulk.call( jQuery( elem ), value );
+ };
+ }
+ }
+
+ if ( fn ) {
+ for ( ; i < length; i++ ) {
+ fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
+ }
+ }
+ }
+
+ return chainable ?
+ elems :
+
+ // Gets
+ bulk ?
+ fn.call( elems ) :
+ length ? fn( elems[0], key ) : emptyGet;
+ },
+
+ now: function() {
+ return ( new Date() ).getTime();
+ }
+});
+
+jQuery.ready.promise = function( obj ) {
+ if ( !readyList ) {
+
+ readyList = jQuery.Deferred();
+
+ // Catch cases where $(document).ready() is called after the browser event has already occurred.
+ // we once tried to use readyState "interactive" here, but it caused issues like the one
+ // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
+ if ( document.readyState === "complete" ) {
+ // Handle it asynchronously to allow scripts the opportunity to delay ready
+ setTimeout( jQuery.ready );
+
+ // Standards-based browsers support DOMContentLoaded
+ } else if ( document.addEventListener ) {
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", completed, false );
+
+ // A fallback to window.onload, that will always work
+ window.addEventListener( "load", completed, false );
+
+ // If IE event model is used
+ } else {
+ // Ensure firing before onload, maybe late but safe also for iframes
+ document.attachEvent( "onreadystatechange", completed );
+
+ // A fallback to window.onload, that will always work
+ window.attachEvent( "onload", completed );
+
+ // If IE and not a frame
+ // continually check to see if the document is ready
+ var top = false;
+
+ try {
+ top = window.frameElement == null && document.documentElement;
+ } catch(e) {}
+
+ if ( top && top.doScroll ) {
+ (function doScrollCheck() {
+ if ( !jQuery.isReady ) {
+
+ try {
+ // Use the trick by Diego Perini
+ // http://javascript.nwbox.com/IEContentLoaded/
+ top.doScroll("left");
+ } catch(e) {
+ return setTimeout( doScrollCheck, 50 );
+ }
+
+ // detach all dom ready events
+ detach();
+
+ // and execute any waiting functions
+ jQuery.ready();
+ }
+ })();
+ }
+ }
+ }
+ return readyList.promise( obj );
+};
+
+// Populate the class2type map
+jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
+ class2type[ "[object " + name + "]" ] = name.toLowerCase();
+});
+
+function isArraylike( obj ) {
+ var length = obj.length,
+ type = jQuery.type( obj );
+
+ if ( jQuery.isWindow( obj ) ) {
+ return false;
+ }
+
+ if ( obj.nodeType === 1 && length ) {
+ return true;
+ }
+
+ return type === "array" || type !== "function" &&
+ ( length === 0 ||
+ typeof length === "number" && length > 0 && ( length - 1 ) in obj );
+}
+
+// All jQuery objects should point back to these
+rootjQuery = jQuery(document);
+// String to Object options format cache
+var optionsCache = {};
+
+// Convert String-formatted options into Object-formatted ones and store in cache
+function createOptions( options ) {
+ var object = optionsCache[ options ] = {};
+ jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) {
+ object[ flag ] = true;
+ });
+ return object;
+}
+
+/*
+ * Create a callback list using the following parameters:
+ *
+ * options: an optional list of space-separated options that will change how
+ * the callback list behaves or a more traditional option object
+ *
+ * By default a callback list will act like an event callback list and can be
+ * "fired" multiple times.
+ *
+ * Possible options:
+ *
+ * once: will ensure the callback list can only be fired once (like a Deferred)
+ *
+ * memory: will keep track of previous values and will call any callback added
+ * after the list has been fired right away with the latest "memorized"
+ * values (like a Deferred)
+ *
+ * unique: will ensure a callback can only be added once (no duplicate in the list)
+ *
+ * stopOnFalse: interrupt callings when a callback returns false
+ *
+ */
+jQuery.Callbacks = function( options ) {
+
+ // Convert options from String-formatted to Object-formatted if needed
+ // (we check in cache first)
+ options = typeof options === "string" ?
+ ( optionsCache[ options ] || createOptions( options ) ) :
+ jQuery.extend( {}, options );
+
+ var // Flag to know if list is currently firing
+ firing,
+ // Last fire value (for non-forgettable lists)
+ memory,
+ // Flag to know if list was already fired
+ fired,
+ // End of the loop when firing
+ firingLength,
+ // Index of currently firing callback (modified by remove if needed)
+ firingIndex,
+ // First callback to fire (used internally by add and fireWith)
+ firingStart,
+ // Actual callback list
+ list = [],
+ // Stack of fire calls for repeatable lists
+ stack = !options.once && [],
+ // Fire callbacks
+ fire = function( data ) {
+ memory = options.memory && data;
+ fired = true;
+ firingIndex = firingStart || 0;
+ firingStart = 0;
+ firingLength = list.length;
+ firing = true;
+ for ( ; list && firingIndex < firingLength; firingIndex++ ) {
+ if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
+ memory = false; // To prevent further calls using add
+ break;
+ }
+ }
+ firing = false;
+ if ( list ) {
+ if ( stack ) {
+ if ( stack.length ) {
+ fire( stack.shift() );
+ }
+ } else if ( memory ) {
+ list = [];
+ } else {
+ self.disable();
+ }
+ }
+ },
+ // Actual Callbacks object
+ self = {
+ // Add a callback or a collection of callbacks to the list
+ add: function() {
+ if ( list ) {
+ // First, we save the current length
+ var start = list.length;
+ (function add( args ) {
+ jQuery.each( args, function( _, arg ) {
+ var type = jQuery.type( arg );
+ if ( type === "function" ) {
+ if ( !options.unique || !self.has( arg ) ) {
+ list.push( arg );
+ }
+ } else if ( arg && arg.length && type !== "string" ) {
+ // Inspect recursively
+ add( arg );
+ }
+ });
+ })( arguments );
+ // Do we need to add the callbacks to the
+ // current firing batch?
+ if ( firing ) {
+ firingLength = list.length;
+ // With memory, if we're not firing then
+ // we should call right away
+ } else if ( memory ) {
+ firingStart = start;
+ fire( memory );
+ }
+ }
+ return this;
+ },
+ // Remove a callback from the list
+ remove: function() {
+ if ( list ) {
+ jQuery.each( arguments, function( _, arg ) {
+ var index;
+ while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
+ list.splice( index, 1 );
+ // Handle firing indexes
+ if ( firing ) {
+ if ( index <= firingLength ) {
+ firingLength--;
+ }
+ if ( index <= firingIndex ) {
+ firingIndex--;
+ }
+ }
+ }
+ });
+ }
+ return this;
+ },
+ // Check if a given callback is in the list.
+ // If no argument is given, return whether or not list has callbacks attached.
+ has: function( fn ) {
+ return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
+ },
+ // Remove all callbacks from the list
+ empty: function() {
+ list = [];
+ return this;
+ },
+ // Have the list do nothing anymore
+ disable: function() {
+ list = stack = memory = undefined;
+ return this;
+ },
+ // Is it disabled?
+ disabled: function() {
+ return !list;
+ },
+ // Lock the list in its current state
+ lock: function() {
+ stack = undefined;
+ if ( !memory ) {
+ self.disable();
+ }
+ return this;
+ },
+ // Is it locked?
+ locked: function() {
+ return !stack;
+ },
+ // Call all callbacks with the given context and arguments
+ fireWith: function( context, args ) {
+ args = args || [];
+ args = [ context, args.slice ? args.slice() : args ];
+ if ( list && ( !fired || stack ) ) {
+ if ( firing ) {
+ stack.push( args );
+ } else {
+ fire( args );
+ }
+ }
+ return this;
+ },
+ // Call all the callbacks with the given arguments
+ fire: function() {
+ self.fireWith( this, arguments );
+ return this;
+ },
+ // To know if the callbacks have already been called at least once
+ fired: function() {
+ return !!fired;
+ }
+ };
+
+ return self;
+};
+jQuery.extend({
+
+ Deferred: function( func ) {
+ var tuples = [
+ // action, add listener, listener list, final state
+ [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
+ [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
+ [ "notify", "progress", jQuery.Callbacks("memory") ]
+ ],
+ state = "pending",
+ promise = {
+ state: function() {
+ return state;
+ },
+ always: function() {
+ deferred.done( arguments ).fail( arguments );
+ return this;
+ },
+ then: function( /* fnDone, fnFail, fnProgress */ ) {
+ var fns = arguments;
+ return jQuery.Deferred(function( newDefer ) {
+ jQuery.each( tuples, function( i, tuple ) {
+ var action = tuple[ 0 ],
+ fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
+ // deferred[ done | fail | progress ] for forwarding actions to newDefer
+ deferred[ tuple[1] ](function() {
+ var returned = fn && fn.apply( this, arguments );
+ if ( returned && jQuery.isFunction( returned.promise ) ) {
+ returned.promise()
+ .done( newDefer.resolve )
+ .fail( newDefer.reject )
+ .progress( newDefer.notify );
+ } else {
+ newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
+ }
+ });
+ });
+ fns = null;
+ }).promise();
+ },
+ // Get a promise for this deferred
+ // If obj is provided, the promise aspect is added to the object
+ promise: function( obj ) {
+ return obj != null ? jQuery.extend( obj, promise ) : promise;
+ }
+ },
+ deferred = {};
+
+ // Keep pipe for back-compat
+ promise.pipe = promise.then;
+
+ // Add list-specific methods
+ jQuery.each( tuples, function( i, tuple ) {
+ var list = tuple[ 2 ],
+ stateString = tuple[ 3 ];
+
+ // promise[ done | fail | progress ] = list.add
+ promise[ tuple[1] ] = list.add;
+
+ // Handle state
+ if ( stateString ) {
+ list.add(function() {
+ // state = [ resolved | rejected ]
+ state = stateString;
+
+ // [ reject_list | resolve_list ].disable; progress_list.lock
+ }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
+ }
+
+ // deferred[ resolve | reject | notify ]
+ deferred[ tuple[0] ] = function() {
+ deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
+ return this;
+ };
+ deferred[ tuple[0] + "With" ] = list.fireWith;
+ });
+
+ // Make the deferred a promise
+ promise.promise( deferred );
+
+ // Call given func if any
+ if ( func ) {
+ func.call( deferred, deferred );
+ }
+
+ // All done!
+ return deferred;
+ },
+
+ // Deferred helper
+ when: function( subordinate /* , ..., subordinateN */ ) {
+ var i = 0,
+ resolveValues = core_slice.call( arguments ),
+ length = resolveValues.length,
+
+ // the count of uncompleted subordinates
+ remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
+
+ // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
+ deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
+
+ // Update function for both resolve and progress values
+ updateFunc = function( i, contexts, values ) {
+ return function( value ) {
+ contexts[ i ] = this;
+ values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;
+ if( values === progressValues ) {
+ deferred.notifyWith( contexts, values );
+ } else if ( !( --remaining ) ) {
+ deferred.resolveWith( contexts, values );
+ }
+ };
+ },
+
+ progressValues, progressContexts, resolveContexts;
+
+ // add listeners to Deferred subordinates; treat others as resolved
+ if ( length > 1 ) {
+ progressValues = new Array( length );
+ progressContexts = new Array( length );
+ resolveContexts = new Array( length );
+ for ( ; i < length; i++ ) {
+ if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
+ resolveValues[ i ].promise()
+ .done( updateFunc( i, resolveContexts, resolveValues ) )
+ .fail( deferred.reject )
+ .progress( updateFunc( i, progressContexts, progressValues ) );
+ } else {
+ --remaining;
+ }
+ }
+ }
+
+ // if we're not waiting on anything, resolve the master
+ if ( !remaining ) {
+ deferred.resolveWith( resolveContexts, resolveValues );
+ }
+
+ return deferred.promise();
+ }
+});
+jQuery.support = (function() {
+
+ var support, all, a,
+ input, select, fragment,
+ opt, eventName, isSupported, i,
+ div = document.createElement("div");
+
+ // Setup
+ div.setAttribute( "className", "t" );
+ div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
+
+ // Support tests won't run in some limited or non-browser environments
+ all = div.getElementsByTagName("*");
+ a = div.getElementsByTagName("a")[ 0 ];
+ if ( !all || !a || !all.length ) {
+ return {};
+ }
+
+ // First batch of tests
+ select = document.createElement("select");
+ opt = select.appendChild( document.createElement("option") );
+ input = div.getElementsByTagName("input")[ 0 ];
+
+ a.style.cssText = "top:1px;float:left;opacity:.5";
+ support = {
+ // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
+ getSetAttribute: div.className !== "t",
+
+ // IE strips leading whitespace when .innerHTML is used
+ leadingWhitespace: div.firstChild.nodeType === 3,
+
+ // Make sure that tbody elements aren't automatically inserted
+ // IE will insert them into empty tables
+ tbody: !div.getElementsByTagName("tbody").length,
+
+ // Make sure that link elements get serialized correctly by innerHTML
+ // This requires a wrapper element in IE
+ htmlSerialize: !!div.getElementsByTagName("link").length,
+
+ // Get the style information from getAttribute
+ // (IE uses .cssText instead)
+ style: /top/.test( a.getAttribute("style") ),
+
+ // Make sure that URLs aren't manipulated
+ // (IE normalizes it by default)
+ hrefNormalized: a.getAttribute("href") === "/a",
+
+ // Make sure that element opacity exists
+ // (IE uses filter instead)
+ // Use a regex to work around a WebKit issue. See #5145
+ opacity: /^0.5/.test( a.style.opacity ),
+
+ // Verify style float existence
+ // (IE uses styleFloat instead of cssFloat)
+ cssFloat: !!a.style.cssFloat,
+
+ // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
+ checkOn: !!input.value,
+
+ // Make sure that a selected-by-default option has a working selected property.
+ // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
+ optSelected: opt.selected,
+
+ // Tests for enctype support on a form (#6743)
+ enctype: !!document.createElement("form").enctype,
+
+ // Makes sure cloning an html5 element does not cause problems
+ // Where outerHTML is undefined, this still works
+ html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>",
+
+ // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode
+ boxModel: document.compatMode === "CSS1Compat",
+
+ // Will be defined later
+ deleteExpando: true,
+ noCloneEvent: true,
+ inlineBlockNeedsLayout: false,
+ shrinkWrapBlocks: false,
+ reliableMarginRight: true,
+ boxSizingReliable: true,
+ pixelPosition: false
+ };
+
+ // Make sure checked status is properly cloned
+ input.checked = true;
+ support.noCloneChecked = input.cloneNode( true ).checked;
+
+ // Make sure that the options inside disabled selects aren't marked as disabled
+ // (WebKit marks them as disabled)
+ select.disabled = true;
+ support.optDisabled = !opt.disabled;
+
+ // Support: IE<9
+ try {
+ delete div.test;
+ } catch( e ) {
+ support.deleteExpando = false;
+ }
+
+ // Check if we can trust getAttribute("value")
+ input = document.createElement("input");
+ input.setAttribute( "value", "" );
+ support.input = input.getAttribute( "value" ) === "";
+
+ // Check if an input maintains its value after becoming a radio
+ input.value = "t";
+ input.setAttribute( "type", "radio" );
+ support.radioValue = input.value === "t";
+
+ // #11217 - WebKit loses check when the name is after the checked attribute
+ input.setAttribute( "checked", "t" );
+ input.setAttribute( "name", "t" );
+
+ fragment = document.createDocumentFragment();
+ fragment.appendChild( input );
+
+ // Check if a disconnected checkbox will retain its checked
+ // value of true after appended to the DOM (IE6/7)
+ support.appendChecked = input.checked;
+
+ // WebKit doesn't clone checked state correctly in fragments
+ support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
+
+ // Support: IE<9
+ // Opera does not clone events (and typeof div.attachEvent === undefined).
+ // IE9-10 clones events bound via attachEvent, but they don't trigger with .click()
+ if ( div.attachEvent ) {
+ div.attachEvent( "onclick", function() {
+ support.noCloneEvent = false;
+ });
+
+ div.cloneNode( true ).click();
+ }
+
+ // Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event)
+ // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP), test/csp.php
+ for ( i in { submit: true, change: true, focusin: true }) {
+ div.setAttribute( eventName = "on" + i, "t" );
+
+ support[ i + "Bubbles" ] = eventName in window || div.attributes[ eventName ].expando === false;
+ }
+
+ div.style.backgroundClip = "content-box";
+ div.cloneNode( true ).style.backgroundClip = "";
+ support.clearCloneStyle = div.style.backgroundClip === "content-box";
+
+ // Run tests that need a body at doc ready
+ jQuery(function() {
+ var container, marginDiv, tds,
+ divReset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",
+ body = document.getElementsByTagName("body")[0];
+
+ if ( !body ) {
+ // Return for frameset docs that don't have a body
+ return;
+ }
+
+ container = document.createElement("div");
+ container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px";
+
+ body.appendChild( container ).appendChild( div );
+
+ // Support: IE8
+ // Check if table cells still have offsetWidth/Height when they are set
+ // to display:none and there are still other visible table cells in a
+ // table row; if so, offsetWidth/Height are not reliable for use when
+ // determining if an element has been hidden directly using
+ // display:none (it is still safe to use offsets if a parent element is
+ // hidden; don safety goggles and see bug #4512 for more information).
+ div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
+ tds = div.getElementsByTagName("td");
+ tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none";
+ isSupported = ( tds[ 0 ].offsetHeight === 0 );
+
+ tds[ 0 ].style.display = "";
+ tds[ 1 ].style.display = "none";
+
+ // Support: IE8
+ // Check if empty table cells still have offsetWidth/Height
+ support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
+
+ // Check box-sizing and margin behavior
+ div.innerHTML = "";
+ div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;";
+ support.boxSizing = ( div.offsetWidth === 4 );
+ support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 );
+
+ // Use window.getComputedStyle because jsdom on node.js will break without it.
+ if ( window.getComputedStyle ) {
+ support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
+ support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
+
+ // Check if div with explicit width and no margin-right incorrectly
+ // gets computed margin-right based on width of container. (#3333)
+ // Fails in WebKit before Feb 2011 nightlies
+ // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+ marginDiv = div.appendChild( document.createElement("div") );
+ marginDiv.style.cssText = div.style.cssText = divReset;
+ marginDiv.style.marginRight = marginDiv.style.width = "0";
+ div.style.width = "1px";
+
+ support.reliableMarginRight =
+ !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );
+ }
+
+ if ( typeof div.style.zoom !== core_strundefined ) {
+ // Support: IE<8
+ // Check if natively block-level elements act like inline-block
+ // elements when setting their display to 'inline' and giving
+ // them layout
+ div.innerHTML = "";
+ div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1";
+ support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );
+
+ // Support: IE6
+ // Check if elements with layout shrink-wrap their children
+ div.style.display = "block";
+ div.innerHTML = "<div></div>";
+ div.firstChild.style.width = "5px";
+ support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );
+
+ if ( support.inlineBlockNeedsLayout ) {
+ // Prevent IE 6 from affecting layout for positioned elements #11048
+ // Prevent IE from shrinking the body in IE 7 mode #12869
+ // Support: IE<8
+ body.style.zoom = 1;
+ }
+ }
+
+ body.removeChild( container );
+
+ // Null elements to avoid leaks in IE
+ container = div = tds = marginDiv = null;
+ });
+
+ // Null elements to avoid leaks in IE
+ all = select = fragment = opt = a = input = null;
+
+ return support;
+})();
+
+var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
+ rmultiDash = /([A-Z])/g;
+
+function internalData( elem, name, data, pvt /* Internal Use Only */ ){
+ if ( !jQuery.acceptData( elem ) ) {
+ return;
+ }
+
+ var thisCache, ret,
+ internalKey = jQuery.expando,
+ getByName = typeof name === "string",
+
+ // We have to handle DOM nodes and JS objects differently because IE6-7
+ // can't GC object references properly across the DOM-JS boundary
+ isNode = elem.nodeType,
+
+ // Only DOM nodes need the global jQuery cache; JS object data is
+ // attached directly to the object so GC can occur automatically
+ cache = isNode ? jQuery.cache : elem,
+
+ // Only defining an ID for JS objects if its cache already exists allows
+ // the code to shortcut on the same path as a DOM node with no cache
+ id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
+
+ // Avoid doing any more work than we need to when trying to get data on an
+ // object that has no data at all
+ if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) {
+ return;
+ }
+
+ if ( !id ) {
+ // Only DOM nodes need a new unique ID for each element since their data
+ // ends up in the global cache
+ if ( isNode ) {
+ elem[ internalKey ] = id = core_deletedIds.pop() || jQuery.guid++;
+ } else {
+ id = internalKey;
+ }
+ }
+
+ if ( !cache[ id ] ) {
+ cache[ id ] = {};
+
+ // Avoids exposing jQuery metadata on plain JS objects when the object
+ // is serialized using JSON.stringify
+ if ( !isNode ) {
+ cache[ id ].toJSON = jQuery.noop;
+ }
+ }
+
+ // An object can be passed to jQuery.data instead of a key/value pair; this gets
+ // shallow copied over onto the existing cache
+ if ( typeof name === "object" || typeof name === "function" ) {
+ if ( pvt ) {
+ cache[ id ] = jQuery.extend( cache[ id ], name );
+ } else {
+ cache[ id ].data = jQuery.extend( cache[ id ].data, name );
+ }
+ }
+
+ thisCache = cache[ id ];
+
+ // jQuery data() is stored in a separate object inside the object's internal data
+ // cache in order to avoid key collisions between internal data and user-defined
+ // data.
+ if ( !pvt ) {
+ if ( !thisCache.data ) {
+ thisCache.data = {};
+ }
+
+ thisCache = thisCache.data;
+ }
+
+ if ( data !== undefined ) {
+ thisCache[ jQuery.camelCase( name ) ] = data;
+ }
+
+ // Check for both converted-to-camel and non-converted data property names
+ // If a data property was specified
+ if ( getByName ) {
+
+ // First Try to find as-is property data
+ ret = thisCache[ name ];
+
+ // Test for null|undefined property data
+ if ( ret == null ) {
+
+ // Try to find the camelCased property
+ ret = thisCache[ jQuery.camelCase( name ) ];
+ }
+ } else {
+ ret = thisCache;
+ }
+
+ return ret;
+}
+
+function internalRemoveData( elem, name, pvt ) {
+ if ( !jQuery.acceptData( elem ) ) {
+ return;
+ }
+
+ var i, l, thisCache,
+ isNode = elem.nodeType,
+
+ // See jQuery.data for more information
+ cache = isNode ? jQuery.cache : elem,
+ id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
+
+ // If there is already no cache entry for this object, there is no
+ // purpose in continuing
+ if ( !cache[ id ] ) {
+ return;
+ }
+
+ if ( name ) {
+
+ thisCache = pvt ? cache[ id ] : cache[ id ].data;
+
+ if ( thisCache ) {
+
+ // Support array or space separated string names for data keys
+ if ( !jQuery.isArray( name ) ) {
+
+ // try the string as a key before any manipulation
+ if ( name in thisCache ) {
+ name = [ name ];
+ } else {
+
+ // split the camel cased version by spaces unless a key with the spaces exists
+ name = jQuery.camelCase( name );
+ if ( name in thisCache ) {
+ name = [ name ];
+ } else {
+ name = name.split(" ");
+ }
+ }
+ } else {
+ // If "name" is an array of keys...
+ // When data is initially created, via ("key", "val") signature,
+ // keys will be converted to camelCase.
+ // Since there is no way to tell _how_ a key was added, remove
+ // both plain key and camelCase key. #12786
+ // This will only penalize the array argument path.
+ name = name.concat( jQuery.map( name, jQuery.camelCase ) );
+ }
+
+ for ( i = 0, l = name.length; i < l; i++ ) {
+ delete thisCache[ name[i] ];
+ }
+
+ // If there is no data left in the cache, we want to continue
+ // and let the cache object itself get destroyed
+ if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) {
+ return;
+ }
+ }
+ }
+
+ // See jQuery.data for more information
+ if ( !pvt ) {
+ delete cache[ id ].data;
+
+ // Don't destroy the parent cache unless the internal data object
+ // had been the only thing left in it
+ if ( !isEmptyDataObject( cache[ id ] ) ) {
+ return;
+ }
+ }
+
+ // Destroy the cache
+ if ( isNode ) {
+ jQuery.cleanData( [ elem ], true );
+
+ // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
+ } else if ( jQuery.support.deleteExpando || cache != cache.window ) {
+ delete cache[ id ];
+
+ // When all else fails, null
+ } else {
+ cache[ id ] = null;
+ }
+}
+
+jQuery.extend({
+ cache: {},
+
+ // Unique for each copy of jQuery on the page
+ // Non-digits removed to match rinlinejQuery
+ expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ),
+
+ // The following elements throw uncatchable exceptions if you
+ // attempt to add expando properties to them.
+ noData: {
+ "embed": true,
+ // Ban all objects except for Flash (which handle expandos)
+ "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
+ "applet": true
+ },
+
+ hasData: function( elem ) {
+ elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
+ return !!elem && !isEmptyDataObject( elem );
+ },
+
+ data: function( elem, name, data ) {
+ return internalData( elem, name, data );
+ },
+
+ removeData: function( elem, name ) {
+ return internalRemoveData( elem, name );
+ },
+
+ // For internal use only.
+ _data: function( elem, name, data ) {
+ return internalData( elem, name, data, true );
+ },
+
+ _removeData: function( elem, name ) {
+ return internalRemoveData( elem, name, true );
+ },
+
+ // A method for determining if a DOM node can handle the data expando
+ acceptData: function( elem ) {
+ // Do not set data on non-element because it will not be cleared (#8335).
+ if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) {
+ return false;
+ }
+
+ var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ];
+
+ // nodes accept data unless otherwise specified; rejection can be conditional
+ return !noData || noData !== true && elem.getAttribute("classid") === noData;
+ }
+});
+
+jQuery.fn.extend({
+ data: function( key, value ) {
+ var attrs, name,
+ elem = this[0],
+ i = 0,
+ data = null;
+
+ // Gets all values
+ if ( key === undefined ) {
+ if ( this.length ) {
+ data = jQuery.data( elem );
+
+ if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
+ attrs = elem.attributes;
+ for ( ; i < attrs.length; i++ ) {
+ name = attrs[i].name;
+
+ if ( !name.indexOf( "data-" ) ) {
+ name = jQuery.camelCase( name.slice(5) );
+
+ dataAttr( elem, name, data[ name ] );
+ }
+ }
+ jQuery._data( elem, "parsedAttrs", true );
+ }
+ }
+
+ return data;
+ }
+
+ // Sets multiple values
+ if ( typeof key === "object" ) {
+ return this.each(function() {
+ jQuery.data( this, key );
+ });
+ }
+
+ return jQuery.access( this, function( value ) {
+
+ if ( value === undefined ) {
+ // Try to fetch any internally stored data first
+ return elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null;
+ }
+
+ this.each(function() {
+ jQuery.data( this, key, value );
+ });
+ }, null, value, arguments.length > 1, null, true );
+ },
+
+ removeData: function( key ) {
+ return this.each(function() {
+ jQuery.removeData( this, key );
+ });
+ }
+});
+
+function dataAttr( elem, key, data ) {
+ // If nothing was found internally, try to fetch any
+ // data from the HTML5 data-* attribute
+ if ( data === undefined && elem.nodeType === 1 ) {
+
+ var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
+
+ data = elem.getAttribute( name );
+
+ if ( typeof data === "string" ) {
+ try {
+ data = data === "true" ? true :
+ data === "false" ? false :
+ data === "null" ? null :
+ // Only convert to a number if it doesn't change the string
+ +data + "" === data ? +data :
+ rbrace.test( data ) ? jQuery.parseJSON( data ) :
+ data;
+ } catch( e ) {}
+
+ // Make sure we set the data so it isn't changed later
+ jQuery.data( elem, key, data );
+
+ } else {
+ data = undefined;
+ }
+ }
+
+ return data;
+}
+
+// checks a cache object for emptiness
+function isEmptyDataObject( obj ) {
+ var name;
+ for ( name in obj ) {
+
+ // if the public data object is empty, the private is still empty
+ if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
+ continue;
+ }
+ if ( name !== "toJSON" ) {
+ return false;
+ }
+ }
+
+ return true;
+}
+jQuery.extend({
+ queue: function( elem, type, data ) {
+ var queue;
+
+ if ( elem ) {
+ type = ( type || "fx" ) + "queue";
+ queue = jQuery._data( elem, type );
+
+ // Speed up dequeue by getting out quickly if this is just a lookup
+ if ( data ) {
+ if ( !queue || jQuery.isArray(data) ) {
+ queue = jQuery._data( elem, type, jQuery.makeArray(data) );
+ } else {
+ queue.push( data );
+ }
+ }
+ return queue || [];
+ }
+ },
+
+ dequeue: function( elem, type ) {
+ type = type || "fx";
+
+ var queue = jQuery.queue( elem, type ),
+ startLength = queue.length,
+ fn = queue.shift(),
+ hooks = jQuery._queueHooks( elem, type ),
+ next = function() {
+ jQuery.dequeue( elem, type );
+ };
+
+ // If the fx queue is dequeued, always remove the progress sentinel
+ if ( fn === "inprogress" ) {
+ fn = queue.shift();
+ startLength--;
+ }
+
+ hooks.cur = fn;
+ if ( fn ) {
+
+ // Add a progress sentinel to prevent the fx queue from being
+ // automatically dequeued
+ if ( type === "fx" ) {
+ queue.unshift( "inprogress" );
+ }
+
+ // clear up the last queue stop function
+ delete hooks.stop;
+ fn.call( elem, next, hooks );
+ }
+
+ if ( !startLength && hooks ) {
+ hooks.empty.fire();
+ }
+ },
+
+ // not intended for public consumption - generates a queueHooks object, or returns the current one
+ _queueHooks: function( elem, type ) {
+ var key = type + "queueHooks";
+ return jQuery._data( elem, key ) || jQuery._data( elem, key, {
+ empty: jQuery.Callbacks("once memory").add(function() {
+ jQuery._removeData( elem, type + "queue" );
+ jQuery._removeData( elem, key );
+ })
+ });
+ }
+});
+
+jQuery.fn.extend({
+ queue: function( type, data ) {
+ var setter = 2;
+
+ if ( typeof type !== "string" ) {
+ data = type;
+ type = "fx";
+ setter--;
+ }
+
+ if ( arguments.length < setter ) {
+ return jQuery.queue( this[0], type );
+ }
+
+ return data === undefined ?
+ this :
+ this.each(function() {
+ var queue = jQuery.queue( this, type, data );
+
+ // ensure a hooks for this queue
+ jQuery._queueHooks( this, type );
+
+ if ( type === "fx" && queue[0] !== "inprogress" ) {
+ jQuery.dequeue( this, type );
+ }
+ });
+ },
+ dequeue: function( type ) {
+ return this.each(function() {
+ jQuery.dequeue( this, type );
+ });
+ },
+ // Based off of the plugin by Clint Helfers, with permission.
+ // http://blindsignals.com/index.php/2009/07/jquery-delay/
+ delay: function( time, type ) {
+ time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
+ type = type || "fx";
+
+ return this.queue( type, function( next, hooks ) {
+ var timeout = setTimeout( next, time );
+ hooks.stop = function() {
+ clearTimeout( timeout );
+ };
+ });
+ },
+ clearQueue: function( type ) {
+ return this.queue( type || "fx", [] );
+ },
+ // Get a promise resolved when queues of a certain type
+ // are emptied (fx is the type by default)
+ promise: function( type, obj ) {
+ var tmp,
+ count = 1,
+ defer = jQuery.Deferred(),
+ elements = this,
+ i = this.length,
+ resolve = function() {
+ if ( !( --count ) ) {
+ defer.resolveWith( elements, [ elements ] );
+ }
+ };
+
+ if ( typeof type !== "string" ) {
+ obj = type;
+ type = undefined;
+ }
+ type = type || "fx";
+
+ while( i-- ) {
+ tmp = jQuery._data( elements[ i ], type + "queueHooks" );
+ if ( tmp && tmp.empty ) {
+ count++;
+ tmp.empty.add( resolve );
+ }
+ }
+ resolve();
+ return defer.promise( obj );
+ }
+});
+var nodeHook, boolHook,
+ rclass = /[\t\r\n]/g,
+ rreturn = /\r/g,
+ rfocusable = /^(?:input|select|textarea|button|object)$/i,
+ rclickable = /^(?:a|area)$/i,
+ rboolean = /^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i,
+ ruseDefault = /^(?:checked|selected)$/i,
+ getSetAttribute = jQuery.support.getSetAttribute,
+ getSetInput = jQuery.support.input;
+
+jQuery.fn.extend({
+ attr: function( name, value ) {
+ return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );
+ },
+
+ removeAttr: function( name ) {
+ return this.each(function() {
+ jQuery.removeAttr( this, name );
+ });
+ },
+
+ prop: function( name, value ) {
+ return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );
+ },
+
+ removeProp: function( name ) {
+ name = jQuery.propFix[ name ] || name;
+ return this.each(function() {
+ // try/catch handles cases where IE balks (such as removing a property on window)
+ try {
+ this[ name ] = undefined;
+ delete this[ name ];
+ } catch( e ) {}
+ });
+ },
+
+ addClass: function( value ) {
+ var classes, elem, cur, clazz, j,
+ i = 0,
+ len = this.length,
+ proceed = typeof value === "string" && value;
+
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function( j ) {
+ jQuery( this ).addClass( value.call( this, j, this.className ) );
+ });
+ }
+
+ if ( proceed ) {
+ // The disjunction here is for better compressibility (see removeClass)
+ classes = ( value || "" ).match( core_rnotwhite ) || [];
+
+ for ( ; i < len; i++ ) {
+ elem = this[ i ];
+ cur = elem.nodeType === 1 && ( elem.className ?
+ ( " " + elem.className + " " ).replace( rclass, " " ) :
+ " "
+ );
+
+ if ( cur ) {
+ j = 0;
+ while ( (clazz = classes[j++]) ) {
+ if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
+ cur += clazz + " ";
+ }
+ }
+ elem.className = jQuery.trim( cur );
+
+ }
+ }
+ }
+
+ return this;
+ },
+
+ removeClass: function( value ) {
+ var classes, elem, cur, clazz, j,
+ i = 0,
+ len = this.length,
+ proceed = arguments.length === 0 || typeof value === "string" && value;
+
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function( j ) {
+ jQuery( this ).removeClass( value.call( this, j, this.className ) );
+ });
+ }
+ if ( proceed ) {
+ classes = ( value || "" ).match( core_rnotwhite ) || [];
+
+ for ( ; i < len; i++ ) {
+ elem = this[ i ];
+ // This expression is here for better compressibility (see addClass)
+ cur = elem.nodeType === 1 && ( elem.className ?
+ ( " " + elem.className + " " ).replace( rclass, " " ) :
+ ""
+ );
+
+ if ( cur ) {
+ j = 0;
+ while ( (clazz = classes[j++]) ) {
+ // Remove *all* instances
+ while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
+ cur = cur.replace( " " + clazz + " ", " " );
+ }
+ }
+ elem.className = value ? jQuery.trim( cur ) : "";
+ }
+ }
+ }
+
+ return this;
+ },
+
+ toggleClass: function( value, stateVal ) {
+ var type = typeof value,
+ isBool = typeof stateVal === "boolean";
+
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function( i ) {
+ jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
+ });
+ }
+
+ return this.each(function() {
+ if ( type === "string" ) {
+ // toggle individual class names
+ var className,
+ i = 0,
+ self = jQuery( this ),
+ state = stateVal,
+ classNames = value.match( core_rnotwhite ) || [];
+
+ while ( (className = classNames[ i++ ]) ) {
+ // check each className given, space separated list
+ state = isBool ? state : !self.hasClass( className );
+ self[ state ? "addClass" : "removeClass" ]( className );
+ }
+
+ // Toggle whole class name
+ } else if ( type === core_strundefined || type === "boolean" ) {
+ if ( this.className ) {
+ // store className if set
+ jQuery._data( this, "__className__", this.className );
+ }
+
+ // If the element has a class name or if we're passed "false",
+ // then remove the whole classname (if there was one, the above saved it).
+ // Otherwise bring back whatever was previously saved (if anything),
+ // falling back to the empty string if nothing was stored.
+ this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
+ }
+ });
+ },
+
+ hasClass: function( selector ) {
+ var className = " " + selector + " ",
+ i = 0,
+ l = this.length;
+ for ( ; i < l; i++ ) {
+ if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
+ return true;
+ }
+ }
+
+ return false;
+ },
+
+ val: function( value ) {
+ var ret, hooks, isFunction,
+ elem = this[0];
+
+ if ( !arguments.length ) {
+ if ( elem ) {
+ hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
+
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
+ return ret;
+ }
+
+ ret = elem.value;
+
+ return typeof ret === "string" ?
+ // handle most common string cases
+ ret.replace(rreturn, "") :
+ // handle cases where value is null/undef or number
+ ret == null ? "" : ret;
+ }
+
+ return;
+ }
+
+ isFunction = jQuery.isFunction( value );
+
+ return this.each(function( i ) {
+ var val,
+ self = jQuery(this);
+
+ if ( this.nodeType !== 1 ) {
+ return;
+ }
+
+ if ( isFunction ) {
+ val = value.call( this, i, self.val() );
+ } else {
+ val = value;
+ }
+
+ // Treat null/undefined as ""; convert numbers to string
+ if ( val == null ) {
+ val = "";
+ } else if ( typeof val === "number" ) {
+ val += "";
+ } else if ( jQuery.isArray( val ) ) {
+ val = jQuery.map(val, function ( value ) {
+ return value == null ? "" : value + "";
+ });
+ }
+
+ hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
+
+ // If set returns undefined, fall back to normal setting
+ if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
+ this.value = val;
+ }
+ });
+ }
+});
+
+jQuery.extend({
+ valHooks: {
+ option: {
+ get: function( elem ) {
+ // attributes.value is undefined in Blackberry 4.7 but
+ // uses .value. See #6932
+ var val = elem.attributes.value;
+ return !val || val.specified ? elem.value : elem.text;
+ }
+ },
+ select: {
+ get: function( elem ) {
+ var value, option,
+ options = elem.options,
+ index = elem.selectedIndex,
+ one = elem.type === "select-one" || index < 0,
+ values = one ? null : [],
+ max = one ? index + 1 : options.length,
+ i = index < 0 ?
+ max :
+ one ? index : 0;
+
+ // Loop through all the selected options
+ for ( ; i < max; i++ ) {
+ option = options[ i ];
+
+ // oldIE doesn't update selected after form reset (#2551)
+ if ( ( option.selected || i === index ) &&
+ // Don't return options that are disabled or in a disabled optgroup
+ ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
+ ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
+
+ // Get the specific value for the option
+ value = jQuery( option ).val();
+
+ // We don't need an array for one selects
+ if ( one ) {
+ return value;
+ }
+
+ // Multi-Selects return an array
+ values.push( value );
+ }
+ }
+
+ return values;
+ },
+
+ set: function( elem, value ) {
+ var values = jQuery.makeArray( value );
+
+ jQuery(elem).find("option").each(function() {
+ this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
+ });
+
+ if ( !values.length ) {
+ elem.selectedIndex = -1;
+ }
+ return values;
+ }
+ }
+ },
+
+ attr: function( elem, name, value ) {
+ var hooks, notxml, ret,
+ nType = elem.nodeType;
+
+ // don't get/set attributes on text, comment and attribute nodes
+ if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+ return;
+ }
+
+ // Fallback to prop when attributes are not supported
+ if ( typeof elem.getAttribute === core_strundefined ) {
+ return jQuery.prop( elem, name, value );
+ }
+
+ notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
+
+ // All attributes are lowercase
+ // Grab necessary hook if one is defined
+ if ( notxml ) {
+ name = name.toLowerCase();
+ hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );
+ }
+
+ if ( value !== undefined ) {
+
+ if ( value === null ) {
+ jQuery.removeAttr( elem, name );
+
+ } else if ( hooks && notxml && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
+ return ret;
+
+ } else {
+ elem.setAttribute( name, value + "" );
+ return value;
+ }
+
+ } else if ( hooks && notxml && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
+ return ret;
+
+ } else {
+
+ // In IE9+, Flash objects don't have .getAttribute (#12945)
+ // Support: IE9+
+ if ( typeof elem.getAttribute !== core_strundefined ) {
+ ret = elem.getAttribute( name );
+ }
+
+ // Non-existent attributes return null, we normalize to undefined
+ return ret == null ?
+ undefined :
+ ret;
+ }
+ },
+
+ removeAttr: function( elem, value ) {
+ var name, propName,
+ i = 0,
+ attrNames = value && value.match( core_rnotwhite );
+
+ if ( attrNames && elem.nodeType === 1 ) {
+ while ( (name = attrNames[i++]) ) {
+ propName = jQuery.propFix[ name ] || name;
+
+ // Boolean attributes get special treatment (#10870)
+ if ( rboolean.test( name ) ) {
+ // Set corresponding property to false for boolean attributes
+ // Also clear defaultChecked/defaultSelected (if appropriate) for IE<8
+ if ( !getSetAttribute && ruseDefault.test( name ) ) {
+ elem[ jQuery.camelCase( "default-" + name ) ] =
+ elem[ propName ] = false;
+ } else {
+ elem[ propName ] = false;
+ }
+
+ // See #9699 for explanation of this approach (setting first, then removal)
+ } else {
+ jQuery.attr( elem, name, "" );
+ }
+
+ elem.removeAttribute( getSetAttribute ? name : propName );
+ }
+ }
+ },
+
+ attrHooks: {
+ type: {
+ set: function( elem, value ) {
+ if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
+ // Setting the type on a radio button after the value resets the value in IE6-9
+ // Reset value to default in case type is set after value during creation
+ var val = elem.value;
+ elem.setAttribute( "type", value );
+ if ( val ) {
+ elem.value = val;
+ }
+ return value;
+ }
+ }
+ }
+ },
+
+ propFix: {
+ tabindex: "tabIndex",
+ readonly: "readOnly",
+ "for": "htmlFor",
+ "class": "className",
+ maxlength: "maxLength",
+ cellspacing: "cellSpacing",
+ cellpadding: "cellPadding",
+ rowspan: "rowSpan",
+ colspan: "colSpan",
+ usemap: "useMap",
+ frameborder: "frameBorder",
+ contenteditable: "contentEditable"
+ },
+
+ prop: function( elem, name, value ) {
+ var ret, hooks, notxml,
+ nType = elem.nodeType;
+
+ // don't get/set properties on text, comment and attribute nodes
+ if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+ return;
+ }
+
+ notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
+
+ if ( notxml ) {
+ // Fix name and attach hooks
+ name = jQuery.propFix[ name ] || name;
+ hooks = jQuery.propHooks[ name ];
+ }
+
+ if ( value !== undefined ) {
+ if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
+ return ret;
+
+ } else {
+ return ( elem[ name ] = value );
+ }
+
+ } else {
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
+ return ret;
+
+ } else {
+ return elem[ name ];
+ }
+ }
+ },
+
+ propHooks: {
+ tabIndex: {
+ get: function( elem ) {
+ // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+ var attributeNode = elem.getAttributeNode("tabindex");
+
+ return attributeNode && attributeNode.specified ?
+ parseInt( attributeNode.value, 10 ) :
+ rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
+ 0 :
+ undefined;
+ }
+ }
+ }
+});
+
+// Hook for boolean attributes
+boolHook = {
+ get: function( elem, name ) {
+ var
+ // Use .prop to determine if this attribute is understood as boolean
+ prop = jQuery.prop( elem, name ),
+
+ // Fetch it accordingly
+ attr = typeof prop === "boolean" && elem.getAttribute( name ),
+ detail = typeof prop === "boolean" ?
+
+ getSetInput && getSetAttribute ?
+ attr != null :
+ // oldIE fabricates an empty string for missing boolean attributes
+ // and conflates checked/selected into attroperties
+ ruseDefault.test( name ) ?
+ elem[ jQuery.camelCase( "default-" + name ) ] :
+ !!attr :
+
+ // fetch an attribute node for properties not recognized as boolean
+ elem.getAttributeNode( name );
+
+ return detail && detail.value !== false ?
+ name.toLowerCase() :
+ undefined;
+ },
+ set: function( elem, value, name ) {
+ if ( value === false ) {
+ // Remove boolean attributes when set to false
+ jQuery.removeAttr( elem, name );
+ } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
+ // IE<8 needs the *property* name
+ elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
+
+ // Use defaultChecked and defaultSelected for oldIE
+ } else {
+ elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
+ }
+
+ return name;
+ }
+};
+
+// fix oldIE value attroperty
+if ( !getSetInput || !getSetAttribute ) {
+ jQuery.attrHooks.value = {
+ get: function( elem, name ) {
+ var ret = elem.getAttributeNode( name );
+ return jQuery.nodeName( elem, "input" ) ?
+
+ // Ignore the value *property* by using defaultValue
+ elem.defaultValue :
+
+ ret && ret.specified ? ret.value : undefined;
+ },
+ set: function( elem, value, name ) {
+ if ( jQuery.nodeName( elem, "input" ) ) {
+ // Does not return so that setAttribute is also used
+ elem.defaultValue = value;
+ } else {
+ // Use nodeHook if defined (#1954); otherwise setAttribute is fine
+ return nodeHook && nodeHook.set( elem, value, name );
+ }
+ }
+ };
+}
+
+// IE6/7 do not support getting/setting some attributes with get/setAttribute
+if ( !getSetAttribute ) {
+
+ // Use this for any attribute in IE6/7
+ // This fixes almost every IE6/7 issue
+ nodeHook = jQuery.valHooks.button = {
+ get: function( elem, name ) {
+ var ret = elem.getAttributeNode( name );
+ return ret && ( name === "id" || name === "name" || name === "coords" ? ret.value !== "" : ret.specified ) ?
+ ret.value :
+ undefined;
+ },
+ set: function( elem, value, name ) {
+ // Set the existing or create a new attribute node
+ var ret = elem.getAttributeNode( name );
+ if ( !ret ) {
+ elem.setAttributeNode(
+ (ret = elem.ownerDocument.createAttribute( name ))
+ );
+ }
+
+ ret.value = value += "";
+
+ // Break association with cloned elements by also using setAttribute (#9646)
+ return name === "value" || value === elem.getAttribute( name ) ?
+ value :
+ undefined;
+ }
+ };
+
+ // Set contenteditable to false on removals(#10429)
+ // Setting to empty string throws an error as an invalid value
+ jQuery.attrHooks.contenteditable = {
+ get: nodeHook.get,
+ set: function( elem, value, name ) {
+ nodeHook.set( elem, value === "" ? false : value, name );
+ }
+ };
+
+ // Set width and height to auto instead of 0 on empty string( Bug #8150 )
+ // This is for removals
+ jQuery.each([ "width", "height" ], function( i, name ) {
+ jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
+ set: function( elem, value ) {
+ if ( value === "" ) {
+ elem.setAttribute( name, "auto" );
+ return value;
+ }
+ }
+ });
+ });
+}
+
+
+// Some attributes require a special call on IE
+// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+if ( !jQuery.support.hrefNormalized ) {
+ jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
+ jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
+ get: function( elem ) {
+ var ret = elem.getAttribute( name, 2 );
+ return ret == null ? undefined : ret;
+ }
+ });
+ });
+
+ // href/src property should get the full normalized URL (#10299/#12915)
+ jQuery.each([ "href", "src" ], function( i, name ) {
+ jQuery.propHooks[ name ] = {
+ get: function( elem ) {
+ return elem.getAttribute( name, 4 );
+ }
+ };
+ });
+}
+
+if ( !jQuery.support.style ) {
+ jQuery.attrHooks.style = {
+ get: function( elem ) {
+ // Return undefined in the case of empty string
+ // Note: IE uppercases css property names, but if we were to .toLowerCase()
+ // .cssText, that would destroy case senstitivity in URL's, like in "background"
+ return elem.style.cssText || undefined;
+ },
+ set: function( elem, value ) {
+ return ( elem.style.cssText = value + "" );
+ }
+ };
+}
+
+// Safari mis-reports the default selected property of an option
+// Accessing the parent's selectedIndex property fixes it
+if ( !jQuery.support.optSelected ) {
+ jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
+ get: function( elem ) {
+ var parent = elem.parentNode;
+
+ if ( parent ) {
+ parent.selectedIndex;
+
+ // Make sure that it also works with optgroups, see #5701
+ if ( parent.parentNode ) {
+ parent.parentNode.selectedIndex;
+ }
+ }
+ return null;
+ }
+ });
+}
+
+// IE6/7 call enctype encoding
+if ( !jQuery.support.enctype ) {
+ jQuery.propFix.enctype = "encoding";
+}
+
+// Radios and checkboxes getter/setter
+if ( !jQuery.support.checkOn ) {
+ jQuery.each([ "radio", "checkbox" ], function() {
+ jQuery.valHooks[ this ] = {
+ get: function( elem ) {
+ // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
+ return elem.getAttribute("value") === null ? "on" : elem.value;
+ }
+ };
+ });
+}
+jQuery.each([ "radio", "checkbox" ], function() {
+ jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
+ set: function( elem, value ) {
+ if ( jQuery.isArray( value ) ) {
+ return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
+ }
+ }
+ });
+});
+var rformElems = /^(?:input|select|textarea)$/i,
+ rkeyEvent = /^key/,
+ rmouseEvent = /^(?:mouse|contextmenu)|click/,
+ rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
+ rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
+
+function returnTrue() {
+ return true;
+}
+
+function returnFalse() {
+ return false;
+}
+
+/*
+ * Helper functions for managing events -- not part of the public interface.
+ * Props to Dean Edwards' addEvent library for many of the ideas.
+ */
+jQuery.event = {
+
+ global: {},
+
+ add: function( elem, types, handler, data, selector ) {
+ var tmp, events, t, handleObjIn,
+ special, eventHandle, handleObj,
+ handlers, type, namespaces, origType,
+ elemData = jQuery._data( elem );
+
+ // Don't attach events to noData or text/comment nodes (but allow plain objects)
+ if ( !elemData ) {
+ return;
+ }
+
+ // Caller can pass in an object of custom data in lieu of the handler
+ if ( handler.handler ) {
+ handleObjIn = handler;
+ handler = handleObjIn.handler;
+ selector = handleObjIn.selector;
+ }
+
+ // Make sure that the handler has a unique ID, used to find/remove it later
+ if ( !handler.guid ) {
+ handler.guid = jQuery.guid++;
+ }
+
+ // Init the element's event structure and main handler, if this is the first
+ if ( !(events = elemData.events) ) {
+ events = elemData.events = {};
+ }
+ if ( !(eventHandle = elemData.handle) ) {
+ eventHandle = elemData.handle = function( e ) {
+ // Discard the second event of a jQuery.event.trigger() and
+ // when an event is called after a page has unloaded
+ return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ?
+ jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
+ undefined;
+ };
+ // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
+ eventHandle.elem = elem;
+ }
+
+ // Handle multiple events separated by a space
+ // jQuery(...).bind("mouseover mouseout", fn);
+ types = ( types || "" ).match( core_rnotwhite ) || [""];
+ t = types.length;
+ while ( t-- ) {
+ tmp = rtypenamespace.exec( types[t] ) || [];
+ type = origType = tmp[1];
+ namespaces = ( tmp[2] || "" ).split( "." ).sort();
+
+ // If event changes its type, use the special event handlers for the changed type
+ special = jQuery.event.special[ type ] || {};
+
+ // If selector defined, determine special event api type, otherwise given type
+ type = ( selector ? special.delegateType : special.bindType ) || type;
+
+ // Update special based on newly reset type
+ special = jQuery.event.special[ type ] || {};
+
+ // handleObj is passed to all event handlers
+ handleObj = jQuery.extend({
+ type: type,
+ origType: origType,
+ data: data,
+ handler: handler,
+ guid: handler.guid,
+ selector: selector,
+ needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
+ namespace: namespaces.join(".")
+ }, handleObjIn );
+
+ // Init the event handler queue if we're the first
+ if ( !(handlers = events[ type ]) ) {
+ handlers = events[ type ] = [];
+ handlers.delegateCount = 0;
+
+ // Only use addEventListener/attachEvent if the special events handler returns false
+ if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+ // Bind the global event handler to the element
+ if ( elem.addEventListener ) {
+ elem.addEventListener( type, eventHandle, false );
+
+ } else if ( elem.attachEvent ) {
+ elem.attachEvent( "on" + type, eventHandle );
+ }
+ }
+ }
+
+ if ( special.add ) {
+ special.add.call( elem, handleObj );
+
+ if ( !handleObj.handler.guid ) {
+ handleObj.handler.guid = handler.guid;
+ }
+ }
+
+ // Add to the element's handler list, delegates in front
+ if ( selector ) {
+ handlers.splice( handlers.delegateCount++, 0, handleObj );
+ } else {
+ handlers.push( handleObj );
+ }
+
+ // Keep track of which events have ever been used, for event optimization
+ jQuery.event.global[ type ] = true;
+ }
+
+ // Nullify elem to prevent memory leaks in IE
+ elem = null;
+ },
+
+ // Detach an event or set of events from an element
+ remove: function( elem, types, handler, selector, mappedTypes ) {
+ var j, handleObj, tmp,
+ origCount, t, events,
+ special, handlers, type,
+ namespaces, origType,
+ elemData = jQuery.hasData( elem ) && jQuery._data( elem );
+
+ if ( !elemData || !(events = elemData.events) ) {
+ return;
+ }
+
+ // Once for each type.namespace in types; type may be omitted
+ types = ( types || "" ).match( core_rnotwhite ) || [""];
+ t = types.length;
+ while ( t-- ) {
+ tmp = rtypenamespace.exec( types[t] ) || [];
+ type = origType = tmp[1];
+ namespaces = ( tmp[2] || "" ).split( "." ).sort();
+
+ // Unbind all events (on this namespace, if provided) for the element
+ if ( !type ) {
+ for ( type in events ) {
+ jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
+ }
+ continue;
+ }
+
+ special = jQuery.event.special[ type ] || {};
+ type = ( selector ? special.delegateType : special.bindType ) || type;
+ handlers = events[ type ] || [];
+ tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
+
+ // Remove matching events
+ origCount = j = handlers.length;
+ while ( j-- ) {
+ handleObj = handlers[ j ];
+
+ if ( ( mappedTypes || origType === handleObj.origType ) &&
+ ( !handler || handler.guid === handleObj.guid ) &&
+ ( !tmp || tmp.test( handleObj.namespace ) ) &&
+ ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
+ handlers.splice( j, 1 );
+
+ if ( handleObj.selector ) {
+ handlers.delegateCount--;
+ }
+ if ( special.remove ) {
+ special.remove.call( elem, handleObj );
+ }
+ }
+ }
+
+ // Remove generic event handler if we removed something and no more handlers exist
+ // (avoids potential for endless recursion during removal of special event handlers)
+ if ( origCount && !handlers.length ) {
+ if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
+ jQuery.removeEvent( elem, type, elemData.handle );
+ }
+
+ delete events[ type ];
+ }
+ }
+
+ // Remove the expando if it's no longer used
+ if ( jQuery.isEmptyObject( events ) ) {
+ delete elemData.handle;
+
+ // removeData also checks for emptiness and clears the expando if empty
+ // so use it instead of delete
+ jQuery._removeData( elem, "events" );
+ }
+ },
+
+ trigger: function( event, data, elem, onlyHandlers ) {
+ var handle, ontype, cur,
+ bubbleType, special, tmp, i,
+ eventPath = [ elem || document ],
+ type = core_hasOwn.call( event, "type" ) ? event.type : event,
+ namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
+
+ cur = tmp = elem = elem || document;
+
+ // Don't do events on text and comment nodes
+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return;
+ }
+
+ // focus/blur morphs to focusin/out; ensure we're not firing them right now
+ if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
+ return;
+ }
+
+ if ( type.indexOf(".") >= 0 ) {
+ // Namespaced trigger; create a regexp to match event type in handle()
+ namespaces = type.split(".");
+ type = namespaces.shift();
+ namespaces.sort();
+ }
+ ontype = type.indexOf(":") < 0 && "on" + type;
+
+ // Caller can pass in a jQuery.Event object, Object, or just an event type string
+ event = event[ jQuery.expando ] ?
+ event :
+ new jQuery.Event( type, typeof event === "object" && event );
+
+ event.isTrigger = true;
+ event.namespace = namespaces.join(".");
+ event.namespace_re = event.namespace ?
+ new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
+ null;
+
+ // Clean up the event in case it is being reused
+ event.result = undefined;
+ if ( !event.target ) {
+ event.target = elem;
+ }
+
+ // Clone any incoming data and prepend the event, creating the handler arg list
+ data = data == null ?
+ [ event ] :
+ jQuery.makeArray( data, [ event ] );
+
+ // Allow special events to draw outside the lines
+ special = jQuery.event.special[ type ] || {};
+ if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
+ return;
+ }
+
+ // Determine event propagation path in advance, per W3C events spec (#9951)
+ // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
+ if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
+
+ bubbleType = special.delegateType || type;
+ if ( !rfocusMorph.test( bubbleType + type ) ) {
+ cur = cur.parentNode;
+ }
+ for ( ; cur; cur = cur.parentNode ) {
+ eventPath.push( cur );
+ tmp = cur;
+ }
+
+ // Only add window if we got to document (e.g., not plain obj or detached DOM)
+ if ( tmp === (elem.ownerDocument || document) ) {
+ eventPath.push( tmp.defaultView || tmp.parentWindow || window );
+ }
+ }
+
+ // Fire handlers on the event path
+ i = 0;
+ while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
+
+ event.type = i > 1 ?
+ bubbleType :
+ special.bindType || type;
+
+ // jQuery handler
+ handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
+ if ( handle ) {
+ handle.apply( cur, data );
+ }
+
+ // Native handler
+ handle = ontype && cur[ ontype ];
+ if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {
+ event.preventDefault();
+ }
+ }
+ event.type = type;
+
+ // If nobody prevented the default action, do it now
+ if ( !onlyHandlers && !event.isDefaultPrevented() ) {
+
+ if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) &&
+ !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
+
+ // Call a native DOM method on the target with the same name name as the event.
+ // Can't use an .isFunction() check here because IE6/7 fails that test.
+ // Don't do default actions on window, that's where global variables be (#6170)
+ if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
+
+ // Don't re-trigger an onFOO event when we call its FOO() method
+ tmp = elem[ ontype ];
+
+ if ( tmp ) {
+ elem[ ontype ] = null;
+ }
+
+ // Prevent re-triggering of the same event, since we already bubbled it above
+ jQuery.event.triggered = type;
+ try {
+ elem[ type ]();
+ } catch ( e ) {
+ // IE<9 dies on focus/blur to hidden element (#1486,#12518)
+ // only reproducible on winXP IE8 native, not IE9 in IE8 mode
+ }
+ jQuery.event.triggered = undefined;
+
+ if ( tmp ) {
+ elem[ ontype ] = tmp;
+ }
+ }
+ }
+ }
+
+ return event.result;
+ },
+
+ dispatch: function( event ) {
+
+ // Make a writable jQuery.Event from the native event object
+ event = jQuery.event.fix( event );
+
+ var i, ret, handleObj, matched, j,
+ handlerQueue = [],
+ args = core_slice.call( arguments ),
+ handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
+ special = jQuery.event.special[ event.type ] || {};
+
+ // Use the fix-ed jQuery.Event rather than the (read-only) native event
+ args[0] = event;
+ event.delegateTarget = this;
+
+ // Call the preDispatch hook for the mapped type, and let it bail if desired
+ if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
+ return;
+ }
+
+ // Determine handlers
+ handlerQueue = jQuery.event.handlers.call( this, event, handlers );
+
+ // Run delegates first; they may want to stop propagation beneath us
+ i = 0;
+ while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
+ event.currentTarget = matched.elem;
+
+ j = 0;
+ while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
+
+ // Triggered event must either 1) have no namespace, or
+ // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
+ if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
+
+ event.handleObj = handleObj;
+ event.data = handleObj.data;
+
+ ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
+ .apply( matched.elem, args );
+
+ if ( ret !== undefined ) {
+ if ( (event.result = ret) === false ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+ }
+ }
+ }
+
+ // Call the postDispatch hook for the mapped type
+ if ( special.postDispatch ) {
+ special.postDispatch.call( this, event );
+ }
+
+ return event.result;
+ },
+
+ handlers: function( event, handlers ) {
+ var sel, handleObj, matches, i,
+ handlerQueue = [],
+ delegateCount = handlers.delegateCount,
+ cur = event.target;
+
+ // Find delegate handlers
+ // Black-hole SVG <use> instance trees (#13180)
+ // Avoid non-left-click bubbling in Firefox (#3861)
+ if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
+
+ for ( ; cur != this; cur = cur.parentNode || this ) {
+
+ // Don't check non-elements (#13208)
+ // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
+ if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) {
+ matches = [];
+ for ( i = 0; i < delegateCount; i++ ) {
+ handleObj = handlers[ i ];
+
+ // Don't conflict with Object.prototype properties (#13203)
+ sel = handleObj.selector + " ";
+
+ if ( matches[ sel ] === undefined ) {
+ matches[ sel ] = handleObj.needsContext ?
+ jQuery( sel, this ).index( cur ) >= 0 :
+ jQuery.find( sel, this, null, [ cur ] ).length;
+ }
+ if ( matches[ sel ] ) {
+ matches.push( handleObj );
+ }
+ }
+ if ( matches.length ) {
+ handlerQueue.push({ elem: cur, handlers: matches });
+ }
+ }
+ }
+ }
+
+ // Add the remaining (directly-bound) handlers
+ if ( delegateCount < handlers.length ) {
+ handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
+ }
+
+ return handlerQueue;
+ },
+
+ fix: function( event ) {
+ if ( event[ jQuery.expando ] ) {
+ return event;
+ }
+
+ // Create a writable copy of the event object and normalize some properties
+ var i, prop, copy,
+ type = event.type,
+ originalEvent = event,
+ fixHook = this.fixHooks[ type ];
+
+ if ( !fixHook ) {
+ this.fixHooks[ type ] = fixHook =
+ rmouseEvent.test( type ) ? this.mouseHooks :
+ rkeyEvent.test( type ) ? this.keyHooks :
+ {};
+ }
+ copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
+
+ event = new jQuery.Event( originalEvent );
+
+ i = copy.length;
+ while ( i-- ) {
+ prop = copy[ i ];
+ event[ prop ] = originalEvent[ prop ];
+ }
+
+ // Support: IE<9
+ // Fix target property (#1925)
+ if ( !event.target ) {
+ event.target = originalEvent.srcElement || document;
+ }
+
+ // Support: Chrome 23+, Safari?
+ // Target should not be a text node (#504, #13143)
+ if ( event.target.nodeType === 3 ) {
+ event.target = event.target.parentNode;
+ }
+
+ // Support: IE<9
+ // For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
+ event.metaKey = !!event.metaKey;
+
+ return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
+ },
+
+ // Includes some event props shared by KeyEvent and MouseEvent
+ props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
+
+ fixHooks: {},
+
+ keyHooks: {
+ props: "char charCode key keyCode".split(" "),
+ filter: function( event, original ) {
+
+ // Add which for key events
+ if ( event.which == null ) {
+ event.which = original.charCode != null ? original.charCode : original.keyCode;
+ }
+
+ return event;
+ }
+ },
+
+ mouseHooks: {
+ props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
+ filter: function( event, original ) {
+ var body, eventDoc, doc,
+ button = original.button,
+ fromElement = original.fromElement;
+
+ // Calculate pageX/Y if missing and clientX/Y available
+ if ( event.pageX == null && original.clientX != null ) {
+ eventDoc = event.target.ownerDocument || document;
+ doc = eventDoc.documentElement;
+ body = eventDoc.body;
+
+ event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
+ event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );
+ }
+
+ // Add relatedTarget, if necessary
+ if ( !event.relatedTarget && fromElement ) {
+ event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
+ }
+
+ // Add which for click: 1 === left; 2 === middle; 3 === right
+ // Note: button is not normalized, so don't use it
+ if ( !event.which && button !== undefined ) {
+ event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
+ }
+
+ return event;
+ }
+ },
+
+ special: {
+ load: {
+ // Prevent triggered image.load events from bubbling to window.load
+ noBubble: true
+ },
+ click: {
+ // For checkbox, fire native event so checked state will be right
+ trigger: function() {
+ if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
+ this.click();
+ return false;
+ }
+ }
+ },
+ focus: {
+ // Fire native event if possible so blur/focus sequence is correct
+ trigger: function() {
+ if ( this !== document.activeElement && this.focus ) {
+ try {
+ this.focus();
+ return false;
+ } catch ( e ) {
+ // Support: IE<9
+ // If we error on focus to hidden element (#1486, #12518),
+ // let .trigger() run the handlers
+ }
+ }
+ },
+ delegateType: "focusin"
+ },
+ blur: {
+ trigger: function() {
+ if ( this === document.activeElement && this.blur ) {
+ this.blur();
+ return false;
+ }
+ },
+ delegateType: "focusout"
+ },
+
+ beforeunload: {
+ postDispatch: function( event ) {
+
+ // Even when returnValue equals to undefined Firefox will still show alert
+ if ( event.result !== undefined ) {
+ event.originalEvent.returnValue = event.result;
+ }
+ }
+ }
+ },
+
+ simulate: function( type, elem, event, bubble ) {
+ // Piggyback on a donor event to simulate a different one.
+ // Fake originalEvent to avoid donor's stopPropagation, but if the
+ // simulated event prevents default then we do the same on the donor.
+ var e = jQuery.extend(
+ new jQuery.Event(),
+ event,
+ { type: type,
+ isSimulated: true,
+ originalEvent: {}
+ }
+ );
+ if ( bubble ) {
+ jQuery.event.trigger( e, null, elem );
+ } else {
+ jQuery.event.dispatch.call( elem, e );
+ }
+ if ( e.isDefaultPrevented() ) {
+ event.preventDefault();
+ }
+ }
+};
+
+jQuery.removeEvent = document.removeEventListener ?
+ function( elem, type, handle ) {
+ if ( elem.removeEventListener ) {
+ elem.removeEventListener( type, handle, false );
+ }
+ } :
+ function( elem, type, handle ) {
+ var name = "on" + type;
+
+ if ( elem.detachEvent ) {
+
+ // #8545, #7054, preventing memory leaks for custom events in IE6-8
+ // detachEvent needed property on element, by name of that event, to properly expose it to GC
+ if ( typeof elem[ name ] === core_strundefined ) {
+ elem[ name ] = null;
+ }
+
+ elem.detachEvent( name, handle );
+ }
+ };
+
+jQuery.Event = function( src, props ) {
+ // Allow instantiation without the 'new' keyword
+ if ( !(this instanceof jQuery.Event) ) {
+ return new jQuery.Event( src, props );
+ }
+
+ // Event object
+ if ( src && src.type ) {
+ this.originalEvent = src;
+ this.type = src.type;
+
+ // Events bubbling up the document may have been marked as prevented
+ // by a handler lower down the tree; reflect the correct value.
+ this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||
+ src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;
+
+ // Event type
+ } else {
+ this.type = src;
+ }
+
+ // Put explicitly provided properties onto the event object
+ if ( props ) {
+ jQuery.extend( this, props );
+ }
+
+ // Create a timestamp if incoming event doesn't have one
+ this.timeStamp = src && src.timeStamp || jQuery.now();
+
+ // Mark it as fixed
+ this[ jQuery.expando ] = true;
+};
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+ isDefaultPrevented: returnFalse,
+ isPropagationStopped: returnFalse,
+ isImmediatePropagationStopped: returnFalse,
+
+ preventDefault: function() {
+ var e = this.originalEvent;
+
+ this.isDefaultPrevented = returnTrue;
+ if ( !e ) {
+ return;
+ }
+
+ // If preventDefault exists, run it on the original event
+ if ( e.preventDefault ) {
+ e.preventDefault();
+
+ // Support: IE
+ // Otherwise set the returnValue property of the original event to false
+ } else {
+ e.returnValue = false;
+ }
+ },
+ stopPropagation: function() {
+ var e = this.originalEvent;
+
+ this.isPropagationStopped = returnTrue;
+ if ( !e ) {
+ return;
+ }
+ // If stopPropagation exists, run it on the original event
+ if ( e.stopPropagation ) {
+ e.stopPropagation();
+ }
+
+ // Support: IE
+ // Set the cancelBubble property of the original event to true
+ e.cancelBubble = true;
+ },
+ stopImmediatePropagation: function() {
+ this.isImmediatePropagationStopped = returnTrue;
+ this.stopPropagation();
+ }
+};
+
+// Create mouseenter/leave events using mouseover/out and event-time checks
+jQuery.each({
+ mouseenter: "mouseover",
+ mouseleave: "mouseout"
+}, function( orig, fix ) {
+ jQuery.event.special[ orig ] = {
+ delegateType: fix,
+ bindType: fix,
+
+ handle: function( event ) {
+ var ret,
+ target = this,
+ related = event.relatedTarget,
+ handleObj = event.handleObj;
+
+ // For mousenter/leave call the handler if related is outside the target.
+ // NB: No relatedTarget if the mouse left/entered the browser window
+ if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
+ event.type = handleObj.origType;
+ ret = handleObj.handler.apply( this, arguments );
+ event.type = fix;
+ }
+ return ret;
+ }
+ };
+});
+
+// IE submit delegation
+if ( !jQuery.support.submitBubbles ) {
+
+ jQuery.event.special.submit = {
+ setup: function() {
+ // Only need this for delegated form submit events
+ if ( jQuery.nodeName( this, "form" ) ) {
+ return false;
+ }
+
+ // Lazy-add a submit handler when a descendant form may potentially be submitted
+ jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
+ // Node name check avoids a VML-related crash in IE (#9807)
+ var elem = e.target,
+ form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
+ if ( form && !jQuery._data( form, "submitBubbles" ) ) {
+ jQuery.event.add( form, "submit._submit", function( event ) {
+ event._submit_bubble = true;
+ });
+ jQuery._data( form, "submitBubbles", true );
+ }
+ });
+ // return undefined since we don't need an event listener
+ },
+
+ postDispatch: function( event ) {
+ // If form was submitted by the user, bubble the event up the tree
+ if ( event._submit_bubble ) {
+ delete event._submit_bubble;
+ if ( this.parentNode && !event.isTrigger ) {
+ jQuery.event.simulate( "submit", this.parentNode, event, true );
+ }
+ }
+ },
+
+ teardown: function() {
+ // Only need this for delegated form submit events
+ if ( jQuery.nodeName( this, "form" ) ) {
+ return false;
+ }
+
+ // Remove delegated handlers; cleanData eventually reaps submit handlers attached above
+ jQuery.event.remove( this, "._submit" );
+ }
+ };
+}
+
+// IE change delegation and checkbox/radio fix
+if ( !jQuery.support.changeBubbles ) {
+
+ jQuery.event.special.change = {
+
+ setup: function() {
+
+ if ( rformElems.test( this.nodeName ) ) {
+ // IE doesn't fire change on a check/radio until blur; trigger it on click
+ // after a propertychange. Eat the blur-change in special.change.handle.
+ // This still fires onchange a second time for check/radio after blur.
+ if ( this.type === "checkbox" || this.type === "radio" ) {
+ jQuery.event.add( this, "propertychange._change", function( event ) {
+ if ( event.originalEvent.propertyName === "checked" ) {
+ this._just_changed = true;
+ }
+ });
+ jQuery.event.add( this, "click._change", function( event ) {
+ if ( this._just_changed && !event.isTrigger ) {
+ this._just_changed = false;
+ }
+ // Allow triggered, simulated change events (#11500)
+ jQuery.event.simulate( "change", this, event, true );
+ });
+ }
+ return false;
+ }
+ // Delegated event; lazy-add a change handler on descendant inputs
+ jQuery.event.add( this, "beforeactivate._change", function( e ) {
+ var elem = e.target;
+
+ if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) {
+ jQuery.event.add( elem, "change._change", function( event ) {
+ if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
+ jQuery.event.simulate( "change", this.parentNode, event, true );
+ }
+ });
+ jQuery._data( elem, "changeBubbles", true );
+ }
+ });
+ },
+
+ handle: function( event ) {
+ var elem = event.target;
+
+ // Swallow native change events from checkbox/radio, we already triggered them above
+ if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
+ return event.handleObj.handler.apply( this, arguments );
+ }
+ },
+
+ teardown: function() {
+ jQuery.event.remove( this, "._change" );
+
+ return !rformElems.test( this.nodeName );
+ }
+ };
+}
+
+// Create "bubbling" focus and blur events
+if ( !jQuery.support.focusinBubbles ) {
+ jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+
+ // Attach a single capturing handler while someone wants focusin/focusout
+ var attaches = 0,
+ handler = function( event ) {
+ jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
+ };
+
+ jQuery.event.special[ fix ] = {
+ setup: function() {
+ if ( attaches++ === 0 ) {
+ document.addEventListener( orig, handler, true );
+ }
+ },
+ teardown: function() {
+ if ( --attaches === 0 ) {
+ document.removeEventListener( orig, handler, true );
+ }
+ }
+ };
+ });
+}
+
+jQuery.fn.extend({
+
+ on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
+ var type, origFn;
+
+ // Types can be a map of types/handlers
+ if ( typeof types === "object" ) {
+ // ( types-Object, selector, data )
+ if ( typeof selector !== "string" ) {
+ // ( types-Object, data )
+ data = data || selector;
+ selector = undefined;
+ }
+ for ( type in types ) {
+ this.on( type, selector, data, types[ type ], one );
+ }
+ return this;
+ }
+
+ if ( data == null && fn == null ) {
+ // ( types, fn )
+ fn = selector;
+ data = selector = undefined;
+ } else if ( fn == null ) {
+ if ( typeof selector === "string" ) {
+ // ( types, selector, fn )
+ fn = data;
+ data = undefined;
+ } else {
+ // ( types, data, fn )
+ fn = data;
+ data = selector;
+ selector = undefined;
+ }
+ }
+ if ( fn === false ) {
+ fn = returnFalse;
+ } else if ( !fn ) {
+ return this;
+ }
+
+ if ( one === 1 ) {
+ origFn = fn;
+ fn = function( event ) {
+ // Can use an empty set, since event contains the info
+ jQuery().off( event );
+ return origFn.apply( this, arguments );
+ };
+ // Use same guid so caller can remove using origFn
+ fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
+ }
+ return this.each( function() {
+ jQuery.event.add( this, types, fn, data, selector );
+ });
+ },
+ one: function( types, selector, data, fn ) {
+ return this.on( types, selector, data, fn, 1 );
+ },
+ off: function( types, selector, fn ) {
+ var handleObj, type;
+ if ( types && types.preventDefault && types.handleObj ) {
+ // ( event ) dispatched jQuery.Event
+ handleObj = types.handleObj;
+ jQuery( types.delegateTarget ).off(
+ handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
+ handleObj.selector,
+ handleObj.handler
+ );
+ return this;
+ }
+ if ( typeof types === "object" ) {
+ // ( types-object [, selector] )
+ for ( type in types ) {
+ this.off( type, selector, types[ type ] );
+ }
+ return this;
+ }
+ if ( selector === false || typeof selector === "function" ) {
+ // ( types [, fn] )
+ fn = selector;
+ selector = undefined;
+ }
+ if ( fn === false ) {
+ fn = returnFalse;
+ }
+ return this.each(function() {
+ jQuery.event.remove( this, types, fn, selector );
+ });
+ },
+
+ bind: function( types, data, fn ) {
+ return this.on( types, null, data, fn );
+ },
+ unbind: function( types, fn ) {
+ return this.off( types, null, fn );
+ },
+
+ delegate: function( selector, types, data, fn ) {
+ return this.on( types, selector, data, fn );
+ },
+ undelegate: function( selector, types, fn ) {
+ // ( namespace ) or ( selector, types [, fn] )
+ return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
+ },
+
+ trigger: function( type, data ) {
+ return this.each(function() {
+ jQuery.event.trigger( type, data, this );
+ });
+ },
+ triggerHandler: function( type, data ) {
+ var elem = this[0];
+ if ( elem ) {
+ return jQuery.event.trigger( type, data, elem, true );
+ }
+ }
+});
+/*!
+ * Sizzle CSS Selector Engine
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://sizzlejs.com/
+ */
+(function( window, undefined ) {
+
+var i,
+ cachedruns,
+ Expr,
+ getText,
+ isXML,
+ compile,
+ hasDuplicate,
+ outermostContext,
+
+ // Local document vars
+ setDocument,
+ document,
+ docElem,
+ documentIsXML,
+ rbuggyQSA,
+ rbuggyMatches,
+ matches,
+ contains,
+ sortOrder,
+
+ // Instance-specific data
+ expando = "sizzle" + -(new Date()),
+ preferredDoc = window.document,
+ support = {},
+ dirruns = 0,
+ done = 0,
+ classCache = createCache(),
+ tokenCache = createCache(),
+ compilerCache = createCache(),
+
+ // General-purpose constants
+ strundefined = typeof undefined,
+ MAX_NEGATIVE = 1 << 31,
+
+ // Array methods
+ arr = [],
+ pop = arr.pop,
+ push = arr.push,
+ slice = arr.slice,
+ // Use a stripped-down indexOf if we can't use a native one
+ indexOf = arr.indexOf || function( elem ) {
+ var i = 0,
+ len = this.length;
+ for ( ; i < len; i++ ) {
+ if ( this[i] === elem ) {
+ return i;
+ }
+ }
+ return -1;
+ },
+
+
+ // Regular expressions
+
+ // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
+ whitespace = "[\\x20\\t\\r\\n\\f]",
+ // http://www.w3.org/TR/css3-syntax/#characters
+ characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
+
+ // Loosely modeled on CSS identifier characters
+ // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
+ // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+ identifier = characterEncoding.replace( "w", "w#" ),
+
+ // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
+ operators = "([*^$|!~]?=)",
+ attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
+ "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
+
+ // Prefer arguments quoted,
+ // then not containing pseudos/brackets,
+ // then attribute selectors/non-parenthetical expressions,
+ // then anything else
+ // These preferences are here to reduce the number of selectors
+ // needing tokenize in the PSEUDO preFilter
+ pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)",
+
+ // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
+ rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
+
+ rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
+ rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ),
+ rpseudo = new RegExp( pseudos ),
+ ridentifier = new RegExp( "^" + identifier + "$" ),
+
+ matchExpr = {
+ "ID": new RegExp( "^#(" + characterEncoding + ")" ),
+ "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
+ "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ),
+ "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
+ "ATTR": new RegExp( "^" + attributes ),
+ "PSEUDO": new RegExp( "^" + pseudos ),
+ "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
+ "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
+ "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
+ // For use in libraries implementing .is()
+ // We use this for POS matching in `select`
+ "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
+ whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
+ },
+
+ rsibling = /[\x20\t\r\n\f]*[+~]/,
+
+ rnative = /^[^{]+\{\s*\[native code/,
+
+ // Easily-parseable/retrievable ID or TAG or CLASS selectors
+ rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
+
+ rinputs = /^(?:input|select|textarea|button)$/i,
+ rheader = /^h\d$/i,
+
+ rescape = /'|\\/g,
+ rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,
+
+ // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
+ runescape = /\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,
+ funescape = function( _, escaped ) {
+ var high = "0x" + escaped - 0x10000;
+ // NaN means non-codepoint
+ return high !== high ?
+ escaped :
+ // BMP codepoint
+ high < 0 ?
+ String.fromCharCode( high + 0x10000 ) :
+ // Supplemental Plane codepoint (surrogate pair)
+ String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
+ };
+
+// Use a stripped-down slice if we can't use a native one
+try {
+ slice.call( preferredDoc.documentElement.childNodes, 0 )[0].nodeType;
+} catch ( e ) {
+ slice = function( i ) {
+ var elem,
+ results = [];
+ while ( (elem = this[i++]) ) {
+ results.push( elem );
+ }
+ return results;
+ };
+}
+
+/**
+ * For feature detection
+ * @param {Function} fn The function to test for native support
+ */
+function isNative( fn ) {
+ return rnative.test( fn + "" );
+}
+
+/**
+ * Create key-value caches of limited size
+ * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
+ * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
+ * deleting the oldest entry
+ */
+function createCache() {
+ var cache,
+ keys = [];
+
+ return (cache = function( key, value ) {
+ // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
+ if ( keys.push( key += " " ) > Expr.cacheLength ) {
+ // Only keep the most recent entries
+ delete cache[ keys.shift() ];
+ }
+ return (cache[ key ] = value);
+ });
+}
+
+/**
+ * Mark a function for special use by Sizzle
+ * @param {Function} fn The function to mark
+ */
+function markFunction( fn ) {
+ fn[ expando ] = true;
+ return fn;
+}
+
+/**
+ * Support testing using an element
+ * @param {Function} fn Passed the created div and expects a boolean result
+ */
+function assert( fn ) {
+ var div = document.createElement("div");
+
+ try {
+ return fn( div );
+ } catch (e) {
+ return false;
+ } finally {
+ // release memory in IE
+ div = null;
+ }
+}
+
+function Sizzle( selector, context, results, seed ) {
+ var match, elem, m, nodeType,
+ // QSA vars
+ i, groups, old, nid, newContext, newSelector;
+
+ if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
+ setDocument( context );
+ }
+
+ context = context || document;
+ results = results || [];
+
+ if ( !selector || typeof selector !== "string" ) {
+ return results;
+ }
+
+ if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
+ return [];
+ }
+
+ if ( !documentIsXML && !seed ) {
+
+ // Shortcuts
+ if ( (match = rquickExpr.exec( selector )) ) {
+ // Speed-up: Sizzle("#ID")
+ if ( (m = match[1]) ) {
+ if ( nodeType === 9 ) {
+ elem = context.getElementById( m );
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ if ( elem && elem.parentNode ) {
+ // Handle the case where IE, Opera, and Webkit return items
+ // by name instead of ID
+ if ( elem.id === m ) {
+ results.push( elem );
+ return results;
+ }
+ } else {
+ return results;
+ }
+ } else {
+ // Context is not a document
+ if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
+ contains( context, elem ) && elem.id === m ) {
+ results.push( elem );
+ return results;
+ }
+ }
+
+ // Speed-up: Sizzle("TAG")
+ } else if ( match[2] ) {
+ push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) );
+ return results;
+
+ // Speed-up: Sizzle(".CLASS")
+ } else if ( (m = match[3]) && support.getByClassName && context.getElementsByClassName ) {
+ push.apply( results, slice.call(context.getElementsByClassName( m ), 0) );
+ return results;
+ }
+ }
+
+ // QSA path
+ if ( support.qsa && !rbuggyQSA.test(selector) ) {
+ old = true;
+ nid = expando;
+ newContext = context;
+ newSelector = nodeType === 9 && selector;
+
+ // qSA works strangely on Element-rooted queries
+ // We can work around this by specifying an extra ID on the root
+ // and working up from there (Thanks to Andrew Dupont for the technique)
+ // IE 8 doesn't work on object elements
+ if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
+ groups = tokenize( selector );
+
+ if ( (old = context.getAttribute("id")) ) {
+ nid = old.replace( rescape, "\\$&" );
+ } else {
+ context.setAttribute( "id", nid );
+ }
+ nid = "[id='" + nid + "'] ";
+
+ i = groups.length;
+ while ( i-- ) {
+ groups[i] = nid + toSelector( groups[i] );
+ }
+ newContext = rsibling.test( selector ) && context.parentNode || context;
+ newSelector = groups.join(",");
+ }
+
+ if ( newSelector ) {
+ try {
+ push.apply( results, slice.call( newContext.querySelectorAll(
+ newSelector
+ ), 0 ) );
+ return results;
+ } catch(qsaError) {
+ } finally {
+ if ( !old ) {
+ context.removeAttribute("id");
+ }
+ }
+ }
+ }
+ }
+
+ // All others
+ return select( selector.replace( rtrim, "$1" ), context, results, seed );
+}
+
+/**
+ * Detect xml
+ * @param {Element|Object} elem An element or a document
+ */
+isXML = Sizzle.isXML = function( elem ) {
+ // documentElement is verified for cases where it doesn't yet exist
+ // (such as loading iframes in IE - #4833)
+ var documentElement = elem && (elem.ownerDocument || elem).documentElement;
+ return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+/**
+ * Sets document-related variables once based on the current document
+ * @param {Element|Object} [doc] An element or document object to use to set the document
+ * @returns {Object} Returns the current document
+ */
+setDocument = Sizzle.setDocument = function( node ) {
+ var doc = node ? node.ownerDocument || node : preferredDoc;
+
+ // If no document and documentElement is available, return
+ if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
+ return document;
+ }
+
+ // Set our document
+ document = doc;
+ docElem = doc.documentElement;
+
+ // Support tests
+ documentIsXML = isXML( doc );
+
+ // Check if getElementsByTagName("*") returns only elements
+ support.tagNameNoComments = assert(function( div ) {
+ div.appendChild( doc.createComment("") );
+ return !div.getElementsByTagName("*").length;
+ });
+
+ // Check if attributes should be retrieved by attribute nodes
+ support.attributes = assert(function( div ) {
+ div.innerHTML = "<select></select>";
+ var type = typeof div.lastChild.getAttribute("multiple");
+ // IE8 returns a string for some attributes even when not present
+ return type !== "boolean" && type !== "string";
+ });
+
+ // Check if getElementsByClassName can be trusted
+ support.getByClassName = assert(function( div ) {
+ // Opera can't find a second classname (in 9.6)
+ div.innerHTML = "<div class='hidden e'></div><div class='hidden'></div>";
+ if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) {
+ return false;
+ }
+
+ // Safari 3.2 caches class attributes and doesn't catch changes
+ div.lastChild.className = "e";
+ return div.getElementsByClassName("e").length === 2;
+ });
+
+ // Check if getElementById returns elements by name
+ // Check if getElementsByName privileges form controls or returns elements by ID
+ support.getByName = assert(function( div ) {
+ // Inject content
+ div.id = expando + 0;
+ div.innerHTML = "<a name='" + expando + "'></a><div name='" + expando + "'></div>";
+ docElem.insertBefore( div, docElem.firstChild );
+
+ // Test
+ var pass = doc.getElementsByName &&
+ // buggy browsers will return fewer than the correct 2
+ doc.getElementsByName( expando ).length === 2 +
+ // buggy browsers will return more than the correct 0
+ doc.getElementsByName( expando + 0 ).length;
+ support.getIdNotName = !doc.getElementById( expando );
+
+ // Cleanup
+ docElem.removeChild( div );
+
+ return pass;
+ });
+
+ // IE6/7 return modified attributes
+ Expr.attrHandle = assert(function( div ) {
+ div.innerHTML = "<a href='#'></a>";
+ return div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&
+ div.firstChild.getAttribute("href") === "#";
+ }) ?
+ {} :
+ {
+ "href": function( elem ) {
+ return elem.getAttribute( "href", 2 );
+ },
+ "type": function( elem ) {
+ return elem.getAttribute("type");
+ }
+ };
+
+ // ID find and filter
+ if ( support.getIdNotName ) {
+ Expr.find["ID"] = function( id, context ) {
+ if ( typeof context.getElementById !== strundefined && !documentIsXML ) {
+ var m = context.getElementById( id );
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ return m && m.parentNode ? [m] : [];
+ }
+ };
+ Expr.filter["ID"] = function( id ) {
+ var attrId = id.replace( runescape, funescape );
+ return function( elem ) {
+ return elem.getAttribute("id") === attrId;
+ };
+ };
+ } else {
+ Expr.find["ID"] = function( id, context ) {
+ if ( typeof context.getElementById !== strundefined && !documentIsXML ) {
+ var m = context.getElementById( id );
+
+ return m ?
+ m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ?
+ [m] :
+ undefined :
+ [];
+ }
+ };
+ Expr.filter["ID"] = function( id ) {
+ var attrId = id.replace( runescape, funescape );
+ return function( elem ) {
+ var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
+ return node && node.value === attrId;
+ };
+ };
+ }
+
+ // Tag
+ Expr.find["TAG"] = support.tagNameNoComments ?
+ function( tag, context ) {
+ if ( typeof context.getElementsByTagName !== strundefined ) {
+ return context.getElementsByTagName( tag );
+ }
+ } :
+ function( tag, context ) {
+ var elem,
+ tmp = [],
+ i = 0,
+ results = context.getElementsByTagName( tag );
+
+ // Filter out possible comments
+ if ( tag === "*" ) {
+ while ( (elem = results[i++]) ) {
+ if ( elem.nodeType === 1 ) {
+ tmp.push( elem );
+ }
+ }
+
+ return tmp;
+ }
+ return results;
+ };
+
+ // Name
+ Expr.find["NAME"] = support.getByName && function( tag, context ) {
+ if ( typeof context.getElementsByName !== strundefined ) {
+ return context.getElementsByName( name );
+ }
+ };
+
+ // Class
+ Expr.find["CLASS"] = support.getByClassName && function( className, context ) {
+ if ( typeof context.getElementsByClassName !== strundefined && !documentIsXML ) {
+ return context.getElementsByClassName( className );
+ }
+ };
+
+ // QSA and matchesSelector support
+
+ // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
+ rbuggyMatches = [];
+
+ // qSa(:focus) reports false when true (Chrome 21),
+ // no need to also add to buggyMatches since matches checks buggyQSA
+ // A support test would require too much code (would include document ready)
+ rbuggyQSA = [ ":focus" ];
+
+ if ( (support.qsa = isNative(doc.querySelectorAll)) ) {
+ // Build QSA regex
+ // Regex strategy adopted from Diego Perini
+ assert(function( div ) {
+ // Select is set to empty string on purpose
+ // This is to test IE's treatment of not explictly
+ // setting a boolean content attribute,
+ // since its presence should be enough
+ // http://bugs.jquery.com/ticket/12359
+ div.innerHTML = "<select><option selected=''></option></select>";
+
+ // IE8 - Some boolean attributes are not treated correctly
+ if ( !div.querySelectorAll("[selected]").length ) {
+ rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" );
+ }
+
+ // Webkit/Opera - :checked should return selected option elements
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+ // IE8 throws error here and will not see later tests
+ if ( !div.querySelectorAll(":checked").length ) {
+ rbuggyQSA.push(":checked");
+ }
+ });
+
+ assert(function( div ) {
+
+ // Opera 10-12/IE8 - ^= $= *= and empty values
+ // Should not select anything
+ div.innerHTML = "<input type='hidden' i=''/>";
+ if ( div.querySelectorAll("[i^='']").length ) {
+ rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" );
+ }
+
+ // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
+ // IE8 throws error here and will not see later tests
+ if ( !div.querySelectorAll(":enabled").length ) {
+ rbuggyQSA.push( ":enabled", ":disabled" );
+ }
+
+ // Opera 10-11 does not throw on post-comma invalid pseudos
+ div.querySelectorAll("*,:x");
+ rbuggyQSA.push(",.*:");
+ });
+ }
+
+ if ( (support.matchesSelector = isNative( (matches = docElem.matchesSelector ||
+ docElem.mozMatchesSelector ||
+ docElem.webkitMatchesSelector ||
+ docElem.oMatchesSelector ||
+ docElem.msMatchesSelector) )) ) {
+
+ assert(function( div ) {
+ // Check to see if it's possible to do matchesSelector
+ // on a disconnected node (IE 9)
+ support.disconnectedMatch = matches.call( div, "div" );
+
+ // This should fail with an exception
+ // Gecko does not error, returns false instead
+ matches.call( div, "[s!='']:x" );
+ rbuggyMatches.push( "!=", pseudos );
+ });
+ }
+
+ rbuggyQSA = new RegExp( rbuggyQSA.join("|") );
+ rbuggyMatches = new RegExp( rbuggyMatches.join("|") );
+
+ // Element contains another
+ // Purposefully does not implement inclusive descendent
+ // As in, an element does not contain itself
+ contains = isNative(docElem.contains) || docElem.compareDocumentPosition ?
+ function( a, b ) {
+ var adown = a.nodeType === 9 ? a.documentElement : a,
+ bup = b && b.parentNode;
+ return a === bup || !!( bup && bup.nodeType === 1 && (
+ adown.contains ?
+ adown.contains( bup ) :
+ a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
+ ));
+ } :
+ function( a, b ) {
+ if ( b ) {
+ while ( (b = b.parentNode) ) {
+ if ( b === a ) {
+ return true;
+ }
+ }
+ }
+ return false;
+ };
+
+ // Document order sorting
+ sortOrder = docElem.compareDocumentPosition ?
+ function( a, b ) {
+ var compare;
+
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+ }
+
+ if ( (compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b )) ) {
+ if ( compare & 1 || a.parentNode && a.parentNode.nodeType === 11 ) {
+ if ( a === doc || contains( preferredDoc, a ) ) {
+ return -1;
+ }
+ if ( b === doc || contains( preferredDoc, b ) ) {
+ return 1;
+ }
+ return 0;
+ }
+ return compare & 4 ? -1 : 1;
+ }
+
+ return a.compareDocumentPosition ? -1 : 1;
+ } :
+ function( a, b ) {
+ var cur,
+ i = 0,
+ aup = a.parentNode,
+ bup = b.parentNode,
+ ap = [ a ],
+ bp = [ b ];
+
+ // Exit early if the nodes are identical
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+
+ // Parentless nodes are either documents or disconnected
+ } else if ( !aup || !bup ) {
+ return a === doc ? -1 :
+ b === doc ? 1 :
+ aup ? -1 :
+ bup ? 1 :
+ 0;
+
+ // If the nodes are siblings, we can do a quick check
+ } else if ( aup === bup ) {
+ return siblingCheck( a, b );
+ }
+
+ // Otherwise we need full lists of their ancestors for comparison
+ cur = a;
+ while ( (cur = cur.parentNode) ) {
+ ap.unshift( cur );
+ }
+ cur = b;
+ while ( (cur = cur.parentNode) ) {
+ bp.unshift( cur );
+ }
+
+ // Walk down the tree looking for a discrepancy
+ while ( ap[i] === bp[i] ) {
+ i++;
+ }
+
+ return i ?
+ // Do a sibling check if the nodes have a common ancestor
+ siblingCheck( ap[i], bp[i] ) :
+
+ // Otherwise nodes in our document sort first
+ ap[i] === preferredDoc ? -1 :
+ bp[i] === preferredDoc ? 1 :
+ 0;
+ };
+
+ // Always assume the presence of duplicates if sort doesn't
+ // pass them to our comparison function (as in Google Chrome).
+ hasDuplicate = false;
+ [0, 0].sort( sortOrder );
+ support.detectDuplicates = hasDuplicate;
+
+ return document;
+};
+
+Sizzle.matches = function( expr, elements ) {
+ return Sizzle( expr, null, null, elements );
+};
+
+Sizzle.matchesSelector = function( elem, expr ) {
+ // Set document vars if needed
+ if ( ( elem.ownerDocument || elem ) !== document ) {
+ setDocument( elem );
+ }
+
+ // Make sure that attribute selectors are quoted
+ expr = expr.replace( rattributeQuotes, "='$1']" );
+
+ // rbuggyQSA always contains :focus, so no need for an existence check
+ if ( support.matchesSelector && !documentIsXML && (!rbuggyMatches || !rbuggyMatches.test(expr)) && !rbuggyQSA.test(expr) ) {
+ try {
+ var ret = matches.call( elem, expr );
+
+ // IE 9's matchesSelector returns false on disconnected nodes
+ if ( ret || support.disconnectedMatch ||
+ // As well, disconnected nodes are said to be in a document
+ // fragment in IE 9
+ elem.document && elem.document.nodeType !== 11 ) {
+ return ret;
+ }
+ } catch(e) {}
+ }
+
+ return Sizzle( expr, document, null, [elem] ).length > 0;
+};
+
+Sizzle.contains = function( context, elem ) {
+ // Set document vars if needed
+ if ( ( context.ownerDocument || context ) !== document ) {
+ setDocument( context );
+ }
+ return contains( context, elem );
+};
+
+Sizzle.attr = function( elem, name ) {
+ var val;
+
+ // Set document vars if needed
+ if ( ( elem.ownerDocument || elem ) !== document ) {
+ setDocument( elem );
+ }
+
+ if ( !documentIsXML ) {
+ name = name.toLowerCase();
+ }
+ if ( (val = Expr.attrHandle[ name ]) ) {
+ return val( elem );
+ }
+ if ( documentIsXML || support.attributes ) {
+ return elem.getAttribute( name );
+ }
+ return ( (val = elem.getAttributeNode( name )) || elem.getAttribute( name ) ) && elem[ name ] === true ?
+ name :
+ val && val.specified ? val.value : null;
+};
+
+Sizzle.error = function( msg ) {
+ throw new Error( "Syntax error, unrecognized expression: " + msg );
+};
+
+// Document sorting and removing duplicates
+Sizzle.uniqueSort = function( results ) {
+ var elem,
+ duplicates = [],
+ i = 1,
+ j = 0;
+
+ // Unless we *know* we can detect duplicates, assume their presence
+ hasDuplicate = !support.detectDuplicates;
+ results.sort( sortOrder );
+
+ if ( hasDuplicate ) {
+ for ( ; (elem = results[i]); i++ ) {
+ if ( elem === results[ i - 1 ] ) {
+ j = duplicates.push( i );
+ }
+ }
+ while ( j-- ) {
+ results.splice( duplicates[ j ], 1 );
+ }
+ }
+
+ return results;
+};
+
+function siblingCheck( a, b ) {
+ var cur = b && a,
+ diff = cur && ( ~b.sourceIndex || MAX_NEGATIVE ) - ( ~a.sourceIndex || MAX_NEGATIVE );
+
+ // Use IE sourceIndex if available on both nodes
+ if ( diff ) {
+ return diff;
+ }
+
+ // Check if b follows a
+ if ( cur ) {
+ while ( (cur = cur.nextSibling) ) {
+ if ( cur === b ) {
+ return -1;
+ }
+ }
+ }
+
+ return a ? 1 : -1;
+}
+
+// Returns a function to use in pseudos for input types
+function createInputPseudo( type ) {
+ return function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && elem.type === type;
+ };
+}
+
+// Returns a function to use in pseudos for buttons
+function createButtonPseudo( type ) {
+ return function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return (name === "input" || name === "button") && elem.type === type;
+ };
+}
+
+// Returns a function to use in pseudos for positionals
+function createPositionalPseudo( fn ) {
+ return markFunction(function( argument ) {
+ argument = +argument;
+ return markFunction(function( seed, matches ) {
+ var j,
+ matchIndexes = fn( [], seed.length, argument ),
+ i = matchIndexes.length;
+
+ // Match elements found at the specified indexes
+ while ( i-- ) {
+ if ( seed[ (j = matchIndexes[i]) ] ) {
+ seed[j] = !(matches[j] = seed[j]);
+ }
+ }
+ });
+ });
+}
+
+/**
+ * Utility function for retrieving the text value of an array of DOM nodes
+ * @param {Array|Element} elem
+ */
+getText = Sizzle.getText = function( elem ) {
+ var node,
+ ret = "",
+ i = 0,
+ nodeType = elem.nodeType;
+
+ if ( !nodeType ) {
+ // If no nodeType, this is expected to be an array
+ for ( ; (node = elem[i]); i++ ) {
+ // Do not traverse comment nodes
+ ret += getText( node );
+ }
+ } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
+ // Use textContent for elements
+ // innerText usage removed for consistency of new lines (see #11153)
+ if ( typeof elem.textContent === "string" ) {
+ return elem.textContent;
+ } else {
+ // Traverse its children
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+ ret += getText( elem );
+ }
+ }
+ } else if ( nodeType === 3 || nodeType === 4 ) {
+ return elem.nodeValue;
+ }
+ // Do not include comment or processing instruction nodes
+
+ return ret;
+};
+
+Expr = Sizzle.selectors = {
+
+ // Can be adjusted by the user
+ cacheLength: 50,
+
+ createPseudo: markFunction,
+
+ match: matchExpr,
+
+ find: {},
+
+ relative: {
+ ">": { dir: "parentNode", first: true },
+ " ": { dir: "parentNode" },
+ "+": { dir: "previousSibling", first: true },
+ "~": { dir: "previousSibling" }
+ },
+
+ preFilter: {
+ "ATTR": function( match ) {
+ match[1] = match[1].replace( runescape, funescape );
+
+ // Move the given value to match[3] whether quoted or unquoted
+ match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape );
+
+ if ( match[2] === "~=" ) {
+ match[3] = " " + match[3] + " ";
+ }
+
+ return match.slice( 0, 4 );
+ },
+
+ "CHILD": function( match ) {
+ /* matches from matchExpr["CHILD"]
+ 1 type (only|nth|...)
+ 2 what (child|of-type)
+ 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
+ 4 xn-component of xn+y argument ([+-]?\d*n|)
+ 5 sign of xn-component
+ 6 x of xn-component
+ 7 sign of y-component
+ 8 y of y-component
+ */
+ match[1] = match[1].toLowerCase();
+
+ if ( match[1].slice( 0, 3 ) === "nth" ) {
+ // nth-* requires argument
+ if ( !match[3] ) {
+ Sizzle.error( match[0] );
+ }
+
+ // numeric x and y parameters for Expr.filter.CHILD
+ // remember that false/true cast respectively to 0/1
+ match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
+ match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
+
+ // other types prohibit arguments
+ } else if ( match[3] ) {
+ Sizzle.error( match[0] );
+ }
+
+ return match;
+ },
+
+ "PSEUDO": function( match ) {
+ var excess,
+ unquoted = !match[5] && match[2];
+
+ if ( matchExpr["CHILD"].test( match[0] ) ) {
+ return null;
+ }
+
+ // Accept quoted arguments as-is
+ if ( match[4] ) {
+ match[2] = match[4];
+
+ // Strip excess characters from unquoted arguments
+ } else if ( unquoted && rpseudo.test( unquoted ) &&
+ // Get excess from tokenize (recursively)
+ (excess = tokenize( unquoted, true )) &&
+ // advance to the next closing parenthesis
+ (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
+
+ // excess is a negative index
+ match[0] = match[0].slice( 0, excess );
+ match[2] = unquoted.slice( 0, excess );
+ }
+
+ // Return only captures needed by the pseudo filter method (type and argument)
+ return match.slice( 0, 3 );
+ }
+ },
+
+ filter: {
+
+ "TAG": function( nodeName ) {
+ if ( nodeName === "*" ) {
+ return function() { return true; };
+ }
+
+ nodeName = nodeName.replace( runescape, funescape ).toLowerCase();
+ return function( elem ) {
+ return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
+ };
+ },
+
+ "CLASS": function( className ) {
+ var pattern = classCache[ className + " " ];
+
+ return pattern ||
+ (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
+ classCache( className, function( elem ) {
+ return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" );
+ });
+ },
+
+ "ATTR": function( name, operator, check ) {
+ return function( elem ) {
+ var result = Sizzle.attr( elem, name );
+
+ if ( result == null ) {
+ return operator === "!=";
+ }
+ if ( !operator ) {
+ return true;
+ }
+
+ result += "";
+
+ return operator === "=" ? result === check :
+ operator === "!=" ? result !== check :
+ operator === "^=" ? check && result.indexOf( check ) === 0 :
+ operator === "*=" ? check && result.indexOf( check ) > -1 :
+ operator === "$=" ? check && result.slice( -check.length ) === check :
+ operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
+ operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
+ false;
+ };
+ },
+
+ "CHILD": function( type, what, argument, first, last ) {
+ var simple = type.slice( 0, 3 ) !== "nth",
+ forward = type.slice( -4 ) !== "last",
+ ofType = what === "of-type";
+
+ return first === 1 && last === 0 ?
+
+ // Shortcut for :nth-*(n)
+ function( elem ) {
+ return !!elem.parentNode;
+ } :
+
+ function( elem, context, xml ) {
+ var cache, outerCache, node, diff, nodeIndex, start,
+ dir = simple !== forward ? "nextSibling" : "previousSibling",
+ parent = elem.parentNode,
+ name = ofType && elem.nodeName.toLowerCase(),
+ useCache = !xml && !ofType;
+
+ if ( parent ) {
+
+ // :(first|last|only)-(child|of-type)
+ if ( simple ) {
+ while ( dir ) {
+ node = elem;
+ while ( (node = node[ dir ]) ) {
+ if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
+ return false;
+ }
+ }
+ // Reverse direction for :only-* (if we haven't yet done so)
+ start = dir = type === "only" && !start && "nextSibling";
+ }
+ return true;
+ }
+
+ start = [ forward ? parent.firstChild : parent.lastChild ];
+
+ // non-xml :nth-child(...) stores cache data on `parent`
+ if ( forward && useCache ) {
+ // Seek `elem` from a previously-cached index
+ outerCache = parent[ expando ] || (parent[ expando ] = {});
+ cache = outerCache[ type ] || [];
+ nodeIndex = cache[0] === dirruns && cache[1];
+ diff = cache[0] === dirruns && cache[2];
+ node = nodeIndex && parent.childNodes[ nodeIndex ];
+
+ while ( (node = ++nodeIndex && node && node[ dir ] ||
+
+ // Fallback to seeking `elem` from the start
+ (diff = nodeIndex = 0) || start.pop()) ) {
+
+ // When found, cache indexes on `parent` and break
+ if ( node.nodeType === 1 && ++diff && node === elem ) {
+ outerCache[ type ] = [ dirruns, nodeIndex, diff ];
+ break;
+ }
+ }
+
+ // Use previously-cached element index if available
+ } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
+ diff = cache[1];
+
+ // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
+ } else {
+ // Use the same loop as above to seek `elem` from the start
+ while ( (node = ++nodeIndex && node && node[ dir ] ||
+ (diff = nodeIndex = 0) || start.pop()) ) {
+
+ if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
+ // Cache the index of each encountered element
+ if ( useCache ) {
+ (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
+ }
+
+ if ( node === elem ) {
+ break;
+ }
+ }
+ }
+ }
+
+ // Incorporate the offset, then check against cycle size
+ diff -= last;
+ return diff === first || ( diff % first === 0 && diff / first >= 0 );
+ }
+ };
+ },
+
+ "PSEUDO": function( pseudo, argument ) {
+ // pseudo-class names are case-insensitive
+ // http://www.w3.org/TR/selectors/#pseudo-classes
+ // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
+ // Remember that setFilters inherits from pseudos
+ var args,
+ fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
+ Sizzle.error( "unsupported pseudo: " + pseudo );
+
+ // The user may use createPseudo to indicate that
+ // arguments are needed to create the filter function
+ // just as Sizzle does
+ if ( fn[ expando ] ) {
+ return fn( argument );
+ }
+
+ // But maintain support for old signatures
+ if ( fn.length > 1 ) {
+ args = [ pseudo, pseudo, "", argument ];
+ return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
+ markFunction(function( seed, matches ) {
+ var idx,
+ matched = fn( seed, argument ),
+ i = matched.length;
+ while ( i-- ) {
+ idx = indexOf.call( seed, matched[i] );
+ seed[ idx ] = !( matches[ idx ] = matched[i] );
+ }
+ }) :
+ function( elem ) {
+ return fn( elem, 0, args );
+ };
+ }
+
+ return fn;
+ }
+ },
+
+ pseudos: {
+ // Potentially complex pseudos
+ "not": markFunction(function( selector ) {
+ // Trim the selector passed to compile
+ // to avoid treating leading and trailing
+ // spaces as combinators
+ var input = [],
+ results = [],
+ matcher = compile( selector.replace( rtrim, "$1" ) );
+
+ return matcher[ expando ] ?
+ markFunction(function( seed, matches, context, xml ) {
+ var elem,
+ unmatched = matcher( seed, null, xml, [] ),
+ i = seed.length;
+
+ // Match elements unmatched by `matcher`
+ while ( i-- ) {
+ if ( (elem = unmatched[i]) ) {
+ seed[i] = !(matches[i] = elem);
+ }
+ }
+ }) :
+ function( elem, context, xml ) {
+ input[0] = elem;
+ matcher( input, null, xml, results );
+ return !results.pop();
+ };
+ }),
+
+ "has": markFunction(function( selector ) {
+ return function( elem ) {
+ return Sizzle( selector, elem ).length > 0;
+ };
+ }),
+
+ "contains": markFunction(function( text ) {
+ return function( elem ) {
+ return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
+ };
+ }),
+
+ // "Whether an element is represented by a :lang() selector
+ // is based solely on the element's language value
+ // being equal to the identifier C,
+ // or beginning with the identifier C immediately followed by "-".
+ // The matching of C against the element's language value is performed case-insensitively.
+ // The identifier C does not have to be a valid language name."
+ // http://www.w3.org/TR/selectors/#lang-pseudo
+ "lang": markFunction( function( lang ) {
+ // lang value must be a valid identifider
+ if ( !ridentifier.test(lang || "") ) {
+ Sizzle.error( "unsupported lang: " + lang );
+ }
+ lang = lang.replace( runescape, funescape ).toLowerCase();
+ return function( elem ) {
+ var elemLang;
+ do {
+ if ( (elemLang = documentIsXML ?
+ elem.getAttribute("xml:lang") || elem.getAttribute("lang") :
+ elem.lang) ) {
+
+ elemLang = elemLang.toLowerCase();
+ return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
+ }
+ } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
+ return false;
+ };
+ }),
+
+ // Miscellaneous
+ "target": function( elem ) {
+ var hash = window.location && window.location.hash;
+ return hash && hash.slice( 1 ) === elem.id;
+ },
+
+ "root": function( elem ) {
+ return elem === docElem;
+ },
+
+ "focus": function( elem ) {
+ return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
+ },
+
+ // Boolean properties
+ "enabled": function( elem ) {
+ return elem.disabled === false;
+ },
+
+ "disabled": function( elem ) {
+ return elem.disabled === true;
+ },
+
+ "checked": function( elem ) {
+ // In CSS3, :checked should return both checked and selected elements
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+ var nodeName = elem.nodeName.toLowerCase();
+ return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
+ },
+
+ "selected": function( elem ) {
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ if ( elem.parentNode ) {
+ elem.parentNode.selectedIndex;
+ }
+
+ return elem.selected === true;
+ },
+
+ // Contents
+ "empty": function( elem ) {
+ // http://www.w3.org/TR/selectors/#empty-pseudo
+ // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),
+ // not comment, processing instructions, or others
+ // Thanks to Diego Perini for the nodeName shortcut
+ // Greater than "@" means alpha characters (specifically not starting with "#" or "?")
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+ if ( elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4 ) {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ "parent": function( elem ) {
+ return !Expr.pseudos["empty"]( elem );
+ },
+
+ // Element/input types
+ "header": function( elem ) {
+ return rheader.test( elem.nodeName );
+ },
+
+ "input": function( elem ) {
+ return rinputs.test( elem.nodeName );
+ },
+
+ "button": function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && elem.type === "button" || name === "button";
+ },
+
+ "text": function( elem ) {
+ var attr;
+ // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
+ // use getAttribute instead to test this case
+ return elem.nodeName.toLowerCase() === "input" &&
+ elem.type === "text" &&
+ ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type );
+ },
+
+ // Position-in-collection
+ "first": createPositionalPseudo(function() {
+ return [ 0 ];
+ }),
+
+ "last": createPositionalPseudo(function( matchIndexes, length ) {
+ return [ length - 1 ];
+ }),
+
+ "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ return [ argument < 0 ? argument + length : argument ];
+ }),
+
+ "even": createPositionalPseudo(function( matchIndexes, length ) {
+ var i = 0;
+ for ( ; i < length; i += 2 ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ }),
+
+ "odd": createPositionalPseudo(function( matchIndexes, length ) {
+ var i = 1;
+ for ( ; i < length; i += 2 ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ }),
+
+ "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ var i = argument < 0 ? argument + length : argument;
+ for ( ; --i >= 0; ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ }),
+
+ "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ var i = argument < 0 ? argument + length : argument;
+ for ( ; ++i < length; ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ })
+ }
+};
+
+// Add button/input type pseudos
+for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
+ Expr.pseudos[ i ] = createInputPseudo( i );
+}
+for ( i in { submit: true, reset: true } ) {
+ Expr.pseudos[ i ] = createButtonPseudo( i );
+}
+
+function tokenize( selector, parseOnly ) {
+ var matched, match, tokens, type,
+ soFar, groups, preFilters,
+ cached = tokenCache[ selector + " " ];
+
+ if ( cached ) {
+ return parseOnly ? 0 : cached.slice( 0 );
+ }
+
+ soFar = selector;
+ groups = [];
+ preFilters = Expr.preFilter;
+
+ while ( soFar ) {
+
+ // Comma and first run
+ if ( !matched || (match = rcomma.exec( soFar )) ) {
+ if ( match ) {
+ // Don't consume trailing commas as valid
+ soFar = soFar.slice( match[0].length ) || soFar;
+ }
+ groups.push( tokens = [] );
+ }
+
+ matched = false;
+
+ // Combinators
+ if ( (match = rcombinators.exec( soFar )) ) {
+ matched = match.shift();
+ tokens.push( {
+ value: matched,
+ // Cast descendant combinators to space
+ type: match[0].replace( rtrim, " " )
+ } );
+ soFar = soFar.slice( matched.length );
+ }
+
+ // Filters
+ for ( type in Expr.filter ) {
+ if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
+ (match = preFilters[ type ]( match ))) ) {
+ matched = match.shift();
+ tokens.push( {
+ value: matched,
+ type: type,
+ matches: match
+ } );
+ soFar = soFar.slice( matched.length );
+ }
+ }
+
+ if ( !matched ) {
+ break;
+ }
+ }
+
+ // Return the length of the invalid excess
+ // if we're just parsing
+ // Otherwise, throw an error or return tokens
+ return parseOnly ?
+ soFar.length :
+ soFar ?
+ Sizzle.error( selector ) :
+ // Cache the tokens
+ tokenCache( selector, groups ).slice( 0 );
+}
+
+function toSelector( tokens ) {
+ var i = 0,
+ len = tokens.length,
+ selector = "";
+ for ( ; i < len; i++ ) {
+ selector += tokens[i].value;
+ }
+ return selector;
+}
+
+function addCombinator( matcher, combinator, base ) {
+ var dir = combinator.dir,
+ checkNonElements = base && dir === "parentNode",
+ doneName = done++;
+
+ return combinator.first ?
+ // Check against closest ancestor/preceding element
+ function( elem, context, xml ) {
+ while ( (elem = elem[ dir ]) ) {
+ if ( elem.nodeType === 1 || checkNonElements ) {
+ return matcher( elem, context, xml );
+ }
+ }
+ } :
+
+ // Check against all ancestor/preceding elements
+ function( elem, context, xml ) {
+ var data, cache, outerCache,
+ dirkey = dirruns + " " + doneName;
+
+ // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
+ if ( xml ) {
+ while ( (elem = elem[ dir ]) ) {
+ if ( elem.nodeType === 1 || checkNonElements ) {
+ if ( matcher( elem, context, xml ) ) {
+ return true;
+ }
+ }
+ }
+ } else {
+ while ( (elem = elem[ dir ]) ) {
+ if ( elem.nodeType === 1 || checkNonElements ) {
+ outerCache = elem[ expando ] || (elem[ expando ] = {});
+ if ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) {
+ if ( (data = cache[1]) === true || data === cachedruns ) {
+ return data === true;
+ }
+ } else {
+ cache = outerCache[ dir ] = [ dirkey ];
+ cache[1] = matcher( elem, context, xml ) || cachedruns;
+ if ( cache[1] === true ) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ };
+}
+
+function elementMatcher( matchers ) {
+ return matchers.length > 1 ?
+ function( elem, context, xml ) {
+ var i = matchers.length;
+ while ( i-- ) {
+ if ( !matchers[i]( elem, context, xml ) ) {
+ return false;
+ }
+ }
+ return true;
+ } :
+ matchers[0];
+}
+
+function condense( unmatched, map, filter, context, xml ) {
+ var elem,
+ newUnmatched = [],
+ i = 0,
+ len = unmatched.length,
+ mapped = map != null;
+
+ for ( ; i < len; i++ ) {
+ if ( (elem = unmatched[i]) ) {
+ if ( !filter || filter( elem, context, xml ) ) {
+ newUnmatched.push( elem );
+ if ( mapped ) {
+ map.push( i );
+ }
+ }
+ }
+ }
+
+ return newUnmatched;
+}
+
+function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
+ if ( postFilter && !postFilter[ expando ] ) {
+ postFilter = setMatcher( postFilter );
+ }
+ if ( postFinder && !postFinder[ expando ] ) {
+ postFinder = setMatcher( postFinder, postSelector );
+ }
+ return markFunction(function( seed, results, context, xml ) {
+ var temp, i, elem,
+ preMap = [],
+ postMap = [],
+ preexisting = results.length,
+
+ // Get initial elements from seed or context
+ elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
+
+ // Prefilter to get matcher input, preserving a map for seed-results synchronization
+ matcherIn = preFilter && ( seed || !selector ) ?
+ condense( elems, preMap, preFilter, context, xml ) :
+ elems,
+
+ matcherOut = matcher ?
+ // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
+ postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
+
+ // ...intermediate processing is necessary
+ [] :
+
+ // ...otherwise use results directly
+ results :
+ matcherIn;
+
+ // Find primary matches
+ if ( matcher ) {
+ matcher( matcherIn, matcherOut, context, xml );
+ }
+
+ // Apply postFilter
+ if ( postFilter ) {
+ temp = condense( matcherOut, postMap );
+ postFilter( temp, [], context, xml );
+
+ // Un-match failing elements by moving them back to matcherIn
+ i = temp.length;
+ while ( i-- ) {
+ if ( (elem = temp[i]) ) {
+ matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
+ }
+ }
+ }
+
+ if ( seed ) {
+ if ( postFinder || preFilter ) {
+ if ( postFinder ) {
+ // Get the final matcherOut by condensing this intermediate into postFinder contexts
+ temp = [];
+ i = matcherOut.length;
+ while ( i-- ) {
+ if ( (elem = matcherOut[i]) ) {
+ // Restore matcherIn since elem is not yet a final match
+ temp.push( (matcherIn[i] = elem) );
+ }
+ }
+ postFinder( null, (matcherOut = []), temp, xml );
+ }
+
+ // Move matched elements from seed to results to keep them synchronized
+ i = matcherOut.length;
+ while ( i-- ) {
+ if ( (elem = matcherOut[i]) &&
+ (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
+
+ seed[temp] = !(results[temp] = elem);
+ }
+ }
+ }
+
+ // Add elements to results, through postFinder if defined
+ } else {
+ matcherOut = condense(
+ matcherOut === results ?
+ matcherOut.splice( preexisting, matcherOut.length ) :
+ matcherOut
+ );
+ if ( postFinder ) {
+ postFinder( null, results, matcherOut, xml );
+ } else {
+ push.apply( results, matcherOut );
+ }
+ }
+ });
+}
+
+function matcherFromTokens( tokens ) {
+ var checkContext, matcher, j,
+ len = tokens.length,
+ leadingRelative = Expr.relative[ tokens[0].type ],
+ implicitRelative = leadingRelative || Expr.relative[" "],
+ i = leadingRelative ? 1 : 0,
+
+ // The foundational matcher ensures that elements are reachable from top-level context(s)
+ matchContext = addCombinator( function( elem ) {
+ return elem === checkContext;
+ }, implicitRelative, true ),
+ matchAnyContext = addCombinator( function( elem ) {
+ return indexOf.call( checkContext, elem ) > -1;
+ }, implicitRelative, true ),
+ matchers = [ function( elem, context, xml ) {
+ return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
+ (checkContext = context).nodeType ?
+ matchContext( elem, context, xml ) :
+ matchAnyContext( elem, context, xml ) );
+ } ];
+
+ for ( ; i < len; i++ ) {
+ if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
+ matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
+ } else {
+ matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
+
+ // Return special upon seeing a positional matcher
+ if ( matcher[ expando ] ) {
+ // Find the next relative operator (if any) for proper handling
+ j = ++i;
+ for ( ; j < len; j++ ) {
+ if ( Expr.relative[ tokens[j].type ] ) {
+ break;
+ }
+ }
+ return setMatcher(
+ i > 1 && elementMatcher( matchers ),
+ i > 1 && toSelector( tokens.slice( 0, i - 1 ) ).replace( rtrim, "$1" ),
+ matcher,
+ i < j && matcherFromTokens( tokens.slice( i, j ) ),
+ j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
+ j < len && toSelector( tokens )
+ );
+ }
+ matchers.push( matcher );
+ }
+ }
+
+ return elementMatcher( matchers );
+}
+
+function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
+ // A counter to specify which element is currently being matched
+ var matcherCachedRuns = 0,
+ bySet = setMatchers.length > 0,
+ byElement = elementMatchers.length > 0,
+ superMatcher = function( seed, context, xml, results, expandContext ) {
+ var elem, j, matcher,
+ setMatched = [],
+ matchedCount = 0,
+ i = "0",
+ unmatched = seed && [],
+ outermost = expandContext != null,
+ contextBackup = outermostContext,
+ // We must always have either seed elements or context
+ elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ),
+ // Use integer dirruns iff this is the outermost matcher
+ dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1);
+
+ if ( outermost ) {
+ outermostContext = context !== document && context;
+ cachedruns = matcherCachedRuns;
+ }
+
+ // Add elements passing elementMatchers directly to results
+ // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
+ for ( ; (elem = elems[i]) != null; i++ ) {
+ if ( byElement && elem ) {
+ j = 0;
+ while ( (matcher = elementMatchers[j++]) ) {
+ if ( matcher( elem, context, xml ) ) {
+ results.push( elem );
+ break;
+ }
+ }
+ if ( outermost ) {
+ dirruns = dirrunsUnique;
+ cachedruns = ++matcherCachedRuns;
+ }
+ }
+
+ // Track unmatched elements for set filters
+ if ( bySet ) {
+ // They will have gone through all possible matchers
+ if ( (elem = !matcher && elem) ) {
+ matchedCount--;
+ }
+
+ // Lengthen the array for every element, matched or not
+ if ( seed ) {
+ unmatched.push( elem );
+ }
+ }
+ }
+
+ // Apply set filters to unmatched elements
+ matchedCount += i;
+ if ( bySet && i !== matchedCount ) {
+ j = 0;
+ while ( (matcher = setMatchers[j++]) ) {
+ matcher( unmatched, setMatched, context, xml );
+ }
+
+ if ( seed ) {
+ // Reintegrate element matches to eliminate the need for sorting
+ if ( matchedCount > 0 ) {
+ while ( i-- ) {
+ if ( !(unmatched[i] || setMatched[i]) ) {
+ setMatched[i] = pop.call( results );
+ }
+ }
+ }
+
+ // Discard index placeholder values to get only actual matches
+ setMatched = condense( setMatched );
+ }
+
+ // Add matches to results
+ push.apply( results, setMatched );
+
+ // Seedless set matches succeeding multiple successful matchers stipulate sorting
+ if ( outermost && !seed && setMatched.length > 0 &&
+ ( matchedCount + setMatchers.length ) > 1 ) {
+
+ Sizzle.uniqueSort( results );
+ }
+ }
+
+ // Override manipulation of globals by nested matchers
+ if ( outermost ) {
+ dirruns = dirrunsUnique;
+ outermostContext = contextBackup;
+ }
+
+ return unmatched;
+ };
+
+ return bySet ?
+ markFunction( superMatcher ) :
+ superMatcher;
+}
+
+compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {
+ var i,
+ setMatchers = [],
+ elementMatchers = [],
+ cached = compilerCache[ selector + " " ];
+
+ if ( !cached ) {
+ // Generate a function of recursive functions that can be used to check each element
+ if ( !group ) {
+ group = tokenize( selector );
+ }
+ i = group.length;
+ while ( i-- ) {
+ cached = matcherFromTokens( group[i] );
+ if ( cached[ expando ] ) {
+ setMatchers.push( cached );
+ } else {
+ elementMatchers.push( cached );
+ }
+ }
+
+ // Cache the compiled function
+ cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
+ }
+ return cached;
+};
+
+function multipleContexts( selector, contexts, results ) {
+ var i = 0,
+ len = contexts.length;
+ for ( ; i < len; i++ ) {
+ Sizzle( selector, contexts[i], results );
+ }
+ return results;
+}
+
+function select( selector, context, results, seed ) {
+ var i, tokens, token, type, find,
+ match = tokenize( selector );
+
+ if ( !seed ) {
+ // Try to minimize operations if there is only one group
+ if ( match.length === 1 ) {
+
+ // Take a shortcut and set the context if the root selector is an ID
+ tokens = match[0] = match[0].slice( 0 );
+ if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
+ context.nodeType === 9 && !documentIsXML &&
+ Expr.relative[ tokens[1].type ] ) {
+
+ context = Expr.find["ID"]( token.matches[0].replace( runescape, funescape ), context )[0];
+ if ( !context ) {
+ return results;
+ }
+
+ selector = selector.slice( tokens.shift().value.length );
+ }
+
+ // Fetch a seed set for right-to-left matching
+ i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
+ while ( i-- ) {
+ token = tokens[i];
+
+ // Abort if we hit a combinator
+ if ( Expr.relative[ (type = token.type) ] ) {
+ break;
+ }
+ if ( (find = Expr.find[ type ]) ) {
+ // Search, expanding context for leading sibling combinators
+ if ( (seed = find(
+ token.matches[0].replace( runescape, funescape ),
+ rsibling.test( tokens[0].type ) && context.parentNode || context
+ )) ) {
+
+ // If seed is empty or no tokens remain, we can return early
+ tokens.splice( i, 1 );
+ selector = seed.length && toSelector( tokens );
+ if ( !selector ) {
+ push.apply( results, slice.call( seed, 0 ) );
+ return results;
+ }
+
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // Compile and execute a filtering function
+ // Provide `match` to avoid retokenization if we modified the selector above
+ compile( selector, match )(
+ seed,
+ context,
+ documentIsXML,
+ results,
+ rsibling.test( selector )
+ );
+ return results;
+}
+
+// Deprecated
+Expr.pseudos["nth"] = Expr.pseudos["eq"];
+
+// Easy API for creating new setFilters
+function setFilters() {}
+Expr.filters = setFilters.prototype = Expr.pseudos;
+Expr.setFilters = new setFilters();
+
+// Initialize with the default document
+setDocument();
+
+// Override sizzle attribute retrieval
+Sizzle.attr = jQuery.attr;
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.pseudos;
+jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = Sizzle.getText;
+jQuery.isXMLDoc = Sizzle.isXML;
+jQuery.contains = Sizzle.contains;
+
+
+})( window );
+var runtil = /Until$/,
+ rparentsprev = /^(?:parents|prev(?:Until|All))/,
+ isSimple = /^.[^:#\[\.,]*$/,
+ rneedsContext = jQuery.expr.match.needsContext,
+ // methods guaranteed to produce a unique set when starting from a unique set
+ guaranteedUnique = {
+ children: true,
+ contents: true,
+ next: true,
+ prev: true
+ };
+
+jQuery.fn.extend({
+ find: function( selector ) {
+ var i, ret, self,
+ len = this.length;
+
+ if ( typeof selector !== "string" ) {
+ self = this;
+ return this.pushStack( jQuery( selector ).filter(function() {
+ for ( i = 0; i < len; i++ ) {
+ if ( jQuery.contains( self[ i ], this ) ) {
+ return true;
+ }
+ }
+ }) );
+ }
+
+ ret = [];
+ for ( i = 0; i < len; i++ ) {
+ jQuery.find( selector, this[ i ], ret );
+ }
+
+ // Needed because $( selector, context ) becomes $( context ).find( selector )
+ ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
+ ret.selector = ( this.selector ? this.selector + " " : "" ) + selector;
+ return ret;
+ },
+
+ has: function( target ) {
+ var i,
+ targets = jQuery( target, this ),
+ len = targets.length;
+
+ return this.filter(function() {
+ for ( i = 0; i < len; i++ ) {
+ if ( jQuery.contains( this, targets[i] ) ) {
+ return true;
+ }
+ }
+ });
+ },
+
+ not: function( selector ) {
+ return this.pushStack( winnow(this, selector, false) );
+ },
+
+ filter: function( selector ) {
+ return this.pushStack( winnow(this, selector, true) );
+ },
+
+ is: function( selector ) {
+ return !!selector && (
+ typeof selector === "string" ?
+ // If this is a positional/relative selector, check membership in the returned set
+ // so $("p:first").is("p:last") won't return true for a doc with two "p".
+ rneedsContext.test( selector ) ?
+ jQuery( selector, this.context ).index( this[0] ) >= 0 :
+ jQuery.filter( selector, this ).length > 0 :
+ this.filter( selector ).length > 0 );
+ },
+
+ closest: function( selectors, context ) {
+ var cur,
+ i = 0,
+ l = this.length,
+ ret = [],
+ pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
+ jQuery( selectors, context || this.context ) :
+ 0;
+
+ for ( ; i < l; i++ ) {
+ cur = this[i];
+
+ while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) {
+ if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
+ ret.push( cur );
+ break;
+ }
+ cur = cur.parentNode;
+ }
+ }
+
+ return this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret );
+ },
+
+ // Determine the position of an element within
+ // the matched set of elements
+ index: function( elem ) {
+
+ // No argument, return index in parent
+ if ( !elem ) {
+ return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;
+ }
+
+ // index in selector
+ if ( typeof elem === "string" ) {
+ return jQuery.inArray( this[0], jQuery( elem ) );
+ }
+
+ // Locate the position of the desired element
+ return jQuery.inArray(
+ // If it receives a jQuery object, the first element is used
+ elem.jquery ? elem[0] : elem, this );
+ },
+
+ add: function( selector, context ) {
+ var set = typeof selector === "string" ?
+ jQuery( selector, context ) :
+ jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
+ all = jQuery.merge( this.get(), set );
+
+ return this.pushStack( jQuery.unique(all) );
+ },
+
+ addBack: function( selector ) {
+ return this.add( selector == null ?
+ this.prevObject : this.prevObject.filter(selector)
+ );
+ }
+});
+
+jQuery.fn.andSelf = jQuery.fn.addBack;
+
+function sibling( cur, dir ) {
+ do {
+ cur = cur[ dir ];
+ } while ( cur && cur.nodeType !== 1 );
+
+ return cur;
+}
+
+jQuery.each({
+ parent: function( elem ) {
+ var parent = elem.parentNode;
+ return parent && parent.nodeType !== 11 ? parent : null;
+ },
+ parents: function( elem ) {
+ return jQuery.dir( elem, "parentNode" );
+ },
+ parentsUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "parentNode", until );
+ },
+ next: function( elem ) {
+ return sibling( elem, "nextSibling" );
+ },
+ prev: function( elem ) {
+ return sibling( elem, "previousSibling" );
+ },
+ nextAll: function( elem ) {
+ return jQuery.dir( elem, "nextSibling" );
+ },
+ prevAll: function( elem ) {
+ return jQuery.dir( elem, "previousSibling" );
+ },
+ nextUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "nextSibling", until );
+ },
+ prevUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "previousSibling", until );
+ },
+ siblings: function( elem ) {
+ return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
+ },
+ children: function( elem ) {
+ return jQuery.sibling( elem.firstChild );
+ },
+ contents: function( elem ) {
+ return jQuery.nodeName( elem, "iframe" ) ?
+ elem.contentDocument || elem.contentWindow.document :
+ jQuery.merge( [], elem.childNodes );
+ }
+}, function( name, fn ) {
+ jQuery.fn[ name ] = function( until, selector ) {
+ var ret = jQuery.map( this, fn, until );
+
+ if ( !runtil.test( name ) ) {
+ selector = until;
+ }
+
+ if ( selector && typeof selector === "string" ) {
+ ret = jQuery.filter( selector, ret );
+ }
+
+ ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
+
+ if ( this.length > 1 && rparentsprev.test( name ) ) {
+ ret = ret.reverse();
+ }
+
+ return this.pushStack( ret );
+ };
+});
+
+jQuery.extend({
+ filter: function( expr, elems, not ) {
+ if ( not ) {
+ expr = ":not(" + expr + ")";
+ }
+
+ return elems.length === 1 ?
+ jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
+ jQuery.find.matches(expr, elems);
+ },
+
+ dir: function( elem, dir, until ) {
+ var matched = [],
+ cur = elem[ dir ];
+
+ while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
+ if ( cur.nodeType === 1 ) {
+ matched.push( cur );
+ }
+ cur = cur[dir];
+ }
+ return matched;
+ },
+
+ sibling: function( n, elem ) {
+ var r = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType === 1 && n !== elem ) {
+ r.push( n );
+ }
+ }
+
+ return r;
+ }
+});
+
+// Implement the identical functionality for filter and not
+function winnow( elements, qualifier, keep ) {
+
+ // Can't pass null or undefined to indexOf in Firefox 4
+ // Set to 0 to skip string check
+ qualifier = qualifier || 0;
+
+ if ( jQuery.isFunction( qualifier ) ) {
+ return jQuery.grep(elements, function( elem, i ) {
+ var retVal = !!qualifier.call( elem, i, elem );
+ return retVal === keep;
+ });
+
+ } else if ( qualifier.nodeType ) {
+ return jQuery.grep(elements, function( elem ) {
+ return ( elem === qualifier ) === keep;
+ });
+
+ } else if ( typeof qualifier === "string" ) {
+ var filtered = jQuery.grep(elements, function( elem ) {
+ return elem.nodeType === 1;
+ });
+
+ if ( isSimple.test( qualifier ) ) {
+ return jQuery.filter(qualifier, filtered, !keep);
+ } else {
+ qualifier = jQuery.filter( qualifier, filtered );
+ }
+ }
+
+ return jQuery.grep(elements, function( elem ) {
+ return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep;
+ });
+}
+function createSafeFragment( document ) {
+ var list = nodeNames.split( "|" ),
+ safeFrag = document.createDocumentFragment();
+
+ if ( safeFrag.createElement ) {
+ while ( list.length ) {
+ safeFrag.createElement(
+ list.pop()
+ );
+ }
+ }
+ return safeFrag;
+}
+
+var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +
+ "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
+ rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
+ rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
+ rleadingWhitespace = /^\s+/,
+ rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
+ rtagName = /<([\w:]+)/,
+ rtbody = /<tbody/i,
+ rhtml = /<|&#?\w+;/,
+ rnoInnerhtml = /<(?:script|style|link)/i,
+ manipulation_rcheckableType = /^(?:checkbox|radio)$/i,
+ // checked="checked" or checked
+ rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
+ rscriptType = /^$|\/(?:java|ecma)script/i,
+ rscriptTypeMasked = /^true\/(.*)/,
+ rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
+
+ // We have to close these tags to support XHTML (#13200)
+ wrapMap = {
+ option: [ 1, "<select multiple='multiple'>", "</select>" ],
+ legend: [ 1, "<fieldset>", "</fieldset>" ],
+ area: [ 1, "<map>", "</map>" ],
+ param: [ 1, "<object>", "</object>" ],
+ thead: [ 1, "<table>", "</table>" ],
+ tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+ col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
+ td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+
+ // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
+ // unless wrapped in a div with non-breaking characters in front of it.
+ _default: jQuery.support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>" ]
+ },
+ safeFragment = createSafeFragment( document ),
+ fragmentDiv = safeFragment.appendChild( document.createElement("div") );
+
+wrapMap.optgroup = wrapMap.option;
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+jQuery.fn.extend({
+ text: function( value ) {
+ return jQuery.access( this, function( value ) {
+ return value === undefined ?
+ jQuery.text( this ) :
+ this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
+ }, null, value, arguments.length );
+ },
+
+ wrapAll: function( html ) {
+ if ( jQuery.isFunction( html ) ) {
+ return this.each(function(i) {
+ jQuery(this).wrapAll( html.call(this, i) );
+ });
+ }
+
+ if ( this[0] ) {
+ // The elements to wrap the target around
+ var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
+
+ if ( this[0].parentNode ) {
+ wrap.insertBefore( this[0] );
+ }
+
+ wrap.map(function() {
+ var elem = this;
+
+ while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
+ elem = elem.firstChild;
+ }
+
+ return elem;
+ }).append( this );
+ }
+
+ return this;
+ },
+
+ wrapInner: function( html ) {
+ if ( jQuery.isFunction( html ) ) {
+ return this.each(function(i) {
+ jQuery(this).wrapInner( html.call(this, i) );
+ });
+ }
+
+ return this.each(function() {
+ var self = jQuery( this ),
+ contents = self.contents();
+
+ if ( contents.length ) {
+ contents.wrapAll( html );
+
+ } else {
+ self.append( html );
+ }
+ });
+ },
+
+ wrap: function( html ) {
+ var isFunction = jQuery.isFunction( html );
+
+ return this.each(function(i) {
+ jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
+ });
+ },
+
+ unwrap: function() {
+ return this.parent().each(function() {
+ if ( !jQuery.nodeName( this, "body" ) ) {
+ jQuery( this ).replaceWith( this.childNodes );
+ }
+ }).end();
+ },
+
+ append: function() {
+ return this.domManip(arguments, true, function( elem ) {
+ if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+ this.appendChild( elem );
+ }
+ });
+ },
+
+ prepend: function() {
+ return this.domManip(arguments, true, function( elem ) {
+ if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+ this.insertBefore( elem, this.firstChild );
+ }
+ });
+ },
+
+ before: function() {
+ return this.domManip( arguments, false, function( elem ) {
+ if ( this.parentNode ) {
+ this.parentNode.insertBefore( elem, this );
+ }
+ });
+ },
+
+ after: function() {
+ return this.domManip( arguments, false, function( elem ) {
+ if ( this.parentNode ) {
+ this.parentNode.insertBefore( elem, this.nextSibling );
+ }
+ });
+ },
+
+ // keepData is for internal use only--do not document
+ remove: function( selector, keepData ) {
+ var elem,
+ i = 0;
+
+ for ( ; (elem = this[i]) != null; i++ ) {
+ if ( !selector || jQuery.filter( selector, [ elem ] ).length > 0 ) {
+ if ( !keepData && elem.nodeType === 1 ) {
+ jQuery.cleanData( getAll( elem ) );
+ }
+
+ if ( elem.parentNode ) {
+ if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
+ setGlobalEval( getAll( elem, "script" ) );
+ }
+ elem.parentNode.removeChild( elem );
+ }
+ }
+ }
+
+ return this;
+ },
+
+ empty: function() {
+ var elem,
+ i = 0;
+
+ for ( ; (elem = this[i]) != null; i++ ) {
+ // Remove element nodes and prevent memory leaks
+ if ( elem.nodeType === 1 ) {
+ jQuery.cleanData( getAll( elem, false ) );
+ }
+
+ // Remove any remaining nodes
+ while ( elem.firstChild ) {
+ elem.removeChild( elem.firstChild );
+ }
+
+ // If this is a select, ensure that it displays empty (#12336)
+ // Support: IE<9
+ if ( elem.options && jQuery.nodeName( elem, "select" ) ) {
+ elem.options.length = 0;
+ }
+ }
+
+ return this;
+ },
+
+ clone: function( dataAndEvents, deepDataAndEvents ) {
+ dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
+ deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
+
+ return this.map( function () {
+ return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
+ });
+ },
+
+ html: function( value ) {
+ return jQuery.access( this, function( value ) {
+ var elem = this[0] || {},
+ i = 0,
+ l = this.length;
+
+ if ( value === undefined ) {
+ return elem.nodeType === 1 ?
+ elem.innerHTML.replace( rinlinejQuery, "" ) :
+ undefined;
+ }
+
+ // See if we can take a shortcut and just use innerHTML
+ if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
+ ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) &&
+ ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
+ !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) {
+
+ value = value.replace( rxhtmlTag, "<$1></$2>" );
+
+ try {
+ for (; i < l; i++ ) {
+ // Remove element nodes and prevent memory leaks
+ elem = this[i] || {};
+ if ( elem.nodeType === 1 ) {
+ jQuery.cleanData( getAll( elem, false ) );
+ elem.innerHTML = value;
+ }
+ }
+
+ elem = 0;
+
+ // If using innerHTML throws an exception, use the fallback method
+ } catch(e) {}
+ }
+
+ if ( elem ) {
+ this.empty().append( value );
+ }
+ }, null, value, arguments.length );
+ },
+
+ replaceWith: function( value ) {
+ var isFunc = jQuery.isFunction( value );
+
+ // Make sure that the elements are removed from the DOM before they are inserted
+ // this can help fix replacing a parent with child elements
+ if ( !isFunc && typeof value !== "string" ) {
+ value = jQuery( value ).not( this ).detach();
+ }
+
+ return this.domManip( [ value ], true, function( elem ) {
+ var next = this.nextSibling,
+ parent = this.parentNode;
+
+ if ( parent ) {
+ jQuery( this ).remove();
+ parent.insertBefore( elem, next );
+ }
+ });
+ },
+
+ detach: function( selector ) {
+ return this.remove( selector, true );
+ },
+
+ domManip: function( args, table, callback ) {
+
+ // Flatten any nested arrays
+ args = core_concat.apply( [], args );
+
+ var first, node, hasScripts,
+ scripts, doc, fragment,
+ i = 0,
+ l = this.length,
+ set = this,
+ iNoClone = l - 1,
+ value = args[0],
+ isFunction = jQuery.isFunction( value );
+
+ // We can't cloneNode fragments that contain checked, in WebKit
+ if ( isFunction || !( l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test( value ) ) ) {
+ return this.each(function( index ) {
+ var self = set.eq( index );
+ if ( isFunction ) {
+ args[0] = value.call( this, index, table ? self.html() : undefined );
+ }
+ self.domManip( args, table, callback );
+ });
+ }
+
+ if ( l ) {
+ fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );
+ first = fragment.firstChild;
+
+ if ( fragment.childNodes.length === 1 ) {
+ fragment = first;
+ }
+
+ if ( first ) {
+ table = table && jQuery.nodeName( first, "tr" );
+ scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
+ hasScripts = scripts.length;
+
+ // Use the original fragment for the last item instead of the first because it can end up
+ // being emptied incorrectly in certain situations (#8070).
+ for ( ; i < l; i++ ) {
+ node = fragment;
+
+ if ( i !== iNoClone ) {
+ node = jQuery.clone( node, true, true );
+
+ // Keep references to cloned scripts for later restoration
+ if ( hasScripts ) {
+ jQuery.merge( scripts, getAll( node, "script" ) );
+ }
+ }
+
+ callback.call(
+ table && jQuery.nodeName( this[i], "table" ) ?
+ findOrAppend( this[i], "tbody" ) :
+ this[i],
+ node,
+ i
+ );
+ }
+
+ if ( hasScripts ) {
+ doc = scripts[ scripts.length - 1 ].ownerDocument;
+
+ // Reenable scripts
+ jQuery.map( scripts, restoreScript );
+
+ // Evaluate executable scripts on first document insertion
+ for ( i = 0; i < hasScripts; i++ ) {
+ node = scripts[ i ];
+ if ( rscriptType.test( node.type || "" ) &&
+ !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
+
+ if ( node.src ) {
+ // Hope ajax is available...
+ jQuery.ajax({
+ url: node.src,
+ type: "GET",
+ dataType: "script",
+ async: false,
+ global: false,
+ "throws": true
+ });
+ } else {
+ jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) );
+ }
+ }
+ }
+ }
+
+ // Fix #11809: Avoid leaking memory
+ fragment = first = null;
+ }
+ }
+
+ return this;
+ }
+});
+
+function findOrAppend( elem, tag ) {
+ return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) );
+}
+
+// Replace/restore the type attribute of script elements for safe DOM manipulation
+function disableScript( elem ) {
+ var attr = elem.getAttributeNode("type");
+ elem.type = ( attr && attr.specified ) + "/" + elem.type;
+ return elem;
+}
+function restoreScript( elem ) {
+ var match = rscriptTypeMasked.exec( elem.type );
+ if ( match ) {
+ elem.type = match[1];
+ } else {
+ elem.removeAttribute("type");
+ }
+ return elem;
+}
+
+// Mark scripts as having already been evaluated
+function setGlobalEval( elems, refElements ) {
+ var elem,
+ i = 0;
+ for ( ; (elem = elems[i]) != null; i++ ) {
+ jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) );
+ }
+}
+
+function cloneCopyEvent( src, dest ) {
+
+ if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
+ return;
+ }
+
+ var type, i, l,
+ oldData = jQuery._data( src ),
+ curData = jQuery._data( dest, oldData ),
+ events = oldData.events;
+
+ if ( events ) {
+ delete curData.handle;
+ curData.events = {};
+
+ for ( type in events ) {
+ for ( i = 0, l = events[ type ].length; i < l; i++ ) {
+ jQuery.event.add( dest, type, events[ type ][ i ] );
+ }
+ }
+ }
+
+ // make the cloned public data object a copy from the original
+ if ( curData.data ) {
+ curData.data = jQuery.extend( {}, curData.data );
+ }
+}
+
+function fixCloneNodeIssues( src, dest ) {
+ var nodeName, e, data;
+
+ // We do not need to do anything for non-Elements
+ if ( dest.nodeType !== 1 ) {
+ return;
+ }
+
+ nodeName = dest.nodeName.toLowerCase();
+
+ // IE6-8 copies events bound via attachEvent when using cloneNode.
+ if ( !jQuery.support.noCloneEvent && dest[ jQuery.expando ] ) {
+ data = jQuery._data( dest );
+
+ for ( e in data.events ) {
+ jQuery.removeEvent( dest, e, data.handle );
+ }
+
+ // Event data gets referenced instead of copied if the expando gets copied too
+ dest.removeAttribute( jQuery.expando );
+ }
+
+ // IE blanks contents when cloning scripts, and tries to evaluate newly-set text
+ if ( nodeName === "script" && dest.text !== src.text ) {
+ disableScript( dest ).text = src.text;
+ restoreScript( dest );
+
+ // IE6-10 improperly clones children of object elements using classid.
+ // IE10 throws NoModificationAllowedError if parent is null, #12132.
+ } else if ( nodeName === "object" ) {
+ if ( dest.parentNode ) {
+ dest.outerHTML = src.outerHTML;
+ }
+
+ // This path appears unavoidable for IE9. When cloning an object
+ // element in IE9, the outerHTML strategy above is not sufficient.
+ // If the src has innerHTML and the destination does not,
+ // copy the src.innerHTML into the dest.innerHTML. #10324
+ if ( jQuery.support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {
+ dest.innerHTML = src.innerHTML;
+ }
+
+ } else if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) {
+ // IE6-8 fails to persist the checked state of a cloned checkbox
+ // or radio button. Worse, IE6-7 fail to give the cloned element
+ // a checked appearance if the defaultChecked value isn't also set
+
+ dest.defaultChecked = dest.checked = src.checked;
+
+ // IE6-7 get confused and end up setting the value of a cloned
+ // checkbox/radio button to an empty string instead of "on"
+ if ( dest.value !== src.value ) {
+ dest.value = src.value;
+ }
+
+ // IE6-8 fails to return the selected option to the default selected
+ // state when cloning options
+ } else if ( nodeName === "option" ) {
+ dest.defaultSelected = dest.selected = src.defaultSelected;
+
+ // IE6-8 fails to set the defaultValue to the correct value when
+ // cloning other types of input fields
+ } else if ( nodeName === "input" || nodeName === "textarea" ) {
+ dest.defaultValue = src.defaultValue;
+ }
+}
+
+jQuery.each({
+ appendTo: "append",
+ prependTo: "prepend",
+ insertBefore: "before",
+ insertAfter: "after",
+ replaceAll: "replaceWith"
+}, function( name, original ) {
+ jQuery.fn[ name ] = function( selector ) {
+ var elems,
+ i = 0,
+ ret = [],
+ insert = jQuery( selector ),
+ last = insert.length - 1;
+
+ for ( ; i <= last; i++ ) {
+ elems = i === last ? this : this.clone(true);
+ jQuery( insert[i] )[ original ]( elems );
+
+ // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
+ core_push.apply( ret, elems.get() );
+ }
+
+ return this.pushStack( ret );
+ };
+});
+
+function getAll( context, tag ) {
+ var elems, elem,
+ i = 0,
+ found = typeof context.getElementsByTagName !== core_strundefined ? context.getElementsByTagName( tag || "*" ) :
+ typeof context.querySelectorAll !== core_strundefined ? context.querySelectorAll( tag || "*" ) :
+ undefined;
+
+ if ( !found ) {
+ for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {
+ if ( !tag || jQuery.nodeName( elem, tag ) ) {
+ found.push( elem );
+ } else {
+ jQuery.merge( found, getAll( elem, tag ) );
+ }
+ }
+ }
+
+ return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
+ jQuery.merge( [ context ], found ) :
+ found;
+}
+
+// Used in buildFragment, fixes the defaultChecked property
+function fixDefaultChecked( elem ) {
+ if ( manipulation_rcheckableType.test( elem.type ) ) {
+ elem.defaultChecked = elem.checked;
+ }
+}
+
+jQuery.extend({
+ clone: function( elem, dataAndEvents, deepDataAndEvents ) {
+ var destElements, node, clone, i, srcElements,
+ inPage = jQuery.contains( elem.ownerDocument, elem );
+
+ if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
+ clone = elem.cloneNode( true );
+
+ // IE<=8 does not properly clone detached, unknown element nodes
+ } else {
+ fragmentDiv.innerHTML = elem.outerHTML;
+ fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
+ }
+
+ if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
+ (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
+
+ // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
+ destElements = getAll( clone );
+ srcElements = getAll( elem );
+
+ // Fix all IE cloning issues
+ for ( i = 0; (node = srcElements[i]) != null; ++i ) {
+ // Ensure that the destination node is not null; Fixes #9587
+ if ( destElements[i] ) {
+ fixCloneNodeIssues( node, destElements[i] );
+ }
+ }
+ }
+
+ // Copy the events from the original to the clone
+ if ( dataAndEvents ) {
+ if ( deepDataAndEvents ) {
+ srcElements = srcElements || getAll( elem );
+ destElements = destElements || getAll( clone );
+
+ for ( i = 0; (node = srcElements[i]) != null; i++ ) {
+ cloneCopyEvent( node, destElements[i] );
+ }
+ } else {
+ cloneCopyEvent( elem, clone );
+ }
+ }
+
+ // Preserve script evaluation history
+ destElements = getAll( clone, "script" );
+ if ( destElements.length > 0 ) {
+ setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
+ }
+
+ destElements = srcElements = node = null;
+
+ // Return the cloned set
+ return clone;
+ },
+
+ buildFragment: function( elems, context, scripts, selection ) {
+ var j, elem, contains,
+ tmp, tag, tbody, wrap,
+ l = elems.length,
+
+ // Ensure a safe fragment
+ safe = createSafeFragment( context ),
+
+ nodes = [],
+ i = 0;
+
+ for ( ; i < l; i++ ) {
+ elem = elems[ i ];
+
+ if ( elem || elem === 0 ) {
+
+ // Add nodes directly
+ if ( jQuery.type( elem ) === "object" ) {
+ jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
+
+ // Convert non-html into a text node
+ } else if ( !rhtml.test( elem ) ) {
+ nodes.push( context.createTextNode( elem ) );
+
+ // Convert html into DOM nodes
+ } else {
+ tmp = tmp || safe.appendChild( context.createElement("div") );
+
+ // Deserialize a standard representation
+ tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase();
+ wrap = wrapMap[ tag ] || wrapMap._default;
+
+ tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[2];
+
+ // Descend through wrappers to the right content
+ j = wrap[0];
+ while ( j-- ) {
+ tmp = tmp.lastChild;
+ }
+
+ // Manually add leading whitespace removed by IE
+ if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
+ nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );
+ }
+
+ // Remove IE's autoinserted <tbody> from table fragments
+ if ( !jQuery.support.tbody ) {
+
+ // String was a <table>, *may* have spurious <tbody>
+ elem = tag === "table" && !rtbody.test( elem ) ?
+ tmp.firstChild :
+
+ // String was a bare <thead> or <tfoot>
+ wrap[1] === "<table>" && !rtbody.test( elem ) ?
+ tmp :
+ 0;
+
+ j = elem && elem.childNodes.length;
+ while ( j-- ) {
+ if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) {
+ elem.removeChild( tbody );
+ }
+ }
+ }
+
+ jQuery.merge( nodes, tmp.childNodes );
+
+ // Fix #12392 for WebKit and IE > 9
+ tmp.textContent = "";
+
+ // Fix #12392 for oldIE
+ while ( tmp.firstChild ) {
+ tmp.removeChild( tmp.firstChild );
+ }
+
+ // Remember the top-level container for proper cleanup
+ tmp = safe.lastChild;
+ }
+ }
+ }
+
+ // Fix #11356: Clear elements from fragment
+ if ( tmp ) {
+ safe.removeChild( tmp );
+ }
+
+ // Reset defaultChecked for any radios and checkboxes
+ // about to be appended to the DOM in IE 6/7 (#8060)
+ if ( !jQuery.support.appendChecked ) {
+ jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
+ }
+
+ i = 0;
+ while ( (elem = nodes[ i++ ]) ) {
+
+ // #4087 - If origin and destination elements are the same, and this is
+ // that element, do not do anything
+ if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
+ continue;
+ }
+
+ contains = jQuery.contains( elem.ownerDocument, elem );
+
+ // Append to fragment
+ tmp = getAll( safe.appendChild( elem ), "script" );
+
+ // Preserve script evaluation history
+ if ( contains ) {
+ setGlobalEval( tmp );
+ }
+
+ // Capture executables
+ if ( scripts ) {
+ j = 0;
+ while ( (elem = tmp[ j++ ]) ) {
+ if ( rscriptType.test( elem.type || "" ) ) {
+ scripts.push( elem );
+ }
+ }
+ }
+ }
+
+ tmp = null;
+
+ return safe;
+ },
+
+ cleanData: function( elems, /* internal */ acceptData ) {
+ var elem, type, id, data,
+ i = 0,
+ internalKey = jQuery.expando,
+ cache = jQuery.cache,
+ deleteExpando = jQuery.support.deleteExpando,
+ special = jQuery.event.special;
+
+ for ( ; (elem = elems[i]) != null; i++ ) {
+
+ if ( acceptData || jQuery.acceptData( elem ) ) {
+
+ id = elem[ internalKey ];
+ data = id && cache[ id ];
+
+ if ( data ) {
+ if ( data.events ) {
+ for ( type in data.events ) {
+ if ( special[ type ] ) {
+ jQuery.event.remove( elem, type );
+
+ // This is a shortcut to avoid jQuery.event.remove's overhead
+ } else {
+ jQuery.removeEvent( elem, type, data.handle );
+ }
+ }
+ }
+
+ // Remove cache only if it was not already removed by jQuery.event.remove
+ if ( cache[ id ] ) {
+
+ delete cache[ id ];
+
+ // IE does not allow us to delete expando properties from nodes,
+ // nor does it have a removeAttribute function on Document nodes;
+ // we must handle all of these cases
+ if ( deleteExpando ) {
+ delete elem[ internalKey ];
+
+ } else if ( typeof elem.removeAttribute !== core_strundefined ) {
+ elem.removeAttribute( internalKey );
+
+ } else {
+ elem[ internalKey ] = null;
+ }
+
+ core_deletedIds.push( id );
+ }
+ }
+ }
+ }
+ }
+});
+var iframe, getStyles, curCSS,
+ ralpha = /alpha\([^)]*\)/i,
+ ropacity = /opacity\s*=\s*([^)]*)/,
+ rposition = /^(top|right|bottom|left)$/,
+ // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
+ // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
+ rdisplayswap = /^(none|table(?!-c[ea]).+)/,
+ rmargin = /^margin/,
+ rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ),
+ rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ),
+ rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ),
+ elemdisplay = { BODY: "block" },
+
+ cssShow = { position: "absolute", visibility: "hidden", display: "block" },
+ cssNormalTransform = {
+ letterSpacing: 0,
+ fontWeight: 400
+ },
+
+ cssExpand = [ "Top", "Right", "Bottom", "Left" ],
+ cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
+
+// return a css property mapped to a potentially vendor prefixed property
+function vendorPropName( style, name ) {
+
+ // shortcut for names that are not vendor prefixed
+ if ( name in style ) {
+ return name;
+ }
+
+ // check for vendor prefixed names
+ var capName = name.charAt(0).toUpperCase() + name.slice(1),
+ origName = name,
+ i = cssPrefixes.length;
+
+ while ( i-- ) {
+ name = cssPrefixes[ i ] + capName;
+ if ( name in style ) {
+ return name;
+ }
+ }
+
+ return origName;
+}
+
+function isHidden( elem, el ) {
+ // isHidden might be called from jQuery#filter function;
+ // in that case, element will be second argument
+ elem = el || elem;
+ return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
+}
+
+function showHide( elements, show ) {
+ var display, elem, hidden,
+ values = [],
+ index = 0,
+ length = elements.length;
+
+ for ( ; index < length; index++ ) {
+ elem = elements[ index ];
+ if ( !elem.style ) {
+ continue;
+ }
+
+ values[ index ] = jQuery._data( elem, "olddisplay" );
+ display = elem.style.display;
+ if ( show ) {
+ // Reset the inline display of this element to learn if it is
+ // being hidden by cascaded rules or not
+ if ( !values[ index ] && display === "none" ) {
+ elem.style.display = "";
+ }
+
+ // Set elements which have been overridden with display: none
+ // in a stylesheet to whatever the default browser style is
+ // for such an element
+ if ( elem.style.display === "" && isHidden( elem ) ) {
+ values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) );
+ }
+ } else {
+
+ if ( !values[ index ] ) {
+ hidden = isHidden( elem );
+
+ if ( display && display !== "none" || !hidden ) {
+ jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
+ }
+ }
+ }
+ }
+
+ // Set the display of most of the elements in a second loop
+ // to avoid the constant reflow
+ for ( index = 0; index < length; index++ ) {
+ elem = elements[ index ];
+ if ( !elem.style ) {
+ continue;
+ }
+ if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
+ elem.style.display = show ? values[ index ] || "" : "none";
+ }
+ }
+
+ return elements;
+}
+
+jQuery.fn.extend({
+ css: function( name, value ) {
+ return jQuery.access( this, function( elem, name, value ) {
+ var len, styles,
+ map = {},
+ i = 0;
+
+ if ( jQuery.isArray( name ) ) {
+ styles = getStyles( elem );
+ len = name.length;
+
+ for ( ; i < len; i++ ) {
+ map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
+ }
+
+ return map;
+ }
+
+ return value !== undefined ?
+ jQuery.style( elem, name, value ) :
+ jQuery.css( elem, name );
+ }, name, value, arguments.length > 1 );
+ },
+ show: function() {
+ return showHide( this, true );
+ },
+ hide: function() {
+ return showHide( this );
+ },
+ toggle: function( state ) {
+ var bool = typeof state === "boolean";
+
+ return this.each(function() {
+ if ( bool ? state : isHidden( this ) ) {
+ jQuery( this ).show();
+ } else {
+ jQuery( this ).hide();
+ }
+ });
+ }
+});
+
+jQuery.extend({
+ // Add in style property hooks for overriding the default
+ // behavior of getting and setting a style property
+ cssHooks: {
+ opacity: {
+ get: function( elem, computed ) {
+ if ( computed ) {
+ // We should always get a number back from opacity
+ var ret = curCSS( elem, "opacity" );
+ return ret === "" ? "1" : ret;
+ }
+ }
+ }
+ },
+
+ // Exclude the following css properties to add px
+ cssNumber: {
+ "columnCount": true,
+ "fillOpacity": true,
+ "fontWeight": true,
+ "lineHeight": true,
+ "opacity": true,
+ "orphans": true,
+ "widows": true,
+ "zIndex": true,
+ "zoom": true
+ },
+
+ // Add in properties whose names you wish to fix before
+ // setting or getting the value
+ cssProps: {
+ // normalize float css property
+ "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
+ },
+
+ // Get and set the style property on a DOM Node
+ style: function( elem, name, value, extra ) {
+ // Don't set styles on text and comment nodes
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
+ return;
+ }
+
+ // Make sure that we're working with the right name
+ var ret, type, hooks,
+ origName = jQuery.camelCase( name ),
+ style = elem.style;
+
+ name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
+
+ // gets hook for the prefixed version
+ // followed by the unprefixed version
+ hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
+
+ // Check if we're setting a value
+ if ( value !== undefined ) {
+ type = typeof value;
+
+ // convert relative number strings (+= or -=) to relative numbers. #7345
+ if ( type === "string" && (ret = rrelNum.exec( value )) ) {
+ value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
+ // Fixes bug #9237
+ type = "number";
+ }
+
+ // Make sure that NaN and null values aren't set. See: #7116
+ if ( value == null || type === "number" && isNaN( value ) ) {
+ return;
+ }
+
+ // If a number was passed in, add 'px' to the (except for certain CSS properties)
+ if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
+ value += "px";
+ }
+
+ // Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
+ // but it would mean to define eight (for every problematic property) identical functions
+ if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) {
+ style[ name ] = "inherit";
+ }
+
+ // If a hook was provided, use that value, otherwise just set the specified value
+ if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
+
+ // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
+ // Fixes bug #5509
+ try {
+ style[ name ] = value;
+ } catch(e) {}
+ }
+
+ } else {
+ // If a hook was provided get the non-computed value from there
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
+ return ret;
+ }
+
+ // Otherwise just get the value from the style object
+ return style[ name ];
+ }
+ },
+
+ css: function( elem, name, extra, styles ) {
+ var num, val, hooks,
+ origName = jQuery.camelCase( name );
+
+ // Make sure that we're working with the right name
+ name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
+
+ // gets hook for the prefixed version
+ // followed by the unprefixed version
+ hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
+
+ // If a hook was provided get the computed value from there
+ if ( hooks && "get" in hooks ) {
+ val = hooks.get( elem, true, extra );
+ }
+
+ // Otherwise, if a way to get the computed value exists, use that
+ if ( val === undefined ) {
+ val = curCSS( elem, name, styles );
+ }
+
+ //convert "normal" to computed value
+ if ( val === "normal" && name in cssNormalTransform ) {
+ val = cssNormalTransform[ name ];
+ }
+
+ // Return, converting to number if forced or a qualifier was provided and val looks numeric
+ if ( extra === "" || extra ) {
+ num = parseFloat( val );
+ return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
+ }
+ return val;
+ },
+
+ // A method for quickly swapping in/out CSS properties to get correct calculations
+ swap: function( elem, options, callback, args ) {
+ var ret, name,
+ old = {};
+
+ // Remember the old values, and insert the new ones
+ for ( name in options ) {
+ old[ name ] = elem.style[ name ];
+ elem.style[ name ] = options[ name ];
+ }
+
+ ret = callback.apply( elem, args || [] );
+
+ // Revert the old values
+ for ( name in options ) {
+ elem.style[ name ] = old[ name ];
+ }
+
+ return ret;
+ }
+});
+
+// NOTE: we've included the "window" in window.getComputedStyle
+// because jsdom on node.js will break without it.
+if ( window.getComputedStyle ) {
+ getStyles = function( elem ) {
+ return window.getComputedStyle( elem, null );
+ };
+
+ curCSS = function( elem, name, _computed ) {
+ var width, minWidth, maxWidth,
+ computed = _computed || getStyles( elem ),
+
+ // getPropertyValue is only needed for .css('filter') in IE9, see #12537
+ ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined,
+ style = elem.style;
+
+ if ( computed ) {
+
+ if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
+ ret = jQuery.style( elem, name );
+ }
+
+ // A tribute to the "awesome hack by Dean Edwards"
+ // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
+ // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
+ // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
+ if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
+
+ // Remember the original values
+ width = style.width;
+ minWidth = style.minWidth;
+ maxWidth = style.maxWidth;
+
+ // Put in the new values to get a computed value out
+ style.minWidth = style.maxWidth = style.width = ret;
+ ret = computed.width;
+
+ // Revert the changed values
+ style.width = width;
+ style.minWidth = minWidth;
+ style.maxWidth = maxWidth;
+ }
+ }
+
+ return ret;
+ };
+} else if ( document.documentElement.currentStyle ) {
+ getStyles = function( elem ) {
+ return elem.currentStyle;
+ };
+
+ curCSS = function( elem, name, _computed ) {
+ var left, rs, rsLeft,
+ computed = _computed || getStyles( elem ),
+ ret = computed ? computed[ name ] : undefined,
+ style = elem.style;
+
+ // Avoid setting ret to empty string here
+ // so we don't default to auto
+ if ( ret == null && style && style[ name ] ) {
+ ret = style[ name ];
+ }
+
+ // From the awesome hack by Dean Edwards
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+ // If we're not dealing with a regular pixel number
+ // but a number that has a weird ending, we need to convert it to pixels
+ // but not position css attributes, as those are proportional to the parent element instead
+ // and we can't measure the parent instead because it might trigger a "stacking dolls" problem
+ if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
+
+ // Remember the original values
+ left = style.left;
+ rs = elem.runtimeStyle;
+ rsLeft = rs && rs.left;
+
+ // Put in the new values to get a computed value out
+ if ( rsLeft ) {
+ rs.left = elem.currentStyle.left;
+ }
+ style.left = name === "fontSize" ? "1em" : ret;
+ ret = style.pixelLeft + "px";
+
+ // Revert the changed values
+ style.left = left;
+ if ( rsLeft ) {
+ rs.left = rsLeft;
+ }
+ }
+
+ return ret === "" ? "auto" : ret;
+ };
+}
+
+function setPositiveNumber( elem, value, subtract ) {
+ var matches = rnumsplit.exec( value );
+ return matches ?
+ // Guard against undefined "subtract", e.g., when used as in cssHooks
+ Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
+ value;
+}
+
+function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
+ var i = extra === ( isBorderBox ? "border" : "content" ) ?
+ // If we already have the right measurement, avoid augmentation
+ 4 :
+ // Otherwise initialize for horizontal or vertical properties
+ name === "width" ? 1 : 0,
+
+ val = 0;
+
+ for ( ; i < 4; i += 2 ) {
+ // both box models exclude margin, so add it if we want it
+ if ( extra === "margin" ) {
+ val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
+ }
+
+ if ( isBorderBox ) {
+ // border-box includes padding, so remove it if we want content
+ if ( extra === "content" ) {
+ val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+ }
+
+ // at this point, extra isn't border nor margin, so remove border
+ if ( extra !== "margin" ) {
+ val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+ }
+ } else {
+ // at this point, extra isn't content, so add padding
+ val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+
+ // at this point, extra isn't content nor padding, so add border
+ if ( extra !== "padding" ) {
+ val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+ }
+ }
+ }
+
+ return val;
+}
+
+function getWidthOrHeight( elem, name, extra ) {
+
+ // Start with offset property, which is equivalent to the border-box value
+ var valueIsBorderBox = true,
+ val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
+ styles = getStyles( elem ),
+ isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
+
+ // some non-html elements return undefined for offsetWidth, so check for null/undefined
+ // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
+ // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
+ if ( val <= 0 || val == null ) {
+ // Fall back to computed then uncomputed css if necessary
+ val = curCSS( elem, name, styles );
+ if ( val < 0 || val == null ) {
+ val = elem.style[ name ];
+ }
+
+ // Computed unit is not pixels. Stop here and return.
+ if ( rnumnonpx.test(val) ) {
+ return val;
+ }
+
+ // we need the check for style in case a browser which returns unreliable values
+ // for getComputedStyle silently falls back to the reliable elem.style
+ valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );
+
+ // Normalize "", auto, and prepare for extra
+ val = parseFloat( val ) || 0;
+ }
+
+ // use the active box-sizing model to add/subtract irrelevant styles
+ return ( val +
+ augmentWidthOrHeight(
+ elem,
+ name,
+ extra || ( isBorderBox ? "border" : "content" ),
+ valueIsBorderBox,
+ styles
+ )
+ ) + "px";
+}
+
+// Try to determine the default display value of an element
+function css_defaultDisplay( nodeName ) {
+ var doc = document,
+ display = elemdisplay[ nodeName ];
+
+ if ( !display ) {
+ display = actualDisplay( nodeName, doc );
+
+ // If the simple way fails, read from inside an iframe
+ if ( display === "none" || !display ) {
+ // Use the already-created iframe if possible
+ iframe = ( iframe ||
+ jQuery("<iframe frameborder='0' width='0' height='0'/>")
+ .css( "cssText", "display:block !important" )
+ ).appendTo( doc.documentElement );
+
+ // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
+ doc = ( iframe[0].contentWindow || iframe[0].contentDocument ).document;
+ doc.write("<!doctype html><html><body>");
+ doc.close();
+
+ display = actualDisplay( nodeName, doc );
+ iframe.detach();
+ }
+
+ // Store the correct default display
+ elemdisplay[ nodeName ] = display;
+ }
+
+ return display;
+}
+
+// Called ONLY from within css_defaultDisplay
+function actualDisplay( name, doc ) {
+ var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
+ display = jQuery.css( elem[0], "display" );
+ elem.remove();
+ return display;
+}
+
+jQuery.each([ "height", "width" ], function( i, name ) {
+ jQuery.cssHooks[ name ] = {
+ get: function( elem, computed, extra ) {
+ if ( computed ) {
+ // certain elements can have dimension info if we invisibly show them
+ // however, it must have a current display style that would benefit from this
+ return elem.offsetWidth === 0 && rdisplayswap.test( jQuery.css( elem, "display" ) ) ?
+ jQuery.swap( elem, cssShow, function() {
+ return getWidthOrHeight( elem, name, extra );
+ }) :
+ getWidthOrHeight( elem, name, extra );
+ }
+ },
+
+ set: function( elem, value, extra ) {
+ var styles = extra && getStyles( elem );
+ return setPositiveNumber( elem, value, extra ?
+ augmentWidthOrHeight(
+ elem,
+ name,
+ extra,
+ jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
+ styles
+ ) : 0
+ );
+ }
+ };
+});
+
+if ( !jQuery.support.opacity ) {
+ jQuery.cssHooks.opacity = {
+ get: function( elem, computed ) {
+ // IE uses filters for opacity
+ return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
+ ( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
+ computed ? "1" : "";
+ },
+
+ set: function( elem, value ) {
+ var style = elem.style,
+ currentStyle = elem.currentStyle,
+ opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
+ filter = currentStyle && currentStyle.filter || style.filter || "";
+
+ // IE has trouble with opacity if it does not have layout
+ // Force it by setting the zoom level
+ style.zoom = 1;
+
+ // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
+ // if value === "", then remove inline opacity #12685
+ if ( ( value >= 1 || value === "" ) &&
+ jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
+ style.removeAttribute ) {
+
+ // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
+ // if "filter:" is present at all, clearType is disabled, we want to avoid this
+ // style.removeAttribute is IE Only, but so apparently is this code path...
+ style.removeAttribute( "filter" );
+
+ // if there is no filter style applied in a css rule or unset inline opacity, we are done
+ if ( value === "" || currentStyle && !currentStyle.filter ) {
+ return;
+ }
+ }
+
+ // otherwise, set new filter values
+ style.filter = ralpha.test( filter ) ?
+ filter.replace( ralpha, opacity ) :
+ filter + " " + opacity;
+ }
+ };
+}
+
+// These hooks cannot be added until DOM ready because the support test
+// for it is not run until after DOM ready
+jQuery(function() {
+ if ( !jQuery.support.reliableMarginRight ) {
+ jQuery.cssHooks.marginRight = {
+ get: function( elem, computed ) {
+ if ( computed ) {
+ // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+ // Work around by temporarily setting element display to inline-block
+ return jQuery.swap( elem, { "display": "inline-block" },
+ curCSS, [ elem, "marginRight" ] );
+ }
+ }
+ };
+ }
+
+ // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
+ // getComputedStyle returns percent when specified for top/left/bottom/right
+ // rather than make the css module depend on the offset module, we just check for it here
+ if ( !jQuery.support.pixelPosition && jQuery.fn.position ) {
+ jQuery.each( [ "top", "left" ], function( i, prop ) {
+ jQuery.cssHooks[ prop ] = {
+ get: function( elem, computed ) {
+ if ( computed ) {
+ computed = curCSS( elem, prop );
+ // if curCSS returns percentage, fallback to offset
+ return rnumnonpx.test( computed ) ?
+ jQuery( elem ).position()[ prop ] + "px" :
+ computed;
+ }
+ }
+ };
+ });
+ }
+
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+ jQuery.expr.filters.hidden = function( elem ) {
+ // Support: Opera <= 12.12
+ // Opera reports offsetWidths and offsetHeights less than zero on some elements
+ return elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||
+ (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
+ };
+
+ jQuery.expr.filters.visible = function( elem ) {
+ return !jQuery.expr.filters.hidden( elem );
+ };
+}
+
+// These hooks are used by animate to expand properties
+jQuery.each({
+ margin: "",
+ padding: "",
+ border: "Width"
+}, function( prefix, suffix ) {
+ jQuery.cssHooks[ prefix + suffix ] = {
+ expand: function( value ) {
+ var i = 0,
+ expanded = {},
+
+ // assumes a single number if not a string
+ parts = typeof value === "string" ? value.split(" ") : [ value ];
+
+ for ( ; i < 4; i++ ) {
+ expanded[ prefix + cssExpand[ i ] + suffix ] =
+ parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
+ }
+
+ return expanded;
+ }
+ };
+
+ if ( !rmargin.test( prefix ) ) {
+ jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
+ }
+});
+var r20 = /%20/g,
+ rbracket = /\[\]$/,
+ rCRLF = /\r?\n/g,
+ rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
+ rsubmittable = /^(?:input|select|textarea|keygen)/i;
+
+jQuery.fn.extend({
+ serialize: function() {
+ return jQuery.param( this.serializeArray() );
+ },
+ serializeArray: function() {
+ return this.map(function(){
+ // Can add propHook for "elements" to filter or add form elements
+ var elements = jQuery.prop( this, "elements" );
+ return elements ? jQuery.makeArray( elements ) : this;
+ })
+ .filter(function(){
+ var type = this.type;
+ // Use .is(":disabled") so that fieldset[disabled] works
+ return this.name && !jQuery( this ).is( ":disabled" ) &&
+ rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
+ ( this.checked || !manipulation_rcheckableType.test( type ) );
+ })
+ .map(function( i, elem ){
+ var val = jQuery( this ).val();
+
+ return val == null ?
+ null :
+ jQuery.isArray( val ) ?
+ jQuery.map( val, function( val ){
+ return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+ }) :
+ { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+ }).get();
+ }
+});
+
+//Serialize an array of form elements or a set of
+//key/values into a query string
+jQuery.param = function( a, traditional ) {
+ var prefix,
+ s = [],
+ add = function( key, value ) {
+ // If value is a function, invoke it and return its value
+ value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
+ s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
+ };
+
+ // Set traditional to true for jQuery <= 1.3.2 behavior.
+ if ( traditional === undefined ) {
+ traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
+ }
+
+ // If an array was passed in, assume that it is an array of form elements.
+ if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
+ // Serialize the form elements
+ jQuery.each( a, function() {
+ add( this.name, this.value );
+ });
+
+ } else {
+ // If traditional, encode the "old" way (the way 1.3.2 or older
+ // did it), otherwise encode params recursively.
+ for ( prefix in a ) {
+ buildParams( prefix, a[ prefix ], traditional, add );
+ }
+ }
+
+ // Return the resulting serialization
+ return s.join( "&" ).replace( r20, "+" );
+};
+
+function buildParams( prefix, obj, traditional, add ) {
+ var name;
+
+ if ( jQuery.isArray( obj ) ) {
+ // Serialize array item.
+ jQuery.each( obj, function( i, v ) {
+ if ( traditional || rbracket.test( prefix ) ) {
+ // Treat each array item as a scalar.
+ add( prefix, v );
+
+ } else {
+ // Item is non-scalar (array or object), encode its numeric index.
+ buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
+ }
+ });
+
+ } else if ( !traditional && jQuery.type( obj ) === "object" ) {
+ // Serialize object item.
+ for ( name in obj ) {
+ buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
+ }
+
+ } else {
+ // Serialize scalar item.
+ add( prefix, obj );
+ }
+}
+jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
+ "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
+ "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
+
+ // Handle event binding
+ jQuery.fn[ name ] = function( data, fn ) {
+ return arguments.length > 0 ?
+ this.on( name, null, data, fn ) :
+ this.trigger( name );
+ };
+});
+
+jQuery.fn.hover = function( fnOver, fnOut ) {
+ return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+};
+var
+ // Document location
+ ajaxLocParts,
+ ajaxLocation,
+ ajax_nonce = jQuery.now(),
+
+ ajax_rquery = /\?/,
+ rhash = /#.*$/,
+ rts = /([?&])_=[^&]*/,
+ rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
+ // #7653, #8125, #8152: local protocol detection
+ rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
+ rnoContent = /^(?:GET|HEAD)$/,
+ rprotocol = /^\/\//,
+ rurl = /^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,
+
+ // Keep a copy of the old load method
+ _load = jQuery.fn.load,
+
+ /* Prefilters
+ * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
+ * 2) These are called:
+ * - BEFORE asking for a transport
+ * - AFTER param serialization (s.data is a string if s.processData is true)
+ * 3) key is the dataType
+ * 4) the catchall symbol "*" can be used
+ * 5) execution will start with transport dataType and THEN continue down to "*" if needed
+ */
+ prefilters = {},
+
+ /* Transports bindings
+ * 1) key is the dataType
+ * 2) the catchall symbol "*" can be used
+ * 3) selection will start with transport dataType and THEN go to "*" if needed
+ */
+ transports = {},
+
+ // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
+ allTypes = "*/".concat("*");
+
+// #8138, IE may throw an exception when accessing
+// a field from window.location if document.domain has been set
+try {
+ ajaxLocation = location.href;
+} catch( e ) {
+ // Use the href attribute of an A element
+ // since IE will modify it given document.location
+ ajaxLocation = document.createElement( "a" );
+ ajaxLocation.href = "";
+ ajaxLocation = ajaxLocation.href;
+}
+
+// Segment location into parts
+ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
+
+// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
+function addToPrefiltersOrTransports( structure ) {
+
+ // dataTypeExpression is optional and defaults to "*"
+ return function( dataTypeExpression, func ) {
+
+ if ( typeof dataTypeExpression !== "string" ) {
+ func = dataTypeExpression;
+ dataTypeExpression = "*";
+ }
+
+ var dataType,
+ i = 0,
+ dataTypes = dataTypeExpression.toLowerCase().match( core_rnotwhite ) || [];
+
+ if ( jQuery.isFunction( func ) ) {
+ // For each dataType in the dataTypeExpression
+ while ( (dataType = dataTypes[i++]) ) {
+ // Prepend if requested
+ if ( dataType[0] === "+" ) {
+ dataType = dataType.slice( 1 ) || "*";
+ (structure[ dataType ] = structure[ dataType ] || []).unshift( func );
+
+ // Otherwise append
+ } else {
+ (structure[ dataType ] = structure[ dataType ] || []).push( func );
+ }
+ }
+ }
+ };
+}
+
+// Base inspection function for prefilters and transports
+function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
+
+ var inspected = {},
+ seekingTransport = ( structure === transports );
+
+ function inspect( dataType ) {
+ var selected;
+ inspected[ dataType ] = true;
+ jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
+ var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
+ if( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
+ options.dataTypes.unshift( dataTypeOrTransport );
+ inspect( dataTypeOrTransport );
+ return false;
+ } else if ( seekingTransport ) {
+ return !( selected = dataTypeOrTransport );
+ }
+ });
+ return selected;
+ }
+
+ return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
+}
+
+// A special extend for ajax options
+// that takes "flat" options (not to be deep extended)
+// Fixes #9887
+function ajaxExtend( target, src ) {
+ var deep, key,
+ flatOptions = jQuery.ajaxSettings.flatOptions || {};
+
+ for ( key in src ) {
+ if ( src[ key ] !== undefined ) {
+ ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
+ }
+ }
+ if ( deep ) {
+ jQuery.extend( true, target, deep );
+ }
+
+ return target;
+}
+
+jQuery.fn.load = function( url, params, callback ) {
+ if ( typeof url !== "string" && _load ) {
+ return _load.apply( this, arguments );
+ }
+
+ var selector, response, type,
+ self = this,
+ off = url.indexOf(" ");
+
+ if ( off >= 0 ) {
+ selector = url.slice( off, url.length );
+ url = url.slice( 0, off );
+ }
+
+ // If it's a function
+ if ( jQuery.isFunction( params ) ) {
+
+ // We assume that it's the callback
+ callback = params;
+ params = undefined;
+
+ // Otherwise, build a param string
+ } else if ( params && typeof params === "object" ) {
+ type = "POST";
+ }
+
+ // If we have elements to modify, make the request
+ if ( self.length > 0 ) {
+ jQuery.ajax({
+ url: url,
+
+ // if "type" variable is undefined, then "GET" method will be used
+ type: type,
+ dataType: "html",
+ data: params
+ }).done(function( responseText ) {
+
+ // Save response for use in complete callback
+ response = arguments;
+
+ self.html( selector ?
+
+ // If a selector was specified, locate the right elements in a dummy div
+ // Exclude scripts to avoid IE 'Permission Denied' errors
+ jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
+
+ // Otherwise use the full result
+ responseText );
+
+ }).complete( callback && function( jqXHR, status ) {
+ self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
+ });
+ }
+
+ return this;
+};
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ){
+ jQuery.fn[ type ] = function( fn ){
+ return this.on( type, fn );
+ };
+});
+
+jQuery.each( [ "get", "post" ], function( i, method ) {
+ jQuery[ method ] = function( url, data, callback, type ) {
+ // shift arguments if data argument was omitted
+ if ( jQuery.isFunction( data ) ) {
+ type = type || callback;
+ callback = data;
+ data = undefined;
+ }
+
+ return jQuery.ajax({
+ url: url,
+ type: method,
+ dataType: type,
+ data: data,
+ success: callback
+ });
+ };
+});
+
+jQuery.extend({
+
+ // Counter for holding the number of active queries
+ active: 0,
+
+ // Last-Modified header cache for next request
+ lastModified: {},
+ etag: {},
+
+ ajaxSettings: {
+ url: ajaxLocation,
+ type: "GET",
+ isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
+ global: true,
+ processData: true,
+ async: true,
+ contentType: "application/x-www-form-urlencoded; charset=UTF-8",
+ /*
+ timeout: 0,
+ data: null,
+ dataType: null,
+ username: null,
+ password: null,
+ cache: null,
+ throws: false,
+ traditional: false,
+ headers: {},
+ */
+
+ accepts: {
+ "*": allTypes,
+ text: "text/plain",
+ html: "text/html",
+ xml: "application/xml, text/xml",
+ json: "application/json, text/javascript"
+ },
+
+ contents: {
+ xml: /xml/,
+ html: /html/,
+ json: /json/
+ },
+
+ responseFields: {
+ xml: "responseXML",
+ text: "responseText"
+ },
+
+ // Data converters
+ // Keys separate source (or catchall "*") and destination types with a single space
+ converters: {
+
+ // Convert anything to text
+ "* text": window.String,
+
+ // Text to html (true = no transformation)
+ "text html": true,
+
+ // Evaluate text as a json expression
+ "text json": jQuery.parseJSON,
+
+ // Parse text as xml
+ "text xml": jQuery.parseXML
+ },
+
+ // For options that shouldn't be deep extended:
+ // you can add your own custom options here if
+ // and when you create one that shouldn't be
+ // deep extended (see ajaxExtend)
+ flatOptions: {
+ url: true,
+ context: true
+ }
+ },
+
+ // Creates a full fledged settings object into target
+ // with both ajaxSettings and settings fields.
+ // If target is omitted, writes into ajaxSettings.
+ ajaxSetup: function( target, settings ) {
+ return settings ?
+
+ // Building a settings object
+ ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
+
+ // Extending ajaxSettings
+ ajaxExtend( jQuery.ajaxSettings, target );
+ },
+
+ ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
+ ajaxTransport: addToPrefiltersOrTransports( transports ),
+
+ // Main method
+ ajax: function( url, options ) {
+
+ // If url is an object, simulate pre-1.5 signature
+ if ( typeof url === "object" ) {
+ options = url;
+ url = undefined;
+ }
+
+ // Force options to be an object
+ options = options || {};
+
+ var // Cross-domain detection vars
+ parts,
+ // Loop variable
+ i,
+ // URL without anti-cache param
+ cacheURL,
+ // Response headers as string
+ responseHeadersString,
+ // timeout handle
+ timeoutTimer,
+
+ // To know if global events are to be dispatched
+ fireGlobals,
+
+ transport,
+ // Response headers
+ responseHeaders,
+ // Create the final options object
+ s = jQuery.ajaxSetup( {}, options ),
+ // Callbacks context
+ callbackContext = s.context || s,
+ // Context for global events is callbackContext if it is a DOM node or jQuery collection
+ globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
+ jQuery( callbackContext ) :
+ jQuery.event,
+ // Deferreds
+ deferred = jQuery.Deferred(),
+ completeDeferred = jQuery.Callbacks("once memory"),
+ // Status-dependent callbacks
+ statusCode = s.statusCode || {},
+ // Headers (they are sent all at once)
+ requestHeaders = {},
+ requestHeadersNames = {},
+ // The jqXHR state
+ state = 0,
+ // Default abort message
+ strAbort = "canceled",
+ // Fake xhr
+ jqXHR = {
+ readyState: 0,
+
+ // Builds headers hashtable if needed
+ getResponseHeader: function( key ) {
+ var match;
+ if ( state === 2 ) {
+ if ( !responseHeaders ) {
+ responseHeaders = {};
+ while ( (match = rheaders.exec( responseHeadersString )) ) {
+ responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
+ }
+ }
+ match = responseHeaders[ key.toLowerCase() ];
+ }
+ return match == null ? null : match;
+ },
+
+ // Raw string
+ getAllResponseHeaders: function() {
+ return state === 2 ? responseHeadersString : null;
+ },
+
+ // Caches the header
+ setRequestHeader: function( name, value ) {
+ var lname = name.toLowerCase();
+ if ( !state ) {
+ name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
+ requestHeaders[ name ] = value;
+ }
+ return this;
+ },
+
+ // Overrides response content-type header
+ overrideMimeType: function( type ) {
+ if ( !state ) {
+ s.mimeType = type;
+ }
+ return this;
+ },
+
+ // Status-dependent callbacks
+ statusCode: function( map ) {
+ var code;
+ if ( map ) {
+ if ( state < 2 ) {
+ for ( code in map ) {
+ // Lazy-add the new callback in a way that preserves old ones
+ statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
+ }
+ } else {
+ // Execute the appropriate callbacks
+ jqXHR.always( map[ jqXHR.status ] );
+ }
+ }
+ return this;
+ },
+
+ // Cancel the request
+ abort: function( statusText ) {
+ var finalText = statusText || strAbort;
+ if ( transport ) {
+ transport.abort( finalText );
+ }
+ done( 0, finalText );
+ return this;
+ }
+ };
+
+ // Attach deferreds
+ deferred.promise( jqXHR ).complete = completeDeferred.add;
+ jqXHR.success = jqXHR.done;
+ jqXHR.error = jqXHR.fail;
+
+ // Remove hash character (#7531: and string promotion)
+ // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
+ // Handle falsy url in the settings object (#10093: consistency with old signature)
+ // We also use the url parameter if available
+ s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
+
+ // Alias method option to type as per ticket #12004
+ s.type = options.method || options.type || s.method || s.type;
+
+ // Extract dataTypes list
+ s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( core_rnotwhite ) || [""];
+
+ // A cross-domain request is in order when we have a protocol:host:port mismatch
+ if ( s.crossDomain == null ) {
+ parts = rurl.exec( s.url.toLowerCase() );
+ s.crossDomain = !!( parts &&
+ ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
+ ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
+ ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
+ );
+ }
+
+ // Convert data if not already a string
+ if ( s.data && s.processData && typeof s.data !== "string" ) {
+ s.data = jQuery.param( s.data, s.traditional );
+ }
+
+ // Apply prefilters
+ inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
+
+ // If request was aborted inside a prefilter, stop there
+ if ( state === 2 ) {
+ return jqXHR;
+ }
+
+ // We can fire global events as of now if asked to
+ fireGlobals = s.global;
+
+ // Watch for a new set of requests
+ if ( fireGlobals && jQuery.active++ === 0 ) {
+ jQuery.event.trigger("ajaxStart");
+ }
+
+ // Uppercase the type
+ s.type = s.type.toUpperCase();
+
+ // Determine if request has content
+ s.hasContent = !rnoContent.test( s.type );
+
+ // Save the URL in case we're toying with the If-Modified-Since
+ // and/or If-None-Match header later on
+ cacheURL = s.url;
+
+ // More options handling for requests with no content
+ if ( !s.hasContent ) {
+
+ // If data is available, append data to url
+ if ( s.data ) {
+ cacheURL = ( s.url += ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
+ // #9682: remove data so that it's not used in an eventual retry
+ delete s.data;
+ }
+
+ // Add anti-cache in url if needed
+ if ( s.cache === false ) {
+ s.url = rts.test( cacheURL ) ?
+
+ // If there is already a '_' parameter, set its value
+ cacheURL.replace( rts, "$1_=" + ajax_nonce++ ) :
+
+ // Otherwise add one to the end
+ cacheURL + ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ajax_nonce++;
+ }
+ }
+
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+ if ( s.ifModified ) {
+ if ( jQuery.lastModified[ cacheURL ] ) {
+ jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
+ }
+ if ( jQuery.etag[ cacheURL ] ) {
+ jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
+ }
+ }
+
+ // Set the correct header, if data is being sent
+ if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
+ jqXHR.setRequestHeader( "Content-Type", s.contentType );
+ }
+
+ // Set the Accepts header for the server, depending on the dataType
+ jqXHR.setRequestHeader(
+ "Accept",
+ s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
+ s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
+ s.accepts[ "*" ]
+ );
+
+ // Check for headers option
+ for ( i in s.headers ) {
+ jqXHR.setRequestHeader( i, s.headers[ i ] );
+ }
+
+ // Allow custom headers/mimetypes and early abort
+ if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
+ // Abort if not done already and return
+ return jqXHR.abort();
+ }
+
+ // aborting is no longer a cancellation
+ strAbort = "abort";
+
+ // Install callbacks on deferreds
+ for ( i in { success: 1, error: 1, complete: 1 } ) {
+ jqXHR[ i ]( s[ i ] );
+ }
+
+ // Get transport
+ transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
+
+ // If no transport, we auto-abort
+ if ( !transport ) {
+ done( -1, "No Transport" );
+ } else {
+ jqXHR.readyState = 1;
+
+ // Send global event
+ if ( fireGlobals ) {
+ globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
+ }
+ // Timeout
+ if ( s.async && s.timeout > 0 ) {
+ timeoutTimer = setTimeout(function() {
+ jqXHR.abort("timeout");
+ }, s.timeout );
+ }
+
+ try {
+ state = 1;
+ transport.send( requestHeaders, done );
+ } catch ( e ) {
+ // Propagate exception as error if not done
+ if ( state < 2 ) {
+ done( -1, e );
+ // Simply rethrow otherwise
+ } else {
+ throw e;
+ }
+ }
+ }
+
+ // Callback for when everything is done
+ function done( status, nativeStatusText, responses, headers ) {
+ var isSuccess, success, error, response, modified,
+ statusText = nativeStatusText;
+
+ // Called once
+ if ( state === 2 ) {
+ return;
+ }
+
+ // State is "done" now
+ state = 2;
+
+ // Clear timeout if it exists
+ if ( timeoutTimer ) {
+ clearTimeout( timeoutTimer );
+ }
+
+ // Dereference transport for early garbage collection
+ // (no matter how long the jqXHR object will be used)
+ transport = undefined;
+
+ // Cache response headers
+ responseHeadersString = headers || "";
+
+ // Set readyState
+ jqXHR.readyState = status > 0 ? 4 : 0;
+
+ // Get response data
+ if ( responses ) {
+ response = ajaxHandleResponses( s, jqXHR, responses );
+ }
+
+ // If successful, handle type chaining
+ if ( status >= 200 && status < 300 || status === 304 ) {
+
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+ if ( s.ifModified ) {
+ modified = jqXHR.getResponseHeader("Last-Modified");
+ if ( modified ) {
+ jQuery.lastModified[ cacheURL ] = modified;
+ }
+ modified = jqXHR.getResponseHeader("etag");
+ if ( modified ) {
+ jQuery.etag[ cacheURL ] = modified;
+ }
+ }
+
+ // if no content
+ if ( status === 204 ) {
+ isSuccess = true;
+ statusText = "nocontent";
+
+ // if not modified
+ } else if ( status === 304 ) {
+ isSuccess = true;
+ statusText = "notmodified";
+
+ // If we have data, let's convert it
+ } else {
+ isSuccess = ajaxConvert( s, response );
+ statusText = isSuccess.state;
+ success = isSuccess.data;
+ error = isSuccess.error;
+ isSuccess = !error;
+ }
+ } else {
+ // We extract error from statusText
+ // then normalize statusText and status for non-aborts
+ error = statusText;
+ if ( status || !statusText ) {
+ statusText = "error";
+ if ( status < 0 ) {
+ status = 0;
+ }
+ }
+ }
+
+ // Set data for the fake xhr object
+ jqXHR.status = status;
+ jqXHR.statusText = ( nativeStatusText || statusText ) + "";
+
+ // Success/Error
+ if ( isSuccess ) {
+ deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
+ } else {
+ deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
+ }
+
+ // Status-dependent callbacks
+ jqXHR.statusCode( statusCode );
+ statusCode = undefined;
+
+ if ( fireGlobals ) {
+ globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
+ [ jqXHR, s, isSuccess ? success : error ] );
+ }
+
+ // Complete
+ completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
+
+ if ( fireGlobals ) {
+ globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
+ // Handle the global AJAX counter
+ if ( !( --jQuery.active ) ) {
+ jQuery.event.trigger("ajaxStop");
+ }
+ }
+ }
+
+ return jqXHR;
+ },
+
+ getScript: function( url, callback ) {
+ return jQuery.get( url, undefined, callback, "script" );
+ },
+
+ getJSON: function( url, data, callback ) {
+ return jQuery.get( url, data, callback, "json" );
+ }
+});
+
+/* Handles responses to an ajax request:
+ * - sets all responseXXX fields accordingly
+ * - finds the right dataType (mediates between content-type and expected dataType)
+ * - returns the corresponding response
+ */
+function ajaxHandleResponses( s, jqXHR, responses ) {
+ var firstDataType, ct, finalDataType, type,
+ contents = s.contents,
+ dataTypes = s.dataTypes,
+ responseFields = s.responseFields;
+
+ // Fill responseXXX fields
+ for ( type in responseFields ) {
+ if ( type in responses ) {
+ jqXHR[ responseFields[type] ] = responses[ type ];
+ }
+ }
+
+ // Remove auto dataType and get content-type in the process
+ while( dataTypes[ 0 ] === "*" ) {
+ dataTypes.shift();
+ if ( ct === undefined ) {
+ ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
+ }
+ }
+
+ // Check if we're dealing with a known content-type
+ if ( ct ) {
+ for ( type in contents ) {
+ if ( contents[ type ] && contents[ type ].test( ct ) ) {
+ dataTypes.unshift( type );
+ break;
+ }
+ }
+ }
+
+ // Check to see if we have a response for the expected dataType
+ if ( dataTypes[ 0 ] in responses ) {
+ finalDataType = dataTypes[ 0 ];
+ } else {
+ // Try convertible dataTypes
+ for ( type in responses ) {
+ if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
+ finalDataType = type;
+ break;
+ }
+ if ( !firstDataType ) {
+ firstDataType = type;
+ }
+ }
+ // Or just use first one
+ finalDataType = finalDataType || firstDataType;
+ }
+
+ // If we found a dataType
+ // We add the dataType to the list if needed
+ // and return the corresponding response
+ if ( finalDataType ) {
+ if ( finalDataType !== dataTypes[ 0 ] ) {
+ dataTypes.unshift( finalDataType );
+ }
+ return responses[ finalDataType ];
+ }
+}
+
+// Chain conversions given the request and the original response
+function ajaxConvert( s, response ) {
+ var conv2, current, conv, tmp,
+ converters = {},
+ i = 0,
+ // Work with a copy of dataTypes in case we need to modify it for conversion
+ dataTypes = s.dataTypes.slice(),
+ prev = dataTypes[ 0 ];
+
+ // Apply the dataFilter if provided
+ if ( s.dataFilter ) {
+ response = s.dataFilter( response, s.dataType );
+ }
+
+ // Create converters map with lowercased keys
+ if ( dataTypes[ 1 ] ) {
+ for ( conv in s.converters ) {
+ converters[ conv.toLowerCase() ] = s.converters[ conv ];
+ }
+ }
+
+ // Convert to each sequential dataType, tolerating list modification
+ for ( ; (current = dataTypes[++i]); ) {
+
+ // There's only work to do if current dataType is non-auto
+ if ( current !== "*" ) {
+
+ // Convert response if prev dataType is non-auto and differs from current
+ if ( prev !== "*" && prev !== current ) {
+
+ // Seek a direct converter
+ conv = converters[ prev + " " + current ] || converters[ "* " + current ];
+
+ // If none found, seek a pair
+ if ( !conv ) {
+ for ( conv2 in converters ) {
+
+ // If conv2 outputs current
+ tmp = conv2.split(" ");
+ if ( tmp[ 1 ] === current ) {
+
+ // If prev can be converted to accepted input
+ conv = converters[ prev + " " + tmp[ 0 ] ] ||
+ converters[ "* " + tmp[ 0 ] ];
+ if ( conv ) {
+ // Condense equivalence converters
+ if ( conv === true ) {
+ conv = converters[ conv2 ];
+
+ // Otherwise, insert the intermediate dataType
+ } else if ( converters[ conv2 ] !== true ) {
+ current = tmp[ 0 ];
+ dataTypes.splice( i--, 0, current );
+ }
+
+ break;
+ }
+ }
+ }
+ }
+
+ // Apply converter (if not an equivalence)
+ if ( conv !== true ) {
+
+ // Unless errors are allowed to bubble, catch and return them
+ if ( conv && s["throws"] ) {
+ response = conv( response );
+ } else {
+ try {
+ response = conv( response );
+ } catch ( e ) {
+ return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
+ }
+ }
+ }
+ }
+
+ // Update prev for next iteration
+ prev = current;
+ }
+ }
+
+ return { state: "success", data: response };
+}
+// Install script dataType
+jQuery.ajaxSetup({
+ accepts: {
+ script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
+ },
+ contents: {
+ script: /(?:java|ecma)script/
+ },
+ converters: {
+ "text script": function( text ) {
+ jQuery.globalEval( text );
+ return text;
+ }
+ }
+});
+
+// Handle cache's special case and global
+jQuery.ajaxPrefilter( "script", function( s ) {
+ if ( s.cache === undefined ) {
+ s.cache = false;
+ }
+ if ( s.crossDomain ) {
+ s.type = "GET";
+ s.global = false;
+ }
+});
+
+// Bind script tag hack transport
+jQuery.ajaxTransport( "script", function(s) {
+
+ // This transport only deals with cross domain requests
+ if ( s.crossDomain ) {
+
+ var script,
+ head = document.head || jQuery("head")[0] || document.documentElement;
+
+ return {
+
+ send: function( _, callback ) {
+
+ script = document.createElement("script");
+
+ script.async = true;
+
+ if ( s.scriptCharset ) {
+ script.charset = s.scriptCharset;
+ }
+
+ script.src = s.url;
+
+ // Attach handlers for all browsers
+ script.onload = script.onreadystatechange = function( _, isAbort ) {
+
+ if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
+
+ // Handle memory leak in IE
+ script.onload = script.onreadystatechange = null;
+
+ // Remove the script
+ if ( script.parentNode ) {
+ script.parentNode.removeChild( script );
+ }
+
+ // Dereference the script
+ script = null;
+
+ // Callback if not abort
+ if ( !isAbort ) {
+ callback( 200, "success" );
+ }
+ }
+ };
+
+ // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
+ // Use native DOM manipulation to avoid our domManip AJAX trickery
+ head.insertBefore( script, head.firstChild );
+ },
+
+ abort: function() {
+ if ( script ) {
+ script.onload( undefined, true );
+ }
+ }
+ };
+ }
+});
+var oldCallbacks = [],
+ rjsonp = /(=)\?(?=&|$)|\?\?/;
+
+// Default jsonp settings
+jQuery.ajaxSetup({
+ jsonp: "callback",
+ jsonpCallback: function() {
+ var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( ajax_nonce++ ) );
+ this[ callback ] = true;
+ return callback;
+ }
+});
+
+// Detect, normalize options and install callbacks for jsonp requests
+jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
+
+ var callbackName, overwritten, responseContainer,
+ jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
+ "url" :
+ typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
+ );
+
+ // Handle iff the expected data type is "jsonp" or we have a parameter to set
+ if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
+
+ // Get callback name, remembering preexisting value associated with it
+ callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
+ s.jsonpCallback() :
+ s.jsonpCallback;
+
+ // Insert callback into url or form data
+ if ( jsonProp ) {
+ s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
+ } else if ( s.jsonp !== false ) {
+ s.url += ( ajax_rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
+ }
+
+ // Use data converter to retrieve json after script execution
+ s.converters["script json"] = function() {
+ if ( !responseContainer ) {
+ jQuery.error( callbackName + " was not called" );
+ }
+ return responseContainer[ 0 ];
+ };
+
+ // force json dataType
+ s.dataTypes[ 0 ] = "json";
+
+ // Install callback
+ overwritten = window[ callbackName ];
+ window[ callbackName ] = function() {
+ responseContainer = arguments;
+ };
+
+ // Clean-up function (fires after converters)
+ jqXHR.always(function() {
+ // Restore preexisting value
+ window[ callbackName ] = overwritten;
+
+ // Save back as free
+ if ( s[ callbackName ] ) {
+ // make sure that re-using the options doesn't screw things around
+ s.jsonpCallback = originalSettings.jsonpCallback;
+
+ // save the callback name for future use
+ oldCallbacks.push( callbackName );
+ }
+
+ // Call if it was a function and we have a response
+ if ( responseContainer && jQuery.isFunction( overwritten ) ) {
+ overwritten( responseContainer[ 0 ] );
+ }
+
+ responseContainer = overwritten = undefined;
+ });
+
+ // Delegate to script
+ return "script";
+ }
+});
+var xhrCallbacks, xhrSupported,
+ xhrId = 0,
+ // #5280: Internet Explorer will keep connections alive if we don't abort on unload
+ xhrOnUnloadAbort = window.ActiveXObject && function() {
+ // Abort all pending requests
+ var key;
+ for ( key in xhrCallbacks ) {
+ xhrCallbacks[ key ]( undefined, true );
+ }
+ };
+
+// Functions to create xhrs
+function createStandardXHR() {
+ try {
+ return new window.XMLHttpRequest();
+ } catch( e ) {}
+}
+
+function createActiveXHR() {
+ try {
+ return new window.ActiveXObject("Microsoft.XMLHTTP");
+ } catch( e ) {}
+}
+
+// Create the request object
+// (This is still attached to ajaxSettings for backward compatibility)
+jQuery.ajaxSettings.xhr = window.ActiveXObject ?
+ /* Microsoft failed to properly
+ * implement the XMLHttpRequest in IE7 (can't request local files),
+ * so we use the ActiveXObject when it is available
+ * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
+ * we need a fallback.
+ */
+ function() {
+ return !this.isLocal && createStandardXHR() || createActiveXHR();
+ } :
+ // For all other browsers, use the standard XMLHttpRequest object
+ createStandardXHR;
+
+// Determine support properties
+xhrSupported = jQuery.ajaxSettings.xhr();
+jQuery.support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
+xhrSupported = jQuery.support.ajax = !!xhrSupported;
+
+// Create transport if the browser can provide an xhr
+if ( xhrSupported ) {
+
+ jQuery.ajaxTransport(function( s ) {
+ // Cross domain only allowed if supported through XMLHttpRequest
+ if ( !s.crossDomain || jQuery.support.cors ) {
+
+ var callback;
+
+ return {
+ send: function( headers, complete ) {
+
+ // Get a new xhr
+ var handle, i,
+ xhr = s.xhr();
+
+ // Open the socket
+ // Passing null username, generates a login popup on Opera (#2865)
+ if ( s.username ) {
+ xhr.open( s.type, s.url, s.async, s.username, s.password );
+ } else {
+ xhr.open( s.type, s.url, s.async );
+ }
+
+ // Apply custom fields if provided
+ if ( s.xhrFields ) {
+ for ( i in s.xhrFields ) {
+ xhr[ i ] = s.xhrFields[ i ];
+ }
+ }
+
+ // Override mime type if needed
+ if ( s.mimeType && xhr.overrideMimeType ) {
+ xhr.overrideMimeType( s.mimeType );
+ }
+
+ // X-Requested-With header
+ // For cross-domain requests, seeing as conditions for a preflight are
+ // akin to a jigsaw puzzle, we simply never set it to be sure.
+ // (it can always be set on a per-request basis or even using ajaxSetup)
+ // For same-domain requests, won't change header if already provided.
+ if ( !s.crossDomain && !headers["X-Requested-With"] ) {
+ headers["X-Requested-With"] = "XMLHttpRequest";
+ }
+
+ // Need an extra try/catch for cross domain requests in Firefox 3
+ try {
+ for ( i in headers ) {
+ xhr.setRequestHeader( i, headers[ i ] );
+ }
+ } catch( err ) {}
+
+ // Do send the request
+ // This may raise an exception which is actually
+ // handled in jQuery.ajax (so no try/catch here)
+ xhr.send( ( s.hasContent && s.data ) || null );
+
+ // Listener
+ callback = function( _, isAbort ) {
+ var status, responseHeaders, statusText, responses;
+
+ // Firefox throws exceptions when accessing properties
+ // of an xhr when a network error occurred
+ // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
+ try {
+
+ // Was never called and is aborted or complete
+ if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
+
+ // Only called once
+ callback = undefined;
+
+ // Do not keep as active anymore
+ if ( handle ) {
+ xhr.onreadystatechange = jQuery.noop;
+ if ( xhrOnUnloadAbort ) {
+ delete xhrCallbacks[ handle ];
+ }
+ }
+
+ // If it's an abort
+ if ( isAbort ) {
+ // Abort it manually if needed
+ if ( xhr.readyState !== 4 ) {
+ xhr.abort();
+ }
+ } else {
+ responses = {};
+ status = xhr.status;
+ responseHeaders = xhr.getAllResponseHeaders();
+
+ // When requesting binary data, IE6-9 will throw an exception
+ // on any attempt to access responseText (#11426)
+ if ( typeof xhr.responseText === "string" ) {
+ responses.text = xhr.responseText;
+ }
+
+ // Firefox throws an exception when accessing
+ // statusText for faulty cross-domain requests
+ try {
+ statusText = xhr.statusText;
+ } catch( e ) {
+ // We normalize with Webkit giving an empty statusText
+ statusText = "";
+ }
+
+ // Filter status for non standard behaviors
+
+ // If the request is local and we have data: assume a success
+ // (success with no data won't get notified, that's the best we
+ // can do given current implementations)
+ if ( !status && s.isLocal && !s.crossDomain ) {
+ status = responses.text ? 200 : 404;
+ // IE - #1450: sometimes returns 1223 when it should be 204
+ } else if ( status === 1223 ) {
+ status = 204;
+ }
+ }
+ }
+ } catch( firefoxAccessException ) {
+ if ( !isAbort ) {
+ complete( -1, firefoxAccessException );
+ }
+ }
+
+ // Call complete if needed
+ if ( responses ) {
+ complete( status, statusText, responses, responseHeaders );
+ }
+ };
+
+ if ( !s.async ) {
+ // if we're in sync mode we fire the callback
+ callback();
+ } else if ( xhr.readyState === 4 ) {
+ // (IE6 & IE7) if it's in cache and has been
+ // retrieved directly we need to fire the callback
+ setTimeout( callback );
+ } else {
+ handle = ++xhrId;
+ if ( xhrOnUnloadAbort ) {
+ // Create the active xhrs callbacks list if needed
+ // and attach the unload handler
+ if ( !xhrCallbacks ) {
+ xhrCallbacks = {};
+ jQuery( window ).unload( xhrOnUnloadAbort );
+ }
+ // Add to list of active xhrs callbacks
+ xhrCallbacks[ handle ] = callback;
+ }
+ xhr.onreadystatechange = callback;
+ }
+ },
+
+ abort: function() {
+ if ( callback ) {
+ callback( undefined, true );
+ }
+ }
+ };
+ }
+ });
+}
+var fxNow, timerId,
+ rfxtypes = /^(?:toggle|show|hide)$/,
+ rfxnum = new RegExp( "^(?:([+-])=|)(" + core_pnum + ")([a-z%]*)$", "i" ),
+ rrun = /queueHooks$/,
+ animationPrefilters = [ defaultPrefilter ],
+ tweeners = {
+ "*": [function( prop, value ) {
+ var end, unit,
+ tween = this.createTween( prop, value ),
+ parts = rfxnum.exec( value ),
+ target = tween.cur(),
+ start = +target || 0,
+ scale = 1,
+ maxIterations = 20;
+
+ if ( parts ) {
+ end = +parts[2];
+ unit = parts[3] || ( jQuery.cssNumber[ prop ] ? "" : "px" );
+
+ // We need to compute starting value
+ if ( unit !== "px" && start ) {
+ // Iteratively approximate from a nonzero starting point
+ // Prefer the current property, because this process will be trivial if it uses the same units
+ // Fallback to end or a simple constant
+ start = jQuery.css( tween.elem, prop, true ) || end || 1;
+
+ do {
+ // If previous iteration zeroed out, double until we get *something*
+ // Use a string for doubling factor so we don't accidentally see scale as unchanged below
+ scale = scale || ".5";
+
+ // Adjust and apply
+ start = start / scale;
+ jQuery.style( tween.elem, prop, start + unit );
+
+ // Update scale, tolerating zero or NaN from tween.cur()
+ // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
+ } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
+ }
+
+ tween.unit = unit;
+ tween.start = start;
+ // If a +=/-= token was provided, we're doing a relative animation
+ tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end;
+ }
+ return tween;
+ }]
+ };
+
+// Animations created synchronously will run synchronously
+function createFxNow() {
+ setTimeout(function() {
+ fxNow = undefined;
+ });
+ return ( fxNow = jQuery.now() );
+}
+
+function createTweens( animation, props ) {
+ jQuery.each( props, function( prop, value ) {
+ var collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
+ index = 0,
+ length = collection.length;
+ for ( ; index < length; index++ ) {
+ if ( collection[ index ].call( animation, prop, value ) ) {
+
+ // we're done with this property
+ return;
+ }
+ }
+ });
+}
+
+function Animation( elem, properties, options ) {
+ var result,
+ stopped,
+ index = 0,
+ length = animationPrefilters.length,
+ deferred = jQuery.Deferred().always( function() {
+ // don't match elem in the :animated selector
+ delete tick.elem;
+ }),
+ tick = function() {
+ if ( stopped ) {
+ return false;
+ }
+ var currentTime = fxNow || createFxNow(),
+ remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
+ // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
+ temp = remaining / animation.duration || 0,
+ percent = 1 - temp,
+ index = 0,
+ length = animation.tweens.length;
+
+ for ( ; index < length ; index++ ) {
+ animation.tweens[ index ].run( percent );
+ }
+
+ deferred.notifyWith( elem, [ animation, percent, remaining ]);
+
+ if ( percent < 1 && length ) {
+ return remaining;
+ } else {
+ deferred.resolveWith( elem, [ animation ] );
+ return false;
+ }
+ },
+ animation = deferred.promise({
+ elem: elem,
+ props: jQuery.extend( {}, properties ),
+ opts: jQuery.extend( true, { specialEasing: {} }, options ),
+ originalProperties: properties,
+ originalOptions: options,
+ startTime: fxNow || createFxNow(),
+ duration: options.duration,
+ tweens: [],
+ createTween: function( prop, end ) {
+ var tween = jQuery.Tween( elem, animation.opts, prop, end,
+ animation.opts.specialEasing[ prop ] || animation.opts.easing );
+ animation.tweens.push( tween );
+ return tween;
+ },
+ stop: function( gotoEnd ) {
+ var index = 0,
+ // if we are going to the end, we want to run all the tweens
+ // otherwise we skip this part
+ length = gotoEnd ? animation.tweens.length : 0;
+ if ( stopped ) {
+ return this;
+ }
+ stopped = true;
+ for ( ; index < length ; index++ ) {
+ animation.tweens[ index ].run( 1 );
+ }
+
+ // resolve when we played the last frame
+ // otherwise, reject
+ if ( gotoEnd ) {
+ deferred.resolveWith( elem, [ animation, gotoEnd ] );
+ } else {
+ deferred.rejectWith( elem, [ animation, gotoEnd ] );
+ }
+ return this;
+ }
+ }),
+ props = animation.props;
+
+ propFilter( props, animation.opts.specialEasing );
+
+ for ( ; index < length ; index++ ) {
+ result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
+ if ( result ) {
+ return result;
+ }
+ }
+
+ createTweens( animation, props );
+
+ if ( jQuery.isFunction( animation.opts.start ) ) {
+ animation.opts.start.call( elem, animation );
+ }
+
+ jQuery.fx.timer(
+ jQuery.extend( tick, {
+ elem: elem,
+ anim: animation,
+ queue: animation.opts.queue
+ })
+ );
+
+ // attach callbacks from options
+ return animation.progress( animation.opts.progress )
+ .done( animation.opts.done, animation.opts.complete )
+ .fail( animation.opts.fail )
+ .always( animation.opts.always );
+}
+
+function propFilter( props, specialEasing ) {
+ var value, name, index, easing, hooks;
+
+ // camelCase, specialEasing and expand cssHook pass
+ for ( index in props ) {
+ name = jQuery.camelCase( index );
+ easing = specialEasing[ name ];
+ value = props[ index ];
+ if ( jQuery.isArray( value ) ) {
+ easing = value[ 1 ];
+ value = props[ index ] = value[ 0 ];
+ }
+
+ if ( index !== name ) {
+ props[ name ] = value;
+ delete props[ index ];
+ }
+
+ hooks = jQuery.cssHooks[ name ];
+ if ( hooks && "expand" in hooks ) {
+ value = hooks.expand( value );
+ delete props[ name ];
+
+ // not quite $.extend, this wont overwrite keys already present.
+ // also - reusing 'index' from above because we have the correct "name"
+ for ( index in value ) {
+ if ( !( index in props ) ) {
+ props[ index ] = value[ index ];
+ specialEasing[ index ] = easing;
+ }
+ }
+ } else {
+ specialEasing[ name ] = easing;
+ }
+ }
+}
+
+jQuery.Animation = jQuery.extend( Animation, {
+
+ tweener: function( props, callback ) {
+ if ( jQuery.isFunction( props ) ) {
+ callback = props;
+ props = [ "*" ];
+ } else {
+ props = props.split(" ");
+ }
+
+ var prop,
+ index = 0,
+ length = props.length;
+
+ for ( ; index < length ; index++ ) {
+ prop = props[ index ];
+ tweeners[ prop ] = tweeners[ prop ] || [];
+ tweeners[ prop ].unshift( callback );
+ }
+ },
+
+ prefilter: function( callback, prepend ) {
+ if ( prepend ) {
+ animationPrefilters.unshift( callback );
+ } else {
+ animationPrefilters.push( callback );
+ }
+ }
+});
+
+function defaultPrefilter( elem, props, opts ) {
+ /*jshint validthis:true */
+ var prop, index, length,
+ value, dataShow, toggle,
+ tween, hooks, oldfire,
+ anim = this,
+ style = elem.style,
+ orig = {},
+ handled = [],
+ hidden = elem.nodeType && isHidden( elem );
+
+ // handle queue: false promises
+ if ( !opts.queue ) {
+ hooks = jQuery._queueHooks( elem, "fx" );
+ if ( hooks.unqueued == null ) {
+ hooks.unqueued = 0;
+ oldfire = hooks.empty.fire;
+ hooks.empty.fire = function() {
+ if ( !hooks.unqueued ) {
+ oldfire();
+ }
+ };
+ }
+ hooks.unqueued++;
+
+ anim.always(function() {
+ // doing this makes sure that the complete handler will be called
+ // before this completes
+ anim.always(function() {
+ hooks.unqueued--;
+ if ( !jQuery.queue( elem, "fx" ).length ) {
+ hooks.empty.fire();
+ }
+ });
+ });
+ }
+
+ // height/width overflow pass
+ if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
+ // Make sure that nothing sneaks out
+ // Record all 3 overflow attributes because IE does not
+ // change the overflow attribute when overflowX and
+ // overflowY are set to the same value
+ opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
+
+ // Set display property to inline-block for height/width
+ // animations on inline elements that are having width/height animated
+ if ( jQuery.css( elem, "display" ) === "inline" &&
+ jQuery.css( elem, "float" ) === "none" ) {
+
+ // inline-level elements accept inline-block;
+ // block-level elements need to be inline with layout
+ if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === "inline" ) {
+ style.display = "inline-block";
+
+ } else {
+ style.zoom = 1;
+ }
+ }
+ }
+
+ if ( opts.overflow ) {
+ style.overflow = "hidden";
+ if ( !jQuery.support.shrinkWrapBlocks ) {
+ anim.always(function() {
+ style.overflow = opts.overflow[ 0 ];
+ style.overflowX = opts.overflow[ 1 ];
+ style.overflowY = opts.overflow[ 2 ];
+ });
+ }
+ }
+
+
+ // show/hide pass
+ for ( index in props ) {
+ value = props[ index ];
+ if ( rfxtypes.exec( value ) ) {
+ delete props[ index ];
+ toggle = toggle || value === "toggle";
+ if ( value === ( hidden ? "hide" : "show" ) ) {
+ continue;
+ }
+ handled.push( index );
+ }
+ }
+
+ length = handled.length;
+ if ( length ) {
+ dataShow = jQuery._data( elem, "fxshow" ) || jQuery._data( elem, "fxshow", {} );
+ if ( "hidden" in dataShow ) {
+ hidden = dataShow.hidden;
+ }
+
+ // store state if its toggle - enables .stop().toggle() to "reverse"
+ if ( toggle ) {
+ dataShow.hidden = !hidden;
+ }
+ if ( hidden ) {
+ jQuery( elem ).show();
+ } else {
+ anim.done(function() {
+ jQuery( elem ).hide();
+ });
+ }
+ anim.done(function() {
+ var prop;
+ jQuery._removeData( elem, "fxshow" );
+ for ( prop in orig ) {
+ jQuery.style( elem, prop, orig[ prop ] );
+ }
+ });
+ for ( index = 0 ; index < length ; index++ ) {
+ prop = handled[ index ];
+ tween = anim.createTween( prop, hidden ? dataShow[ prop ] : 0 );
+ orig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop );
+
+ if ( !( prop in dataShow ) ) {
+ dataShow[ prop ] = tween.start;
+ if ( hidden ) {
+ tween.end = tween.start;
+ tween.start = prop === "width" || prop === "height" ? 1 : 0;
+ }
+ }
+ }
+ }
+}
+
+function Tween( elem, options, prop, end, easing ) {
+ return new Tween.prototype.init( elem, options, prop, end, easing );
+}
+jQuery.Tween = Tween;
+
+Tween.prototype = {
+ constructor: Tween,
+ init: function( elem, options, prop, end, easing, unit ) {
+ this.elem = elem;
+ this.prop = prop;
+ this.easing = easing || "swing";
+ this.options = options;
+ this.start = this.now = this.cur();
+ this.end = end;
+ this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
+ },
+ cur: function() {
+ var hooks = Tween.propHooks[ this.prop ];
+
+ return hooks && hooks.get ?
+ hooks.get( this ) :
+ Tween.propHooks._default.get( this );
+ },
+ run: function( percent ) {
+ var eased,
+ hooks = Tween.propHooks[ this.prop ];
+
+ if ( this.options.duration ) {
+ this.pos = eased = jQuery.easing[ this.easing ](
+ percent, this.options.duration * percent, 0, 1, this.options.duration
+ );
+ } else {
+ this.pos = eased = percent;
+ }
+ this.now = ( this.end - this.start ) * eased + this.start;
+
+ if ( this.options.step ) {
+ this.options.step.call( this.elem, this.now, this );
+ }
+
+ if ( hooks && hooks.set ) {
+ hooks.set( this );
+ } else {
+ Tween.propHooks._default.set( this );
+ }
+ return this;
+ }
+};
+
+Tween.prototype.init.prototype = Tween.prototype;
+
+Tween.propHooks = {
+ _default: {
+ get: function( tween ) {
+ var result;
+
+ if ( tween.elem[ tween.prop ] != null &&
+ (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
+ return tween.elem[ tween.prop ];
+ }
+
+ // passing an empty string as a 3rd parameter to .css will automatically
+ // attempt a parseFloat and fallback to a string if the parse fails
+ // so, simple values such as "10px" are parsed to Float.
+ // complex values such as "rotate(1rad)" are returned as is.
+ result = jQuery.css( tween.elem, tween.prop, "" );
+ // Empty strings, null, undefined and "auto" are converted to 0.
+ return !result || result === "auto" ? 0 : result;
+ },
+ set: function( tween ) {
+ // use step hook for back compat - use cssHook if its there - use .style if its
+ // available and use plain properties where available
+ if ( jQuery.fx.step[ tween.prop ] ) {
+ jQuery.fx.step[ tween.prop ]( tween );
+ } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
+ jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
+ } else {
+ tween.elem[ tween.prop ] = tween.now;
+ }
+ }
+ }
+};
+
+// Remove in 2.0 - this supports IE8's panic based approach
+// to setting things on disconnected nodes
+
+Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
+ set: function( tween ) {
+ if ( tween.elem.nodeType && tween.elem.parentNode ) {
+ tween.elem[ tween.prop ] = tween.now;
+ }
+ }
+};
+
+jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
+ var cssFn = jQuery.fn[ name ];
+ jQuery.fn[ name ] = function( speed, easing, callback ) {
+ return speed == null || typeof speed === "boolean" ?
+ cssFn.apply( this, arguments ) :
+ this.animate( genFx( name, true ), speed, easing, callback );
+ };
+});
+
+jQuery.fn.extend({
+ fadeTo: function( speed, to, easing, callback ) {
+
+ // show any hidden elements after setting opacity to 0
+ return this.filter( isHidden ).css( "opacity", 0 ).show()
+
+ // animate to the value specified
+ .end().animate({ opacity: to }, speed, easing, callback );
+ },
+ animate: function( prop, speed, easing, callback ) {
+ var empty = jQuery.isEmptyObject( prop ),
+ optall = jQuery.speed( speed, easing, callback ),
+ doAnimation = function() {
+ // Operate on a copy of prop so per-property easing won't be lost
+ var anim = Animation( this, jQuery.extend( {}, prop ), optall );
+ doAnimation.finish = function() {
+ anim.stop( true );
+ };
+ // Empty animations, or finishing resolves immediately
+ if ( empty || jQuery._data( this, "finish" ) ) {
+ anim.stop( true );
+ }
+ };
+ doAnimation.finish = doAnimation;
+
+ return empty || optall.queue === false ?
+ this.each( doAnimation ) :
+ this.queue( optall.queue, doAnimation );
+ },
+ stop: function( type, clearQueue, gotoEnd ) {
+ var stopQueue = function( hooks ) {
+ var stop = hooks.stop;
+ delete hooks.stop;
+ stop( gotoEnd );
+ };
+
+ if ( typeof type !== "string" ) {
+ gotoEnd = clearQueue;
+ clearQueue = type;
+ type = undefined;
+ }
+ if ( clearQueue && type !== false ) {
+ this.queue( type || "fx", [] );
+ }
+
+ return this.each(function() {
+ var dequeue = true,
+ index = type != null && type + "queueHooks",
+ timers = jQuery.timers,
+ data = jQuery._data( this );
+
+ if ( index ) {
+ if ( data[ index ] && data[ index ].stop ) {
+ stopQueue( data[ index ] );
+ }
+ } else {
+ for ( index in data ) {
+ if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
+ stopQueue( data[ index ] );
+ }
+ }
+ }
+
+ for ( index = timers.length; index--; ) {
+ if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
+ timers[ index ].anim.stop( gotoEnd );
+ dequeue = false;
+ timers.splice( index, 1 );
+ }
+ }
+
+ // start the next in the queue if the last step wasn't forced
+ // timers currently will call their complete callbacks, which will dequeue
+ // but only if they were gotoEnd
+ if ( dequeue || !gotoEnd ) {
+ jQuery.dequeue( this, type );
+ }
+ });
+ },
+ finish: function( type ) {
+ if ( type !== false ) {
+ type = type || "fx";
+ }
+ return this.each(function() {
+ var index,
+ data = jQuery._data( this ),
+ queue = data[ type + "queue" ],
+ hooks = data[ type + "queueHooks" ],
+ timers = jQuery.timers,
+ length = queue ? queue.length : 0;
+
+ // enable finishing flag on private data
+ data.finish = true;
+
+ // empty the queue first
+ jQuery.queue( this, type, [] );
+
+ if ( hooks && hooks.cur && hooks.cur.finish ) {
+ hooks.cur.finish.call( this );
+ }
+
+ // look for any active animations, and finish them
+ for ( index = timers.length; index--; ) {
+ if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
+ timers[ index ].anim.stop( true );
+ timers.splice( index, 1 );
+ }
+ }
+
+ // look for any animations in the old queue and finish them
+ for ( index = 0; index < length; index++ ) {
+ if ( queue[ index ] && queue[ index ].finish ) {
+ queue[ index ].finish.call( this );
+ }
+ }
+
+ // turn off finishing flag
+ delete data.finish;
+ });
+ }
+});
+
+// Generate parameters to create a standard animation
+function genFx( type, includeWidth ) {
+ var which,
+ attrs = { height: type },
+ i = 0;
+
+ // if we include width, step value is 1 to do all cssExpand values,
+ // if we don't include width, step value is 2 to skip over Left and Right
+ includeWidth = includeWidth? 1 : 0;
+ for( ; i < 4 ; i += 2 - includeWidth ) {
+ which = cssExpand[ i ];
+ attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
+ }
+
+ if ( includeWidth ) {
+ attrs.opacity = attrs.width = type;
+ }
+
+ return attrs;
+}
+
+// Generate shortcuts for custom animations
+jQuery.each({
+ slideDown: genFx("show"),
+ slideUp: genFx("hide"),
+ slideToggle: genFx("toggle"),
+ fadeIn: { opacity: "show" },
+ fadeOut: { opacity: "hide" },
+ fadeToggle: { opacity: "toggle" }
+}, function( name, props ) {
+ jQuery.fn[ name ] = function( speed, easing, callback ) {
+ return this.animate( props, speed, easing, callback );
+ };
+});
+
+jQuery.speed = function( speed, easing, fn ) {
+ var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
+ complete: fn || !fn && easing ||
+ jQuery.isFunction( speed ) && speed,
+ duration: speed,
+ easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
+ };
+
+ opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+ opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
+
+ // normalize opt.queue - true/undefined/null -> "fx"
+ if ( opt.queue == null || opt.queue === true ) {
+ opt.queue = "fx";
+ }
+
+ // Queueing
+ opt.old = opt.complete;
+
+ opt.complete = function() {
+ if ( jQuery.isFunction( opt.old ) ) {
+ opt.old.call( this );
+ }
+
+ if ( opt.queue ) {
+ jQuery.dequeue( this, opt.queue );
+ }
+ };
+
+ return opt;
+};
+
+jQuery.easing = {
+ linear: function( p ) {
+ return p;
+ },
+ swing: function( p ) {
+ return 0.5 - Math.cos( p*Math.PI ) / 2;
+ }
+};
+
+jQuery.timers = [];
+jQuery.fx = Tween.prototype.init;
+jQuery.fx.tick = function() {
+ var timer,
+ timers = jQuery.timers,
+ i = 0;
+
+ fxNow = jQuery.now();
+
+ for ( ; i < timers.length; i++ ) {
+ timer = timers[ i ];
+ // Checks the timer has not already been removed
+ if ( !timer() && timers[ i ] === timer ) {
+ timers.splice( i--, 1 );
+ }
+ }
+
+ if ( !timers.length ) {
+ jQuery.fx.stop();
+ }
+ fxNow = undefined;
+};
+
+jQuery.fx.timer = function( timer ) {
+ if ( timer() && jQuery.timers.push( timer ) ) {
+ jQuery.fx.start();
+ }
+};
+
+jQuery.fx.interval = 13;
+
+jQuery.fx.start = function() {
+ if ( !timerId ) {
+ timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
+ }
+};
+
+jQuery.fx.stop = function() {
+ clearInterval( timerId );
+ timerId = null;
+};
+
+jQuery.fx.speeds = {
+ slow: 600,
+ fast: 200,
+ // Default speed
+ _default: 400
+};
+
+// Back Compat <1.8 extension point
+jQuery.fx.step = {};
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+ jQuery.expr.filters.animated = function( elem ) {
+ return jQuery.grep(jQuery.timers, function( fn ) {
+ return elem === fn.elem;
+ }).length;
+ };
+}
+jQuery.fn.offset = function( options ) {
+ if ( arguments.length ) {
+ return options === undefined ?
+ this :
+ this.each(function( i ) {
+ jQuery.offset.setOffset( this, options, i );
+ });
+ }
+
+ var docElem, win,
+ box = { top: 0, left: 0 },
+ elem = this[ 0 ],
+ doc = elem && elem.ownerDocument;
+
+ if ( !doc ) {
+ return;
+ }
+
+ docElem = doc.documentElement;
+
+ // Make sure it's not a disconnected DOM node
+ if ( !jQuery.contains( docElem, elem ) ) {
+ return box;
+ }
+
+ // If we don't have gBCR, just use 0,0 rather than error
+ // BlackBerry 5, iOS 3 (original iPhone)
+ if ( typeof elem.getBoundingClientRect !== core_strundefined ) {
+ box = elem.getBoundingClientRect();
+ }
+ win = getWindow( doc );
+ return {
+ top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ),
+ left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
+ };
+};
+
+jQuery.offset = {
+
+ setOffset: function( elem, options, i ) {
+ var position = jQuery.css( elem, "position" );
+
+ // set position first, in-case top/left are set even on static elem
+ if ( position === "static" ) {
+ elem.style.position = "relative";
+ }
+
+ var curElem = jQuery( elem ),
+ curOffset = curElem.offset(),
+ curCSSTop = jQuery.css( elem, "top" ),
+ curCSSLeft = jQuery.css( elem, "left" ),
+ calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
+ props = {}, curPosition = {}, curTop, curLeft;
+
+ // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
+ if ( calculatePosition ) {
+ curPosition = curElem.position();
+ curTop = curPosition.top;
+ curLeft = curPosition.left;
+ } else {
+ curTop = parseFloat( curCSSTop ) || 0;
+ curLeft = parseFloat( curCSSLeft ) || 0;
+ }
+
+ if ( jQuery.isFunction( options ) ) {
+ options = options.call( elem, i, curOffset );
+ }
+
+ if ( options.top != null ) {
+ props.top = ( options.top - curOffset.top ) + curTop;
+ }
+ if ( options.left != null ) {
+ props.left = ( options.left - curOffset.left ) + curLeft;
+ }
+
+ if ( "using" in options ) {
+ options.using.call( elem, props );
+ } else {
+ curElem.css( props );
+ }
+ }
+};
+
+
+jQuery.fn.extend({
+
+ position: function() {
+ if ( !this[ 0 ] ) {
+ return;
+ }
+
+ var offsetParent, offset,
+ parentOffset = { top: 0, left: 0 },
+ elem = this[ 0 ];
+
+ // fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent
+ if ( jQuery.css( elem, "position" ) === "fixed" ) {
+ // we assume that getBoundingClientRect is available when computed position is fixed
+ offset = elem.getBoundingClientRect();
+ } else {
+ // Get *real* offsetParent
+ offsetParent = this.offsetParent();
+
+ // Get correct offsets
+ offset = this.offset();
+ if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
+ parentOffset = offsetParent.offset();
+ }
+
+ // Add offsetParent borders
+ parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
+ parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
+ }
+
+ // Subtract parent offsets and element margins
+ // note: when an element has margin: auto the offsetLeft and marginLeft
+ // are the same in Safari causing offset.left to incorrectly be 0
+ return {
+ top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
+ left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true)
+ };
+ },
+
+ offsetParent: function() {
+ return this.map(function() {
+ var offsetParent = this.offsetParent || document.documentElement;
+ while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position") === "static" ) ) {
+ offsetParent = offsetParent.offsetParent;
+ }
+ return offsetParent || document.documentElement;
+ });
+ }
+});
+
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {
+ var top = /Y/.test( prop );
+
+ jQuery.fn[ method ] = function( val ) {
+ return jQuery.access( this, function( elem, method, val ) {
+ var win = getWindow( elem );
+
+ if ( val === undefined ) {
+ return win ? (prop in win) ? win[ prop ] :
+ win.document.documentElement[ method ] :
+ elem[ method ];
+ }
+
+ if ( win ) {
+ win.scrollTo(
+ !top ? val : jQuery( win ).scrollLeft(),
+ top ? val : jQuery( win ).scrollTop()
+ );
+
+ } else {
+ elem[ method ] = val;
+ }
+ }, method, val, arguments.length, null );
+ };
+});
+
+function getWindow( elem ) {
+ return jQuery.isWindow( elem ) ?
+ elem :
+ elem.nodeType === 9 ?
+ elem.defaultView || elem.parentWindow :
+ false;
+}
+// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
+jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
+ jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
+ // margin is only for outerHeight, outerWidth
+ jQuery.fn[ funcName ] = function( margin, value ) {
+ var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
+ extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
+
+ return jQuery.access( this, function( elem, type, value ) {
+ var doc;
+
+ if ( jQuery.isWindow( elem ) ) {
+ // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
+ // isn't a whole lot we can do. See pull request at this URL for discussion:
+ // https://github.com/jquery/jquery/pull/764
+ return elem.document.documentElement[ "client" + name ];
+ }
+
+ // Get document width or height
+ if ( elem.nodeType === 9 ) {
+ doc = elem.documentElement;
+
+ // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
+ // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
+ return Math.max(
+ elem.body[ "scroll" + name ], doc[ "scroll" + name ],
+ elem.body[ "offset" + name ], doc[ "offset" + name ],
+ doc[ "client" + name ]
+ );
+ }
+
+ return value === undefined ?
+ // Get width or height on the element, requesting but not forcing parseFloat
+ jQuery.css( elem, type, extra ) :
+
+ // Set width or height on the element
+ jQuery.style( elem, type, value, extra );
+ }, type, chainable ? margin : undefined, chainable, null );
+ };
+ });
+});
+// Limit scope pollution from any deprecated API
+// (function() {
+
+// })();
+// Expose jQuery to the global object
+window.jQuery = window.$ = jQuery;
+
+// Expose jQuery as an AMD module, but only for AMD loaders that
+// understand the issues with loading multiple versions of jQuery
+// in a page that all might call define(). The loader will indicate
+// they have special allowances for multiple jQuery versions by
+// specifying define.amd.jQuery = true. Register as a named module,
+// since jQuery can be concatenated with other files that may use define,
+// but not use a proper concatenation script that understands anonymous
+// AMD modules. A named AMD is safest and most robust way to register.
+// Lowercase jquery is used because AMD module names are derived from
+// file names, and jQuery is normally delivered in a lowercase file name.
+// Do this after creating the global so that if an AMD module wants to call
+// noConflict to hide this version of jQuery, it will work.
+if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
+ define( "jquery", [], function () { return jQuery; } );
+}
+
+})( window );
Added: gnucash/trunk/src/report/jqplot/jquery.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/jquery.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/jquery.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,5 @@
+/*! jQuery v1.9.1 | (c) 2005, 2012 jQuery Foundation, Inc. | jquery.org/license
+//@ sourceMappingURL=jquery.min.map
+*/(function(e,t){var n,r,i=typeof t,o=e.document,a=e.location,s=e.jQuery,u=e.$,l={},c=[],p="1.9.1",f=c.concat,d=c.push,h=c.slice,g=c.indexOf,m=l.toString,y=l.hasOwnProperty,v=p.trim,b=function(e,t){return new b.fn.init(e,t,r)},x=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,w=/\S+/g,T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,k=/^[\],:{}\s]*$/,E=/(?:^|:|,)(?:\s*\[)+/g,S=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,A=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,j=/^-ms-/,D=/-([\da-z])/gi,L=function(e,t){return t.toUpperCase()},H=function(e){(o.addEventListener||"load"===e.type||"complete"===o.readyState)&&(q(),b.ready())},q=function(){o.addEventListener?(o.removeEventListener("DOMContentLoaded",H,!1),e.removeEventListener("load",H,!1)):(o.detachEvent("onreadystatechange",H),e.detachEvent("onload",H))};b.fn=b.prototype={jquery:p,constructor:b,init:function(e,n,r){var i,a;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof b?n[0]:n,b.merge(this,b.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:o,!0)),C.test(i[1])&&b.isPlainObject(n))for(i in n)b.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(a=o.getElementById(i[2]),a&&a.parentNode){if(a.id!==i[2])return r.find(e);this.length=1,this[0]=a}return this.context=o,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):b.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),b.makeArray(e,this))},selector:"",length:0,size:function(){return this.length},toArray:function(){return h.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=b.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return b.each(this,e,t)},ready:func!
tion(e){return b.ready.promise().done(e),this},slice:function(){return this.pushStack(h.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(b.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:d,sort:[].sort,splice:[].splice},b.fn.init.prototype=b.fn,b.extend=b.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},u=1,l=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},u=2),"object"==typeof s||b.isFunction(s)||(s={}),l===u&&(s=this,--u);l>u;u++)if(null!=(o=arguments[u]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(b.isPlainObject(r)||(n=b.isArray(r)))?(n?(n=!1,a=e&&b.isArray(e)?e:[]):a=e&&b.isPlainObject(e)?e:{},s[i]=b.extend(c,a,r)):r!==t&&(s[i]=r));return s},b.extend({noConflict:function(t){return e.$===b&&(e.$=u),t&&e.jQuery===b&&(e.jQuery=s),b},isReady:!1,readyWait:1,holdReady:function(e){e?b.readyWait++:b.ready(!0)},ready:function(e){if(e===!0?!--b.readyWait:!b.isReady){if(!o.body)return setTimeout(b.ready);b.isReady=!0,e!==!0&&--b.readyWait>0||(n.resolveWith(o,[b]),b.fn.trigger&&b(o).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===b.type(e)},isArray:Array.isArray||function(e){return"array"===b.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[m.call(e)]||"object":typeof e},isPlainObject:function(e){if(!e||"object"!==b.type(e)||e.nodeType||b.isWindow(e))return!1;try{if(e.constructor&&!y.call(e,"constructor")&&!y.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||y.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)re!
turn null;"boolean"==typeof t&&(n=t,t=!1),t=t||o;var r=C.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=b.buildFragment([e],t,i),i&&b(i).remove(),b.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=b.trim(n),n&&k.test(n.replace(S,"@").replace(A,"]").replace(E,"")))?Function("return "+n)():(b.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||b.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&b.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(j,"ms-").replace(D,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:v&&!v.call("\ufeff\u00a0")?function(e){return null==e?"":v.call(e)}:function(e){return null==e?"":(e+"").replace(T,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?b.merge(n,"string"==typeof e?[e]:e):d.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(g)return g.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e!
)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return f.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),b.isFunction(e)?(r=h.call(arguments,2),i=function(){return e.apply(n||this,r.concat(h.call(arguments)))},i.guid=e.guid=e.guid||b.guid++,i):t},access:function(e,n,r,i,o,a,s){var u=0,l=e.length,c=null==r;if("object"===b.type(r)){o=!0;for(u in r)b.access(e,n,u,r[u],!0,a,s)}else if(i!==t&&(o=!0,b.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(b(e),n)})),n))for(;l>u;u++)n(e[u],r,s?i:i.call(e[u],u,n(e[u],r)));return o?e:c?n.call(e):l?n(e[0],r):a},now:function(){return(new Date).getTime()}}),b.ready.promise=function(t){if(!n)if(n=b.Deferred(),"complete"===o.readyState)setTimeout(b.ready);else if(o.addEventListener)o.addEventListener("DOMContentLoaded",H,!1),e.addEventListener("load",H,!1);else{o.attachEvent("onreadystatechange",H),e.attachEvent("onload",H);var r=!1;try{r=null==e.frameElement&&o.documentElement}catch(i){}r&&r.doScroll&&function a(){if(!b.isReady){try{r.doScroll("left")}catch(e){return setTimeout(a,50)}q(),b.ready()}}()}return n.promise(t)},b.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=b.type(e);return b.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=b(o);var _={};function F(e){var t=_[e]={};return b.each(e.match(w)||[],function(e,n){t[n]=!0}),t}b.Callbacks=function(e){e="string"==typeof e?_[e]||F(e):b.extend({},e);var n,r,i,o,a,s,u=[],l=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=u.length,n=!0;u&&o>a;a++)if(u[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,u&&(l?l.length&&c(l.shift()):r?u=[]:p.disable())},p={add:function(){if(u){var t=u.length;(function i(t){b.each(t,function(t,n){var r=b.type(n);"function"===r?e.unique&&p.has(n)||u.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=u.length:r&&(s=t,c(r))}return !
this},remove:function(){return u&&b.each(arguments,function(e,t){var r;while((r=b.inArray(t,u,r))>-1)u.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?b.inArray(e,u)>-1:!(!u||!u.length)},empty:function(){return u=[],this},disable:function(){return u=l=r=t,this},disabled:function(){return!u},lock:function(){return l=t,r||p.disable(),this},locked:function(){return!l},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],!u||i&&!l||(n?l.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},b.extend({Deferred:function(e){var t=[["resolve","done",b.Callbacks("once memory"),"resolved"],["reject","fail",b.Callbacks("once memory"),"rejected"],["notify","progress",b.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return b.Deferred(function(n){b.each(t,function(t,o){var a=o[0],s=b.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&b.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?b.extend(e,r):r}},i={};return r.pipe=r.then,b.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=h.call(arguments),r=n.length,i=1!==r||e&&b.isFunction(e.promise)?r:0,o=1===i?e:b.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?h.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,u,l;if(r>1)for(s=Array(r),u=Array(r),l=Array(r);r>t;t++)n[t]&&b.isFunction(n[t].promise)?n[t].promise().done(a(t,l,n)).fail(o.reject).progress(a(t,u,s)):--i;return i||o.resolveWith(l,n),o.promise()}}),b.support=function(){var t,n,!
r,a,s,u,l,c,p,f,d=o.createElement("div");if(d.setAttribute("className","t"),d.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=d.getElementsByTagName("*"),r=d.getElementsByTagName("a")[0],!n||!r||!n.length)return{};s=o.createElement("select"),l=s.appendChild(o.createElement("option")),a=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={getSetAttribute:"t"!==d.className,leadingWhitespace:3===d.firstChild.nodeType,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:"/a"===r.getAttribute("href"),opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:!!a.value,optSelected:l.selected,enctype:!!o.createElement("form").enctype,html5Clone:"<:nav></:nav>"!==o.createElement("nav").cloneNode(!0).outerHTML,boxModel:"CSS1Compat"===o.compatMode,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},a.checked=!0,t.noCloneChecked=a.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!l.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}a=o.createElement("input"),a.setAttribute("value",""),t.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),t.radioValue="t"===a.value,a.setAttribute("checked","t"),a.setAttribute("name","t"),u=o.createDocumentFragment(),u.appendChild(a),t.appendChecked=a.checked,t.checkClone=u.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;return d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip,b(function(){var n,r,a,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webk!
it-box-sizing:content-box;",u=o.getElementsByTagName("body")[0];u&&(n=o.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",u.appendChild(n).appendChild(d),d.innerHTML="<table><tr><td></td><td>t</td></tr></table>",a=d.getElementsByTagName("td"),a[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===a[0].offsetHeight,a[0].style.display="",a[1].style.display="none",t.reliableHiddenOffsets=p&&0===a[0].offsetHeight,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=4===d.offsetWidth,t.doesNotIncludeMarginInBodyOffset=1!==u.offsetTop,e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(o.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="<div></div>",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(u.style.zoom=1)),u.removeChild(n),n=d=a=r=null)}),n=s=u=l=r=a=null,t}();var O=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,B=/([A-Z])/g;function P(e,n,r,i){if(b.acceptData(e)){var o,a,s=b.expando,u="string"==typeof n,l=e.nodeType,p=l?b.cache:e,f=l?e[s]:e[s]&&s;if(f&&p[f]&&(i||p[f].data)||!u||r!==t)return f||(l?e[s]=f=c.pop()||b.guid++:f=s),p[f]||(p[f]={},l||(p[f].toJSON=b.noop)),("object"==typeof n||"function"==typeof n)&&(i?p[f]=b.extend(p[f],n):p[f].data=b.extend(p[f].data,n)),o=p[f],i||(o.data||(o.data={}),o=o.data),r!==t&&(o[b.camelCase(n)]=r),u?(a=o[n],null==a&&(a=o[b.camelCase(n)])):a=o,a}}function R(e,t,n){if!
(b.acceptData(e)){var r,i,o,a=e.nodeType,s=a?b.cache:e,u=a?e[b.expando]:b.expando;if(s[u]){if(t&&(o=n?s[u]:s[u].data)){b.isArray(t)?t=t.concat(b.map(t,b.camelCase)):t in o?t=[t]:(t=b.camelCase(t),t=t in o?[t]:t.split(" "));for(r=0,i=t.length;i>r;r++)delete o[t[r]];if(!(n?$:b.isEmptyObject)(o))return}(n||(delete s[u].data,$(s[u])))&&(a?b.cleanData([e],!0):b.support.deleteExpando||s!=s.window?delete s[u]:s[u]=null)}}}b.extend({cache:{},expando:"jQuery"+(p+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?b.cache[e[b.expando]]:e[b.expando],!!e&&!$(e)},data:function(e,t,n){return P(e,t,n)},removeData:function(e,t){return R(e,t)},_data:function(e,t,n){return P(e,t,n,!0)},_removeData:function(e,t){return R(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&b.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),b.fn.extend({data:function(e,n){var r,i,o=this[0],a=0,s=null;if(e===t){if(this.length&&(s=b.data(o),1===o.nodeType&&!b._data(o,"parsedAttrs"))){for(r=o.attributes;r.length>a;a++)i=r[a].name,i.indexOf("data-")||(i=b.camelCase(i.slice(5)),W(o,i,s[i]));b._data(o,"parsedAttrs",!0)}return s}return"object"==typeof e?this.each(function(){b.data(this,e)}):b.access(this,function(n){return n===t?o?W(o,e,b.data(o,e)):null:(this.each(function(){b.data(this,e,n)}),t)},null,n,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){b.removeData(this,e)})}});function W(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(B,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:O.test(r)?b.parseJSON(r):r}catch(o){}b.data(e,n,r)}else r=t}return r}function $(e){var t;for(t in e)if(("data"!==t||!b.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}b.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=b._data(e,n),r&&(!i||b.isArray!
(r)?i=b._data(e,n,b.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=b.queue(e,t),r=n.length,i=n.shift(),o=b._queueHooks(e,t),a=function(){b.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),o.cur=i,i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return b._data(e,n)||b._data(e,n,{empty:b.Callbacks("once memory").add(function(){b._removeData(e,t+"queue"),b._removeData(e,n)})})}}),b.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?b.queue(this[0],e):n===t?this:this.each(function(){var t=b.queue(this,e,n);b._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&b.dequeue(this,e)})},dequeue:function(e){return this.each(function(){b.dequeue(this,e)})},delay:function(e,t){return e=b.fx?b.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=b.Deferred(),a=this,s=this.length,u=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=b._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(u));return u(),o.promise(n)}});var I,z,X=/[\t\r\n]/g,U=/\r/g,V=/^(?:input|select|textarea|button|object)$/i,Y=/^(?:a|area)$/i,J=/^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i,G=/^(?:checked|selected)$/i,Q=b.support.getSetAttribute,K=b.support.input;b.fn.extend({attr:function(e,t){return b.access(this,b.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){b.removeAttr(this,e)})},prop:function(e,t){return b.access(this,b.prop,e,t,arguments.length>1)},removeProp:function(e){return e=b.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,u="string"==typeof e&&e;if(b.isFunction(e))return this.each(function(t){b(this).add!
Class(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(X," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=b.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,u=0===arguments.length||"string"==typeof e&&e;if(b.isFunction(e))return this.each(function(t){b(this).removeClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(X," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?b.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e,r="boolean"==typeof t;return b.isFunction(e)?this.each(function(n){b(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var o,a=0,s=b(this),u=t,l=e.match(w)||[];while(o=l[a++])u=r?u:!s.hasClass(o),s[u?"addClass":"removeClass"](o)}else(n===i||"boolean"===n)&&(this.className&&b._data(this,"__className__",this.className),this.className=this.className||e===!1?"":b._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(X," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=b.isFunction(e),this.each(function(n){var o,a=b(this);1===this.nodeType&&(o=i?e.call(this,n,a.val()):e,null==o?o="":"number"==typeof o?o+="":b.isArray(o)&&(o=b.map(o,function(e){return null==e?"":e+""})),r=b.valHooks[this.type]||b.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=b.valHooks[o.type]||b.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(U,""):null==n?"":n)}}}),b.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:functi!
on(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,u=0>i?s:o?i:0;for(;s>u;u++)if(n=r[u],!(!n.selected&&u!==i||(b.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&b.nodeName(n.parentNode,"optgroup"))){if(t=b(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n=b.makeArray(t);return b(e).find("option").each(function(){this.selected=b.inArray(b(this).val(),n)>=0}),n.length||(e.selectedIndex=-1),n}}},attr:function(e,n,r){var o,a,s,u=e.nodeType;if(e&&3!==u&&8!==u&&2!==u)return typeof e.getAttribute===i?b.prop(e,n,r):(a=1!==u||!b.isXMLDoc(e),a&&(n=n.toLowerCase(),o=b.attrHooks[n]||(J.test(n)?z:I)),r===t?o&&a&&"get"in o&&null!==(s=o.get(e,n))?s:(typeof e.getAttribute!==i&&(s=e.getAttribute(n)),null==s?t:s):null!==r?o&&a&&"set"in o&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r):(b.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(w);if(o&&1===e.nodeType)while(n=o[i++])r=b.propFix[n]||n,J.test(n)?!Q&&G.test(n)?e[b.camelCase("default-"+n)]=e[r]=!1:e[r]=!1:b.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!b.support.radioValue&&"radio"===t&&b.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!b.isXMLDoc(e),a&&(n=b.propFix[n]||n,o=b.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var n=e.getAttributeNode("tabindex");return n&&n.specified?parseInt(n.value,10):V.test(e.nodeName)||Y.test(e.nodeName)&&e.href?0:t}}}}),z={get:function(e,n){var r=b.prop(e,n),i="boolean"==typeof r&&e.getAttribu!
te(n),o="boolean"==typeof r?K&&Q?null!=i:G.test(n)?e[b.camelCase("default-"+n)]:!!i:e.getAttributeNode(n);return o&&o.value!==!1?n.toLowerCase():t},set:function(e,t,n){return t===!1?b.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&b.propFix[n]||n,n):e[b.camelCase("default-"+n)]=e[n]=!0,n}},K&&Q||(b.attrHooks.value={get:function(e,n){var r=e.getAttributeNode(n);return b.nodeName(e,"input")?e.defaultValue:r&&r.specified?r.value:t},set:function(e,n,r){return b.nodeName(e,"input")?(e.defaultValue=n,t):I&&I.set(e,n,r)}}),Q||(I=b.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&("id"===n||"name"===n||"coords"===n?""!==r.value:r.specified)?r.value:t},set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},b.attrHooks.contenteditable={get:I.get,set:function(e,t,n){I.set(e,""===t?!1:t,n)}},b.each(["width","height"],function(e,n){b.attrHooks[n]=b.extend(b.attrHooks[n],{set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}})})),b.support.hrefNormalized||(b.each(["href","src","width","height"],function(e,n){b.attrHooks[n]=b.extend(b.attrHooks[n],{get:function(e){var r=e.getAttribute(n,2);return null==r?t:r}})}),b.each(["href","src"],function(e,t){b.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}})),b.support.style||(b.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),b.support.optSelected||(b.propHooks.selected=b.extend(b.propHooks.selected,{get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}})),b.support.enctype||(b.propFix.enctype="encoding"),b.support.checkOn||b.each(["radio","checkbox"],function(){b.valHooks[this]={get:function(e){return null===e.getAttribute("value")?"on":e.value}}}),b.each(["radio","checkbox"],function(){b.valHooks[this]=b.extend(b.valHooks[this],{set:function(e,n){return b.isArray(n)?e.checked=b.inArray(b(e).val(),n)>=0:t}})}!
);var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}b.event={global:{},add:function(e,n,r,o,a){var s,u,l,c,p,f,d,h,g,m,y,v=b._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=b.guid++),(u=v.events)||(u=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof b===i||e&&b.event.triggered===e.type?t:b.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(w)||[""],l=n.length;while(l--)s=rt.exec(n[l])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),p=b.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=b.event.special[g]||{},d=b.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&b.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=u[g])||(h=u[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),b.event.global[g]=!0;e=null}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,p,f,d,h,g,m=b.hasData(e)&&b._data(e);if(m&&(c=m.events)){t=(t||"").match(w)||[""],l=t.length;while(l--)if(s=rt.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=b.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),u=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));u&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||b.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)b.event.remove(e,d+t[l],n,r,!0);b.isEmptyObject(c)&&(delete m.handle,b._removeData(e,"events"))}},trigger:function(n,r,i,a){var s,u,l,c,p,f,d,h=[i||o],g=y.call(n,"type")?n.type:n,m=y.call(n,"namespace")?n.name!
space.split("."):[];if(l=f=i=i||o,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+b.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),u=0>g.indexOf(":")&&"on"+g,n=n[b.expando]?n:new b.Event(g,"object"==typeof n&&n),n.isTrigger=!0,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:b.makeArray(r,[n]),p=b.event.special[g]||{},a||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!a&&!p.noBubble&&!b.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(l=l.parentNode);l;l=l.parentNode)h.push(l),f=l;f===(i.ownerDocument||o)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((l=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(b._data(l,"events")||{})[n.type]&&b._data(l,"handle"),s&&s.apply(l,r),s=u&&l[u],s&&b.acceptData(l)&&s.apply&&s.apply(l,r)===!1&&n.preventDefault();if(n.type=g,!(a||n.isDefaultPrevented()||p._default&&p._default.apply(i.ownerDocument,r)!==!1||"click"===g&&b.nodeName(i,"a")||!b.acceptData(i)||!u||!i[g]||b.isWindow(i))){f=i[u],f&&(i[u]=null),b.event.triggered=g;try{i[g]()}catch(v){}b.event.triggered=t,f&&(i[u]=f)}return n.result}},dispatch:function(e){e=b.event.fix(e);var n,r,i,o,a,s=[],u=h.call(arguments),l=(b._data(this,"events")||{})[e.type]||[],c=b.event.special[e.type]||{};if(u[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=b.event.handlers.call(this,e,l),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((b.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,u),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],u=n.delegateCount,l=e.target;if(u&&l.nodeType&&(!e.button||"click"!==e.type))for(;l!=this;l=l.parentNode||this)if(1===l.nodeTyp!
e&&(l.disabled!==!0||"click"!==e.type)){for(o=[],a=0;u>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?b(r,this).index(l)>=0:b.find(r,this,null,[l]).length),o[r]&&o.push(i);o.length&&s.push({elem:l,handlers:o})}return n.length>u&&s.push({elem:this,handlers:n.slice(u)}),s},fix:function(e){if(e[b.expando])return e;var t,n,r,i=e.type,a=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new b.Event(a),t=r.length;while(t--)n=r[t],e[n]=a[n];return e.target||(e.target=a.srcElement||o),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,a):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,a,s=n.button,u=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||o,a=i.documentElement,r=i.body,e.pageX=n.clientX+(a&&a.scrollLeft||r&&r.scrollLeft||0)-(a&&a.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(a&&a.scrollTop||r&&r.scrollTop||0)-(a&&a.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&u&&(e.relatedTarget=u===e.target?n.toElement:u),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},click:{trigger:function(){return b.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t}},focus:{trigger:function(){if(this!==o.activeElement&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===o.activeElement&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.r!
esult)}}},simulate:function(e,t,n,r){var i=b.extend(new b.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?b.event.trigger(i,null,t):b.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},b.removeEvent=o.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},b.Event=function(e,n){return this instanceof b.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&b.extend(this,n),this.timeStamp=e&&e.timeStamp||b.now(),this[b.expando]=!0,t):new b.Event(e,n)},b.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},b.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){b.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;
+return(!i||i!==r&&!b.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),b.support.submitBubbles||(b.event.special.submit={setup:function(){return b.nodeName(this,"form")?!1:(b.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=b.nodeName(n,"input")||b.nodeName(n,"button")?n.form:t;r&&!b._data(r,"submitBubbles")&&(b.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),b._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&b.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return b.nodeName(this,"form")?!1:(b.event.remove(this,"._submit"),t)}}),b.support.changeBubbles||(b.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(b.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),b.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),b.event.simulate("change",this,e,!0)})),!1):(b.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!b._data(t,"changeBubbles")&&(b.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||b.event.simulate("change",this.parentNode,e,!0)}),b._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return b.event.remove(this,"._change"),!Z.test(this.nodeName)}}),b.support.focusinBubbles||b.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){b.event.simulate(t,e.target,b.event.fix(e),!0)};b.event.special[t]={setup:function(){0===n++&&o.addEventListener(e,r,!0)},teardown:function(){0===--n&&o.removeEventListener(e,r,!0)}}}),b.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string!
"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return b().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=b.guid++)),this.each(function(){b.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,b(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){b.event.remove(this,e,r,n)})},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},trigger:function(e,t){return this.each(function(){b.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?b.event.trigger(e,n,r,!0):t}}),function(e,t){var n,r,i,o,a,s,u,l,c,p,f,d,h,g,m,y,v,x="sizzle"+-new Date,w=e.document,T={},N=0,C=0,k=it(),E=it(),S=it(),A=typeof t,j=1<<31,D=[],L=D.pop,H=D.push,q=D.slice,M=D.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},_="[\\x20\\t\\r\\n\\f]",F="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=F.replace("w","w#"),B="([*^$|!~]?=)",P="\\["+_+"*("+F+")"+_+"*(?:"+B+_+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+O+")|)|)"+_+"*\\]",R=":("+F+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+P.replace(3,8)+")*)|.*)\\)|)",W=RegExp("^"+_+"+|((?:^|[^\\\\])(?:\\\\.)*)"+_+"+$","g"),$=RegExp("^"+_+"*,"+_+"*"),I=RegExp("^"+_+"*([\\x20\\t\\r\\n\\f>+~])"+_+"*"),z=RegExp(R),X=RegExp("^"+O+"$"),U={ID:RegExp("^#("+F+")"),CLASS:RegExp("^\\.("+F+")"),NAME:RegExp("^\\[name=['\"]?("+F+")['\"]?\\]"),TAG:RegExp("^("+F.replace("w","w*")+")"),ATT!
R:RegExp("^"+P),PSEUDO:RegExp("^"+R),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+_+"*(even|odd|(([+-]|)(\\d*)n|)"+_+"*(?:([+-]|)"+_+"*(\\d+)|))"+_+"*\\)|)","i"),needsContext:RegExp("^"+_+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+_+"*((?:-\\d)?\\d*)"+_+"*\\)|)(?=[^-]|$)","i")},V=/[\x20\t\r\n\f]*[+~]/,Y=/^[^{]+\{\s*\[native code/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,G=/^(?:input|select|textarea|button)$/i,Q=/^h\d$/i,K=/'|\\/g,Z=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,et=/\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,tt=function(e,t){var n="0x"+t-65536;return n!==n?t:0>n?String.fromCharCode(n+65536):String.fromCharCode(55296|n>>10,56320|1023&n)};try{q.call(w.documentElement.childNodes,0)[0].nodeType}catch(nt){q=function(e){var t,n=[];while(t=this[e++])n.push(t);return n}}function rt(e){return Y.test(e+"")}function it(){var e,t=[];return e=function(n,r){return t.push(n+=" ")>i.cacheLength&&delete e[t.shift()],e[n]=r}}function ot(e){return e[x]=!0,e}function at(e){var t=p.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}}function st(e,t,n,r){var i,o,a,s,u,l,f,g,m,v;if((t?t.ownerDocument||t:w)!==p&&c(t),t=t||p,n=n||[],!e||"string"!=typeof e)return n;if(1!==(s=t.nodeType)&&9!==s)return[];if(!d&&!r){if(i=J.exec(e))if(a=i[1]){if(9===s){if(o=t.getElementById(a),!o||!o.parentNode)return n;if(o.id===a)return n.push(o),n}else if(t.ownerDocument&&(o=t.ownerDocument.getElementById(a))&&y(t,o)&&o.id===a)return n.push(o),n}else{if(i[2])return H.apply(n,q.call(t.getElementsByTagName(e),0)),n;if((a=i[3])&&T.getByClassName&&t.getElementsByClassName)return H.apply(n,q.call(t.getElementsByClassName(a),0)),n}if(T.qsa&&!h.test(e)){if(f=!0,g=x,m=t,v=9===s&&e,1===s&&"object"!==t.nodeName.toLowerCase()){l=ft(e),(f=t.getAttribute("id"))?g=f.replace(K,"\\$&"):t.setAttribute("id",g),g="[id='"+g+"'] ",u=l.length;while(u--)l[u]=g+dt(l[u]);m=V.test(e)&&t.parentNode||t,v=l.join(",")}if(v)try{return H.apply(n,q.call(m.querySelectorAll(v),0)),n}catch(b){}finally{f||t.removeAttribute("id")}}}!
return wt(e.replace(W,"$1"),t,n,r)}a=st.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},c=st.setDocument=function(e){var n=e?e.ownerDocument||e:w;return n!==p&&9===n.nodeType&&n.documentElement?(p=n,f=n.documentElement,d=a(n),T.tagNameNoComments=at(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),T.attributes=at(function(e){e.innerHTML="<select></select>";var t=typeof e.lastChild.getAttribute("multiple");return"boolean"!==t&&"string"!==t}),T.getByClassName=at(function(e){return e.innerHTML="<div class='hidden e'></div><div class='hidden'></div>",e.getElementsByClassName&&e.getElementsByClassName("e").length?(e.lastChild.className="e",2===e.getElementsByClassName("e").length):!1}),T.getByName=at(function(e){e.id=x+0,e.innerHTML="<a name='"+x+"'></a><div name='"+x+"'></div>",f.insertBefore(e,f.firstChild);var t=n.getElementsByName&&n.getElementsByName(x).length===2+n.getElementsByName(x+0).length;return T.getIdNotName=!n.getElementById(x),f.removeChild(e),t}),i.attrHandle=at(function(e){return e.innerHTML="<a href='#'></a>",e.firstChild&&typeof e.firstChild.getAttribute!==A&&"#"===e.firstChild.getAttribute("href")})?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},T.getIdNotName?(i.find.ID=function(e,t){if(typeof t.getElementById!==A&&!d){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},i.filter.ID=function(e){var t=e.replace(et,tt);return function(e){return e.getAttribute("id")===t}}):(i.find.ID=function(e,n){if(typeof n.getElementById!==A&&!d){var r=n.getElementById(e);return r?r.id===e||typeof r.getAttributeNode!==A&&r.getAttributeNode("id").value===e?[r]:t:[]}},i.filter.ID=function(e){var t=e.replace(et,tt);return function(e){var n=typeof e.getAttributeNode!==A&&e.getAttributeNode("id");return n&&n.value===t}}),i.find.TAG=T.tagNameNoComments?function(e,n){return typeof n.getElementsByTagName!==A?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.g!
etElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},i.find.NAME=T.getByName&&function(e,n){return typeof n.getElementsByName!==A?n.getElementsByName(name):t},i.find.CLASS=T.getByClassName&&function(e,n){return typeof n.getElementsByClassName===A||d?t:n.getElementsByClassName(e)},g=[],h=[":focus"],(T.qsa=rt(n.querySelectorAll))&&(at(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||h.push("\\["+_+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||h.push(":checked")}),at(function(e){e.innerHTML="<input type='hidden' i=''/>",e.querySelectorAll("[i^='']").length&&h.push("[*^$]="+_+"*(?:\"\"|'')"),e.querySelectorAll(":enabled").length||h.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),h.push(",.*:")})),(T.matchesSelector=rt(m=f.matchesSelector||f.mozMatchesSelector||f.webkitMatchesSelector||f.oMatchesSelector||f.msMatchesSelector))&&at(function(e){T.disconnectedMatch=m.call(e,"div"),m.call(e,"[s!='']:x"),g.push("!=",R)}),h=RegExp(h.join("|")),g=RegExp(g.join("|")),y=rt(f.contains)||f.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},v=f.compareDocumentPosition?function(e,t){var r;return e===t?(u=!0,0):(r=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t))?1&r||e.parentNode&&11===e.parentNode.nodeType?e===n||y(w,e)?-1:t===n||y(w,t)?1:0:4&r?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return u=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:0;if(o===a)return ut(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?ut(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},u=!1,[0,0].s!
ort(v),T..detectDuplicates=u,p):p},st.matches=function(e,t){return st(e,null,null,t)},st.matchesSelector=function(e,t){if((e.ownerDocument||e)!==p&&c(e),t=t.replace(Z,"='$1']"),!(!T.matchesSelector||d||g&&g.test(t)||h.test(t)))try{var n=m.call(e,t);if(n||T.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(r){}return st(t,p,null,[e]).length>0},st.contains=function(e,t){return(e.ownerDocument||e)!==p&&c(e),y(e,t)},st.attr=function(e,t){var n;return(e.ownerDocument||e)!==p&&c(e),d||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):d||T.attributes?e.getAttribute(t):((n=e.getAttributeNode(t))||e.getAttribute(t))&&e[t]===!0?t:n&&n.specified?n.value:null},st.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},st.uniqueSort=function(e){var t,n=[],r=1,i=0;if(u=!T.detectDuplicates,e.sort(v),u){for(;t=e[r];r++)t===e[r-1]&&(i=n.push(r));while(i--)e.splice(n[i],1)}return e};function ut(e,t){var n=t&&e,r=n&&(~t.sourceIndex||j)-(~e.sourceIndex||j);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function lt(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function ct(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function pt(e){return ot(function(t){return t=+t,ot(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}o=st.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=o(t);return n},i=st.selectors={cacheLength:50,createPseudo:ot,match:U,find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(et,tt),e[3]=(e[4]||e[5]||"").replace(et,tt),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[!
1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||st.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&st.error(e[0]),e},PSEUDO:function(e){var t,n=!e[5]&&e[2];return U.CHILD.test(e[0])?null:(e[4]?e[2]=e[4]:n&&z.test(n)&&(t=ft(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){return"*"===e?function(){return!0}:(e=e.replace(et,tt).toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[e+" "];return t||(t=RegExp("(^|"+_+")"+e+"("+_+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==A&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=st.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!u&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[x]||(m[x]={}),l=c[e]||[],d=l[0]===N&&l[1],f=l[0]===N&&l[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[N,d,f];break}}else if(v&&(l=(t[x]||(t[x]={}))[e])&&l[0]===N)f=l[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[x]||(p[x]={}))[e]=[N,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||st.error("unsupported pseudo: "+e);return r[x]?r(t):r.length>1?(n=[e,e,"",t]!
,i.setFilters.hasOwnProperty(e.toLowerCase())?ot(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=M.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:ot(function(e){var t=[],n=[],r=s(e.replace(W,"$1"));return r[x]?ot(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:ot(function(e){return function(t){return st(e,t).length>0}}),contains:ot(function(e){return function(t){return(t.textContent||t.innerText||o(t)).indexOf(e)>-1}}),lang:ot(function(e){return X.test(e||"")||st.error("unsupported lang: "+e),e=e.replace(et,tt).toLowerCase(),function(t){var n;do if(n=d?t.getAttribute("xml:lang")||t.getAttribute("lang"):t.lang)return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===f},focus:function(e){return e===p.activeElement&&(!p.hasFocus||p.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!i.pseudos.empty(e)},header:function(e){return Q.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:pt(function(){return[0]}),last:pt(function(e,t){return[t-1]}),eq:pt(function(e,t,n){return[0>n?n+t:n]}),even:pt(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return !
e}),odd:pt(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:pt(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:pt(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}};for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})i.pseudos[n]=lt(n);for(n in{submit:!0,reset:!0})i.pseudos[n]=ct(n);function ft(e,t){var n,r,o,a,s,u,l,c=E[e+" "];if(c)return t?0:c.slice(0);s=e,u=[],l=i.preFilter;while(s){(!n||(r=$.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),u.push(o=[])),n=!1,(r=I.exec(s))&&(n=r.shift(),o.push({value:n,type:r[0].replace(W," ")}),s=s.slice(n.length));for(a in i.filter)!(r=U[a].exec(s))||l[a]&&!(r=l[a](r))||(n=r.shift(),o.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?st.error(e):E(e,u).slice(0)}function dt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function ht(e,t,n){var i=t.dir,o=n&&"parentNode"===i,a=C++;return t.first?function(t,n,r){while(t=t[i])if(1===t.nodeType||o)return e(t,n,r)}:function(t,n,s){var u,l,c,p=N+" "+a;if(s){while(t=t[i])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[i])if(1===t.nodeType||o)if(c=t[x]||(t[x]={}),(l=c[i])&&l[0]===p){if((u=l[1])===!0||u===r)return u===!0}else if(l=c[i]=[p],l[1]=e(t,n,s)||r,l[1]===!0)return!0}}function gt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function mt(e,t,n,r,i){var o,a=[],s=0,u=e.length,l=null!=t;for(;u>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),l&&t.push(s));return a}function yt(e,t,n,r,i,o){return r&&!r[x]&&(r=yt(r)),i&&!i[x]&&(i=yt(i,o)),ot(function(o,a,s,u){var l,c,p,f=[],d=[],h=a.length,g=o||xt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:mt(g,f,e,s,u),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,u),r){l=mt(y,d),r(l,[],s,u),c=l.length;while(c--)(p=l[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){l=[],c=y.length;while(c--)(p=y[c])&&l.push(m[c]=p);i(null,y=[],l,u)}c=y.length;while(c--)(p=y[c])&&(l=i?M.call(o,p):f[c])>-1&&(o[l]=!(a[l]=p))}}else y=mt(y===a?y.splice(h,y.length):y),i?i!
(null,a,y,u):H.apply(a,y)})}function vt(e){var t,n,r,o=e.length,a=i.relative[e[0].type],s=a||i.relative[" "],u=a?1:0,c=ht(function(e){return e===t},s,!0),p=ht(function(e){return M.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;o>u;u++)if(n=i.relative[e[u].type])f=[ht(gt(f),n)];else{if(n=i.filter[e[u].type].apply(null,e[u].matches),n[x]){for(r=++u;o>r;r++)if(i.relative[e[r].type])break;return yt(u>1&>(f),u>1&&dt(e.slice(0,u-1)).replace(W,"$1"),n,r>u&&vt(e.slice(u,r)),o>r&&vt(e=e.slice(r)),o>r&&dt(e))}f.push(n)}return gt(f)}function bt(e,t){var n=0,o=t.length>0,a=e.length>0,s=function(s,u,c,f,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,T=l,C=s||a&&i.find.TAG("*",d&&u.parentNode||u),k=N+=null==T?1:Math.random()||.1;for(w&&(l=u!==p&&u,r=n);null!=(h=C[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,u,c)){f.push(h);break}w&&(N=k,r=++n)}o&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,o&&b!==v){g=0;while(m=t[g++])m(x,y,u,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=L.call(f));y=mt(y)}H.apply(f,y),w&&!s&&y.length>0&&v+t.length>1&&st.uniqueSort(f)}return w&&(N=k,l=T),x};return o?ot(s):s}s=st.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=ft(e)),n=t.length;while(n--)o=vt(t[n]),o[x]?r.push(o):i.push(o);o=S(e,bt(i,r))}return o};function xt(e,t,n){var r=0,i=t.length;for(;i>r;r++)st(e,t[r],n);return n}function wt(e,t,n,r){var o,a,u,l,c,p=ft(e);if(!r&&1===p.length){if(a=p[0]=p[0].slice(0),a.length>2&&"ID"===(u=a[0]).type&&9===t.nodeType&&!d&&i.relative[a[1].type]){if(t=i.find.ID(u.matches[0].replace(et,tt),t)[0],!t)return n;e=e.slice(a.shift().value.length)}o=U.needsContext.test(e)?0:a.length;while(o--){if(u=a[o],i.relative[l=u.type])break;if((c=i.find[l])&&(r=c(u.matches[0].replace(et,tt),V.test(a[0].type)&&t.parentNode||t))){if(a.splice(o,1),e=r.length&&dt(a),!e)return H.apply(n,q.call(r,0)),n;break}}}return s(e,p)(r,t,d,n,V.test(e)),n}i.pseudos.nth=i.pseudos.eq;function Tt(){}i.filters=Tt.prototype=i.pseudos,i.setFilters=new Tt,c(),st.attr=b.attr,b.find=st,b.expr!
=st.selectors,b.expr[":"]=b.expr.pseudos,b.unique=st.uniqueSort,b.text=st.getText,b.isXMLDoc=st.isXML,b.contains=st.contains}(e);var at=/Until$/,st=/^(?:parents|prev(?:Until|All))/,ut=/^.[^:#\[\.,]*$/,lt=b.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};b.fn.extend({find:function(e){var t,n,r,i=this.length;if("string"!=typeof e)return r=this,this.pushStack(b(e).filter(function(){for(t=0;i>t;t++)if(b.contains(r[t],this))return!0}));for(n=[],t=0;i>t;t++)b.find(e,this[t],n);return n=this.pushStack(i>1?b.unique(n):n),n.selector=(this.selector?this.selector+" ":"")+e,n},has:function(e){var t,n=b(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(b.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e,!1))},filter:function(e){return this.pushStack(ft(this,e,!0))},is:function(e){return!!e&&("string"==typeof e?lt.test(e)?b(e,this.context).index(this[0])>=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,o=[],a=lt.test(e)||"string"!=typeof e?b(e,t||this.context):0;for(;i>r;r++){n=this[r];while(n&&n.ownerDocument&&n!==t&&11!==n.nodeType){if(a?a.index(n)>-1:b.find.matchesSelector(n,e)){o.push(n);break}n=n.parentNode}}return this.pushStack(o.length>1?b.unique(o):o)},index:function(e){return e?"string"==typeof e?b.inArray(this[0],b(e)):b.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?b(e,t):b.makeArray(e&&e.nodeType?[e]:e),r=b.merge(this.get(),n);return this.pushStack(b.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),b.fn.andSelf=b.fn.addBack;function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}b.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(e,t,n){return b.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSi!
bling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(e,t,n){return b.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return b.dir(e,"previousSibling",n)},siblings:function(e){return b.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.merge([],e.childNodes)}},function(e,t){b.fn[e]=function(n,r){var i=b.map(this,t,n);return at.test(e)||(r=n),r&&"string"==typeof r&&(i=b.filter(r,i)),i=this.length>1&&!ct[e]?b.unique(i):i,this.length>1&&st.test(e)&&(i=i.reverse()),this.pushStack(i)}}),b.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),1===t.length?b.find.matchesSelector(t[0],e)?[t[0]]:[]:b.find.matches(e,t)},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!b(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(t=t||0,b.isFunction(t))return b.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return b.grep(e,function(e){return e===t===n});if("string"==typeof t){var r=b.grep(e,function(e){return 1===e.nodeType});if(ut.test(t))return b.filter(t,r,!n);t=b.filter(t,r)}return b.grep(e,function(e){return b.inArray(e,t)>=0===n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/<tbody/i,wt=/<|&#?\w+;/,Tt=/<(?:script|style|link)/i,Nt=/^(?:checkbox|radio)$/i,Ct=/checked\s*(?:[^=]|=\s*.checked.)/i,kt=/^$|\/(?:!
java|ecma)script/i,Et=/^true\/(.*)/,St=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,At={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:b.support.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},jt=dt(o),Dt=jt.appendChild(o.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,b.fn.extend({text:function(e){return b.access(this,function(e){return e===t?b.text(this):this.empty().append((this[0]&&this[0].ownerDocument||o).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(b.isFunction(e))return this.each(function(t){b(this).wrapAll(e.call(this,t))});if(this[0]){var t=b(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return b.isFunction(e)?this.each(function(t){b(this).wrapInner(e.call(this,t))}):this.each(function(){var t=b(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=b.isFunction(e);return this.each(function(n){b(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){b.nodeName(this,"body")||b(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.insertBefore(e,this.firstChild)})},before:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(!
arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=0;for(;null!=(n=this[r]);r++)(!e||b.filter(e,[n]).length>0)&&(t||1!==n.nodeType||b.cleanData(Ot(n)),n.parentNode&&(t&&b.contains(n.ownerDocument,n)&&Mt(Ot(n,"script")),n.parentNode.removeChild(n)));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&b.cleanData(Ot(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&b.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return b.clone(this,e,t)})},html:function(e){return b.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!b.support.htmlSerialize&&mt.test(e)||!b.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1></$2>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(b.cleanData(Ot(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(e){var t=b.isFunction(e);return t||"string"==typeof e||(e=b(e).not(this).detach()),this.domManip([e],!0,function(e){var t=this.nextSibling,n=this.parentNode;n&&(b(this).remove(),n.insertBefore(e,t))})},detach:function(e){return this.remove(e,!0)},domManip:function(e,n,r){e=f.apply([],e);var i,o,a,s,u,l,c=0,p=this.length,d=this,h=p-1,g=e[0],m=b.isFunction(g);if(m||!(1>=p||"string"!=typeof g||b.support.checkClone)&&Ct.test(g))return this.each(function(i){var o=d.eq(i);m&&(e[0]=g.call(this,i,n?o.html():t)),o.domManip(e,n,r)});if(p&&(l=b.buildFragment(e,this[0].ownerDocument,!1,this),i=l.firstChild,1===l.childNodes.length&&(l=i),i)){for(n=n&&b.nodeName(i,"tr"),s=b.map(Ot(l,"script"),Ht),a=s.length;p>c;c++)o=l,c!==h&&(o=b.clone(o,!0,!0),a&&b.merge(s,Ot(o,"script"))),r.call(n&&b.nodeName(this[c],"table")?Lt(this[c],"tbody"):this[c],o,c);if(a)for(u=s[s.length-1].ownerDocument,b.map(s,!
qt),c=0;a>c;c++)o=s[c],kt.test(o.type||"")&&!b._data(o,"globalEval")&&b.contains(u,o)&&(o.src?b.ajax({url:o.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):b.globalEval((o.text||o.textContent||o.innerHTML||"").replace(St,"")));l=i=null}return this}});function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function Ht(e){var t=e.getAttributeNode("type");return e.type=(t&&t.specified)+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function Mt(e,t){var n,r=0;for(;null!=(n=e[r]);r++)b._data(n,"globalEval",!t||b._data(t[r],"globalEval"))}function _t(e,t){if(1===t.nodeType&&b.hasData(e)){var n,r,i,o=b._data(e),a=b._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)b.event.add(t,n,s[n][r])}a.data&&(a.data=b.extend({},a.data))}}function Ft(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!b.support.noCloneEvent&&t[b.expando]){i=b._data(t);for(r in i.events)b.removeEvent(t,r,i.handle);t.removeAttribute(b.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),b.support.html5Clone&&e.innerHTML&&!b.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Nt.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}b.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){b.fn[e]=function(e){var n,r=0,i=[],o=b(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),b(o[r])[t](n),d.apply(i,n.get());return this.pushStack(i)}});function Ot(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||b.nodeName(o,n)?s.push(o):b.merg!
e(s,Ot(o,n));return n===t||n&&b.nodeName(e,n)?b.merge([e],s):s}function Bt(e){Nt.test(e.type)&&(e.defaultChecked=e.checked)}b.extend({clone:function(e,t,n){var r,i,o,a,s,u=b.contains(e.ownerDocument,e);if(b.support.html5Clone||b.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(b.support.noCloneEvent&&b.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||b.isXMLDoc(e)))for(r=Ot(o),s=Ot(e),a=0;null!=(i=s[a]);++a)r[a]&&Ft(i,r[a]);if(t)if(n)for(s=s||Ot(e),r=r||Ot(o),a=0;null!=(i=s[a]);a++)_t(i,r[a]);else _t(e,o);return r=Ot(o,"script"),r.length>0&&Mt(r,!u&&Ot(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,u,l,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===b.type(o))b.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),u=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[u]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1></$2>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!b.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!b.support.tbody){o="table"!==u||xt.test(o)?"<table>"!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)b.nodeName(l=o.childNodes[i],"tbody")&&!l.childNodes.length&&o.removeChild(l)
+}b.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),b.support.appendChecked||b.grep(Ot(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===b.inArray(o,r))&&(a=b.contains(o.ownerDocument,o),s=Ot(f.appendChild(o),"script"),a&&Mt(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,u=b.expando,l=b.cache,p=b.support.deleteExpando,f=b.event.special;for(;null!=(n=e[s]);s++)if((t||b.acceptData(n))&&(o=n[u],a=o&&l[o])){if(a.events)for(r in a.events)f[r]?b.event.remove(n,r):b.removeEvent(n,r,a.handle);l[o]&&(delete l[o],p?delete n[u]:typeof n.removeAttribute!==i?n.removeAttribute(u):n[u]=null,c.push(o))}}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+x+")(.*)$","i"),Yt=RegExp("^("+x+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+x+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===b.css(e,"display")||!b.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=b._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=b._data(r,"olddisplay",un(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&b._data(r,"olddisplay",i?n:b.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}b.fn.extend({css:function(e,n){return b.access(this,function(e,n,r){var i,o,a={},s=0;if(b.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=b.css(e,n[s],!1,o);re!
turn a}return r!==t?b.style(e,n,r):b.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){var t="boolean"==typeof e;return this.each(function(){(t?e:nn(this))?b(this).show():b(this).hide()})}}),b.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":b.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,u=b.camelCase(n),l=e.style;if(n=b.cssProps[u]||(b.cssProps[u]=tn(l,u)),s=b.cssHooks[n]||b.cssHooks[u],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:l[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(b.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||b.cssNumber[u]||(r+="px"),b.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(l[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{l[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,u=b.camelCase(n);return n=b.cssProps[u]||(b.cssProps[u]=tn(e.style,u)),s=b.cssHooks[n]||b.cssHooks[u],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||b.isNumeric(o)?o||0:a):a},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s.getPropertyValue(n)||s[n]:t,l=e.style;return s&&(""!==u||b.contains(e.ownerDocument,e)||(u=b.style(e,n)),Yt.test(u)&&Ut.test(n)&&(i=l.width,o=l.minWidth,a=l.maxWidth,l.minWidth=l.maxWidth=l.width=u,u=s.width,l.width=i,l.minWidth=o,l.maxWidth=a)),u}):o.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s[n]:t,l=e.style;return null==u&&l&&l[n]&&(u=l[n]),!
Yt.test(u)&&!zt.test(n)&&(i=l.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),l.left="fontSize"===n?"1em":u,u=l.pixelLeft+"px",l.left=i,a&&(o.left=a)),""===u?"auto":u});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=b.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=b.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=b.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=b.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=b.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=b.support.boxSizing&&"border-box"===b.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(b.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function un(e){var t=o,n=Gt[e];return n||(n=ln(e,t),"none"!==n&&n||(Pt=(Pt||b("<iframe frameborder='0' width='0' height='0'/>").css("cssText","display:block !important")).appendTo(t.documentElement),t=(Pt[0].contentWindow||Pt[0].contentDocument).document,t.write("<!doctype html><html><body>"),t.close(),n=ln(e,t),Pt.detach()),Gt[e]=n),n}function ln(e,t){var n=b(t.createElement(e)).appendTo(t.body),r=b.css(n[0],"display");return n.remove(),r}b.each(["height","width"],function(e,n){b.cssHooks[n]={get:function(e,r,i){return r?0===e.offsetWidth&&Xt.test(b.css(e,"display"))?b.swap(e,Qt,function(){return sn(e,n,i)}):sn(e,n,i):t},set:function(e,t,r){var i=r&&Rt(e);return on(e,t,r?an(e,n,r,b.support.boxSizing&&"border-box"===b.css(e,"boxSizing",!1,i),i):0)}}}),b.support.opacity||(b.cssHooks.opacity={get:function(e,t){return It.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=b.isNumeric(t)?"alpha(opacity="+100*t+")":"",o=r&&r.filter||n.filter||"";n.zoom=1,(t>=1||""===t)!
&&""===b..trim(o.replace($t,""))&&n.removeAttribute&&(n.removeAttribute("filter"),""===t||r&&!r.filter)||(n.filter=$t.test(o)?o.replace($t,i):o+" "+i)}}),b(function(){b.support.reliableMarginRight||(b.cssHooks.marginRight={get:function(e,n){return n?b.swap(e,{display:"inline-block"},Wt,[e,"marginRight"]):t}}),!b.support.pixelPosition&&b.fn.position&&b.each(["top","left"],function(e,n){b.cssHooks[n]={get:function(e,r){return r?(r=Wt(e,n),Yt.test(r)?b(e).position()[n]+"px":r):t}}})}),b.expr&&b.expr.filters&&(b.expr.filters.hidden=function(e){return 0>=e.offsetWidth&&0>=e.offsetHeight||!b.support.reliableHiddenOffsets&&"none"===(e.style&&e.style.display||b.css(e,"display"))},b.expr.filters.visible=function(e){return!b.expr.filters.hidden(e)}),b.each({margin:"",padding:"",border:"Width"},function(e,t){b.cssHooks[e+t]={expand:function(n){var r=0,i={},o="string"==typeof n?n.split(" "):[n];for(;4>r;r++)i[e+Zt[r]+t]=o[r]||o[r-2]||o[0];return i}},Ut.test(e)||(b.cssHooks[e+t].set=on)});var cn=/%20/g,pn=/\[\]$/,fn=/\r?\n/g,dn=/^(?:submit|button|image|reset|file)$/i,hn=/^(?:input|select|textarea|keygen)/i;b.fn.extend({serialize:function(){return b.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=b.prop(this,"elements");return e?b.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!b(this).is(":disabled")&&hn.test(this.nodeName)&&!dn.test(e)&&(this.checked||!Nt.test(e))}).map(function(e,t){var n=b(this).val();return null==n?null:b.isArray(n)?b.map(n,function(e){return{name:t.name,value:e.replace(fn,"\r\n")}}):{name:t.name,value:n.replace(fn,"\r\n")}}).get()}}),b.param=function(e,n){var r,i=[],o=function(e,t){t=b.isFunction(t)?t():null==t?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(n===t&&(n=b.ajaxSettings&&b.ajaxSettings.traditional),b.isArray(e)||e.jquery&&!b.isPlainObject(e))b.each(e,function(){o(this.name,this.value)});else for(r in e)gn(r,e[r],n,o);return i.join("&").replace(cn,"+")};function gn(e,t,n,r){var i;if(b.isArray(t))b.each(t,fu!
nction(t,i){n||pn.test(e)?r(e,i):gn(e+"["+("object"==typeof i?t:"")+"]",i,n,r)});else if(n||"object"!==b.type(t))r(e,t);else for(i in t)gn(e+"["+i+"]",t[i],n,r)}b.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){b.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),b.fn.hover=function(e,t){return this.mouseenter(e).mouseleave(t||e)};var mn,yn,vn=b.now(),bn=/\?/,xn=/#.*$/,wn=/([?&])_=[^&]*/,Tn=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Nn=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Cn=/^(?:GET|HEAD)$/,kn=/^\/\//,En=/^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,Sn=b.fn.load,An={},jn={},Dn="*/".concat("*");try{yn=a.href}catch(Ln){yn=o.createElement("a"),yn.href="",yn=yn.href}mn=En.exec(yn.toLowerCase())||[];function Hn(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(w)||[];if(b.isFunction(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function qn(e,n,r,i){var o={},a=e===jn;function s(u){var l;return o[u]=!0,b.each(e[u]||[],function(e,u){var c=u(n,r,i);return"string"!=typeof c||a||o[c]?a?!(l=c):t:(n.dataTypes.unshift(c),s(c),!1)}),l}return s(n.dataTypes[0])||!o["*"]&&s("*")}function Mn(e,n){var r,i,o=b.ajaxSettings.flatOptions||{};for(i in n)n[i]!==t&&((o[i]?e:r||(r={}))[i]=n[i]);return r&&b.extend(!0,e,r),e}b.fn.load=function(e,n,r){if("string"!=typeof e&&Sn)return Sn.apply(this,arguments);var i,o,a,s=this,u=e.indexOf(" ");return u>=0&&(i=e.slice(u,e.length),e=e.slice(0,u)),b.isFunction(n)?(r=n,n=t):n&&"object"==typeof n&&(a="POST"),s.length>0&&b.ajax({url:e,type:a,dataType:"html",data:n}).done(function(e){o=arguments,s.html(i?b("<div>").append(b.parseHTML(e)).find(i):e)}).complete(r&&function(e,t){s.each(r,o||[e.responseText,t,e])}),this},b.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSu!
ccess","ajaxSend"],function(e,t){b.fn[t]=function(e){return this.on(t,e)}}),b.each(["get","post"],function(e,n){b[n]=function(e,r,i,o){return b.isFunction(r)&&(o=o||i,i=r,r=t),b.ajax({url:e,type:n,dataType:o,data:r,success:i})}}),b.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:yn,type:"GET",isLocal:Nn.test(mn[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Dn,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":b.parseJSON,"text xml":b.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Mn(Mn(e,b.ajaxSettings),t):Mn(b.ajaxSettings,e)},ajaxPrefilter:Hn(An),ajaxTransport:Hn(jn),ajax:function(e,n){"object"==typeof e&&(n=e,e=t),n=n||{};var r,i,o,a,s,u,l,c,p=b.ajaxSetup({},n),f=p.context||p,d=p.context&&(f.nodeType||f.jquery)?b(f):b.event,h=b.Deferred(),g=b.Callbacks("once memory"),m=p.statusCode||{},y={},v={},x=0,T="canceled",N={readyState:0,getResponseHeader:function(e){var t;if(2===x){if(!c){c={};while(t=Tn.exec(a))c[t[1].toLowerCase()]=t[2]}t=c[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===x?a:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return x||(e=v[n]=v[n]||e,y[e]=t),this},overrideMimeType:function(e){return x||(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>x)for(t in e)m[t]=[m[t],e[t]];else N.always(e[N.status]);return this},abort:function(e){var t=e||T;return l&&l.abort(t),k(0,t),this}};if(h.promise(N).complete=g.add,N.success=N.done,N.error=N.fail,p.url=((e||p.url||yn)+"").replace(xn,"").replace(kn,mn[1]+"//"),p.type=n.method||n.type||p.method||p.type,p.dataTypes=b.trim(p.dataType||"*").toLowerCase().match(w)||[""],null==p.crossDomain&&(r=En.exec(p.url.toLowerCase()),p.crossDomain=!(!r||r[1]===mn[1]&&r[2]===mn[2]&&(r[3]||("http:"===!
r[1]?80:443))==(mn[3]||("http:"===mn[1]?80:443)))),p.data&&p.processData&&"string"!=typeof p.data&&(p.data=b.param(p.data,p.traditional)),qn(An,p,n,N),2===x)return N;u=p.global,u&&0===b.active++&&b.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Cn.test(p.type),o=p.url,p.hasContent||(p.data&&(o=p.url+=(bn.test(o)?"&":"?")+p.data,delete p.data),p.cache===!1&&(p.url=wn.test(o)?o.replace(wn,"$1_="+vn++):o+(bn.test(o)?"&":"?")+"_="+vn++)),p.ifModified&&(b.lastModified[o]&&N.setRequestHeader("If-Modified-Since",b.lastModified[o]),b.etag[o]&&N.setRequestHeader("If-None-Match",b.etag[o])),(p.data&&p.hasContent&&p.contentType!==!1||n.contentType)&&N.setRequestHeader("Content-Type",p.contentType),N.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Dn+"; q=0.01":""):p.accepts["*"]);for(i in p.headers)N.setRequestHeader(i,p.headers[i]);if(p.beforeSend&&(p.beforeSend.call(f,N,p)===!1||2===x))return N.abort();T="abort";for(i in{success:1,error:1,complete:1})N[i](p[i]);if(l=qn(jn,p,n,N)){N.readyState=1,u&&d.trigger("ajaxSend",[N,p]),p.async&&p.timeout>0&&(s=setTimeout(function(){N.abort("timeout")},p.timeout));try{x=1,l.send(y,k)}catch(C){if(!(2>x))throw C;k(-1,C)}}else k(-1,"No Transport");function k(e,n,r,i){var c,y,v,w,T,C=n;2!==x&&(x=2,s&&clearTimeout(s),l=t,a=i||"",N.readyState=e>0?4:0,r&&(w=_n(p,N,r)),e>=200&&300>e||304===e?(p.ifModified&&(T=N.getResponseHeader("Last-Modified"),T&&(b.lastModified[o]=T),T=N.getResponseHeader("etag"),T&&(b.etag[o]=T)),204===e?(c=!0,C="nocontent"):304===e?(c=!0,C="notmodified"):(c=Fn(p,w),C=c.state,y=c.data,v=c.error,c=!v)):(v=C,(e||!C)&&(C="error",0>e&&(e=0))),N.status=e,N.statusText=(n||C)+"",c?h.resolveWith(f,[y,C,N]):h.rejectWith(f,[N,C,v]),N.statusCode(m),m=t,u&&d.trigger(c?"ajaxSuccess":"ajaxError",[N,p,c?y:v]),g.fireWith(f,[N,C]),u&&(d.trigger("ajaxComplete",[N,p]),--b.active||b.event.trigger("ajaxStop")))}return N},getScript:function(e,n){return b.get(e,t,n,"script")},getJSON:function(e,t,n)!
{return b.get(e,t,n,"json")}});function _n(e,n,r){var i,o,a,s,u=e.contents,l=e.dataTypes,c=e.responseFields;for(s in c)s in r&&(n[c[s]]=r[s]);while("*"===l[0])l.shift(),o===t&&(o=e.mimeType||n.getResponseHeader("Content-Type"));if(o)for(s in u)if(u[s]&&u[s].test(o)){l.unshift(s);break}if(l[0]in r)a=l[0];else{for(s in r){if(!l[0]||e.converters[s+" "+l[0]]){a=s;break}i||(i=s)}a=a||i}return a?(a!==l[0]&&l.unshift(a),r[a]):t}function Fn(e,t){var n,r,i,o,a={},s=0,u=e.dataTypes.slice(),l=u[0];if(e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u[1])for(i in e.converters)a[i.toLowerCase()]=e.converters[i];for(;r=u[++s];)if("*"!==r){if("*"!==l&&l!==r){if(i=a[l+" "+r]||a["* "+r],!i)for(n in a)if(o=n.split(" "),o[1]===r&&(i=a[l+" "+o[0]]||a["* "+o[0]])){i===!0?i=a[n]:a[n]!==!0&&(r=o[0],u.splice(s--,0,r));break}if(i!==!0)if(i&&e["throws"])t=i(t);else try{t=i(t)}catch(c){return{state:"parsererror",error:i?c:"No conversion from "+l+" to "+r}}}l=r}return{state:"success",data:t}}b.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return b.globalEval(e),e}}}),b.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),b.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=o.head||b("head")[0]||o.documentElement;return{send:function(t,i){n=o.createElement("script"),n.async=!0,e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,t){(t||!n.readyState||/loaded|complete/.test(n.readyState))&&(n.onload=n.onreadystatechange=null,n.parentNode&&n.parentNode.removeChild(n),n=null,t||i(200,"success"))},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(t,!0)}}}});var On=[],Bn=/(=)\?(?=&|$)|\?\?/;b.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=On.pop()||b.expando+"_"+vn++;return this[e]=!0,e}}),b.ajaxPrefilter("json jsonp",function(n,r,i){var o,a,s,u=n.jsonp!==!1&&(Bn.test(n.ur!
l)?"url":"string"==typeof n.data&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Bn.test(n.data)&&"data");return u||"jsonp"===n.dataTypes[0]?(o=n.jsonpCallback=b.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,u?n[u]=n[u].replace(Bn,"$1"+o):n.jsonp!==!1&&(n.url+=(bn.test(n.url)?"&":"?")+n.jsonp+"="+o),n.converters["script json"]=function(){return s||b.error(o+" was not called"),s[0]},n.dataTypes[0]="json",a=e[o],e[o]=function(){s=arguments},i.always(function(){e[o]=a,n[o]&&(n.jsonpCallback=r.jsonpCallback,On.push(o)),s&&b.isFunction(a)&&a(s[0]),s=a=t}),"script"):t});var Pn,Rn,Wn=0,$n=e.ActiveXObject&&function(){var e;for(e in Pn)Pn[e](t,!0)};function In(){try{return new e.XMLHttpRequest}catch(t){}}function zn(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}b.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&In()||zn()}:In,Rn=b.ajaxSettings.xhr(),b.support.cors=!!Rn&&"withCredentials"in Rn,Rn=b.support.ajax=!!Rn,Rn&&b.ajaxTransport(function(n){if(!n.crossDomain||b.support.cors){var r;return{send:function(i,o){var a,s,u=n.xhr();if(n.username?u.open(n.type,n.url,n.async,n.username,n.password):u.open(n.type,n.url,n.async),n.xhrFields)for(s in n.xhrFields)u[s]=n.xhrFields[s];n.mimeType&&u.overrideMimeType&&u.overrideMimeType(n.mimeType),n.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");try{for(s in i)u.setRequestHeader(s,i[s])}catch(l){}u.send(n.hasContent&&n.data||null),r=function(e,i){var s,l,c,p;try{if(r&&(i||4===u.readyState))if(r=t,a&&(u.onreadystatechange=b.noop,$n&&delete Pn[a]),i)4!==u.readyState&&u.abort();else{p={},s=u.status,l=u.getAllResponseHeaders(),"string"==typeof u.responseText&&(p.text=u.responseText);try{c=u.statusText}catch(f){c=""}s||!n.isLocal||n.crossDomain?1223===s&&(s=204):s=p.text?200:404}}catch(d){i||o(-1,d)}p&&o(s,c,p,l)},n.async?4===u.readyState?setTimeout(r):(a=++Wn,$n&&(Pn||(Pn={},b(e).unload($n)),Pn[a]=r),u.onreadystatechange=r):r()},abort:function(){r&&r(t,!0)}}}});var Xn,Un,Vn=/^(?:toggle|s!
how|hide)$/,Yn=RegExp("^(?:([+-])=|)("+x+")([a-z%]*)$","i"),Jn=/queueHooks$/,Gn=[nr],Qn={"*":[function(e,t){var n,r,i=this.createTween(e,t),o=Yn.exec(t),a=i.cur(),s=+a||0,u=1,l=20;if(o){if(n=+o[2],r=o[3]||(b.cssNumber[e]?"":"px"),"px"!==r&&s){s=b.css(i.elem,e,!0)||n||1;do u=u||".5",s/=u,b.style(i.elem,e,s+r);while(u!==(u=i.cur()/a)&&1!==u&&--l)}i.unit=r,i.start=s,i.end=o[1]?s+(o[1]+1)*n:n}return i}]};function Kn(){return setTimeout(function(){Xn=t}),Xn=b.now()}function Zn(e,t){b.each(t,function(t,n){var r=(Qn[t]||[]).concat(Qn["*"]),i=0,o=r.length;for(;o>i;i++)if(r[i].call(e,t,n))return})}function er(e,t,n){var r,i,o=0,a=Gn.length,s=b.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;var t=Xn||Kn(),n=Math.max(0,l.startTime+l.duration-t),r=n/l.duration||0,o=1-r,a=0,u=l.tweens.length;for(;u>a;a++)l.tweens[a].run(o);return s.notifyWith(e,[l,o,n]),1>o&&u?n:(s.resolveWith(e,[l]),!1)},l=s.promise({elem:e,props:b.extend({},t),opts:b.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:Xn||Kn(),duration:n.duration,tweens:[],createTween:function(t,n){var r=b.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)l.tweens[n].run(1);return t?s.resolveWith(e,[l,t]):s.rejectWith(e,[l,t]),this}}),c=l.props;for(tr(c,l.opts.specialEasing);a>o;o++)if(r=Gn[o].call(l,e,c,l.opts))return r;return Zn(l,c),b.isFunction(l.opts.start)&&l.opts.start.call(e,l),b.fx.timer(b.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always)}function tr(e,t){var n,r,i,o,a;for(i in e)if(r=b.camelCase(i),o=t[r],n=e[i],b.isArray(n)&&(o=n[1],n=e[i]=n[0]),i!==r&&(e[r]=n,delete e[i]),a=b.cssHooks[r],a&&"expand"in a){n=a.expand(n),delete e[r];for(i in n)i in e||(e[i]=n[i],t[i]=o)}else t[r]=o}b.Animation=b.extend(er,{tweener:function(e,t){b.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;i>!
r;r++)n=e[r],Qn[n]=Qn[n]||[],Qn[n].unshift(t)},prefilter:function(e,t){t?Gn.unshift(e):Gn.push(e)}});function nr(e,t,n){var r,i,o,a,s,u,l,c,p,f=this,d=e.style,h={},g=[],m=e.nodeType&&nn(e);n.queue||(c=b._queueHooks(e,"fx"),null==c.unqueued&&(c.unqueued=0,p=c.empty.fire,c.empty.fire=function(){c.unqueued||p()}),c.unqueued++,f.always(function(){f.always(function(){c.unqueued--,b.queue(e,"fx").length||c.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[d.overflow,d.overflowX,d.overflowY],"inline"===b.css(e,"display")&&"none"===b.css(e,"float")&&(b.support.inlineBlockNeedsLayout&&"inline"!==un(e.nodeName)?d.zoom=1:d.display="inline-block")),n.overflow&&(d.overflow="hidden",b.support.shrinkWrapBlocks||f.always(function(){d.overflow=n.overflow[0],d.overflowX=n.overflow[1],d.overflowY=n.overflow[2]}));for(i in t)if(a=t[i],Vn.exec(a)){if(delete t[i],u=u||"toggle"===a,a===(m?"hide":"show"))continue;g.push(i)}if(o=g.length){s=b._data(e,"fxshow")||b._data(e,"fxshow",{}),"hidden"in s&&(m=s.hidden),u&&(s.hidden=!m),m?b(e).show():f.done(function(){b(e).hide()}),f.done(function(){var t;b._removeData(e,"fxshow");for(t in h)b.style(e,t,h[t])});for(i=0;o>i;i++)r=g[i],l=f.createTween(r,m?s[r]:0),h[r]=s[r]||b.style(e,r),r in s||(s[r]=l.start,m&&(l.end=l.start,l.start="width"===r||"height"===r?1:0))}}function rr(e,t,n,r,i){return new rr.prototype.init(e,t,n,r,i)}b.Tween=rr,rr.prototype={constructor:rr,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(b.cssNumber[n]?"":"px")},cur:function(){var e=rr.propHooks[this.prop];return e&&e.get?e.get(this):rr.propHooks._default.get(this)},run:function(e){var t,n=rr.propHooks[this.prop];return this.pos=t=this.options.duration?b.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):rr.propHooks._default.set(this),this}},rr.pr!
ototype.init.prototype=rr.prototype,rr.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=b.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){b.fx.step[e.prop]?b.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[b.cssProps[e.prop]]||b.cssHooks[e.prop])?b.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},rr.propHooks.scrollTop=rr.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},b.each(["toggle","show","hide"],function(e,t){var n=b.fn[t];b.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(ir(t,!0),e,r,i)}}),b.fn.extend({fadeTo:function(e,t,n,r){return this.filter(nn).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=b.isEmptyObject(e),o=b.speed(t,n,r),a=function(){var t=er(this,b.extend({},e),o);a.finish=function(){t.stop(!0)},(i||b._data(this,"finish"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return"string"!=typeof e&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=null!=e&&e+"queueHooks",o=b.timers,a=b._data(this);if(n)a[n]&&a[n].stop&&i(a[n]);else for(n in a)a[n]&&a[n].stop&&Jn.test(n)&&i(a[n]);for(n=o.length;n--;)o[n].elem!==this||null!=e&&o[n].queue!==e||(o[n].anim.stop(r),t=!1,o.splice(n,1));(t||!r)&&b.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=b._data(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=b.timers,a=r?r.length:0;for(n.finish=!0,b.queue(this,e,[]),i&&i.cur&&i.cur.finish&&i.cur.finish.call(this),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;a>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}});function ir(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=Zt[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.w!
idth=e),r}b.each({slideDown:ir("show"),slideUp:ir("hide"),slideToggle:ir("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){b.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),b.speed=function(e,t,n){var r=e&&"object"==typeof e?b.extend({},e):{complete:n||!n&&t||b.isFunction(e)&&e,duration:e,easing:n&&t||t&&!b.isFunction(t)&&t};return r.duration=b.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in b.fx.speeds?b.fx.speeds[r.duration]:b.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){b.isFunction(r.old)&&r.old.call(this),r.queue&&b.dequeue(this,r.queue)},r},b.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},b.timers=[],b.fx=rr.prototype.init,b.fx.tick=function(){var e,n=b.timers,r=0;for(Xn=b.now();n.length>r;r++)e=n[r],e()||n[r]!==e||n.splice(r--,1);n.length||b.fx.stop(),Xn=t},b.fx.timer=function(e){e()&&b.timers.push(e)&&b.fx.start()},b.fx.interval=13,b.fx.start=function(){Un||(Un=setInterval(b.fx.tick,b.fx.interval))},b.fx.stop=function(){clearInterval(Un),Un=null},b.fx.speeds={slow:600,fast:200,_default:400},b.fx.step={},b.expr&&b.expr.filters&&(b.expr.filters.animated=function(e){return b.grep(b.timers,function(t){return e===t.elem}).length}),b.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){b.offset.setOffset(this,e,t)});var n,r,o={top:0,left:0},a=this[0],s=a&&a.ownerDocument;if(s)return n=s.documentElement,b.contains(n,a)?(typeof a.getBoundingClientRect!==i&&(o=a.getBoundingClientRect()),r=or(s),{top:o.top+(r.pageYOffset||n.scrollTop)-(n.clientTop||0),left:o.left+(r.pageXOffset||n.scrollLeft)-(n.clientLeft||0)}):o},b.offset={setOffset:function(e,t,n){var r=b.css(e,"position");"static"===r&&(e.style.position="relative");var i=b(e),o=i.offset(),a=b.css(e,"top"),s=b.css(e,"left"),u=("absolute"===r||"fixed"===r)&&b.inArray("auto",[a,s])>-1,l={},c={},p,f;u?(c=i.position(),p=c.top,f=c.left):(p=parseFloat(a)||0,f=parseFlo!
at(s)||0),b.isFunction(t)&&(t=t.call(e,n,o)),null!=t.top&&(l.top=t.top-o.top+p),null!=t.left&&(l.left=t.left-o.left+f),"using"in t?t.using.call(e,l):i.css(l)}},b.fn.extend({position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return"fixed"===b.css(r,"position")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),b.nodeName(e[0],"html")||(n=e.offset()),n.top+=b.css(e[0],"borderTopWidth",!0),n.left+=b.css(e[0],"borderLeftWidth",!0)),{top:t.top-n.top-b.css(r,"marginTop",!0),left:t.left-n.left-b.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||o.documentElement;while(e&&!b.nodeName(e,"html")&&"static"===b.css(e,"position"))e=e.offsetParent;return e||o.documentElement})}}),b.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);b.fn[e]=function(i){return b.access(this,function(e,i,o){var a=or(e);return o===t?a?n in a?a[n]:a.document.documentElement[i]:e[i]:(a?a.scrollTo(r?b(a).scrollLeft():o,r?o:b(a).scrollTop()):e[i]=o,t)},e,i,arguments.length,null)}});function or(e){return b.isWindow(e)?e:9===e.nodeType?e.defaultView||e.parentWindow:!1}b.each({Height:"height",Width:"width"},function(e,n){b.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){b.fn[i]=function(i,o){var a=arguments.length&&(r||"boolean"!=typeof i),s=r||(i===!0||o===!0?"margin":"border");return b.access(this,function(n,r,i){var o;return b.isWindow(n)?n.document.documentElement["client"+e]:9===n.nodeType?(o=n.documentElement,Math.max(n.body["scroll"+e],o["scroll"+e],n.body["offset"+e],o["offset"+e],o["client"+e])):i===t?b.css(n,r,s):b.style(n,r,i,s)},n,a?i:t,a,null)}})}),e.jQuery=e.$=b,"function"==typeof define&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return b})})(window);
\ No newline at end of file
Added: gnucash/trunk/src/report/jqplot/optionsTutorial.txt
===================================================================
--- gnucash/trunk/src/report/jqplot/optionsTutorial.txt (rev 0)
+++ gnucash/trunk/src/report/jqplot/optionsTutorial.txt 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,240 @@
+Title: Options Tutorial
+
+This document will help you understand how jqPlot's options
+relate to the API documentation and the jqPlot object
+itself. For a listing of options available to jqPlot,
+see <jqPlot Options> in the jqPlotOptions.txt file.
+
+The key to effectively using jqPlot is understanding jqPlot's
+options. The online documentation is API documentation. While
+it explains what attributes and methods various objects posses,
+it doesn't explain how to use or set those attributes through
+options. This tutorial will help explain that.
+
+Lets assume you are creating a plot
+like this:
+
+> chart = $.jqplot('chart', dataSeries, optionsObj);
+
+First, note that you shouldn't try to directly set attributes on the
+"chart" object (like chart.grid.shadow) after your call to $.jqplot().
+At best this won't do anything **(see below). You should pass options in via
+the "optionsObj".
+
+the optionsObj really represents the plot object (jqPlot object, not
+to be confused with the $.jqplot function which will create a jqPlot
+object). Attributes you specify on that object will be merged with
+attributes in the jqPlot object. The axes, legend, series, etc. are
+attributes on the jqPlot object. The jqPlot/optionsObj object looks
+something like (only some attributes shown):
+
+> jqPlot-|
+> |-seriesColors
+> |-textColor
+> |-fontFamily
+> |-fontSize
+> |-stackSeries
+> |-series(Array)-|
+> | |-Series1-|
+> | | |-lineWidth
+> | | |-linePattern
+> | | |-shadow
+> | | |-showLine
+> | | |-showMarker
+> | | |-color
+> | |-Series2...
+> | |-...
+> | |-SeriesN
+> |
+> |-grid(Object)-|
+> | |-drawGridLines
+> | |-background
+> | |-borderColor
+> | |-borderWidth
+> | |-shadow
+> |
+> |-title(Object)-|
+> | |-text
+> | |-show
+> | |-fontFamily
+> | |-fontSize
+> | |-textAlign
+> | |-textColor
+> |
+> |-axes(Object)-|
+> | |-xais-|
+> | | |-min
+> | | |-max
+> | | |-numberTicks
+> | | |-showTicks
+> | | |-showTickMarks
+> | | |-pad
+> |
+> | ... and so on
+
+The optionsObj should follow the same construction as if it were a
+jqPlot object (with some exceptions/shortcuts I'll mention in a
+moment). So generally, when you see something like
+"this.drawGridLines" in the grid properties in the docs, just replace
+"this" with "grid" in your options object. So it becomes
+optionsObj.grid.drawGridLines. Do likewise with the other objects in
+the plot, replacing "this", with the respective attribute on the plot
+like "legend" or "title". Series and Axes are handled a little
+different, because series is an array and axes has 4 distinct children
+"xaxis", "yaxis", "x2axis" and "y2axis".
+
+So, to remove the shadow from the grid and change the grid border size
+you would do:
+
+> optionObj = {grid:{shadow:false, borderWidth:9.0}};
+
+To do the same as above but also make all the text in the plot red you
+would do:
+
+> optionObj = {
+> textColor:"#ff0000",
+> grid:{shadow:false, borderWidth:9.0}
+> }
+
+Here is a more deeply nested example. Say you want to specify a min
+and max on your y axis and use a specific color for your second
+series. That would look like:
+
+> optionsObj = {
+> axes:{yaxis:{min:5, max:230}},
+> series:[{},{color:"#33ff66"}]
+> }
+
+Note that series options are an array in order of the series data you
+sent in to your plot. To get to the second series, you have to put an
+object (even if empty) in place of the first series.
+
+There is a handy shortcut to assign options to all axes or all series
+at one go. Use axesDefaults and seriesDefaults. So, if you wanted
+both x and y axes to start at 0 and you wanted all series to not show
+markers, you could do:
+
+> optionsObj = {axesDefaults:{min:0}, seriesDefaults:{showMarker:false}}
+
+Another shortcut is for the plot title. Normally, you would assign
+options to the title as an object. If you specify a title option as a
+string, it will assign that to the title.text property automatically.
+So these two are equivalent:
+
+> optionsObj = {title:{text:"My Plot"}}
+
+and
+
+> optionsObj = {title:"My Plot"}
+
+Where things need more explaination is with renderers, plugins and
+their options. Briefly, what's renderer, what's a plugin.
+
+A renderer is an object that is used to draw something and gets
+attached to an existing object in the plot in order to draw it. A
+plugin does more than just provide drawing functionality to an
+object. It will do more like calculate a trend line, change the
+cursor, provide event driven functionality, etc. I consider renderers
+plugins, but plugins don't have to be renderers.
+
+So, how do you use renderers, plugins, and specify their options?
+Some common renderes are for bar charts and category axes. If you
+want to render your series as a bar chart with each set of bars
+showing up in a category on the x axis, you do:
+
+> optionsObj = {
+> seriesDefaults:{renderer:$.jqplot.BarRenderer},
+> axes:{xaxis:{renderer:$.jqplot.CategoryAxisRenderer}}
+> }
+
+This replaces the default renderer used for all series in the plot
+with a bar renderer and the x axis default renderer (but not any other
+axis) with a category renderer.
+
+Now, how would I assign options to those renderers? The renderer's
+attributes may not be present in the pre-existing jqPlot object, they
+may be specific to the renderer. This is done through the
+"rendererOptions" option on the appropriate object. So, if I wanted my
+bars to be 25 pixels wide, I would do:
+
+
+> optionsObj = {
+> seriesDefaults:{
+> renderer:$.jqplot.BarRenderer},
+> rendererOptions:{
+> barWidth:25
+> },
+> axes:{xaxis:{renderer:$.jqplot.CategoryAxisRenderer}}
+> }
+
+Again, this is using the "seriesDefaults" option, which will apply
+options to all series in the plot. You could do the same on any
+particular series in the plot through the "series" options array.
+
+Plugins are free to add their own options. For example, the
+highlighter plugin has it's own set of options that are unique to it.
+As a result, it responds to options placed in the "highlighter"
+attribute of your options object. So, if I wanted to change the
+highlighter tooltip to fade in and out slowly and be positioned
+directly above the point I'm highlighting:
+
+> optionsObj = {
+> highlighter:{tooltipFadeSpeed:'slow', tooltipLocation:'n'}
+> }
+
+Other plugins, like dragable and trendlines, add their options in with
+the series. This is because both of those plugins can have different
+options for different series in the plot. So, if you wanted to specify the
+color of the dragable and constrain it to drag only on the x axis as well
+as specify the color of the trend line you could do:
+
+> series:[{
+> dragable: {
+> color: '#ff3366',
+> constrainTo: 'x'
+> },
+> trendline: {
+> color: '#cccccc'
+> }
+> }]
+
+This would apply those options to the first series only. If you had 2 series
+and wanted to turn off dragging and trend lines on the second series, you could do:
+
+> series:[{
+> dragable: {
+> color: '#ff3366',
+> constrainTo: 'x'
+> },
+> trendline: {
+> color: '#cccccc'
+> }
+> }, {
+> isDragable: false,
+> trendline:{
+> show: false
+> }
+> }]
+
+Note, series dragability is turned off with the "isDragable" option directly on
+the series itself, not with a suboption of "dragable". This may be improved
+in the future.
+
+I hope this is helpful.
+A few key points to remember:
+
+- When you see "this" in the api docs, you generally replace it with
+the name of the object (in lowercase) you are looking at in your
+options object.
+- seriesDefaults and axesDefaults are convenient shortcuts.
+- to assign options to a renderer, generally use the "rendererOptions"
+- plugins may add their own options attribute, like "highlighter" or
+"cursor".
+
+** Note: you can set attributes after the plot is created (like
+plot.grid.shadow = false), but you'll have to issue the appropriate
+calls to possibly reinitialize and redraw the plot. jqPlot can
+definitely handle this to change the plot after creation (this is how
+the dragable plugin updates the plot data and the trend line plugin
+recomputes itself when data changes). This hasn't been documented
+yet, however.
\ No newline at end of file
Modified: gnucash/trunk/src/report/jqplot/plugins/jqplot.BezierCurveRenderer.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.BezierCurveRenderer.js 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.BezierCurveRenderer.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -1,18 +1,31 @@
/**
- * Copyright (c) 2009 - 2010 Chris Leonello
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
- * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
- * The author would appreciate an email letting him know of any substantial
- * use of jqPlot. You can reach the author at: chris at jqplot dot com
- * or see http://www.jqplot.com/info.php . This is, of course,
- * not required.
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
- * Thanks for using jqPlot!
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
*
*/
(function($) {
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.BezierCurveRenderer.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.BezierCurveRenderer.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.BezierCurveRenderer.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(b){b.jqplot.BezierCurveRenderer=function(){b.jqplot.LineRenderer.call(this)};b.jqplot.BezierCurveRenderer.prototype=new b.jqplot.LineRenderer();b.jqplot.BezierCurveRenderer.prototype.constructor=b.jqplot.BezierCurveRenderer;b.jqplot.BezierCurveRenderer.prototype.setGridData=function(h){var e=this._xaxis.series_u2p;var g=this._yaxis.series_u2p;var f=this.data;this.gridData=[];this._prevGridData=[];var d=this.index;if(f.length==2){if(d==0){this.gridData=[[e.call(this._xaxis,f[0][0]),g.call(this._yaxis,f[0][1])],[e.call(this._xaxis,f[1][0]),g.call(this._yaxis,f[1][1]),e.call(this._xaxis,f[1][2]),g.call(this._yaxis,f[1][3]),e.call(this._xaxis,f[1][4]),g.call(this._yaxis,f[1][5])],[e.call(this._xaxis,f[1][4]),g.call(this._yaxis,this._yaxis.min)],[e.call(this._xaxis,f[0][0]),g.call(this._yaxis,this._yaxis.min)]]}else{var c=h.series[d-1].data;this.gridData=[[e.call(this._xaxis,f[0][0]),g.call(this._yaxis,f[0][1])],[e.call(this._xaxis,f[1][0]),g.call(this._yaxis,f[1][1]),e.call(this._xaxis,f[1][2]),g.call(this._yaxis,f[1][3]),e.call(this._xaxis,f[1][4]),g.call(this._yaxis,f[1][5])],[e.call(this._xaxis,c[1][4]),g.call(this._yaxis,c[1][5])],[e.call(this._xaxis,c[1][2]),g.call(this._yaxis,c[1][3]),e.call(this._xaxis,c[1][0]),g.call(this._yaxis,c[1][1]),e.call(this._xaxis,c[0][0]),g.call(this._yaxis,c[0][1])]]}}else{if(d==0){this.gridData=[[e.call(this._xaxis,f[0][0]),g.call(this._yaxis,f[0][1])],[e.call(this._xaxis,f[1][0]),g.call(this._yaxis,f[1][1]),e.call(this._xaxis,f[2][0]),g.call(this._yaxis,f[2][1]),e.call(this._xaxis,f[3][0]),g.call(this._yaxis,f[3][1])],[e.call(this._xaxis,f[3][1]),g.call(this._yaxis,this._yaxis.min)],[e.call(this._xaxis,f[0][0]),g.call(this._yaxis,this._yaxis.min)]]}else{var c=h.series[d-1].data;this.gridData=[[e.call(this._xaxis,f[0][0]),g.call(this._yaxis,f[0][1])],[e.call(this._xaxis,f[1][0]),g.call(this._yaxis,f[1][1]),e.call(this._xaxis,f[2][0]),g.call(this._yaxis,f[2][1]),e.call(this._xaxis,f[3][0]),g.call(this._yaxis,f[3][1])],[e.call(this._xaxis,c[3][0]),g.call(this.!
_yaxis,c[3][1])],[e.call(this._xaxis,c[2][0]),g.call(this._yaxis,c[2][1]),e.call(this._xaxis,c[1][0]),g.call(this._yaxis,c[1][1]),e.call(this._xaxis,c[0][0]),g.call(this._yaxis,c[0][1])]]}}};b.jqplot.BezierCurveRenderer.prototype.makeGridData=function(g,i){var f=this._xaxis.series_u2p;var h=this._yaxis.series_u2p;var e=[];var j=[];var d=this.index;if(g.length==2){if(d==0){e=[[f.call(this._xaxis,g[0][0]),h.call(this._yaxis,g[0][1])],[f.call(this._xaxis,g[1][0]),h.call(this._yaxis,g[1][1]),f.call(this._xaxis,g[1][2]),h.call(this._yaxis,g[1][3]),f.call(this._xaxis,g[1][4]),h.call(this._yaxis,g[1][5])],[f.call(this._xaxis,g[1][4]),h.call(this._yaxis,this._yaxis.min)],[f.call(this._xaxis,g[0][0]),h.call(this._yaxis,this._yaxis.min)]]}else{var c=i.series[d-1].data;e=[[f.call(this._xaxis,g[0][0]),h.call(this._yaxis,g[0][1])],[f.call(this._xaxis,g[1][0]),h.call(this._yaxis,g[1][1]),f.call(this._xaxis,g[1][2]),h.call(this._yaxis,g[1][3]),f.call(this._xaxis,g[1][4]),h.call(this._yaxis,g[1][5])],[f.call(this._xaxis,c[1][4]),h.call(this._yaxis,c[1][5])],[f.call(this._xaxis,c[1][2]),h.call(this._yaxis,c[1][3]),f.call(this._xaxis,c[1][0]),h.call(this._yaxis,c[1][1]),f.call(this._xaxis,c[0][0]),h.call(this._yaxis,c[0][1])]]}}else{if(d==0){e=[[f.call(this._xaxis,g[0][0]),h.call(this._yaxis,g[0][1])],[f.call(this._xaxis,g[1][0]),h.call(this._yaxis,g[1][1]),f.call(this._xaxis,g[2][0]),h.call(this._yaxis,g[2][1]),f.call(this._xaxis,g[3][0]),h.call(this._yaxis,g[3][1])],[f.call(this._xaxis,g[3][1]),h.call(this._yaxis,this._yaxis.min)],[f.call(this._xaxis,g[0][0]),h.call(this._yaxis,this._yaxis.min)]]}else{var c=i.series[d-1].data;e=[[f.call(this._xaxis,g[0][0]),h.call(this._yaxis,g[0][1])],[f.call(this._xaxis,g[1][0]),h.call(this._yaxis,g[1][1]),f.call(this._xaxis,g[2][0]),h.call(this._yaxis,g[2][1]),f.call(this._xaxis,g[3][0]),h.call(this._yaxis,g[3][1])],[f.call(this._xaxis,c[3][0]),h.call(this._yaxis,c[3][1])],[f.call(this._xaxis,c[2][0]),h.call(this._yaxis,c[2][1]),f.call(this._xaxis,c[1][0]),h.call(this._yaxis,c[1][1]),f.call(!
this._xaxis,c[0][0]),h.call(this._yaxis,c[0][1])]]}}return e};b.jqplot.BezierCurveRenderer.prototype.draw=function(c,g,d){var e;c.save();if(g.length){if(this.showLine){c.save();var f=(d!=null)?d:{};c.fillStyle=f.fillStyle||this.color;c.beginPath();c.moveTo(g[0][0],g[0][1]);c.bezierCurveTo(g[1][0],g[1][1],g[1][2],g[1][3],g[1][4],g[1][5]);c.lineTo(g[2][0],g[2][1]);if(g[3].length==2){c.lineTo(g[3][0],g[3][1])}else{c.bezierCurveTo(g[3][0],g[3][1],g[3][2],g[3][3],g[3][4],g[3][5])}c.closePath();c.fill();c.restore()}}c.restore()};b.jqplot.BezierCurveRenderer.prototype.drawShadow=function(c,e,d){};b.jqplot.BezierAxisRenderer=function(){b.jqplot.LinearAxisRenderer.call(this)};b.jqplot.BezierAxisRenderer.prototype=new b.jqplot.LinearAxisRenderer();b.jqplot.BezierAxisRenderer.prototype.constructor=b.jqplot.BezierAxisRenderer;b.jqplot.BezierAxisRenderer.prototype.init=function(f){b.extend(true,this,f);var c=this._dataBounds;for(var g=0;g<this._series.length;g++){var h=this._series[g];var k=h.data;if(k.length==4){for(var e=0;e<k.length;e++){if(this.name=="xaxis"||this.name=="x2axis"){if(k[e][0]<c.min||c.min==null){c.min=k[e][0]}if(k[e][0]>c.max||c.max==null){c.max=k[e][0]}}else{if(k[e][1]<c.min||c.min==null){c.min=k[e][1]}if(k[e][1]>c.max||c.max==null){c.max=k[e][1]}}}}else{if(this.name=="xaxis"||this.name=="x2axis"){if(k[0][0]<c.min||c.min==null){c.min=k[0][0]}if(k[0][0]>c.max||c.max==null){c.max=k[0][0]}for(var e=0;e<5;e+=2){if(k[1][e]<c.min||c.min==null){c.min=k[1][e]}if(k[1][e]>c.max||c.max==null){c.max=k[1][e]}}}else{if(k[0][1]<c.min||c.min==null){c.min=k[0][1]}if(k[0][1]>c.max||c.max==null){c.max=k[0][1]}for(var e=1;e<6;e+=2){if(k[1][e]<c.min||c.min==null){c.min=k[1][e]}if(k[1][e]>c.max||c.max==null){c.max=k[1][e]}}}}}};function a(g,f,d){d=d||{};d.axesDefaults=b.extend(true,{pad:0},d.axesDefaults);d.legend=b.extend(true,{placement:"outside"},d.legend);var c=false;if(d.seriesDefaults.renderer==b.jqplot.BezierCurveRenderer){c=true}else{if(d.series){for(var e=0;e<d.series.length;e++){if(d.series[e].renderer==b.jqplot.Bezi!
erCurveRenderer){c=true}}}}if(c){d.axesDefaults.renderer=b.jqplot.BezierAxisRenderer}}b.jqplot.preInitHooks.push(a)})(jQuery);
\ No newline at end of file
Modified: gnucash/trunk/src/report/jqplot/plugins/jqplot.barRenderer.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.barRenderer.js 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.barRenderer.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -1,18 +1,31 @@
/**
- * Copyright (c) 2009 - 2010 Chris Leonello
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
- * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
- * The author would appreciate an email letting him know of any substantial
- * use of jqPlot. You can reach the author at: chris at jqplot dot com
- * or see http://www.jqplot.com/info.php . This is, of course,
- * not required.
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
- * Thanks for using jqPlot!
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
*
*/
(function($) {
@@ -80,16 +93,45 @@
// prop: highlightColors
// an array of colors to use when highlighting a bar.
this.highlightColors = [];
+ // prop: transposedData
+ // NOT IMPLEMENTED YET. True if this is a horizontal bar plot and
+ // x and y values are "transposed". Tranposed, or "swapped", data is
+ // required prior to rev. 894 builds of jqPlot with horizontal bars.
+ // Allows backward compatability of bar renderer horizontal bars with
+ // old style data sets.
+ this.transposedData = true;
+ this.renderer.animation = {
+ show: false,
+ direction: 'down',
+ speed: 3000,
+ _supported: true
+ };
+ this._type = 'bar';
// if user has passed in highlightMouseDown option and not set highlightMouseOver, disable highlightMouseOver
if (options.highlightMouseDown && options.highlightMouseOver == null) {
options.highlightMouseOver = false;
}
+ //////
+ // This is probably wrong here.
+ // After going back and forth on wether renderer should be the thing
+ // or extend the thing, it seems that it it best if it is a property
+ // on the thing. This should be something that is commonized
+ // among series renderers in the future.
+ //////
$.extend(true, this, options);
+
+ // really should probably do this
+ $.extend(true, this.renderer, options);
// fill is still needed to properly draw the legend.
// bars have to be filled.
this.fill = true;
+
+ // if horizontal bar and animating, reset the default direction
+ if (this.barDirection === 'horizontal' && this.rendererOptions.animation && this.rendererOptions.animation.direction == null) {
+ this.renderer.animation.direction = 'left';
+ }
if (this.waterfall) {
this.fillToZero = false;
@@ -139,7 +181,7 @@
if (this.rendererOptions.waterfall == true) {
this._data = $.extend(true, [], this.data);
var sum = 0;
- var pos = (!this.rendererOptions.barDirection || this.rendererOptions.barDirection == 'vertical') ? 1 : 0;
+ var pos = (!this.rendererOptions.barDirection || this.rendererOptions.barDirection === 'vertical' || this.transposedData === false) ? 1 : 0;
for(var i=0; i<this.data.length; i++) {
sum += this.data[i][pos];
if (i>0) {
@@ -156,14 +198,20 @@
var count = 0;
for (var i=skip; i<l; i+=skip) {
this.data.splice(i+count, 0, [null, null]);
+ this._plotData.splice(i+count, 0, [null, null]);
+ this._stackData.splice(i+count, 0, [null, null]);
count++;
}
for (i=0; i<this.data.length; i++) {
if (this._primaryAxis == '_xaxis') {
this.data[i][0] = i+1;
+ this._plotData[i][0] = i+1;
+ this._stackData[i][0] = i+1;
}
else {
this.data[i][1] = i+1;
+ this._plotData[i][1] = i+1;
+ this._stackData[i][1] = i+1;
}
}
}
@@ -243,10 +291,45 @@
}
return ret;
}
+
+ function getStart(sidx, didx, comp, plot, axis) {
+ // check if sign change
+ var seriesIndex = sidx,
+ prevSeriesIndex = sidx - 1,
+ start,
+ prevVal,
+ aidx = (axis === 'x') ? 0 : 1;
+
+ // is this not the first series?
+ if (seriesIndex > 0) {
+ prevVal = plot.series[prevSeriesIndex]._plotData[didx][aidx];
+
+ // is there a sign change
+ if ((comp * prevVal) < 0) {
+ start = getStart(prevSeriesIndex, didx, comp, plot, axis);
+ }
+
+ // no sign change.
+ else {
+ start = plot.series[prevSeriesIndex].gridData[didx][aidx];
+ }
+
+ }
+
+ // if first series, return value at 0
+ else {
+
+ start = (aidx === 0) ? plot.series[seriesIndex]._xaxis.series_u2p(0) : plot.series[seriesIndex]._yaxis.series_u2p(0);
+ }
+
+ return start;
+ }
+
- $.jqplot.BarRenderer.prototype.draw = function(ctx, gridData, options) {
+ $.jqplot.BarRenderer.prototype.draw = function(ctx, gridData, options, plot) {
var i;
- var opts = (options != undefined) ? options : {};
+ // Ughhh, have to make a copy of options b/c it may be modified later.
+ var opts = $.extend({}, options);
var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow;
var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine;
var fill = (opts.fill != undefined) ? opts.fill : this.fill;
@@ -254,7 +337,7 @@
var yaxis = this.yaxis;
var xp = this._xaxis.series_u2p;
var yp = this._yaxis.series_u2p;
- var pointx, pointy, nvals, nseries, pos;
+ var pointx, pointy;
// clear out data colors.
this._dataColors = [];
this._barPoints = [];
@@ -264,9 +347,10 @@
}
var temp = this._plotSeriesInfo = this.renderer.calcSeriesNumbers.call(this);
- nvals = temp[0];
- nseries = temp[1];
- pos = temp[2];
+ var nvals = temp[0];
+ var nseries = temp[1];
+ var pos = temp[2];
+ var points = [];
if (this._stack) {
this._barNudge = 0;
@@ -282,21 +366,24 @@
negativeColor = opts.fillStyle;
}
var positiveColor = opts.fillStyle;
+ var base;
+ var xstart;
+ var ystart;
if (this.barDirection == 'vertical') {
for (var i=0; i<gridData.length; i++) {
- if (this.data[i][1] == null) {
+ if (!this._stack && this.data[i][1] == null) {
continue;
}
points = [];
- var base = gridData[i][0] + this._barNudge;
- var ystart;
+ base = gridData[i][0] + this._barNudge;
// stacked
if (this._stack && this._prevGridData.length) {
- ystart = this._prevGridData[i][1];
+ ystart = getStart(this.index, i, this._plotData[i][1], plot, 'y');
}
- // not stacked and first series in stack
+
+ // not stacked
else {
if (this.fillToZero) {
ystart = this._yaxis.series_u2p(0);
@@ -304,6 +391,28 @@
else if (this.waterfall && i > 0 && i < this.gridData.length-1) {
ystart = this.gridData[i-1][1];
}
+ else if (this.waterfall && i == 0 && i < this.gridData.length-1) {
+ if (this._yaxis.min <= 0 && this._yaxis.max >= 0) {
+ ystart = this._yaxis.series_u2p(0);
+ }
+ else if (this._yaxis.min > 0) {
+ ystart = ctx.canvas.height;
+ }
+ else {
+ ystart = 0;
+ }
+ }
+ else if (this.waterfall && i == this.gridData.length - 1) {
+ if (this._yaxis.min <= 0 && this._yaxis.max >= 0) {
+ ystart = this._yaxis.series_u2p(0);
+ }
+ else if (this._yaxis.min > 0) {
+ ystart = ctx.canvas.height;
+ }
+ else {
+ ystart = 0;
+ }
+ }
else {
ystart = ctx.canvas.height;
}
@@ -329,11 +438,20 @@
opts.fillStyle = positiveColor;
}
}
-
- points.push([base-this.barWidth/2, ystart]);
- points.push([base-this.barWidth/2, gridData[i][1]]);
- points.push([base+this.barWidth/2, gridData[i][1]]);
- points.push([base+this.barWidth/2, ystart]);
+
+ if (!this.fillToZero || this._plotData[i][1] >= 0) {
+ points.push([base-this.barWidth/2, ystart]);
+ points.push([base-this.barWidth/2, gridData[i][1]]);
+ points.push([base+this.barWidth/2, gridData[i][1]]);
+ points.push([base+this.barWidth/2, ystart]);
+ }
+ // for negative bars make sure points are always ordered clockwise
+ else {
+ points.push([base-this.barWidth/2, gridData[i][1]]);
+ points.push([base-this.barWidth/2, ystart]);
+ points.push([base+this.barWidth/2, ystart]);
+ points.push([base+this.barWidth/2, gridData[i][1]]);
+ }
this._barPoints.push(points);
// now draw the shadows if not stacked.
// for stacked plots, they are predrawn by drawShadow
@@ -351,24 +469,46 @@
else if (this.barDirection == 'horizontal'){
for (var i=0; i<gridData.length; i++) {
- if (this.data[i][0] == null) {
+ if (!this._stack && this.data[i][0] == null) {
continue;
}
points = [];
- var base = gridData[i][1] - this._barNudge;
- var xstart;
+ base = gridData[i][1] - this._barNudge;
+ xstart;
if (this._stack && this._prevGridData.length) {
- xstart = this._prevGridData[i][0];
+ xstart = getStart(this.index, i, this._plotData[i][0], plot, 'x');
}
- // not stacked and first series in stack
+ // not stacked
else {
if (this.fillToZero) {
xstart = this._xaxis.series_u2p(0);
}
else if (this.waterfall && i > 0 && i < this.gridData.length-1) {
- xstart = this.gridData[i-1][1];
+ xstart = this.gridData[i-1][0];
}
+ else if (this.waterfall && i == 0 && i < this.gridData.length-1) {
+ if (this._xaxis.min <= 0 && this._xaxis.max >= 0) {
+ xstart = this._xaxis.series_u2p(0);
+ }
+ else if (this._xaxis.min > 0) {
+ xstart = 0;
+ }
+ else {
+ xstart = 0;
+ }
+ }
+ else if (this.waterfall && i == this.gridData.length - 1) {
+ if (this._xaxis.min <= 0 && this._xaxis.max >= 0) {
+ xstart = this._xaxis.series_u2p(0);
+ }
+ else if (this._xaxis.min > 0) {
+ xstart = 0;
+ }
+ else {
+ xstart = ctx.canvas.width;
+ }
+ }
else {
xstart = 0;
}
@@ -392,10 +532,20 @@
}
}
- points.push([xstart, base+this.barWidth/2]);
- points.push([xstart, base-this.barWidth/2]);
- points.push([gridData[i][0], base-this.barWidth/2]);
- points.push([gridData[i][0], base+this.barWidth/2]);
+
+ if (!this.fillToZero || this._plotData[i][0] >= 0) {
+ points.push([xstart, base + this.barWidth / 2]);
+ points.push([xstart, base - this.barWidth / 2]);
+ points.push([gridData[i][0], base - this.barWidth / 2]);
+ points.push([gridData[i][0], base + this.barWidth / 2]);
+ }
+ else {
+ points.push([gridData[i][0], base + this.barWidth / 2]);
+ points.push([gridData[i][0], base - this.barWidth / 2]);
+ points.push([xstart, base - this.barWidth / 2]);
+ points.push([xstart, base + this.barWidth / 2]);
+ }
+
this._barPoints.push(points);
// now draw the shadows if not stacked.
// for stacked plots, they are predrawn by drawShadow
@@ -406,13 +556,13 @@
}
var clr = opts.fillStyle || this.color;
this._dataColors.push(clr);
- this.renderer.shapeRenderer.draw(ctx, points, opts);
- }
+ this.renderer.shapeRenderer.draw(ctx, points, opts);
+ }
}
}
if (this.highlightColors.length == 0) {
- this.highlightColors = computeHighlightColors(this._dataColors);
+ this.highlightColors = $.jqplot.computeHighlightColors(this._dataColors);
}
else if (typeof(this.highlightColors) == 'string') {
@@ -427,7 +577,7 @@
// for stacked plots, shadows will be pre drawn by drawShadow.
- $.jqplot.BarRenderer.prototype.drawShadow = function(ctx, gridData, options) {
+ $.jqplot.BarRenderer.prototype.drawShadow = function(ctx, gridData, options, plot) {
var i;
var opts = (options != undefined) ? options : {};
var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow;
@@ -437,7 +587,7 @@
var yaxis = this.yaxis;
var xp = this._xaxis.series_u2p;
var yp = this._yaxis.series_u2p;
- var pointx, pointy, nvals, nseries, pos;
+ var pointx, points, pointy, nvals, nseries, pos;
if (this._stack && this.shadow) {
if (this.barWidth == null) {
@@ -467,7 +617,7 @@
var ystart;
if (this._stack && this._prevGridData.length) {
- ystart = this._prevGridData[i][1];
+ ystart = getStart(this.index, i, this._plotData[i][1], plot, 'y');
}
else {
if (this.fillToZero) {
@@ -496,10 +646,15 @@
var xstart;
if (this._stack && this._prevGridData.length) {
- xstart = this._prevGridData[i][0];
+ xstart = getStart(this.index, i, this._plotData[i][0], plot, 'x');
}
else {
- xstart = 0;
+ if (this.fillToZero) {
+ xstart = this._xaxis.series_u2p(0);
+ }
+ else {
+ xstart = 0;
+ }
}
points.push([xstart, base+this.barWidth/2]);
@@ -515,7 +670,7 @@
};
function postInit(target, data, options) {
- for (i=0; i<this.series.length; i++) {
+ for (var i=0; i<this.series.length; i++) {
if (this.series[i].renderer.constructor == $.jqplot.BarRenderer) {
// don't allow mouseover and mousedown at same time.
if (this.series[i].highlightMouseOver) {
@@ -523,18 +678,25 @@
}
}
}
- this.target.bind('mouseout', {plot:this}, function (ev) { unhighlight(ev.data.plot); });
}
// called within context of plot
// create a canvas which we can draw on.
// insert it before the eventCanvas, so eventCanvas will still capture events.
function postPlotDraw() {
+ // Memory Leaks patch
+ if (this.plugins.barRenderer && this.plugins.barRenderer.highlightCanvas) {
+
+ this.plugins.barRenderer.highlightCanvas.resetCanvas();
+ this.plugins.barRenderer.highlightCanvas = null;
+ }
+
this.plugins.barRenderer = {highlightedSeriesIndex:null};
this.plugins.barRenderer.highlightCanvas = new $.jqplot.GenericCanvas();
- this.eventCanvas._elem.before(this.plugins.barRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-barRenderer-highlight-canvas', this._plotDimensions));
- var hctx = this.plugins.barRenderer.highlightCanvas.setContext();
+ this.eventCanvas._elem.before(this.plugins.barRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-barRenderer-highlight-canvas', this._plotDimensions, this));
+ this.plugins.barRenderer.highlightCanvas.setContext();
+ this.eventCanvas._elem.bind('mouseleave', {plot:this}, function (ev) { unhighlight(ev.data.plot); });
}
function highlight (plot, sidx, pidx, points) {
@@ -545,6 +707,7 @@
plot.plugins.barRenderer.highlightedSeriesIndex = sidx;
var opts = {fillStyle: s.highlightColors[pidx]};
s.renderer.shapeRenderer.draw(canvas._ctx, points, opts);
+ canvas = null;
}
function unhighlight (plot) {
@@ -555,6 +718,7 @@
}
plot.plugins.barRenderer.highlightedSeriesIndex = null;
plot.target.trigger('jqplotDataUnhighlight');
+ canvas = null;
}
@@ -567,6 +731,7 @@
plot.target.trigger(evt1, ins);
if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.barRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) {
var evt = jQuery.Event('jqplotDataHighlight');
+ evt.which = ev.which;
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
plot.target.trigger(evt, ins);
@@ -583,6 +748,7 @@
var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
if (plot.series[ins[0]].highlightMouseDown && !(ins[0] == plot.plugins.barRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) {
var evt = jQuery.Event('jqplotDataHighlight');
+ evt.which = ev.which;
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
plot.target.trigger(evt, ins);
@@ -605,6 +771,7 @@
if (neighbor) {
var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
var evt = jQuery.Event('jqplotDataClick');
+ evt.which = ev.which;
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
plot.target.trigger(evt, ins);
@@ -619,6 +786,7 @@
unhighlight(plot);
}
var evt = jQuery.Event('jqplotDataRightClick');
+ evt.which = ev.which;
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
plot.target.trigger(evt, ins);
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.barRenderer.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.barRenderer.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.barRenderer.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(d){d.jqplot.BarRenderer=function(){d.jqplot.LineRenderer.call(this)};d.jqplot.BarRenderer.prototype=new d.jqplot.LineRenderer();d.jqplot.BarRenderer.prototype.constructor=d.jqplot.BarRenderer;d.jqplot.BarRenderer.prototype.init=function(o,q){this.barPadding=8;this.barMargin=10;this.barDirection="vertical";this.barWidth=null;this.shadowOffset=2;this.shadowDepth=5;this.shadowAlpha=0.08;this.waterfall=false;this.groups=1;this.varyBarColor=false;this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColors=[];this.transposedData=true;this.renderer.animation={show:false,direction:"down",speed:3000,_supported:true};this._type="bar";if(o.highlightMouseDown&&o.highlightMouseOver==null){o.highlightMouseOver=false}d.extend(true,this,o);d.extend(true,this.renderer,o);this.fill=true;if(this.barDirection==="horizontal"&&this.rendererOptions.animation&&this.rendererOptions.animation.direction==null){this.renderer.animation.direction="left"}if(this.waterfall){this.fillToZero=false;this.disableStack=true}if(this.barDirection=="vertical"){this._primaryAxis="_xaxis";this._stackAxis="y";this.fillAxis="y"}else{this._primaryAxis="_yaxis";this._stackAxis="x";this.fillAxis="x"}this._highlightedPoint=null;this._plotSeriesInfo=null;this._dataColors=[];this._barPoints=[];var p={lineJoin:"miter",lineCap:"round",fill:true,isarc:false,strokeStyle:this.color,fillStyle:this.color,closePath:this.fill};this.renderer.shapeRenderer.init(p);var n={lineJoin:"miter",lineCap:"round",fill:true,isarc:false,angle:this.shadowAngle,offset:this.shadowOffset,alpha:this.shadowAlpha,depth:this.shadowDepth,closePath:this.fill};this.renderer.shadowRenderer.init(n);q.postInitHooks.addOnce(h);q.postDrawHooks.addOnce(j);q.eventListenerHooks.addOnce("jqplotMouseMove",b);q.eventListenerHooks.addOnce("jqplotMouseDown",a);q.eventListenerHooks.addOnce("jqplotMouseUp",l);q.eventListenerHooks.addOnce("jqplotClick",e);q.eventListenerHooks.addOnce("jqplotRightClick",m)};function g(t,p,o,w){if(this.rendererOptions.barDirection=="horiz!
ontal"){this._stackAxis="x";this._primaryAxis="_yaxis"}if(this.rendererOptions.waterfall==true){this._data=d.extend(true,[],this.data);var s=0;var u=(!this.rendererOptions.barDirection||this.rendererOptions.barDirection==="vertical"||this.transposedData===false)?1:0;for(var q=0;q<this.data.length;q++){s+=this.data[q][u];if(q>0){this.data[q][u]+=this.data[q-1][u]}}this.data[this.data.length]=(u==1)?[this.data.length+1,s]:[s,this.data.length+1];this._data[this._data.length]=(u==1)?[this._data.length+1,s]:[s,this._data.length+1]}if(this.rendererOptions.groups>1){this.breakOnNull=true;var n=this.data.length;var v=parseInt(n/this.rendererOptions.groups,10);var r=0;for(var q=v;q<n;q+=v){this.data.splice(q+r,0,[null,null]);this._plotData.splice(q+r,0,[null,null]);this._stackData.splice(q+r,0,[null,null]);r++}for(q=0;q<this.data.length;q++){if(this._primaryAxis=="_xaxis"){this.data[q][0]=q+1;this._plotData[q][0]=q+1;this._stackData[q][0]=q+1}else{this.data[q][1]=q+1;this._plotData[q][1]=q+1;this._stackData[q][1]=q+1}}}}d.jqplot.preSeriesInitHooks.push(g);d.jqplot.BarRenderer.prototype.calcSeriesNumbers=function(){var r=0;var t=0;var q=this[this._primaryAxis];var p,o,u;for(var n=0;n<q._series.length;n++){o=q._series[n];if(o===this){u=n}if(o.renderer.constructor==d.jqplot.BarRenderer){r+=o.data.length;t+=1}}return[r,t,u]};d.jqplot.BarRenderer.prototype.setBarWidth=function(){var q;var n=0;var o=0;var t=this[this._primaryAxis];var x,r,v;var w=this._plotSeriesInfo=this.renderer.calcSeriesNumbers.call(this);n=w[0];o=w[1];var u=t.numberTicks;var p=(u-1)/2;if(t.name=="xaxis"||t.name=="x2axis"){if(this._stack){this.barWidth=(t._offsets.max-t._offsets.min)/n*o-this.barMargin}else{this.barWidth=((t._offsets.max-t._offsets.min)/p-this.barPadding*(o-1)-this.barMargin*2)/o}}else{if(this._stack){this.barWidth=(t._offsets.min-t._offsets.max)/n*o-this.barMargin}else{this.barWidth=((t._offsets.min-t._offsets.max)/p-this.barPadding*(o-1)-this.barMargin*2)/o}}return[n,o]};function f(o){var q=[];for(var s=0;s<o.length;s++){var r=d.jqplot.g!
etColorComponents(o[s]);var n=[r[0],r[1],r[2]];var t=n[0]+n[1]+n[2];for(var p=0;p<3;p++){n[p]=(t>570)?n[p]*0.8:n[p]+0.3*(255-n[p]);n[p]=parseInt(n[p],10)}q.push("rgb("+n[0]+","+n[1]+","+n[2]+")")}return q}function i(v,u,s,t,o){var q=v,w=v-1,n,p,r=(o==="x")?0:1;if(q>0){p=t.series[w]._plotData[u][r];if((s*p)<0){n=i(w,u,s,t,o)}else{n=t.series[w].gridData[u][r]}}else{n=(r===0)?t.series[q]._xaxis.series_u2p(0):t.series[q]._yaxis.series_u2p(0)}return n}d.jqplot.BarRenderer.prototype.draw=function(E,L,q,G){var I;var A=d.extend({},q);var w=(A.shadow!=undefined)?A.shadow:this.shadow;var O=(A.showLine!=undefined)?A.showLine:this.showLine;var F=(A.fill!=undefined)?A.fill:this.fill;var p=this.xaxis;var J=this.yaxis;var y=this._xaxis.series_u2p;var K=this._yaxis.series_u2p;var D,C;this._dataColors=[];this._barPoints=[];if(this.barWidth==null){this.renderer.setBarWidth.call(this)}var N=this._plotSeriesInfo=this.renderer.calcSeriesNumbers.call(this);var x=N[0];var v=N[1];var s=N[2];var H=[];if(this._stack){this._barNudge=0}else{this._barNudge=(-Math.abs(v/2-0.5)+s)*(this.barWidth+this.barPadding)}if(O){var u=new d.jqplot.ColorGenerator(this.negativeSeriesColors);var B=new d.jqplot.ColorGenerator(this.seriesColors);var M=u.get(this.index);if(!this.useNegativeColors){M=A.fillStyle}var t=A.fillStyle;var r;var P;var o;if(this.barDirection=="vertical"){for(var I=0;I<L.length;I++){if(!this._stack&&this.data[I][1]==null){continue}H=[];r=L[I][0]+this._barNudge;if(this._stack&&this._prevGridData.length){o=i(this.index,I,this._plotData[I][1],G,"y")}else{if(this.fillToZero){o=this._yaxis.series_u2p(0)}else{if(this.waterfall&&I>0&&I<this.gridData.length-1){o=this.gridData[I-1][1]}else{if(this.waterfall&&I==0&&I<this.gridData.length-1){if(this._yaxis.min<=0&&this._yaxis.max>=0){o=this._yaxis.series_u2p(0)}else{if(this._yaxis.min>0){o=E.canvas.height}else{o=0}}}else{if(this.waterfall&&I==this.gridData.length-1){if(this._yaxis.min<=0&&this._yaxis.max>=0){o=this._yaxis.series_u2p(0)}else{if(this._yaxis.min>0){o=E.canvas.height}else{o=0}}}else!
{o=E.canvas.height}}}}}if((this.fillToZero&&this._plotData[I][1]<0)||(this.waterfall&&this._data[I][1]<0)){if(this.varyBarColor&&!this._stack){if(this.useNegativeColors){A.fillStyle=u.next()}else{A.fillStyle=B.next()}}else{A.fillStyle=M}}else{if(this.varyBarColor&&!this._stack){A.fillStyle=B.next()}else{A.fillStyle=t}}if(!this.fillToZero||this._plotData[I][1]>=0){H.push([r-this.barWidth/2,o]);H.push([r-this.barWidth/2,L[I][1]]);H.push([r+this.barWidth/2,L[I][1]]);H.push([r+this.barWidth/2,o])}else{H.push([r-this.barWidth/2,L[I][1]]);H.push([r-this.barWidth/2,o]);H.push([r+this.barWidth/2,o]);H.push([r+this.barWidth/2,L[I][1]])}this._barPoints.push(H);if(w&&!this._stack){var z=d.extend(true,{},A);delete z.fillStyle;this.renderer.shadowRenderer.draw(E,H,z)}var n=A.fillStyle||this.color;this._dataColors.push(n);this.renderer.shapeRenderer.draw(E,H,A)}}else{if(this.barDirection=="horizontal"){for(var I=0;I<L.length;I++){if(!this._stack&&this.data[I][0]==null){continue}H=[];r=L[I][1]-this._barNudge;P;if(this._stack&&this._prevGridData.length){P=i(this.index,I,this._plotData[I][0],G,"x")}else{if(this.fillToZero){P=this._xaxis.series_u2p(0)}else{if(this.waterfall&&I>0&&I<this.gridData.length-1){P=this.gridData[I-1][0]}else{if(this.waterfall&&I==0&&I<this.gridData.length-1){if(this._xaxis.min<=0&&this._xaxis.max>=0){P=this._xaxis.series_u2p(0)}else{if(this._xaxis.min>0){P=0}else{P=0}}}else{if(this.waterfall&&I==this.gridData.length-1){if(this._xaxis.min<=0&&this._xaxis.max>=0){P=this._xaxis.series_u2p(0)}else{if(this._xaxis.min>0){P=0}else{P=E.canvas.width}}}else{P=0}}}}}if((this.fillToZero&&this._plotData[I][1]<0)||(this.waterfall&&this._data[I][1]<0)){if(this.varyBarColor&&!this._stack){if(this.useNegativeColors){A.fillStyle=u.next()}else{A.fillStyle=B.next()}}}else{if(this.varyBarColor&&!this._stack){A.fillStyle=B.next()}else{A.fillStyle=t}}if(!this.fillToZero||this._plotData[I][0]>=0){H.push([P,r+this.barWidth/2]);H.push([P,r-this.barWidth/2]);H.push([L[I][0],r-this.barWidth/2]);H.push([L[I][0],r+this.barWidth/2])}e!
lse{H.push([L[I][0],r+this.barWidth/2]);H.push([L[I][0],r-this.barWidth/2]);H.push([P,r-this.barWidth/2]);H.push([P,r+this.barWidth/2])}this._barPoints.push(H);if(w&&!this._stack){var z=d.extend(true,{},A);delete z.fillStyle;this.renderer.shadowRenderer.draw(E,H,z)}var n=A.fillStyle||this.color;this._dataColors.push(n);this.renderer.shapeRenderer.draw(E,H,A)}}}}if(this.highlightColors.length==0){this.highlightColors=d.jqplot.computeHighlightColors(this._dataColors)}else{if(typeof(this.highlightColors)=="string"){var N=this.highlightColors;this.highlightColors=[];for(var I=0;I<this._dataColors.length;I++){this.highlightColors.push(N)}}}};d.jqplot.BarRenderer.prototype.drawShadow=function(z,G,p,B){var D;var w=(p!=undefined)?p:{};var t=(w.shadow!=undefined)?w.shadow:this.shadow;var I=(w.showLine!=undefined)?w.showLine:this.showLine;var A=(w.fill!=undefined)?w.fill:this.fill;var o=this.xaxis;var E=this.yaxis;var v=this._xaxis.series_u2p;var F=this._yaxis.series_u2p;var y,C,x,u,s,r;if(this._stack&&this.shadow){if(this.barWidth==null){this.renderer.setBarWidth.call(this)}var H=this._plotSeriesInfo=this.renderer.calcSeriesNumbers.call(this);u=H[0];s=H[1];r=H[2];if(this._stack){this._barNudge=0}else{this._barNudge=(-Math.abs(s/2-0.5)+r)*(this.barWidth+this.barPadding)}if(I){if(this.barDirection=="vertical"){for(var D=0;D<G.length;D++){if(this.data[D][1]==null){continue}C=[];var q=G[D][0]+this._barNudge;var n;if(this._stack&&this._prevGridData.length){n=i(this.index,D,this._plotData[D][1],B,"y")}else{if(this.fillToZero){n=this._yaxis.series_u2p(0)}else{n=z.canvas.height}}C.push([q-this.barWidth/2,n]);C.push([q-this.barWidth/2,G[D][1]]);C.push([q+this.barWidth/2,G[D][1]]);C.push([q+this.barWidth/2,n]);this.renderer.shadowRenderer.draw(z,C,w)}}else{if(this.barDirection=="horizontal"){for(var D=0;D<G.length;D++){if(this.data[D][0]==null){continue}C=[];var q=G[D][1]-this._barNudge;var J;if(this._stack&&this._prevGridData.length){J=i(this.index,D,this._plotData[D][0],B,"x")}else{if(this.fillToZero){J=this._xaxis.series_u2p(0)!
}else{J=0}}C.push([J,q+this.barWidth/2]);C.push([G[D][0],q+this.barWidth/2]);C.push([G[D][0],q-this.barWidth/2]);C.push([J,q-this.barWidth/2]);this.renderer.shadowRenderer.draw(z,C,w)}}}}}};function h(q,p,n){for(var o=0;o<this.series.length;o++){if(this.series[o].renderer.constructor==d.jqplot.BarRenderer){if(this.series[o].highlightMouseOver){this.series[o].highlightMouseDown=false}}}}function j(){if(this.plugins.barRenderer&&this.plugins.barRenderer.highlightCanvas){this.plugins.barRenderer.highlightCanvas.resetCanvas();this.plugins.barRenderer.highlightCanvas=null}this.plugins.barRenderer={highlightedSeriesIndex:null};this.plugins.barRenderer.highlightCanvas=new d.jqplot.GenericCanvas();this.eventCanvas._elem.before(this.plugins.barRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-barRenderer-highlight-canvas",this._plotDimensions,this));this.plugins.barRenderer.highlightCanvas.setContext();this.eventCanvas._elem.bind("mouseleave",{plot:this},function(n){k(n.data.plot)})}function c(u,t,q,p){var o=u.series[t];var n=u.plugins.barRenderer.highlightCanvas;n._ctx.clearRect(0,0,n._ctx.canvas.width,n._ctx.canvas.height);o._highlightedPoint=q;u.plugins.barRenderer.highlightedSeriesIndex=t;var r={fillStyle:o.highlightColors[q]};o.renderer.shapeRenderer.draw(n._ctx,p,r);n=null}function k(p){var n=p.plugins.barRenderer.highlightCanvas;n._ctx.clearRect(0,0,n._ctx.canvas.width,n._ctx.canvas.height);for(var o=0;o<p.series.length;o++){p.series[o]._highlightedPoint=null}p.plugins.barRenderer.highlightedSeriesIndex=null;p.target.trigger("jqplotDataUnhighlight");n=null}function b(r,q,u,t,s){if(t){var p=[t.seriesIndex,t.pointIndex,t.data];var o=jQuery.Event("jqplotDataMouseOver");o.pageX=r.pageX;o.pageY=r.pageY;s.target.trigger(o,p);if(s.series[p[0]].highlightMouseOver&&!(p[0]==s.plugins.barRenderer.highlightedSeriesIndex&&p[1]==s.series[p[0]]._highlightedPoint)){var n=jQuery.Event("jqplotDataHighlight");n.which=r.which;n.pageX=r.pageX;n.pageY=r.pageY;s.target.trigger(n,p);c(s,t.seriesIndex,t.pointIndex,t.points)!
}}else{if(t==null){k(s)}}}function a(q,p,t,s,r){if(s){var o=[s.seriesIndex,s.pointIndex,s.data];if(r.series[o[0]].highlightMouseDown&&!(o[0]==r.plugins.barRenderer.highlightedSeriesIndex&&o[1]==r.series[o[0]]._highlightedPoint)){var n=jQuery.Event("jqplotDataHighlight");n.which=q.which;n.pageX=q.pageX;n.pageY=q.pageY;r.target.trigger(n,o);c(r,s.seriesIndex,s.pointIndex,s.points)}}else{if(s==null){k(r)}}}function l(p,o,s,r,q){var n=q.plugins.barRenderer.highlightedSeriesIndex;if(n!=null&&q.series[n].highlightMouseDown){k(q)}}function e(q,p,t,s,r){if(s){var o=[s.seriesIndex,s.pointIndex,s.data];var n=jQuery.Event("jqplotDataClick");n.which=q.which;n.pageX=q.pageX;n.pageY=q.pageY;r.target.trigger(n,o)}}function m(r,q,u,t,s){if(t){var p=[t.seriesIndex,t.pointIndex,t.data];var n=s.plugins.barRenderer.highlightedSeriesIndex;if(n!=null&&s.series[n].highlightMouseDown){k(s)}var o=jQuery.Event("jqplotDataRightClick");o.which=r.which;o.pageX=r.pageX;o.pageY=r.pageY;s.target.trigger(o,p)}}})(jQuery);
\ No newline at end of file
Modified: gnucash/trunk/src/report/jqplot/plugins/jqplot.blockRenderer.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.blockRenderer.js 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.blockRenderer.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -1,18 +1,31 @@
/**
- * Copyright (c) 2009 - 2010 Chris Leonello
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
- * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
- * The author would appreciate an email letting him know of any substantial
- * use of jqPlot. You can reach the author at: chris at jqplot dot com
- * or see http://www.jqplot.com/info.php . This is, of course,
- * not required.
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
- * Thanks for using jqPlot!
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
*
*/
(function($) {
@@ -77,6 +90,7 @@
this.shadowCanvas = new $.jqplot.BlockCanvas();
this.canvas._plotDimensions = this._plotDimensions;
this.shadowCanvas._plotDimensions = this._plotDimensions;
+ this._type = 'block';
// group: Methods
//
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.blockRenderer.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.blockRenderer.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.blockRenderer.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(a){a.jqplot.BlockRenderer=function(){a.jqplot.LineRenderer.call(this)};a.jqplot.BlockRenderer.prototype=new a.jqplot.LineRenderer();a.jqplot.BlockRenderer.prototype.constructor=a.jqplot.BlockRenderer;a.jqplot.BlockRenderer.prototype.init=function(b){this.css={padding:"2px",border:"1px solid #999",textAlign:"center"};this.escapeHtml=false;this.insertBreaks=true;this.varyBlockColors=false;a.extend(true,this,b);if(this.css.backgroundColor){this.color=this.css.backgroundColor}else{if(this.css.background){this.color=this.css.background}else{if(!this.varyBlockColors){this.css.background=this.color}}}this.canvas=new a.jqplot.BlockCanvas();this.shadowCanvas=new a.jqplot.BlockCanvas();this.canvas._plotDimensions=this._plotDimensions;this.shadowCanvas._plotDimensions=this._plotDimensions;this._type="block";this.moveBlock=function(l,j,i,e){var c=this.canvas._elem.children(":eq("+l+")");this.data[l][0]=j;this.data[l][1]=i;this._plotData[l][0]=j;this._plotData[l][1]=i;this._stackData[l][0]=j;this._stackData[l][1]=i;this.gridData[l][0]=this._xaxis.series_u2p(j);this.gridData[l][1]=this._yaxis.series_u2p(i);var k=c.outerWidth();var f=c.outerHeight();var d=this.gridData[l][0]-k/2+"px";var g=this.gridData[l][1]-f/2+"px";if(e){if(parseInt(e,10)){e=parseInt(e,10)}c.animate({left:d,top:g},e)}else{c.css({left:d,top:g})}c=null}};a.jqplot.BlockRenderer.prototype.draw=function(q,o,r){if(this.plugins.pointLabels){this.plugins.pointLabels.show=false}var f,c,l,o,p,k,n,g,e,m;var b=(r!=undefined)?r:{};var j=new a.jqplot.ColorGenerator(this.seriesColors);this.canvas._elem.empty();for(f=0;f<this.gridData.length;f++){l=this.data[f];o=this.gridData[f];p="";k={};if(typeof l[2]=="string"){p=l[2]}else{if(typeof l[2]=="object"){k=l[2]}}if(typeof l[3]=="object"){k=l[3]}if(this.insertBreaks){p=p.replace(/ /g,"<br />")}k=a.extend(true,{},this.css,k);c=a('<div style="position:absolute;margin-left:auto;margin-right:auto;"></div>');this.canvas._elem.append(c);this.escapeHtml?c.text(p):c.html(p);delete k.position;delete k.marginRight!
;delete k.marginLeft;if(!k.background&&!k.backgroundColor&&!k.backgroundImage){k.background=j.next()}c.css(k);n=c.outerWidth();g=c.outerHeight();e=o[0]-n/2+"px";m=o[1]-g/2+"px";c.css({left:e,top:m});c=null}};a.jqplot.BlockCanvas=function(){a.jqplot.ElemContainer.call(this);this._ctx};a.jqplot.BlockCanvas.prototype=new a.jqplot.ElemContainer();a.jqplot.BlockCanvas.prototype.constructor=a.jqplot.BlockCanvas;a.jqplot.BlockCanvas.prototype.createElement=function(i,e,c){this._offsets=i;var b="jqplot-blockCanvas";if(e!=undefined){b=e}var g;if(this._elem){g=this._elem.get(0)}else{g=document.createElement("div")}if(c!=undefined){this._plotDimensions=c}var d=this._plotDimensions.width-this._offsets.left-this._offsets.right+"px";var f=this._plotDimensions.height-this._offsets.top-this._offsets.bottom+"px";this._elem=a(g);this._elem.css({position:"absolute",width:d,height:f,left:this._offsets.left,top:this._offsets.top});this._elem.addClass(b);return this._elem};a.jqplot.BlockCanvas.prototype.setContext=function(){this._ctx={canvas:{width:0,height:0},clearRect:function(){return null}};return this._ctx}})(jQuery);
\ No newline at end of file
Modified: gnucash/trunk/src/report/jqplot/plugins/jqplot.bubbleRenderer.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.bubbleRenderer.js 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.bubbleRenderer.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -1,18 +1,31 @@
/**
- * Copyright (c) 2009 - 2010 Chris Leonello
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
- * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
- * The author would appreciate an email letting him know of any substantial
- * use of jqPlot. You can reach the author at: chris at jqplot dot com
- * or see http://www.jqplot.com/info.php . This is, of course,
- * not required.
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
- * Thanks for using jqPlot!
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
*
*/
(function($) {
@@ -131,6 +144,7 @@
// array of jQuery labels.
this.labels = [];
this.bubbleCanvases = [];
+ this._type = 'bubble';
// if user has passed in highlightMouseDown option and not set highlightMouseOver, disable highlightMouseOver
if (options.highlightMouseDown && options.highlightMouseOver == null) {
@@ -153,6 +167,7 @@
// adjust the series colors for options colors passed in with data or for alpha.
// note, this can leave undefined holes in the seriesColors array.
+ var comps;
for (var i=0; i<this.data.length; i++) {
var color = null;
var d = this.data[i];
@@ -296,7 +311,8 @@
var idx = this.radii[i][0];
var t=null;
var color = null;
- var el = tel = null;
+ var el = null;
+ var tel = null;
var d = this.data[idx];
var gd = this.gridData[idx];
if (d[3]) {
@@ -443,7 +459,7 @@
var x = ctx.canvas.width/2;
var y = ctx.canvas.height/2;
ctx.save();
- if (gradients && !$.browser.msie) {
+ if (gradients && !$.jqplot.use_excanvas) {
r = r*1.04;
var comps = $.jqplot.getColorComponents(color);
var colorinner = 'rgba('+Math.round(comps[0]+0.8*(255-comps[0]))+', '+Math.round(comps[1]+0.8*(255-comps[1]))+', '+Math.round(comps[2]+0.8*(255-comps[2]))+', '+comps[3]+')';
@@ -492,7 +508,16 @@
$.jqplot.BubbleAxisRenderer.prototype.init = function(options){
$.extend(true, this, options);
var db = this._dataBounds;
- var minsidx=minpidx=maxsids=maxpidx=maxr=minr=minMaxRadius=maxMaxRadius=maxMult=minMult=0;
+ var minsidx = 0,
+ minpidx = 0,
+ maxsidx = 0,
+ maxpidx = 0,
+ maxr = 0,
+ minr = 0,
+ minMaxRadius = 0,
+ maxMaxRadius = 0,
+ maxMult = 0,
+ minMult = 0;
// Go through all the series attached to this axis and find
// the min/max bounds for this axis.
for (var i=0; i<this._series.length; i++) {
@@ -607,6 +632,7 @@
plot.target.trigger(evt1, ins);
if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.bubbleRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) {
var evt = jQuery.Event('jqplotDataHighlight');
+ evt.which = ev.which;
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
plot.target.trigger(evt, ins);
@@ -625,6 +651,7 @@
var ins = [si, pi, neighbor.data, plot.series[si].gridData[pi][2]];
if (plot.series[ins[0]].highlightMouseDown && !(ins[0] == plot.plugins.bubbleRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) {
var evt = jQuery.Event('jqplotDataHighlight');
+ evt.which = ev.which;
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
plot.target.trigger(evt, ins);
@@ -649,6 +676,7 @@
var pi = neighbor.pointIndex;
var ins = [si, pi, neighbor.data, plot.series[si].gridData[pi][2]];
var evt = jQuery.Event('jqplotDataClick');
+ evt.which = ev.which;
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
plot.target.trigger(evt, ins);
@@ -665,6 +693,7 @@
unhighlight(plot);
}
var evt = jQuery.Event('jqplotDataRightClick');
+ evt.which = ev.which;
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
plot.target.trigger(evt, ins);
@@ -675,6 +704,12 @@
// create a canvas which we can draw on.
// insert it before the eventCanvas, so eventCanvas will still capture events.
function postPlotDraw() {
+ // Memory Leaks patch
+ if (this.plugins.bubbleRenderer && this.plugins.bubbleRenderer.highlightCanvas) {
+ this.plugins.bubbleRenderer.highlightCanvas.resetCanvas();
+ this.plugins.bubbleRenderer.highlightCanvas = null;
+ }
+
this.plugins.bubbleRenderer = {highlightedSeriesIndex:null};
this.plugins.bubbleRenderer.highlightCanvas = new $.jqplot.GenericCanvas();
this.plugins.bubbleRenderer.highlightLabel = null;
@@ -685,7 +720,7 @@
var height = this._plotDimensions.height - this._gridPadding.top - this._gridPadding.bottom;
this.plugins.bubbleRenderer.highlightLabelCanvas.css({top:top, left:left, width:width+'px', height:height+'px'});
- this.eventCanvas._elem.before(this.plugins.bubbleRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-bubbleRenderer-highlight-canvas', this._plotDimensions));
+ this.eventCanvas._elem.before(this.plugins.bubbleRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-bubbleRenderer-highlight-canvas', this._plotDimensions, this));
this.eventCanvas._elem.before(this.plugins.bubbleRenderer.highlightLabelCanvas);
var hctx = this.plugins.bubbleRenderer.highlightCanvas.setContext();
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.bubbleRenderer.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.bubbleRenderer.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.bubbleRenderer.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(f){var d=function(m){return Math.max.apply(Math,m)};var j=function(m){return Math.min.apply(Math,m)};f.jqplot.BubbleRenderer=function(){f.jqplot.LineRenderer.call(this)};f.jqplot.BubbleRenderer.prototype=new f.jqplot.LineRenderer();f.jqplot.BubbleRenderer.prototype.constructor=f.jqplot.BubbleRenderer;f.jqplot.BubbleRenderer.prototype.init=function(w,t){this.varyBubbleColors=true;this.autoscaleBubbles=true;this.autoscaleMultiplier=1;this.autoscalePointsFactor=-0.07;this.escapeHtml=true;this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColors=[];this.bubbleAlpha=1;this.highlightAlpha=null;this.bubbleGradients=false;this.showLabels=true;this.radii=[];this.maxRadius=0;this._highlightedPoint=null;this.labels=[];this.bubbleCanvases=[];this._type="bubble";if(w.highlightMouseDown&&w.highlightMouseOver==null){w.highlightMouseOver=false}f.extend(true,this,w);if(this.highlightAlpha==null){this.highlightAlpha=this.bubbleAlpha;if(this.bubbleGradients){this.highlightAlpha=0.35}}this.autoscaleMultiplier=this.autoscaleMultiplier*Math.pow(this.data.length,this.autoscalePointsFactor);this._highlightedPoint=null;var n;for(var r=0;r<this.data.length;r++){var p=null;var v=this.data[r];this.maxRadius=Math.max(this.maxRadius,v[2]);if(v[3]){if(typeof(v[3])=="object"){p=v[3]["color"]}}if(p==null){if(this.seriesColors[r]!=null){p=this.seriesColors[r]}}if(p&&this.bubbleAlpha<1){n=f.jqplot.getColorComponents(p);p="rgba("+n[0]+", "+n[1]+", "+n[2]+", "+this.bubbleAlpha+")"}if(p){this.seriesColors[r]=p}}if(!this.varyBubbleColors){this.seriesColors=[this.color]}this.colorGenerator=new f.jqplot.ColorGenerator(this.seriesColors);if(this.highlightColors.length==0){for(var r=0;r<this.seriesColors.length;r++){var o=f.jqplot.getColorComponents(this.seriesColors[r]);var u=[o[0],o[1],o[2]];var s=u[0]+u[1]+u[2];for(var q=0;q<3;q++){u[q]=(s>570)?u[q]*0.8:u[q]+0.3*(255-u[q]);u[q]=parseInt(u[q],10)}this.highlightColors.push("rgba("+u[0]+","+u[1]+","+u[2]+", "+this.highlightAlpha+")")}}this.highlightColorGenerat!
or=new f..jqplot.ColorGenerator(this.highlightColors);var m={fill:true,isarc:true,angle:this.shadowAngle,alpha:this.shadowAlpha,closePath:true};this.renderer.shadowRenderer.init(m);this.canvas=new f.jqplot.DivCanvas();this.canvas._plotDimensions=this._plotDimensions;t.eventListenerHooks.addOnce("jqplotMouseMove",a);t.eventListenerHooks.addOnce("jqplotMouseDown",b);t.eventListenerHooks.addOnce("jqplotMouseUp",k);t.eventListenerHooks.addOnce("jqplotClick",g);t.eventListenerHooks.addOnce("jqplotRightClick",l);t.postDrawHooks.addOnce(h)};f.jqplot.BubbleRenderer.prototype.setGridData=function(w){var q=this._xaxis.series_u2p;var m=this._yaxis.series_u2p;var t=this._plotData;this.gridData=[];var s=[];this.radii=[];var v=Math.min(w._height,w._width);for(var u=0;u<this.data.length;u++){if(t[u]!=null){this.gridData.push([q.call(this._xaxis,t[u][0]),m.call(this._yaxis,t[u][1]),t[u][2]]);this.radii.push([u,t[u][2]]);s.push(t[u][2])}}var n,o,x=this.maxRadius=d(s);var p=this.gridData.length;if(this.autoscaleBubbles){for(var u=0;u<p;u++){o=s[u]/x;n=this.autoscaleMultiplier*v/6;this.gridData[u][2]=n*o}}this.radii.sort(function(y,r){return r[1]-y[1]})};f.jqplot.BubbleRenderer.prototype.makeGridData=function(t,w){var q=this._xaxis.series_u2p;var n=this._yaxis.series_u2p;var x=[];var s=[];this.radii=[];var v=Math.min(w._height,w._width);for(var u=0;u<t.length;u++){if(t[u]!=null){x.push([q.call(this._xaxis,t[u][0]),n.call(this._yaxis,t[u][1]),t[u][2]]);s.push(t[u][2]);this.radii.push([u,t[u][2]])}}var m,o,y=this.maxRadius=d(s);var p=this.gridData.length;if(this.autoscaleBubbles){for(var u=0;u<p;u++){o=s[u]/y;m=this.autoscaleMultiplier*v/6;x[u][2]=m*o}}this.radii.sort(function(z,r){return r[1]-z[1]});return x};f.jqplot.BubbleRenderer.prototype.draw=function(D,J,n){if(this.plugins.pointLabels){this.plugins.pointLabels.show=false}var A=(n!=undefined)?n:{};var r=(A.shadow!=undefined)?A.shadow:this.shadow;this.canvas._elem.empty();for(var G=0;G<this.radii.length;G++){var C=this.radii[G][0];var z=null;var F=null;var m=null;var p=null;var !
I=this.data[C];var J=this.gridData[C];if(I[3]){if(typeof(I[3])=="object"){z=I[3]["label"]}else{if(typeof(I[3])=="string"){z=I[3]}}}F=this.colorGenerator.get(C);var E=J[2];var q,K;if(this.shadow){q=(0.7+J[2]/40).toFixed(1);K=1+Math.ceil(J[2]/15);E+=q*K}this.bubbleCanvases[C]=new f.jqplot.BubbleCanvas();this.canvas._elem.append(this.bubbleCanvases[C].createElement(J[0],J[1],E));this.bubbleCanvases[C].setContext();var D=this.bubbleCanvases[C]._ctx;var u=D.canvas.width/2;var s=D.canvas.height/2;if(this.shadow){this.renderer.shadowRenderer.draw(D,[u,s,J[2],0,2*Math.PI],{offset:q,depth:K})}this.bubbleCanvases[C].draw(J[2],F,this.bubbleGradients,this.shadowAngle/180*Math.PI);if(z&&this.showLabels){p=f('<div style="position:absolute;" class="jqplot-bubble-label"></div>');if(this.escapeHtml){p.text(z)}else{p.html(z)}this.canvas._elem.append(p);var H=f(p).outerHeight();var v=f(p).outerWidth();var B=J[1]-0.5*H;var o=J[0]-0.5*v;p.css({top:B,left:o});this.labels[C]=f(p)}}};f.jqplot.DivCanvas=function(){f.jqplot.ElemContainer.call(this);this._ctx};f.jqplot.DivCanvas.prototype=new f.jqplot.ElemContainer();f.jqplot.DivCanvas.prototype.constructor=f.jqplot.DivCanvas;f.jqplot.DivCanvas.prototype.createElement=function(s,p,n){this._offsets=s;var m="jqplot-DivCanvas";if(p!=undefined){m=p}var r;if(this._elem){r=this._elem.get(0)}else{r=document.createElement("div")}if(n!=undefined){this._plotDimensions=n}var o=this._plotDimensions.width-this._offsets.left-this._offsets.right+"px";var q=this._plotDimensions.height-this._offsets.top-this._offsets.bottom+"px";this._elem=f(r);this._elem.css({position:"absolute",width:o,height:q,left:this._offsets.left,top:this._offsets.top});this._elem.addClass(m);return this._elem};f.jqplot.DivCanvas.prototype.setContext=function(){this._ctx={canvas:{width:0,height:0},clearRect:function(){return null}};return this._ctx};f.jqplot.BubbleCanvas=function(){f.jqplot.ElemContainer.call(this);this._ctx};f.jqplot.BubbleCanvas.prototype=new f.jqplot.ElemContainer();f.jqplot.BubbleCanvas.prototype.constructor=f.!
jqplot.BubbleCanvas;f.jqplot.BubbleCanvas.prototype.createElement=function(n,u,s){var m="jqplot-bubble-point";var q;if(this._elem){q=this._elem.get(0)}else{q=document.createElement("canvas")}q.width=(s!=null)?2*s:q.width;q.height=(s!=null)?2*s:q.height;this._elem=f(q);var o=(n!=null&&s!=null)?n-s:this._elem.css("left");var p=(u!=null&&s!=null)?u-s:this._elem.css("top");this._elem.css({position:"absolute",left:o,top:p});this._elem.addClass(m);if(f.jqplot.use_excanvas){window.G_vmlCanvasManager.init_(document);q=window.G_vmlCanvasManager.initElement(q)}return this._elem};f.jqplot.BubbleCanvas.prototype.draw=function(m,s,v,p){var D=this._ctx;var B=D.canvas.width/2;var z=D.canvas.height/2;D.save();if(v&&!f.jqplot.use_excanvas){m=m*1.04;var o=f.jqplot.getColorComponents(s);var u="rgba("+Math.round(o[0]+0.8*(255-o[0]))+", "+Math.round(o[1]+0.8*(255-o[1]))+", "+Math.round(o[2]+0.8*(255-o[2]))+", "+o[3]+")";var t="rgba("+o[0]+", "+o[1]+", "+o[2]+", 0)";var C=0.35*m;var A=B-Math.cos(p)*0.33*m;var n=z-Math.sin(p)*0.33*m;var w=D.createRadialGradient(A,n,C,B,z,m);w.addColorStop(0,u);w.addColorStop(0.93,s);w.addColorStop(0.96,t);w.addColorStop(1,t);D.fillStyle=w;D.fillRect(0,0,D.canvas.width,D.canvas.height)}else{D.fillStyle=s;D.strokeStyle=s;D.lineWidth=1;D.beginPath();var q=2*Math.PI;D.arc(B,z,m,0,q,0);D.closePath();D.fill()}D.restore()};f.jqplot.BubbleCanvas.prototype.setContext=function(){this._ctx=this._elem.get(0).getContext("2d");return this._ctx};f.jqplot.BubbleAxisRenderer=function(){f.jqplot.LinearAxisRenderer.call(this)};f.jqplot.BubbleAxisRenderer.prototype=new f.jqplot.LinearAxisRenderer();f.jqplot.BubbleAxisRenderer.prototype.constructor=f.jqplot.BubbleAxisRenderer;f.jqplot.BubbleAxisRenderer.prototype.init=function(n){f.extend(true,this,n);var I=this._dataBounds;var H=0,v=0,m=0,y=0,q=0,r=0,D=0,t=0,F=0,z=0;for(var E=0;E<this._series.length;E++){var x=this._series[E];var G=x._plotData;for(var B=0;B<G.length;B++){if(this.name=="xaxis"||this.name=="x2axis"){if(G[B][0]<I.min||I.min==null){I.min=G[B][0];H=E;v=B;r=G[!
B][2];D=x.maxRadius;z=x.autoscaleMultiplier}if(G[B][0]>I.max||I.max==null){I.max=G[B][0];m=E;y=B;q=G[B][2];t=x.maxRadius;F=x.autoscaleMultiplier}}else{if(G[B][1]<I.min||I.min==null){I.min=G[B][1];H=E;v=B;r=G[B][2];D=x.maxRadius;z=x.autoscaleMultiplier}if(G[B][1]>I.max||I.max==null){I.max=G[B][1];m=E;y=B;q=G[B][2];t=x.maxRadius;F=x.autoscaleMultiplier}}}}var o=r/D;var w=q/t;var C=I.max-I.min;var A=Math.min(this._plotDimensions.width,this._plotDimensions.height);var p=o*z/3*C;var u=w*F/3*C;I.max+=u;I.min-=p};function e(p,v,q){p.plugins.bubbleRenderer.highlightLabelCanvas.empty();var z=p.series[v];var n=p.plugins.bubbleRenderer.highlightCanvas;var w=n._ctx;w.clearRect(0,0,w.canvas.width,w.canvas.height);z._highlightedPoint=q;p.plugins.bubbleRenderer.highlightedSeriesIndex=v;var o=z.highlightColorGenerator.get(q);var u=z.gridData[q][0],t=z.gridData[q][1],m=z.gridData[q][2];w.save();w.fillStyle=o;w.strokeStyle=o;w.lineWidth=1;w.beginPath();w.arc(u,t,m,0,2*Math.PI,0);w.closePath();w.fill();w.restore();if(z.labels[q]){p.plugins.bubbleRenderer.highlightLabel=z.labels[q].clone();p.plugins.bubbleRenderer.highlightLabel.appendTo(p.plugins.bubbleRenderer.highlightLabelCanvas);p.plugins.bubbleRenderer.highlightLabel.addClass("jqplot-bubble-label-highlight")}}function i(p){var m=p.plugins.bubbleRenderer.highlightCanvas;var o=p.plugins.bubbleRenderer.highlightedSeriesIndex;p.plugins.bubbleRenderer.highlightLabelCanvas.empty();m._ctx.clearRect(0,0,m._ctx.canvas.width,m._ctx.canvas.height);for(var n=0;n<p.series.length;n++){p.series[n]._highlightedPoint=null}p.plugins.bubbleRenderer.highlightedSeriesIndex=null;p.target.trigger("jqplotDataUnhighlight")}function a(s,p,m,v,r){if(v){var n=v.seriesIndex;var o=v.pointIndex;var q=[n,o,v.data,r.series[n].gridData[o][2]];var t=jQuery.Event("jqplotDataMouseOver");t.pageX=s.pageX;t.pageY=s.pageY;r.target.trigger(t,q);if(r.series[q[0]].highlightMouseOver&&!(q[0]==r.plugins.bubbleRenderer.highlightedSeriesIndex&&q[1]==r.series[q[0]]._highlightedPoint)){var u=jQuery.Event("jqplotDataHighlight!
");u.which=s.which;u.pageX=s.pageX;u.pageY=s.pageY;r.target.trigger(u,q);e(r,q[0],q[1])}}else{if(v==null){i(r)}}}function b(s,p,m,u,r){if(u){var n=u.seriesIndex;var o=u.pointIndex;var q=[n,o,u.data,r.series[n].gridData[o][2]];if(r.series[q[0]].highlightMouseDown&&!(q[0]==r.plugins.bubbleRenderer.highlightedSeriesIndex&&q[1]==r.series[q[0]]._highlightedPoint)){var t=jQuery.Event("jqplotDataHighlight");t.which=s.which;t.pageX=s.pageX;t.pageY=s.pageY;r.target.trigger(t,q);e(r,q[0],q[1])}}else{if(u==null){i(r)}}}function k(o,n,r,q,p){var m=p.plugins.bubbleRenderer.highlightedSeriesIndex;if(m!=null&&p.series[m].highlightMouseDown){i(p)}}function g(s,p,m,u,r){if(u){var n=u.seriesIndex;var o=u.pointIndex;var q=[n,o,u.data,r.series[n].gridData[o][2]];var t=jQuery.Event("jqplotDataClick");t.which=s.which;t.pageX=s.pageX;t.pageY=s.pageY;r.target.trigger(t,q)}}function l(s,p,m,v,r){if(v){var n=v.seriesIndex;var o=v.pointIndex;var q=[n,o,v.data,r.series[n].gridData[o][2]];var t=r.plugins.bubbleRenderer.highlightedSeriesIndex;if(t!=null&&r.series[t].highlightMouseDown){i(r)}var u=jQuery.Event("jqplotDataRightClick");u.which=s.which;u.pageX=s.pageX;u.pageY=s.pageY;r.target.trigger(u,q)}}function h(){if(this.plugins.bubbleRenderer&&this.plugins.bubbleRenderer.highlightCanvas){this.plugins.bubbleRenderer.highlightCanvas.resetCanvas();this.plugins.bubbleRenderer.highlightCanvas=null}this.plugins.bubbleRenderer={highlightedSeriesIndex:null};this.plugins.bubbleRenderer.highlightCanvas=new f.jqplot.GenericCanvas();this.plugins.bubbleRenderer.highlightLabel=null;this.plugins.bubbleRenderer.highlightLabelCanvas=f('<div style="position:absolute;"></div>');var q=this._gridPadding.top;var p=this._gridPadding.left;var n=this._plotDimensions.width-this._gridPadding.left-this._gridPadding.right;var m=this._plotDimensions.height-this._gridPadding.top-this._gridPadding.bottom;this.plugins.bubbleRenderer.highlightLabelCanvas.css({top:q,left:p,width:n+"px",height:m+"px"});this.eventCanvas._elem.before(this.plugins.bubbleRenderer.highlightCanva!
s.createElement(this._gridPadding,"jqplot-bubbleRenderer-highlight-canvas",this._plotDimensions,this));this.eventCanvas._elem.before(this.plugins.bubbleRenderer.highlightLabelCanvas);var o=this.plugins.bubbleRenderer.highlightCanvas.setContext()}function c(q,p,n){n=n||{};n.axesDefaults=n.axesDefaults||{};n.seriesDefaults=n.seriesDefaults||{};var m=false;if(n.seriesDefaults.renderer==f.jqplot.BubbleRenderer){m=true}else{if(n.series){for(var o=0;o<n.series.length;o++){if(n.series[o].renderer==f.jqplot.BubbleRenderer){m=true}}}}if(m){n.axesDefaults.renderer=f.jqplot.BubbleAxisRenderer;n.sortData=false}}f.jqplot.preInitHooks.push(c)})(jQuery);
\ No newline at end of file
Modified: gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasAxisLabelRenderer.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasAxisLabelRenderer.js 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasAxisLabelRenderer.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -1,18 +1,31 @@
/**
- * Copyright (c) 2009 - 2010 Chris Leonello
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
- * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
- * The author would appreciate an email letting him know of any substantial
- * use of jqPlot. You can reach the author at: chris at jqplot dot com
- * or see http://www.jqplot.com/info.php . This is, of course,
- * not required.
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
- * Thanks for using jqPlot!
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
*
*/
(function($) {
@@ -97,12 +110,7 @@
}
if (this.enableFontSupport) {
-
- function support_canvas_text() {
- return !!(document.createElement('canvas').getContext && typeof document.createElement('canvas').getContext('2d').fillText == 'function');
- }
-
- if (support_canvas_text()) {
+ if ($.jqplot.support_canvas_text()) {
this._textRenderer = new $.jqplot.CanvasFontRenderer(ropts);
}
@@ -155,33 +163,41 @@
return a;
};
- $.jqplot.CanvasAxisLabelRenderer.prototype.draw = function(ctx) {
+ $.jqplot.CanvasAxisLabelRenderer.prototype.draw = function(ctx, plot) {
+ // Memory Leaks patch
+ if (this._elem) {
+ if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) {
+ window.G_vmlCanvasManager.uninitElement(this._elem.get(0));
+ }
+
+ this._elem.emptyForce();
+ this._elem = null;
+ }
+
// create a canvas here, but can't draw on it untill it is appended
// to dom for IE compatability.
- var domelem = document.createElement('canvas');
+ var elem = plot.canvasManager.getCanvas();
+
this._textRenderer.setText(this.label, ctx);
var w = this.getWidth(ctx);
var h = this.getHeight(ctx);
- domelem.width = w;
- domelem.height = h;
- domelem.style.width = w;
- domelem.style.height = h;
- // domelem.style.textAlign = 'center';
- domelem.style.position = 'absolute';
- this._domelem = domelem;
- this._elem = $(domelem);
+ elem.width = w;
+ elem.height = h;
+ elem.style.width = w;
+ elem.style.height = h;
+
+ elem = plot.canvasManager.initCanvas(elem);
+
+ this._elem = $(elem);
+ this._elem.css({ position: 'absolute'});
this._elem.addClass('jqplot-'+this.axis+'-label');
+ elem = null;
return this._elem;
};
$.jqplot.CanvasAxisLabelRenderer.prototype.pack = function() {
- if ($.jqplot.use_excanvas) {
- window.G_vmlCanvasManager.init_(document);
- this._domelem = window.G_vmlCanvasManager.initElement(this._domelem);
- }
- var ctx = this._elem.get(0).getContext("2d");
- this._textRenderer.draw(ctx, this.label);
+ this._textRenderer.draw(this._elem.get(0).getContext("2d"), this.label);
};
})(jQuery);
\ No newline at end of file
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasAxisLabelRenderer.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasAxisLabelRenderer.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasAxisLabelRenderer.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(a){a.jqplot.CanvasAxisLabelRenderer=function(b){this.angle=0;this.axis;this.show=true;this.showLabel=true;this.label="";this.fontFamily='"Trebuchet MS", Arial, Helvetica, sans-serif';this.fontSize="11pt";this.fontWeight="normal";this.fontStretch=1;this.textColor="#666666";this.enableFontSupport=true;this.pt2px=null;this._elem;this._ctx;this._plotWidth;this._plotHeight;this._plotDimensions={height:null,width:null};a.extend(true,this,b);if(b.angle==null&&this.axis!="xaxis"&&this.axis!="x2axis"){this.angle=-90}var c={fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily};if(this.pt2px){c.pt2px=this.pt2px}if(this.enableFontSupport){if(a.jqplot.support_canvas_text()){this._textRenderer=new a.jqplot.CanvasFontRenderer(c)}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(c)}}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(c)}};a.jqplot.CanvasAxisLabelRenderer.prototype.init=function(b){a.extend(true,this,b);this._textRenderer.init({fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily})};a.jqplot.CanvasAxisLabelRenderer.prototype.getWidth=function(d){if(this._elem){return this._elem.outerWidth(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.sin(f.angle)*e)+Math.abs(Math.cos(f.angle)*c);return b}};a.jqplot.CanvasAxisLabelRenderer.prototype.getHeight=function(d){if(this._elem){return this._elem.outerHeight(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.cos(f.angle)*e)+Math.abs(Math.sin(f.angle)*c);return b}};a.jqplot.CanvasAxisLabelRenderer.prototype.getAngleRad=function(){var b=this.angle*Math.PI/180;return b};a.jqplot.CanvasAxisLabelRenderer.prototype.draw=function(c,f){if(this._elem){if(a.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==undefined){window.G_vmlCanvasManage!
r.uninitElement(this._elem.get(0))}this._elem.emptyForce();this._elem=null}var e=f.canvasManager.getCanvas();this._textRenderer.setText(this.label,c);var b=this.getWidth(c);var d=this.getHeight(c);e.width=b;e.height=d;e.style.width=b;e.style.height=d;e=f.canvasManager.initCanvas(e);this._elem=a(e);this._elem.css({position:"absolute"});this._elem.addClass("jqplot-"+this.axis+"-label");e=null;return this._elem};a.jqplot.CanvasAxisLabelRenderer.prototype.pack=function(){this._textRenderer.draw(this._elem.get(0).getContext("2d"),this.label)}})(jQuery);
\ No newline at end of file
Modified: gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasAxisTickRenderer.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasAxisTickRenderer.js 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasAxisTickRenderer.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -1,18 +1,31 @@
/**
- * Copyright (c) 2009 - 2010 Chris Leonello
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
- * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
- * The author would appreciate an email letting him know of any substantial
- * use of jqPlot. You can reach the author at: chris at jqplot dot com
- * or see http://www.jqplot.com/info.php . This is, of course,
- * not required.
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
- * Thanks for using jqPlot!
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
*
*/
(function($) {
@@ -73,7 +86,8 @@
// string passed to the formatter.
this.formatString = '';
// prop: prefix
- // string appended to the tick label if no formatString is specified.
+ // String to prepend to the tick label.
+ // Prefix is prepended to the formatted tick label.
this.prefix = '';
// prop: fontFamily
// css spec for the font-family css attribute.
@@ -119,12 +133,7 @@
}
if (this.enableFontSupport) {
-
- function support_canvas_text() {
- return !!(document.createElement('canvas').getContext && typeof document.createElement('canvas').getContext('2d').fillText == 'function');
- }
-
- if (support_canvas_text()) {
+ if ($.jqplot.support_canvas_text()) {
this._textRenderer = new $.jqplot.CanvasFontRenderer(ropts);
}
@@ -186,41 +195,49 @@
return this;
};
- $.jqplot.CanvasAxisTickRenderer.prototype.draw = function(ctx) {
+ $.jqplot.CanvasAxisTickRenderer.prototype.draw = function(ctx, plot) {
if (!this.label) {
- this.label = this.formatter(this.formatString, this.value);
+ this.label = this.prefix + this.formatter(this.formatString, this.value);
}
- // add prefix if needed
- if (this.prefix && !this.formatString) {
- this.label = this.prefix + this.label;
+
+ // Memory Leaks patch
+ if (this._elem) {
+ if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) {
+ window.G_vmlCanvasManager.uninitElement(this._elem.get(0));
+ }
+
+ this._elem.emptyForce();
+ this._elem = null;
}
+
// create a canvas here, but can't draw on it untill it is appended
// to dom for IE compatability.
- var domelem = document.createElement('canvas');
+
+ var elem = plot.canvasManager.getCanvas();
+
this._textRenderer.setText(this.label, ctx);
var w = this.getWidth(ctx);
var h = this.getHeight(ctx);
- domelem.width = w;
- domelem.height = h;
- domelem.style.width = w;
- domelem.style.height = h;
- domelem.style.textAlign = 'left';
- domelem.style.position = 'absolute';
- this._domelem = domelem;
- this._elem = $(domelem);
+ // canvases seem to need to have width and heigh attributes directly set.
+ elem.width = w;
+ elem.height = h;
+ elem.style.width = w;
+ elem.style.height = h;
+ elem.style.textAlign = 'left';
+ elem.style.position = 'absolute';
+
+ elem = plot.canvasManager.initCanvas(elem);
+
+ this._elem = $(elem);
this._elem.css(this._styles);
this._elem.addClass('jqplot-'+this.axis+'-tick');
-
+
+ elem = null;
return this._elem;
};
$.jqplot.CanvasAxisTickRenderer.prototype.pack = function() {
- if ($.jqplot.use_excanvas) {
- window.G_vmlCanvasManager.init_(document);
- this._domelem = window.G_vmlCanvasManager.initElement(this._domelem);
- }
- var ctx = this._elem.get(0).getContext("2d");
- this._textRenderer.draw(ctx, this.label);
+ this._textRenderer.draw(this._elem.get(0).getContext("2d"), this.label);
};
})(jQuery);
\ No newline at end of file
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasAxisTickRenderer.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasAxisTickRenderer.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasAxisTickRenderer.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(a){a.jqplot.CanvasAxisTickRenderer=function(b){this.mark="outside";this.showMark=true;this.showGridline=true;this.isMinorTick=false;this.angle=0;this.markSize=4;this.show=true;this.showLabel=true;this.labelPosition="auto";this.label="";this.value=null;this._styles={};this.formatter=a.jqplot.DefaultTickFormatter;this.formatString="";this.prefix="";this.fontFamily='"Trebuchet MS", Arial, Helvetica, sans-serif';this.fontSize="10pt";this.fontWeight="normal";this.fontStretch=1;this.textColor="#666666";this.enableFontSupport=true;this.pt2px=null;this._elem;this._ctx;this._plotWidth;this._plotHeight;this._plotDimensions={height:null,width:null};a.extend(true,this,b);var c={fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily};if(this.pt2px){c.pt2px=this.pt2px}if(this.enableFontSupport){if(a.jqplot.support_canvas_text()){this._textRenderer=new a.jqplot.CanvasFontRenderer(c)}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(c)}}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(c)}};a.jqplot.CanvasAxisTickRenderer.prototype.init=function(b){a.extend(true,this,b);this._textRenderer.init({fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily})};a.jqplot.CanvasAxisTickRenderer.prototype.getWidth=function(d){if(this._elem){return this._elem.outerWidth(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.sin(f.angle)*e)+Math.abs(Math.cos(f.angle)*c);return b}};a.jqplot.CanvasAxisTickRenderer.prototype.getHeight=function(d){if(this._elem){return this._elem.outerHeight(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.cos(f.angle)*e)+Math.abs(Math.sin(f.angle)*c);return b}};a.jqplot.CanvasAxisTickRenderer.prototype.getAngleRad=function(){var b=this.angle*Math.PI/180;return b};a.jqplot.CanvasAxisTickRender!
er.prototype.setTick=function(b,d,c){this.value=b;if(c){this.isMinorTick=true}return this};a.jqplot.CanvasAxisTickRenderer.prototype.draw=function(c,f){if(!this.label){this.label=this.prefix+this.formatter(this.formatString,this.value)}if(this._elem){if(a.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==undefined){window.G_vmlCanvasManager.uninitElement(this._elem.get(0))}this._elem.emptyForce();this._elem=null}var e=f.canvasManager.getCanvas();this._textRenderer.setText(this.label,c);var b=this.getWidth(c);var d=this.getHeight(c);e.width=b;e.height=d;e.style.width=b;e.style.height=d;e.style.textAlign="left";e.style.position="absolute";e=f.canvasManager.initCanvas(e);this._elem=a(e);this._elem.css(this._styles);this._elem.addClass("jqplot-"+this.axis+"-tick");e=null;return this._elem};a.jqplot.CanvasAxisTickRenderer.prototype.pack=function(){this._textRenderer.draw(this._elem.get(0).getContext("2d"),this.label)}})(jQuery);
\ No newline at end of file
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasOverlay.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasOverlay.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasOverlay.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,865 @@
+/**
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
+ * jqPlot is currently available for use in all personal or commercial projects
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
+ * choose the license that best suits your project and use it accordingly.
+ *
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
+ *
+ * If you are feeling kind and generous, consider supporting the project by
+ * making a donation at: http://www.jqplot.com/donate.php .
+ *
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
+ *
+ */
+(function($) {
+ var objCounter = 0;
+ // class: $.jqplot.CanvasOverlay
+ $.jqplot.CanvasOverlay = function(opts){
+ var options = opts || {};
+ this.options = {
+ show: $.jqplot.config.enablePlugins,
+ deferDraw: false
+ };
+ // prop: objects
+ this.objects = [];
+ this.objectNames = [];
+ this.canvas = null;
+ this.markerRenderer = new $.jqplot.MarkerRenderer({style:'line'});
+ this.markerRenderer.init();
+ this.highlightObjectIndex = null;
+ if (options.objects) {
+ var objs = options.objects,
+ obj;
+ for (var i=0; i<objs.length; i++) {
+ obj = objs[i];
+ for (var n in obj) {
+ switch (n) {
+ case 'line':
+ this.addLine(obj[n]);
+ break;
+ case 'horizontalLine':
+ this.addHorizontalLine(obj[n]);
+ break;
+ case 'dashedHorizontalLine':
+ this.addDashedHorizontalLine(obj[n]);
+ break;
+ case 'verticalLine':
+ this.addVerticalLine(obj[n]);
+ break;
+ case 'dashedVerticalLine':
+ this.addDashedVerticalLine(obj[n]);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ $.extend(true, this.options, options);
+ };
+
+ // called with scope of a plot object
+ $.jqplot.CanvasOverlay.postPlotInit = function (target, data, opts) {
+ var options = opts || {};
+ // add a canvasOverlay attribute to the plot
+ this.plugins.canvasOverlay = new $.jqplot.CanvasOverlay(options.canvasOverlay);
+ };
+
+
+ function LineBase() {
+ this.uid = null;
+ this.type = null;
+ this.gridStart = null;
+ this.gridStop = null;
+ this.tooltipWidthFactor = 0;
+ this.options = {
+ // prop: name
+ // Optional name for the overlay object.
+ // Can be later used to retrieve the object by name.
+ name: null,
+ // prop: show
+ // true to show (draw), false to not draw.
+ show: true,
+ // prop: lineWidth
+ // Width of the line.
+ lineWidth: 2,
+ // prop: lineCap
+ // Type of ending placed on the line ['round', 'butt', 'square']
+ lineCap: 'round',
+ // prop: color
+ // color of the line
+ color: '#666666',
+ // prop: shadow
+ // wether or not to draw a shadow on the line
+ shadow: true,
+ // prop: shadowAngle
+ // Shadow angle in degrees
+ shadowAngle: 45,
+ // prop: shadowOffset
+ // Shadow offset from line in pixels
+ shadowOffset: 1,
+ // prop: shadowDepth
+ // Number of times shadow is stroked, each stroke offset shadowOffset from the last.
+ shadowDepth: 3,
+ // prop: shadowAlpha
+ // Alpha channel transparency of shadow. 0 = transparent.
+ shadowAlpha: '0.07',
+ // prop: xaxis
+ // X axis to use for positioning/scaling the line.
+ xaxis: 'xaxis',
+ // prop: yaxis
+ // Y axis to use for positioning/scaling the line.
+ yaxis: 'yaxis',
+ // prop: showTooltip
+ // Show a tooltip with data point values.
+ showTooltip: false,
+ // prop: showTooltipPrecision
+ // Controls how close to line cursor must be to show tooltip.
+ // Higher number = closer to line, lower number = farther from line.
+ // 1.0 = cursor must be over line.
+ showTooltipPrecision: 0.6,
+ // prop: tooltipLocation
+ // Where to position tooltip, 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw'
+ tooltipLocation: 'nw',
+ // prop: fadeTooltip
+ // true = fade in/out tooltip, flase = show/hide tooltip
+ fadeTooltip: true,
+ // prop: tooltipFadeSpeed
+ // 'slow', 'def', 'fast', or number of milliseconds.
+ tooltipFadeSpeed: "fast",
+ // prop: tooltipOffset
+ // Pixel offset of tooltip from the highlight.
+ tooltipOffset: 4,
+ // prop: tooltipFormatString
+ // Format string passed the x and y values of the cursor on the line.
+ // e.g., 'Dogs: %.2f, Cats: %d'.
+ tooltipFormatString: '%d, %d'
+ };
+ }
+
+ /**
+ * Class: Line
+ * A straight line.
+ */
+ function Line(options) {
+ LineBase.call(this);
+ this.type = 'line';
+ var opts = {
+ // prop: start
+ // [x, y] coordinates for the start of the line.
+ start: [],
+ // prop: stop
+ // [x, y] coordinates for the end of the line.
+ stop: []
+ };
+ $.extend(true, this.options, opts, options);
+
+ if (this.options.showTooltipPrecision < 0.01) {
+ this.options.showTooltipPrecision = 0.01;
+ }
+ }
+
+ Line.prototype = new LineBase();
+ Line.prototype.constructor = Line;
+
+
+ /**
+ * Class: HorizontalLine
+ * A straight horizontal line.
+ */
+ function HorizontalLine(options) {
+ LineBase.call(this);
+ this.type = 'horizontalLine';
+ var opts = {
+ // prop: y
+ // y value to position the line
+ y: null,
+ // prop: xmin
+ // x value for the start of the line, null to scale to axis min.
+ xmin: null,
+ // prop: xmax
+ // x value for the end of the line, null to scale to axis max.
+ xmax: null,
+ // prop xOffset
+ // offset ends of the line inside the grid. Number
+ xOffset: '6px', // number or string. Number interpreted as units, string as pixels.
+ xminOffset: null,
+ xmaxOffset: null
+ };
+ $.extend(true, this.options, opts, options);
+
+ if (this.options.showTooltipPrecision < 0.01) {
+ this.options.showTooltipPrecision = 0.01;
+ }
+ }
+
+ HorizontalLine.prototype = new LineBase();
+ HorizontalLine.prototype.constructor = HorizontalLine;
+
+
+ /**
+ * Class: DashedHorizontalLine
+ * A straight dashed horizontal line.
+ */
+ function DashedHorizontalLine(options) {
+ LineBase.call(this);
+ this.type = 'dashedHorizontalLine';
+ var opts = {
+ y: null,
+ xmin: null,
+ xmax: null,
+ xOffset: '6px', // number or string. Number interpreted as units, string as pixels.
+ xminOffset: null,
+ xmaxOffset: null,
+ // prop: dashPattern
+ // Array of line, space settings in pixels.
+ // Default is 8 pixel of line, 8 pixel of space.
+ // Note, limit to a 2 element array b/c of bug with higher order arrays.
+ dashPattern: [8,8]
+ };
+ $.extend(true, this.options, opts, options);
+
+ if (this.options.showTooltipPrecision < 0.01) {
+ this.options.showTooltipPrecision = 0.01;
+ }
+ }
+
+ DashedHorizontalLine.prototype = new LineBase();
+ DashedHorizontalLine.prototype.constructor = DashedHorizontalLine;
+
+
+ /**
+ * Class: VerticalLine
+ * A straight vertical line.
+ */
+ function VerticalLine(options) {
+ LineBase.call(this);
+ this.type = 'verticalLine';
+ var opts = {
+ x: null,
+ ymin: null,
+ ymax: null,
+ yOffset: '6px', // number or string. Number interpreted as units, string as pixels.
+ yminOffset: null,
+ ymaxOffset: null
+ };
+ $.extend(true, this.options, opts, options);
+
+ if (this.options.showTooltipPrecision < 0.01) {
+ this.options.showTooltipPrecision = 0.01;
+ }
+ }
+
+ VerticalLine.prototype = new LineBase();
+ VerticalLine.prototype.constructor = VerticalLine;
+
+
+ /**
+ * Class: DashedVerticalLine
+ * A straight dashed vertical line.
+ */
+ function DashedVerticalLine(options) {
+ LineBase.call(this);
+ this.type = 'dashedVerticalLine';
+ this.start = null;
+ this.stop = null;
+ var opts = {
+ x: null,
+ ymin: null,
+ ymax: null,
+ yOffset: '6px', // number or string. Number interpreted as units, string as pixels.
+ yminOffset: null,
+ ymaxOffset: null,
+ // prop: dashPattern
+ // Array of line, space settings in pixels.
+ // Default is 8 pixel of line, 8 pixel of space.
+ // Note, limit to a 2 element array b/c of bug with higher order arrays.
+ dashPattern: [8,8]
+ };
+ $.extend(true, this.options, opts, options);
+
+ if (this.options.showTooltipPrecision < 0.01) {
+ this.options.showTooltipPrecision = 0.01;
+ }
+ }
+
+ DashedVerticalLine.prototype = new LineBase();
+ DashedVerticalLine.prototype.constructor = DashedVerticalLine;
+
+ $.jqplot.CanvasOverlay.prototype.addLine = function(opts) {
+ var line = new Line(opts);
+ line.uid = objCounter++;
+ this.objects.push(line);
+ this.objectNames.push(line.options.name);
+ };
+
+ $.jqplot.CanvasOverlay.prototype.addHorizontalLine = function(opts) {
+ var line = new HorizontalLine(opts);
+ line.uid = objCounter++;
+ this.objects.push(line);
+ this.objectNames.push(line.options.name);
+ };
+
+ $.jqplot.CanvasOverlay.prototype.addDashedHorizontalLine = function(opts) {
+ var line = new DashedHorizontalLine(opts);
+ line.uid = objCounter++;
+ this.objects.push(line);
+ this.objectNames.push(line.options.name);
+ };
+
+ $.jqplot.CanvasOverlay.prototype.addVerticalLine = function(opts) {
+ var line = new VerticalLine(opts);
+ line.uid = objCounter++;
+ this.objects.push(line);
+ this.objectNames.push(line.options.name);
+ };
+
+ $.jqplot.CanvasOverlay.prototype.addDashedVerticalLine = function(opts) {
+ var line = new DashedVerticalLine(opts);
+ line.uid = objCounter++;
+ this.objects.push(line);
+ this.objectNames.push(line.options.name);
+ };
+
+ $.jqplot.CanvasOverlay.prototype.removeObject = function(idx) {
+ // check if integer, remove by index
+ if ($.type(idx) == 'number') {
+ this.objects.splice(idx, 1);
+ this.objectNames.splice(idx, 1);
+ }
+ // if string, remove by name
+ else {
+ var id = $.inArray(idx, this.objectNames);
+ if (id != -1) {
+ this.objects.splice(id, 1);
+ this.objectNames.splice(id, 1);
+ }
+ }
+ };
+
+ $.jqplot.CanvasOverlay.prototype.getObject = function(idx) {
+ // check if integer, remove by index
+ if ($.type(idx) == 'number') {
+ return this.objects[idx];
+ }
+ // if string, remove by name
+ else {
+ var id = $.inArray(idx, this.objectNames);
+ if (id != -1) {
+ return this.objects[id];
+ }
+ }
+ };
+
+ // Set get as alias for getObject.
+ $.jqplot.CanvasOverlay.prototype.get = $.jqplot.CanvasOverlay.prototype.getObject;
+
+ $.jqplot.CanvasOverlay.prototype.clear = function(plot) {
+ this.canvas._ctx.clearRect(0,0,this.canvas.getWidth(), this.canvas.getHeight());
+ };
+
+ $.jqplot.CanvasOverlay.prototype.draw = function(plot) {
+ var obj,
+ objs = this.objects,
+ mr = this.markerRenderer,
+ start,
+ stop;
+ if (this.options.show) {
+ this.canvas._ctx.clearRect(0,0,this.canvas.getWidth(), this.canvas.getHeight());
+ for (var k=0; k<objs.length; k++) {
+ obj = objs[k];
+ var opts = $.extend(true, {}, obj.options);
+ if (obj.options.show) {
+ // style and shadow properties should be set before
+ // every draw of marker renderer.
+ mr.shadow = obj.options.shadow;
+ obj.tooltipWidthFactor = obj.options.lineWidth / obj.options.showTooltipPrecision;
+ switch (obj.type) {
+ case 'line':
+ // style and shadow properties should be set before
+ // every draw of marker renderer.
+ mr.style = 'line';
+ opts.closePath = false;
+ start = [plot.axes[obj.options.xaxis].series_u2p(obj.options.start[0]), plot.axes[obj.options.yaxis].series_u2p(obj.options.start[1])];
+ stop = [plot.axes[obj.options.xaxis].series_u2p(obj.options.stop[0]), plot.axes[obj.options.yaxis].series_u2p(obj.options.stop[1])];
+ obj.gridStart = start;
+ obj.gridStop = stop;
+ mr.draw(start, stop, this.canvas._ctx, opts);
+ break;
+ case 'horizontalLine':
+
+ // style and shadow properties should be set before
+ // every draw of marker renderer.
+ if (obj.options.y != null) {
+ mr.style = 'line';
+ opts.closePath = false;
+ var xaxis = plot.axes[obj.options.xaxis],
+ xstart,
+ xstop,
+ y = plot.axes[obj.options.yaxis].series_u2p(obj.options.y),
+ xminoff = obj.options.xminOffset || obj.options.xOffset,
+ xmaxoff = obj.options.xmaxOffset || obj.options.xOffset;
+ if (obj.options.xmin != null) {
+ xstart = xaxis.series_u2p(obj.options.xmin);
+ }
+ else if (xminoff != null) {
+ if ($.type(xminoff) == "number") {
+ xstart = xaxis.series_u2p(xaxis.min + xminoff);
+ }
+ else if ($.type(xminoff) == "string") {
+ xstart = xaxis.series_u2p(xaxis.min) + parseFloat(xminoff);
+ }
+ }
+ if (obj.options.xmax != null) {
+ xstop = xaxis.series_u2p(obj.options.xmax);
+ }
+ else if (xmaxoff != null) {
+ if ($.type(xmaxoff) == "number") {
+ xstop = xaxis.series_u2p(xaxis.max - xmaxoff);
+ }
+ else if ($.type(xmaxoff) == "string") {
+ xstop = xaxis.series_u2p(xaxis.max) - parseFloat(xmaxoff);
+ }
+ }
+ if (xstop != null && xstart != null) {
+ obj.gridStart = [xstart, y];
+ obj.gridStop = [xstop, y];
+ mr.draw([xstart, y], [xstop, y], this.canvas._ctx, opts);
+ }
+ }
+ break;
+
+ case 'dashedHorizontalLine':
+
+ var dashPat = obj.options.dashPattern;
+ var dashPatLen = 0;
+ for (var i=0; i<dashPat.length; i++) {
+ dashPatLen += dashPat[i];
+ }
+
+ // style and shadow properties should be set before
+ // every draw of marker renderer.
+ if (obj.options.y != null) {
+ mr.style = 'line';
+ opts.closePath = false;
+ var xaxis = plot.axes[obj.options.xaxis],
+ xstart,
+ xstop,
+ y = plot.axes[obj.options.yaxis].series_u2p(obj.options.y),
+ xminoff = obj.options.xminOffset || obj.options.xOffset,
+ xmaxoff = obj.options.xmaxOffset || obj.options.xOffset;
+ if (obj.options.xmin != null) {
+ xstart = xaxis.series_u2p(obj.options.xmin);
+ }
+ else if (xminoff != null) {
+ if ($.type(xminoff) == "number") {
+ xstart = xaxis.series_u2p(xaxis.min + xminoff);
+ }
+ else if ($.type(xminoff) == "string") {
+ xstart = xaxis.series_u2p(xaxis.min) + parseFloat(xminoff);
+ }
+ }
+ if (obj.options.xmax != null) {
+ xstop = xaxis.series_u2p(obj.options.xmax);
+ }
+ else if (xmaxoff != null) {
+ if ($.type(xmaxoff) == "number") {
+ xstop = xaxis.series_u2p(xaxis.max - xmaxoff);
+ }
+ else if ($.type(xmaxoff) == "string") {
+ xstop = xaxis.series_u2p(xaxis.max) - parseFloat(xmaxoff);
+ }
+ }
+ if (xstop != null && xstart != null) {
+ obj.gridStart = [xstart, y];
+ obj.gridStop = [xstop, y];
+ var numDash = Math.ceil((xstop - xstart)/dashPatLen);
+ var b=xstart, e;
+ for (var i=0; i<numDash; i++) {
+ for (var j=0; j<dashPat.length; j+=2) {
+ e = b+dashPat[j];
+ mr.draw([b, y], [e, y], this.canvas._ctx, opts);
+ b += dashPat[j];
+ if (j < dashPat.length-1) {
+ b += dashPat[j+1];
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case 'verticalLine':
+
+ // style and shadow properties should be set before
+ // every draw of marker renderer.
+ if (obj.options.x != null) {
+ mr.style = 'line';
+ opts.closePath = false;
+ var yaxis = plot.axes[obj.options.yaxis],
+ ystart,
+ ystop,
+ x = plot.axes[obj.options.xaxis].series_u2p(obj.options.x),
+ yminoff = obj.options.yminOffset || obj.options.yOffset,
+ ymaxoff = obj.options.ymaxOffset || obj.options.yOffset;
+ if (obj.options.ymin != null) {
+ ystart = yaxis.series_u2p(obj.options.ymin);
+ }
+ else if (yminoff != null) {
+ if ($.type(yminoff) == "number") {
+ ystart = yaxis.series_u2p(yaxis.min - yminoff);
+ }
+ else if ($.type(yminoff) == "string") {
+ ystart = yaxis.series_u2p(yaxis.min) - parseFloat(yminoff);
+ }
+ }
+ if (obj.options.ymax != null) {
+ ystop = yaxis.series_u2p(obj.options.ymax);
+ }
+ else if (ymaxoff != null) {
+ if ($.type(ymaxoff) == "number") {
+ ystop = yaxis.series_u2p(yaxis.max + ymaxoff);
+ }
+ else if ($.type(ymaxoff) == "string") {
+ ystop = yaxis.series_u2p(yaxis.max) + parseFloat(ymaxoff);
+ }
+ }
+ if (ystop != null && ystart != null) {
+ obj.gridStart = [x, ystart];
+ obj.gridStop = [x, ystop];
+ mr.draw([x, ystart], [x, ystop], this.canvas._ctx, opts);
+ }
+ }
+ break;
+
+ case 'dashedVerticalLine':
+
+ var dashPat = obj.options.dashPattern;
+ var dashPatLen = 0;
+ for (var i=0; i<dashPat.length; i++) {
+ dashPatLen += dashPat[i];
+ }
+
+ // style and shadow properties should be set before
+ // every draw of marker renderer.
+ if (obj.options.x != null) {
+ mr.style = 'line';
+ opts.closePath = false;
+ var yaxis = plot.axes[obj.options.yaxis],
+ ystart,
+ ystop,
+ x = plot.axes[obj.options.xaxis].series_u2p(obj.options.x),
+ yminoff = obj.options.yminOffset || obj.options.yOffset,
+ ymaxoff = obj.options.ymaxOffset || obj.options.yOffset;
+ if (obj.options.ymin != null) {
+ ystart = yaxis.series_u2p(obj.options.ymin);
+ }
+ else if (yminoff != null) {
+ if ($.type(yminoff) == "number") {
+ ystart = yaxis.series_u2p(yaxis.min - yminoff);
+ }
+ else if ($.type(yminoff) == "string") {
+ ystart = yaxis.series_u2p(yaxis.min) - parseFloat(yminoff);
+ }
+ }
+ if (obj.options.ymax != null) {
+ ystop = yaxis.series_u2p(obj.options.ymax);
+ }
+ else if (ymaxoff != null) {
+ if ($.type(ymaxoff) == "number") {
+ ystop = yaxis.series_u2p(yaxis.max + ymaxoff);
+ }
+ else if ($.type(ymaxoff) == "string") {
+ ystop = yaxis.series_u2p(yaxis.max) + parseFloat(ymaxoff);
+ }
+ }
+
+
+ if (ystop != null && ystart != null) {
+ obj.gridStart = [x, ystart];
+ obj.gridStop = [x, ystop];
+ var numDash = Math.ceil((ystart - ystop)/dashPatLen);
+ var firstDashAdjust = ((numDash * dashPatLen) - (ystart - ystop))/2.0;
+ var b=ystart, e, bs, es;
+ for (var i=0; i<numDash; i++) {
+ for (var j=0; j<dashPat.length; j+=2) {
+ e = b - dashPat[j];
+ if (e < ystop) {
+ e = ystop;
+ }
+ if (b < ystop) {
+ b = ystop;
+ }
+ // es = e;
+ // if (i == 0) {
+ // es += firstDashAdjust;
+ // }
+ mr.draw([x, b], [x, e], this.canvas._ctx, opts);
+ b -= dashPat[j];
+ if (j < dashPat.length-1) {
+ b -= dashPat[j+1];
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+ };
+
+ // called within context of plot
+ // create a canvas which we can draw on.
+ // insert it before the eventCanvas, so eventCanvas will still capture events.
+ $.jqplot.CanvasOverlay.postPlotDraw = function() {
+ var co = this.plugins.canvasOverlay;
+ // Memory Leaks patch
+ if (co && co.highlightCanvas) {
+ co.highlightCanvas.resetCanvas();
+ co.highlightCanvas = null;
+ }
+ co.canvas = new $.jqplot.GenericCanvas();
+
+ this.eventCanvas._elem.before(co.canvas.createElement(this._gridPadding, 'jqplot-overlayCanvas-canvas', this._plotDimensions, this));
+ co.canvas.setContext();
+ if (!co.deferDraw) {
+ co.draw(this);
+ }
+
+ var elem = document.createElement('div');
+ co._tooltipElem = $(elem);
+ elem = null;
+ co._tooltipElem.addClass('jqplot-canvasOverlay-tooltip');
+ co._tooltipElem.css({position:'absolute', display:'none'});
+
+ this.eventCanvas._elem.before(co._tooltipElem);
+ this.eventCanvas._elem.bind('mouseleave', { elem: co._tooltipElem }, function (ev) { ev.data.elem.hide(); });
+
+ var co = null;
+ };
+
+
+ function showTooltip(plot, obj, gridpos, datapos) {
+ var co = plot.plugins.canvasOverlay;
+ var elem = co._tooltipElem;
+
+ var opts = obj.options, x, y;
+
+ elem.html($.jqplot.sprintf(opts.tooltipFormatString, datapos[0], datapos[1]));
+
+ switch (opts.tooltipLocation) {
+ case 'nw':
+ x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset;
+ y = gridpos[1] + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true);
+ break;
+ case 'n':
+ x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true)/2;
+ y = gridpos[1] + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true);
+ break;
+ case 'ne':
+ x = gridpos[0] + plot._gridPadding.left + opts.tooltipOffset;
+ y = gridpos[1] + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true);
+ break;
+ case 'e':
+ x = gridpos[0] + plot._gridPadding.left + opts.tooltipOffset;
+ y = gridpos[1] + plot._gridPadding.top - elem.outerHeight(true)/2;
+ break;
+ case 'se':
+ x = gridpos[0] + plot._gridPadding.left + opts.tooltipOffset;
+ y = gridpos[1] + plot._gridPadding.top + opts.tooltipOffset;
+ break;
+ case 's':
+ x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true)/2;
+ y = gridpos[1] + plot._gridPadding.top + opts.tooltipOffset;
+ break;
+ case 'sw':
+ x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset;
+ y = gridpos[1] + plot._gridPadding.top + opts.tooltipOffset;
+ break;
+ case 'w':
+ x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset;
+ y = gridpos[1] + plot._gridPadding.top - elem.outerHeight(true)/2;
+ break;
+ default: // same as 'nw'
+ x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset;
+ y = gridpos[1] + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true);
+ break;
+ }
+
+ elem.css('left', x);
+ elem.css('top', y);
+ if (opts.fadeTooltip) {
+ // Fix for stacked up animations. Thnanks Trevor!
+ elem.stop(true,true).fadeIn(opts.tooltipFadeSpeed);
+ }
+ else {
+ elem.show();
+ }
+ elem = null;
+ }
+
+
+ function isNearLine(point, lstart, lstop, width) {
+ // r is point to test, p and q are end points.
+ var rx = point[0];
+ var ry = point[1];
+ var px = Math.round(lstop[0]);
+ var py = Math.round(lstop[1]);
+ var qx = Math.round(lstart[0]);
+ var qy = Math.round(lstart[1]);
+
+ var l = Math.sqrt(Math.pow(px-qx, 2) + Math.pow(py-qy, 2));
+
+ // scale error term by length of line.
+ var eps = width*l;
+ var res = Math.abs((qx-px) * (ry-py) - (qy-py) * (rx-px));
+ var ret = (res < eps) ? true : false;
+ return ret;
+ }
+
+
+ function handleMove(ev, gridpos, datapos, neighbor, plot) {
+ var co = plot.plugins.canvasOverlay;
+ var objs = co.objects;
+ var l = objs.length;
+ var obj, haveHighlight=false;
+ var elem;
+ for (var i=0; i<l; i++) {
+ obj = objs[i];
+ if (obj.options.showTooltip) {
+ var n = isNearLine([gridpos.x, gridpos.y], obj.gridStart, obj.gridStop, obj.tooltipWidthFactor);
+ datapos = [plot.axes[obj.options.xaxis].series_p2u(gridpos.x), plot.axes[obj.options.yaxis].series_p2u(gridpos.y)];
+
+ // cases:
+ // near line, no highlighting
+ // near line, highliting on this line
+ // near line, highlighting another line
+ // not near any line, highlighting
+ // not near any line, no highlighting
+
+ // near line, not currently highlighting
+ if (n && co.highlightObjectIndex == null) {
+ switch (obj.type) {
+ case 'line':
+ showTooltip(plot, obj, [gridpos.x, gridpos.y], datapos);
+ break;
+
+ case 'horizontalLine':
+ case 'dashedHorizontalLine':
+ showTooltip(plot, obj, [gridpos.x, obj.gridStart[1]], [datapos[0], obj.options.y]);
+ break;
+
+ case 'verticalLine':
+ case 'dashedVerticalLine':
+ showTooltip(plot, obj, [obj.gridStart[0], gridpos.y], [obj.options.x, datapos[1]]);
+ break;
+ default:
+ break;
+ }
+ co.highlightObjectIndex = i;
+ haveHighlight = true;
+ break;
+ }
+
+ // near line, highlighting another line.
+ else if (n && co.highlightObjectIndex !== i) {
+ // turn off tooltip.
+ elem = co._tooltipElem;
+ if (obj.fadeTooltip) {
+ elem.fadeOut(obj.tooltipFadeSpeed);
+ }
+ else {
+ elem.hide();
+ }
+
+ // turn on right tooltip.
+ switch (obj.type) {
+ case 'line':
+ showTooltip(plot, obj, [gridpos.x, gridpos.y], datapos);
+ break;
+
+ case 'horizontalLine':
+ case 'dashedHorizontalLine':
+ showTooltip(plot, obj, [gridpos.x, obj.gridStart[1]], [datapos[0], obj.options.y]);
+ break;
+
+ case 'verticalLine':
+ case 'dashedVerticalLine':
+ showTooltip(plot, obj, [obj.gridStart[0], gridpos.y], [obj.options.x, datapos[1]]);
+ break;
+ default:
+ break;
+ }
+
+ co.highlightObjectIndex = i;
+ haveHighlight = true;
+ break;
+ }
+
+ // near line, already highlighting this line, update
+ else if (n) {
+ switch (obj.type) {
+ case 'line':
+ showTooltip(plot, obj, [gridpos.x, gridpos.y], datapos);
+ break;
+
+ case 'horizontalLine':
+ case 'dashedHorizontalLine':
+ showTooltip(plot, obj, [gridpos.x, obj.gridStart[1]], [datapos[0], obj.options.y]);
+ break;
+
+ case 'verticalLine':
+ case 'dashedVerticalLine':
+ showTooltip(plot, obj, [obj.gridStart[0], gridpos.y], [obj.options.x, datapos[1]]);
+ break;
+ default:
+ break;
+ }
+
+ haveHighlight = true;
+ break;
+ }
+ }
+ }
+
+ // check if we are highlighting and not near a line, turn it off.
+ if (!haveHighlight && co.highlightObjectIndex !== null) {
+ elem = co._tooltipElem;
+ obj = co.getObject(co.highlightObjectIndex);
+ if (obj.fadeTooltip) {
+ elem.fadeOut(obj.tooltipFadeSpeed);
+ }
+ else {
+ elem.hide();
+ }
+ co.highlightObjectIndex = null;
+ }
+ }
+
+ $.jqplot.postInitHooks.push($.jqplot.CanvasOverlay.postPlotInit);
+ $.jqplot.postDrawHooks.push($.jqplot.CanvasOverlay.postPlotDraw);
+ $.jqplot.eventListenerHooks.push(['jqplotMouseMove', handleMove]);
+
+})(jQuery);
\ No newline at end of file
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasOverlay.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasOverlay.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasOverlay.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(d){var f=0;d.jqplot.CanvasOverlay=function(o){var l=o||{};this.options={show:d.jqplot.config.enablePlugins,deferDraw:false};this.objects=[];this.objectNames=[];this.canvas=null;this.markerRenderer=new d.jqplot.MarkerRenderer({style:"line"});this.markerRenderer.init();this.highlightObjectIndex=null;if(l.objects){var q=l.objects,p;for(var m=0;m<q.length;m++){p=q[m];for(var r in p){switch(r){case"line":this.addLine(p[r]);break;case"horizontalLine":this.addHorizontalLine(p[r]);break;case"dashedHorizontalLine":this.addDashedHorizontalLine(p[r]);break;case"verticalLine":this.addVerticalLine(p[r]);break;case"dashedVerticalLine":this.addDashedVerticalLine(p[r]);break;default:break}}}}d.extend(true,this.options,l)};d.jqplot.CanvasOverlay.postPlotInit=function(o,n,m){var l=m||{};this.plugins.canvasOverlay=new d.jqplot.CanvasOverlay(l.canvasOverlay)};function h(){this.uid=null;this.type=null;this.gridStart=null;this.gridStop=null;this.tooltipWidthFactor=0;this.options={name:null,show:true,lineWidth:2,lineCap:"round",color:"#666666",shadow:true,shadowAngle:45,shadowOffset:1,shadowDepth:3,shadowAlpha:"0.07",xaxis:"xaxis",yaxis:"yaxis",showTooltip:false,showTooltipPrecision:0.6,tooltipLocation:"nw",fadeTooltip:true,tooltipFadeSpeed:"fast",tooltipOffset:4,tooltipFormatString:"%d, %d"}}function b(l){h.call(this);this.type="line";var m={start:[],stop:[]};d.extend(true,this.options,m,l);if(this.options.showTooltipPrecision<0.01){this.options.showTooltipPrecision=0.01}}b.prototype=new h();b.prototype.constructor=b;function e(l){h.call(this);this.type="horizontalLine";var m={y:null,xmin:null,xmax:null,xOffset:"6px",xminOffset:null,xmaxOffset:null};d.extend(true,this.options,m,l);if(this.options.showTooltipPrecision<0.01){this.options.showTooltipPrecision=0.01}}e.prototype=new h();e.prototype.constructor=e;function i(l){h.call(this);this.type="dashedHorizontalLine";var m={y:null,xmin:null,xmax:null,xOffset:"6px",xminOffset:null,xmaxOffset:null,dashPattern:[8,8]};d.extend(true,this.options,m,l);if(this.options.s!
howTooltipPrecision<0.01){this.options.showTooltipPrecision=0.01}}i.prototype=new h();i.prototype.constructor=i;function c(l){h.call(this);this.type="verticalLine";var m={x:null,ymin:null,ymax:null,yOffset:"6px",yminOffset:null,ymaxOffset:null};d.extend(true,this.options,m,l);if(this.options.showTooltipPrecision<0.01){this.options.showTooltipPrecision=0.01}}c.prototype=new h();c.prototype.constructor=c;function k(l){h.call(this);this.type="dashedVerticalLine";this.start=null;this.stop=null;var m={x:null,ymin:null,ymax:null,yOffset:"6px",yminOffset:null,ymaxOffset:null,dashPattern:[8,8]};d.extend(true,this.options,m,l);if(this.options.showTooltipPrecision<0.01){this.options.showTooltipPrecision=0.01}}k.prototype=new h();k.prototype.constructor=k;d.jqplot.CanvasOverlay.prototype.addLine=function(m){var l=new b(m);l.uid=f++;this.objects.push(l);this.objectNames.push(l.options.name)};d.jqplot.CanvasOverlay.prototype.addHorizontalLine=function(m){var l=new e(m);l.uid=f++;this.objects.push(l);this.objectNames.push(l.options.name)};d.jqplot.CanvasOverlay.prototype.addDashedHorizontalLine=function(m){var l=new i(m);l.uid=f++;this.objects.push(l);this.objectNames.push(l.options.name)};d.jqplot.CanvasOverlay.prototype.addVerticalLine=function(m){var l=new c(m);l.uid=f++;this.objects.push(l);this.objectNames.push(l.options.name)};d.jqplot.CanvasOverlay.prototype.addDashedVerticalLine=function(m){var l=new k(m);l.uid=f++;this.objects.push(l);this.objectNames.push(l.options.name)};d.jqplot.CanvasOverlay.prototype.removeObject=function(l){if(d.type(l)=="number"){this.objects.splice(l,1);this.objectNames.splice(l,1)}else{var m=d.inArray(l,this.objectNames);if(m!=-1){this.objects.splice(m,1);this.objectNames.splice(m,1)}}};d.jqplot.CanvasOverlay.prototype.getObject=function(l){if(d.type(l)=="number"){return this.objects[l]}else{var m=d.inArray(l,this.objectNames);if(m!=-1){return this.objects[m]}}};d.jqplot.CanvasOverlay.prototype.get=d.jqplot.CanvasOverlay.prototype.getObject;d.jqplot.CanvasOverlay.prototype.clear=function(l){!
this.canvas._ctx.clearRect(0,0,this.canvas.getWidth(),this.canvas.getHeight())};d.jqplot.CanvasOverlay.prototype.draw=function(I){var w,t=this.objects,D=this.markerRenderer,q,E;if(this.options.show){this.canvas._ctx.clearRect(0,0,this.canvas.getWidth(),this.canvas.getHeight());for(var F=0;F<t.length;F++){w=t[F];var z=d.extend(true,{},w.options);if(w.options.show){D.shadow=w.options.shadow;w.tooltipWidthFactor=w.options.lineWidth/w.options.showTooltipPrecision;switch(w.type){case"line":D.style="line";z.closePath=false;q=[I.axes[w.options.xaxis].series_u2p(w.options.start[0]),I.axes[w.options.yaxis].series_u2p(w.options.start[1])];E=[I.axes[w.options.xaxis].series_u2p(w.options.stop[0]),I.axes[w.options.yaxis].series_u2p(w.options.stop[1])];w.gridStart=q;w.gridStop=E;D.draw(q,E,this.canvas._ctx,z);break;case"horizontalLine":if(w.options.y!=null){D.style="line";z.closePath=false;var n=I.axes[w.options.xaxis],Q,J,u=I.axes[w.options.yaxis].series_u2p(w.options.y),G=w.options.xminOffset||w.options.xOffset,r=w.options.xmaxOffset||w.options.xOffset;if(w.options.xmin!=null){Q=n.series_u2p(w.options.xmin)}else{if(G!=null){if(d.type(G)=="number"){Q=n.series_u2p(n.min+G)}else{if(d.type(G)=="string"){Q=n.series_u2p(n.min)+parseFloat(G)}}}}if(w.options.xmax!=null){J=n.series_u2p(w.options.xmax)}else{if(r!=null){if(d.type(r)=="number"){J=n.series_u2p(n.max-r)}else{if(d.type(r)=="string"){J=n.series_u2p(n.max)-parseFloat(r)}}}}if(J!=null&&Q!=null){w.gridStart=[Q,u];w.gridStop=[J,u];D.draw([Q,u],[J,u],this.canvas._ctx,z)}}break;case"dashedHorizontalLine":var m=w.options.dashPattern;var C=0;for(var K=0;K<m.length;K++){C+=m[K]}if(w.options.y!=null){D.style="line";z.closePath=false;var n=I.axes[w.options.xaxis],Q,J,u=I.axes[w.options.yaxis].series_u2p(w.options.y),G=w.options.xminOffset||w.options.xOffset,r=w.options.xmaxOffset||w.options.xOffset;if(w.options.xmin!=null){Q=n.series_u2p(w.options.xmin)}else{if(G!=null){if(d.type(G)=="number"){Q=n.series_u2p(n.min+G)}else{if(d.type(G)=="string"){Q=n.series_u2p(n.min)+parseFloat(G)}}}!
}if(w.options.xmax!=null){J=n.series_u2p(w.options.xmax)}else{if(r!=null){if(d.type(r)=="number"){J=n.series_u2p(n.max-r)}else{if(d.type(r)=="string"){J=n.series_u2p(n.max)-parseFloat(r)}}}}if(J!=null&&Q!=null){w.gridStart=[Q,u];w.gridStop=[J,u];var p=Math.ceil((J-Q)/C);var O=Q,M;for(var K=0;K<p;K++){for(var H=0;H<m.length;H+=2){M=O+m[H];D.draw([O,u],[M,u],this.canvas._ctx,z);O+=m[H];if(H<m.length-1){O+=m[H+1]}}}}}break;case"verticalLine":if(w.options.x!=null){D.style="line";z.closePath=false;var L=I.axes[w.options.yaxis],l,s,v=I.axes[w.options.xaxis].series_u2p(w.options.x),B=w.options.yminOffset||w.options.yOffset,o=w.options.ymaxOffset||w.options.yOffset;if(w.options.ymin!=null){l=L.series_u2p(w.options.ymin)}else{if(B!=null){if(d.type(B)=="number"){l=L.series_u2p(L.min-B)}else{if(d.type(B)=="string"){l=L.series_u2p(L.min)-parseFloat(B)}}}}if(w.options.ymax!=null){s=L.series_u2p(w.options.ymax)}else{if(o!=null){if(d.type(o)=="number"){s=L.series_u2p(L.max+o)}else{if(d.type(o)=="string"){s=L.series_u2p(L.max)+parseFloat(o)}}}}if(s!=null&&l!=null){w.gridStart=[v,l];w.gridStop=[v,s];D.draw([v,l],[v,s],this.canvas._ctx,z)}}break;case"dashedVerticalLine":var m=w.options.dashPattern;var C=0;for(var K=0;K<m.length;K++){C+=m[K]}if(w.options.x!=null){D.style="line";z.closePath=false;var L=I.axes[w.options.yaxis],l,s,v=I.axes[w.options.xaxis].series_u2p(w.options.x),B=w.options.yminOffset||w.options.yOffset,o=w.options.ymaxOffset||w.options.yOffset;if(w.options.ymin!=null){l=L.series_u2p(w.options.ymin)}else{if(B!=null){if(d.type(B)=="number"){l=L.series_u2p(L.min-B)}else{if(d.type(B)=="string"){l=L.series_u2p(L.min)-parseFloat(B)}}}}if(w.options.ymax!=null){s=L.series_u2p(w.options.ymax)}else{if(o!=null){if(d.type(o)=="number"){s=L.series_u2p(L.max+o)}else{if(d.type(o)=="string"){s=L.series_u2p(L.max)+parseFloat(o)}}}}if(s!=null&&l!=null){w.gridStart=[v,l];w.gridStop=[v,s];var p=Math.ceil((l-s)/C);var A=((p*C)-(l-s))/2;var O=l,M,N,P;for(var K=0;K<p;K++){for(var H=0;H<m.length;H+=2){M=O-m[H];if(M<s){M=s}if(O<s){O=s}D.d!
raw([v,O],[v,M],this.canvas._ctx,z);O-=m[H];if(H<m.length-1){O-=m[H+1]}}}}}break;default:break}}}}};d.jqplot.CanvasOverlay.postPlotDraw=function(){var m=this.plugins.canvasOverlay;if(m&&m.highlightCanvas){m.highlightCanvas.resetCanvas();m.highlightCanvas=null}m.canvas=new d.jqplot.GenericCanvas();this.eventCanvas._elem.before(m.canvas.createElement(this._gridPadding,"jqplot-overlayCanvas-canvas",this._plotDimensions,this));m.canvas.setContext();if(!m.deferDraw){m.draw(this)}var l=document.createElement("div");m._tooltipElem=d(l);l=null;m._tooltipElem.addClass("jqplot-canvasOverlay-tooltip");m._tooltipElem.css({position:"absolute",display:"none"});this.eventCanvas._elem.before(m._tooltipElem);this.eventCanvas._elem.bind("mouseleave",{elem:m._tooltipElem},function(n){n.data.elem.hide()});var m=null};function j(q,o,p,n){var s=q.plugins.canvasOverlay;var m=s._tooltipElem;var l=o.options,t,r;m.html(d.jqplot.sprintf(l.tooltipFormatString,n[0],n[1]));switch(l.tooltipLocation){case"nw":t=p[0]+q._gridPadding.left-m.outerWidth(true)-l.tooltipOffset;r=p[1]+q._gridPadding.top-l.tooltipOffset-m.outerHeight(true);break;case"n":t=p[0]+q._gridPadding.left-m.outerWidth(true)/2;r=p[1]+q._gridPadding.top-l.tooltipOffset-m.outerHeight(true);break;case"ne":t=p[0]+q._gridPadding.left+l.tooltipOffset;r=p[1]+q._gridPadding.top-l.tooltipOffset-m.outerHeight(true);break;case"e":t=p[0]+q._gridPadding.left+l.tooltipOffset;r=p[1]+q._gridPadding.top-m.outerHeight(true)/2;break;case"se":t=p[0]+q._gridPadding.left+l.tooltipOffset;r=p[1]+q._gridPadding.top+l.tooltipOffset;break;case"s":t=p[0]+q._gridPadding.left-m.outerWidth(true)/2;r=p[1]+q._gridPadding.top+l.tooltipOffset;break;case"sw":t=p[0]+q._gridPadding.left-m.outerWidth(true)-l.tooltipOffset;r=p[1]+q._gridPadding.top+l.tooltipOffset;break;case"w":t=p[0]+q._gridPadding.left-m.outerWidth(true)-l.tooltipOffset;r=p[1]+q._gridPadding.top-m.outerHeight(true)/2;break;default:t=p[0]+q._gridPadding.left-m.outerWidth(true)-l.tooltipOffset;r=p[1]+q._gridPadding.top-l.tooltipOffset-m.outerHeight(tr!
ue);break}m.css("left",t);m.css("top",r);if(l.fadeTooltip){m.stop(true,true).fadeIn(l.tooltipFadeSpeed)}else{m.show()}m=null}function g(y,p,r,o){var n=y[0];var m=y[1];var x=Math.round(r[0]);var w=Math.round(r[1]);var t=Math.round(p[0]);var s=Math.round(p[1]);var q=Math.sqrt(Math.pow(x-t,2)+Math.pow(w-s,2));var z=o*q;var v=Math.abs((t-x)*(m-w)-(s-w)*(n-x));var u=(v<z)?true:false;return u}function a(y,v,q,z,w){var x=w.plugins.canvasOverlay;var u=x.objects;var r=u.length;var t,m=false;var p;for(var s=0;s<r;s++){t=u[s];if(t.options.showTooltip){var o=g([v.x,v.y],t.gridStart,t.gridStop,t.tooltipWidthFactor);q=[w.axes[t.options.xaxis].series_p2u(v.x),w.axes[t.options.yaxis].series_p2u(v.y)];if(o&&x.highlightObjectIndex==null){switch(t.type){case"line":j(w,t,[v.x,v.y],q);break;case"horizontalLine":case"dashedHorizontalLine":j(w,t,[v.x,t.gridStart[1]],[q[0],t.options.y]);break;case"verticalLine":case"dashedVerticalLine":j(w,t,[t.gridStart[0],v.y],[t.options.x,q[1]]);break;default:break}x.highlightObjectIndex=s;m=true;break}else{if(o&&x.highlightObjectIndex!==s){p=x._tooltipElem;if(t.fadeTooltip){p.fadeOut(t.tooltipFadeSpeed)}else{p.hide()}switch(t.type){case"line":j(w,t,[v.x,v.y],q);break;case"horizontalLine":case"dashedHorizontalLine":j(w,t,[v.x,t.gridStart[1]],[q[0],t.options.y]);break;case"verticalLine":case"dashedVerticalLine":j(w,t,[t.gridStart[0],v.y],[t.options.x,q[1]]);break;default:break}x.highlightObjectIndex=s;m=true;break}else{if(o){switch(t.type){case"line":j(w,t,[v.x,v.y],q);break;case"horizontalLine":case"dashedHorizontalLine":j(w,t,[v.x,t.gridStart[1]],[q[0],t.options.y]);break;case"verticalLine":case"dashedVerticalLine":j(w,t,[t.gridStart[0],v.y],[t.options.x,q[1]]);break;default:break}m=true;break}}}}}if(!m&&x.highlightObjectIndex!==null){p=x._tooltipElem;t=x.getObject(x.highlightObjectIndex);if(t.fadeTooltip){p.fadeOut(t.tooltipFadeSpeed)}else{p.hide()}x.highlightObjectIndex=null}}d.jqplot.postInitHooks.push(d.jqplot.CanvasOverlay.postPlotInit);d.jqplot.postDrawHooks.push(d.jqplot.CanvasOverlay.postPl!
otDraw);d.jqplot.eventListenerHooks.push(["jqplotMouseMove",a])})(jQuery);
\ No newline at end of file
Modified: gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasTextRenderer.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasTextRenderer.js 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasTextRenderer.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -1,20 +1,61 @@
/**
- * Copyright (c) 2009 - 2010 Chris Leonello
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
- * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
- * The author would appreciate an email letting him know of any substantial
- * use of jqPlot. You can reach the author at: chris at jqplot dot com
- * or see http://www.jqplot.com/info.php . This is, of course,
- * not required.
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
- * Thanks for using jqPlot!
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
+ *
+ * included jsDate library by Chris Leonello:
+ *
+ * Copyright (c) 2010-2013 Chris Leonello
+ *
+ * jsDate is currently available for use in all personal or commercial projects
+ * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * choose the license that best suits your project and use it accordingly.
+ *
+ * jsDate borrows many concepts and ideas from the Date Instance
+ * Methods by Ken Snyder along with some parts of Ken's actual code.
*
+ * Ken's origianl Date Instance Methods and copyright notice:
+ *
+ * Ken Snyder (ken d snyder at gmail dot com)
+ * 2008-09-10
+ * version 2.0.2 (http://kendsnyder.com/sandbox/date/)
+ * Creative Commons Attribution License 3.0 (http://creativecommons.org/licenses/by/3.0/)
+ *
+ * jqplotToImage function based on Larry Siden's export-jqplot-to-png.js.
+ * Larry has generously given permission to adapt his code for inclusion
+ * into jqPlot.
+ *
+ * Larry's original code can be found here:
+ *
+ * https://github.com/lsiden/export-jqplot-to-png
+ *
+ *
*/
+
(function($) {
// This code is a modified version of the canvastext.js code, copyright below:
//
@@ -52,7 +93,7 @@
// returns float
$.jqplot.CanvasTextRenderer.prototype.normalizeFontSize = function(sz) {
sz = String(sz);
- n = parseFloat(sz);
+ var n = parseFloat(sz);
if (sz.indexOf('px') > -1) {
return n/this.pt2px;
}
@@ -161,7 +202,7 @@
var total = 0;
var len = str.length;
- for ( i = 0; i < len; i++) {
+ for (var i = 0; i < len; i++) {
var c = this.letter(str.charAt(i));
if (c) {
total += c.width * this.normalizedFontSize / 25.0 * this.fontStretch;
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasTextRenderer.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasTextRenderer.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.canvasTextRenderer.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(a){a.jqplot.CanvasTextRenderer=function(b){this.fontStyle="normal";this.fontVariant="normal";this.fontWeight="normal";this.fontSize="10px";this.fontFamily="sans-serif";this.fontStretch=1;this.fillStyle="#666666";this.angle=0;this.textAlign="start";this.textBaseline="alphabetic";this.text;this.width;this.height;this.pt2px=1.28;a.extend(true,this,b);this.normalizedFontSize=this.normalizeFontSize(this.fontSize);this.setHeight()};a.jqplot.CanvasTextRenderer.prototype.init=function(b){a.extend(true,this,b);this.normalizedFontSize=this.normalizeFontSize(this.fontSize);this.setHeight()};a.jqplot.CanvasTextRenderer.prototype.normalizeFontSize=function(b){b=String(b);var c=parseFloat(b);if(b.indexOf("px")>-1){return c/this.pt2px}else{if(b.indexOf("pt")>-1){return c}else{if(b.indexOf("em")>-1){return c*12}else{if(b.indexOf("%")>-1){return c*12/100}else{return c/this.pt2px}}}}};a.jqplot.CanvasTextRenderer.prototype.fontWeight2Float=function(b){if(Number(b)){return b/400}else{switch(b){case"normal":return 1;break;case"bold":return 1.75;break;case"bolder":return 2.25;break;case"lighter":return 0.75;break;default:return 1;break}}};a.jqplot.CanvasTextRenderer.prototype.getText=function(){return this.text};a.jqplot.CanvasTextRenderer.prototype.setText=function(c,b){this.text=c;this.setWidth(b);return this};a.jqplot.CanvasTextRenderer.prototype.getWidth=function(b){return this.width};a.jqplot.CanvasTextRenderer.prototype.setWidth=function(c,b){if(!b){this.width=this.measure(c,this.text)}else{this.width=b}return this};a.jqplot.CanvasTextRenderer.prototype.getHeight=function(b){return this.height};a.jqplot.CanvasTextRenderer.prototype.setHeight=function(b){if(!b){this.height=this.normalizedFontSize*this.pt2px}else{this.height=b}return this};a.jqplot.CanvasTextRenderer.prototype.letter=function(b){return this.letters[b]};a.jqplot.CanvasTextRenderer.prototype.ascent=function(){return this.normalizedFontSize};a.jqplot.CanvasTextRenderer.prototype.descent=function(){return 7*this.normalizedFontSize/25};a.jqplot.C!
anvasTextRenderer.prototype.measure=function(d,g){var f=0;var b=g.length;for(var e=0;e<b;e++){var h=this.letter(g.charAt(e));if(h){f+=h.width*this.normalizedFontSize/25*this.fontStretch}}return f};a.jqplot.CanvasTextRenderer.prototype.draw=function(s,n){var r=0;var o=this.height*0.72;var p=0;var l=n.length;var k=this.normalizedFontSize/25;s.save();var h,f;if((-Math.PI/2<=this.angle&&this.angle<=0)||(Math.PI*3/2<=this.angle&&this.angle<=Math.PI*2)){h=0;f=-Math.sin(this.angle)*this.width}else{if((0<this.angle&&this.angle<=Math.PI/2)||(-Math.PI*2<=this.angle&&this.angle<=-Math.PI*3/2)){h=Math.sin(this.angle)*this.height;f=0}else{if((-Math.PI<this.angle&&this.angle<-Math.PI/2)||(Math.PI<=this.angle&&this.angle<=Math.PI*3/2)){h=-Math.cos(this.angle)*this.width;f=-Math.sin(this.angle)*this.width-Math.cos(this.angle)*this.height}else{if((-Math.PI*3/2<this.angle&&this.angle<Math.PI)||(Math.PI/2<this.angle&&this.angle<Math.PI)){h=Math.sin(this.angle)*this.height-Math.cos(this.angle)*this.width;f=-Math.cos(this.angle)*this.height}}}}s.strokeStyle=this.fillStyle;s.fillStyle=this.fillStyle;s.translate(h,f);s.rotate(this.angle);s.lineCap="round";var t=(this.normalizedFontSize>30)?2:2+(30-this.normalizedFontSize)/20;s.lineWidth=t*k*this.fontWeight2Float(this.fontWeight);for(var g=0;g<l;g++){var m=this.letter(n.charAt(g));if(!m){continue}s.beginPath();var e=1;var b=0;for(var d=0;d<m.points.length;d++){var q=m.points[d];if(q[0]==-1&&q[1]==-1){e=1;continue}if(e){s.moveTo(r+q[0]*k*this.fontStretch,o-q[1]*k);e=false}else{s.lineTo(r+q[0]*k*this.fontStretch,o-q[1]*k)}}s.stroke();r+=m.width*k*this.fontStretch}s.restore();return p};a.jqplot.CanvasTextRenderer.prototype.letters={" ":{width:16,points:[]},"!":{width:10,points:[[5,21],[5,7],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]]},'"':{width:16,points:[[4,21],[4,14],[-1,-1],[12,21],[12,14]]},"#":{width:21,points:[[11,25],[4,-7],[-1,-1],[17,25],[10,-7],[-1,-1],[4,12],[18,12],[-1,-1],[3,6],[17,6]]},"$":{width:20,points:[[8,25],[8,-4],[-1,-1],[12,25],[12,-4],[-1,-1],[17,18],[15,20],[12,21],[8!
,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]]},"%":{width:24,points:[[21,21],[3,0],[-1,-1],[8,21],[10,19],[10,17],[9,15],[7,14],[5,14],[3,16],[3,18],[4,20],[6,21],[8,21],[10,20],[13,19],[16,19],[19,20],[21,21],[-1,-1],[17,7],[15,6],[14,4],[14,2],[16,0],[18,0],[20,1],[21,3],[21,5],[19,7],[17,7]]},"&":{width:26,points:[[23,12],[23,13],[22,14],[21,14],[20,13],[19,11],[17,6],[15,3],[13,1],[11,0],[7,0],[5,1],[4,2],[3,4],[3,6],[4,8],[5,9],[12,13],[13,14],[14,16],[14,18],[13,20],[11,21],[9,20],[8,18],[8,16],[9,13],[11,10],[16,3],[18,1],[20,0],[22,0],[23,1],[23,2]]},"'":{width:10,points:[[5,19],[4,20],[5,21],[6,20],[6,18],[5,16],[4,15]]},"(":{width:14,points:[[11,25],[9,23],[7,20],[5,16],[4,11],[4,7],[5,2],[7,-2],[9,-5],[11,-7]]},")":{width:14,points:[[3,25],[5,23],[7,20],[9,16],[10,11],[10,7],[9,2],[7,-2],[5,-5],[3,-7]]},"*":{width:16,points:[[8,21],[8,9],[-1,-1],[3,18],[13,12],[-1,-1],[13,18],[3,12]]},"+":{width:26,points:[[13,18],[13,0],[-1,-1],[4,9],[22,9]]},",":{width:10,points:[[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]]},"-":{width:18,points:[[6,9],[12,9]]},".":{width:10,points:[[5,2],[4,1],[5,0],[6,1],[5,2]]},"/":{width:22,points:[[20,25],[2,-7]]},"0":{width:20,points:[[9,21],[6,20],[4,17],[3,12],[3,9],[4,4],[6,1],[9,0],[11,0],[14,1],[16,4],[17,9],[17,12],[16,17],[14,20],[11,21],[9,21]]},"1":{width:20,points:[[6,17],[8,18],[11,21],[11,0]]},"2":{width:20,points:[[4,16],[4,17],[5,19],[6,20],[8,21],[12,21],[14,20],[15,19],[16,17],[16,15],[15,13],[13,10],[3,0],[17,0]]},"3":{width:20,points:[[5,21],[16,21],[10,13],[13,13],[15,12],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]]},"4":{width:20,points:[[13,21],[3,7],[18,7],[-1,-1],[13,21],[13,0]]},"5":{width:20,points:[[15,21],[5,21],[4,12],[5,13],[8,14],[11,14],[14,13],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]]},"6":{width:20,points:[[16,18],[15,20],[12,21],[10,21],[7,20],[5,17],[4,12],[4,7],[5,3],[7,1],[10,0],[11,0],[14,1],[16,3],[17,6],[17,7],[16!
,10],[14,12],[11,13],[10,13],[7,12],[5,10],[4,7]]},"7":{width:20,points:[[17,21],[7,0],[-1,-1],[3,21],[17,21]]},"8":{width:20,points:[[8,21],[5,20],[4,18],[4,16],[5,14],[7,13],[11,12],[14,11],[16,9],[17,7],[17,4],[16,2],[15,1],[12,0],[8,0],[5,1],[4,2],[3,4],[3,7],[4,9],[6,11],[9,12],[13,13],[15,14],[16,16],[16,18],[15,20],[12,21],[8,21]]},"9":{width:20,points:[[16,14],[15,11],[13,9],[10,8],[9,8],[6,9],[4,11],[3,14],[3,15],[4,18],[6,20],[9,21],[10,21],[13,20],[15,18],[16,14],[16,9],[15,4],[13,1],[10,0],[8,0],[5,1],[4,3]]},":":{width:10,points:[[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]]},";":{width:10,points:[[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]]},"<":{width:24,points:[[20,18],[4,9],[20,0]]},"=":{width:26,points:[[4,12],[22,12],[-1,-1],[4,6],[22,6]]},">":{width:24,points:[[4,18],[20,9],[4,0]]},"?":{width:18,points:[[3,16],[3,17],[4,19],[5,20],[7,21],[11,21],[13,20],[14,19],[15,17],[15,15],[14,13],[13,12],[9,10],[9,7],[-1,-1],[9,2],[8,1],[9,0],[10,1],[9,2]]},"@":{width:27,points:[[18,13],[17,15],[15,16],[12,16],[10,15],[9,14],[8,11],[8,8],[9,6],[11,5],[14,5],[16,6],[17,8],[-1,-1],[12,16],[10,14],[9,11],[9,8],[10,6],[11,5],[-1,-1],[18,16],[17,8],[17,6],[19,5],[21,5],[23,7],[24,10],[24,12],[23,15],[22,17],[20,19],[18,20],[15,21],[12,21],[9,20],[7,19],[5,17],[4,15],[3,12],[3,9],[4,6],[5,4],[7,2],[9,1],[12,0],[15,0],[18,1],[20,2],[21,3],[-1,-1],[19,16],[18,8],[18,6],[19,5]]},A:{width:18,points:[[9,21],[1,0],[-1,-1],[9,21],[17,0],[-1,-1],[4,7],[14,7]]},B:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[-1,-1],[4,11],[13,11],[16,10],[17,9],[18,7],[18,4],[17,2],[16,1],[13,0],[4,0]]},C:{width:21,points:[[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5]]},D:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[11,21],[14,20],[16,18],[17,16],[18,13],[18,8],[17,5],[16,3],[14,1],[11,0],[4,0]]},E:{width:19,points:!
[[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11],[-1,-1],[4,0],[17,0]]},F:{width:18,points:[[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11]]},G:{width:21,points:[[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[18,8],[-1,-1],[13,8],[18,8]]},H:{width:22,points:[[4,21],[4,0],[-1,-1],[18,21],[18,0],[-1,-1],[4,11],[18,11]]},I:{width:8,points:[[4,21],[4,0]]},J:{width:16,points:[[12,21],[12,5],[11,2],[10,1],[8,0],[6,0],[4,1],[3,2],[2,5],[2,7]]},K:{width:21,points:[[4,21],[4,0],[-1,-1],[18,21],[4,7],[-1,-1],[9,12],[18,0]]},L:{width:17,points:[[4,21],[4,0],[-1,-1],[4,0],[16,0]]},M:{width:24,points:[[4,21],[4,0],[-1,-1],[4,21],[12,0],[-1,-1],[20,21],[12,0],[-1,-1],[20,21],[20,0]]},N:{width:22,points:[[4,21],[4,0],[-1,-1],[4,21],[18,0],[-1,-1],[18,21],[18,0]]},O:{width:22,points:[[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21]]},P:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,14],[17,12],[16,11],[13,10],[4,10]]},Q:{width:22,points:[[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21],[-1,-1],[12,4],[18,-2]]},R:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[4,11],[-1,-1],[11,11],[18,0]]},S:{width:20,points:[[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]]},T:{width:16,points:[[8,21],[8,0],[-1,-1],[1,21],[15,21]]},U:{width:22,points:[[4,21],[4,6],[5,3],[7,1],[10,0],[12,0],[15,1],[17,3],[18,6],[18,21]]},V:{width:18,points:[[1,21],[9,0],[-1,-1],[17,21],[9,0]]},W:{width:24,points:[[2,21],[7,0],[-1,-1],[12,21],[7,0],[-1,-1],[12,21],[17,0],[-1,-1],[22,21],[17,0]]},X:{width:20,points:[[3,21],[17,0],[-1,-1],[17,21],[3,0]]},Y:{width:18,points:[[1,21],[9,11!
],[9,0],[-1,-1],[17,21],[9,11]]},Z:{width:20,points:[[17,21],[3,0],[-1,-1],[3,21],[17,21],[-1,-1],[3,0],[17,0]]},"[":{width:14,points:[[4,25],[4,-7],[-1,-1],[5,25],[5,-7],[-1,-1],[4,25],[11,25],[-1,-1],[4,-7],[11,-7]]},"\\":{width:14,points:[[0,21],[14,-3]]},"]":{width:14,points:[[9,25],[9,-7],[-1,-1],[10,25],[10,-7],[-1,-1],[3,25],[10,25],[-1,-1],[3,-7],[10,-7]]},"^":{width:16,points:[[6,15],[8,18],[10,15],[-1,-1],[3,12],[8,17],[13,12],[-1,-1],[8,17],[8,0]]},_:{width:16,points:[[0,-2],[16,-2]]},"`":{width:10,points:[[6,21],[5,20],[4,18],[4,16],[5,15],[6,16],[5,17]]},a:{width:19,points:[[15,14],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},b:{width:19,points:[[4,21],[4,0],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]]},c:{width:18,points:[[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},d:{width:19,points:[[15,21],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},e:{width:18,points:[[3,8],[15,8],[15,10],[14,12],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},f:{width:12,points:[[10,21],[8,21],[6,20],[5,17],[5,0],[-1,-1],[2,14],[9,14]]},g:{width:19,points:[[15,14],[15,-2],[14,-5],[13,-6],[11,-7],[8,-7],[6,-6],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},h:{width:19,points:[[4,21],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]]},i:{width:8,points:[[3,21],[4,20],[5,21],[4,22],[3,21],[-1,-1],[4,14],[4,0]]},j:{width:10,points:[[5,21],[6,20],[7,21],[6,22],[5,21],[-1,-1],[6,14],[6,-3],[5,-6],[3,-7],[1,-7]]},k:{width:17,points:[[4,21],[4,0],[-1,-1],[14,14],[4,4],[-1,-1],[8,8],[15,0]]},l:{width:8,points:[[4,21],[4,0]]},m:{width:30,points:[[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0],[-1,-1],[15,10],[18,13],[20,14],[23,14],[25,13],[26,10],[!
26,0]]},n:{width:19,points:[[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]]},o:{width:19,points:[[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3],[16,6],[16,8],[15,11],[13,13],[11,14],[8,14]]},p:{width:19,points:[[4,14],[4,-7],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]]},q:{width:19,points:[[15,14],[15,-7],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},r:{width:13,points:[[4,14],[4,0],[-1,-1],[4,8],[5,11],[7,13],[9,14],[12,14]]},s:{width:17,points:[[14,11],[13,13],[10,14],[7,14],[4,13],[3,11],[4,9],[6,8],[11,7],[13,6],[14,4],[14,3],[13,1],[10,0],[7,0],[4,1],[3,3]]},t:{width:12,points:[[5,21],[5,4],[6,1],[8,0],[10,0],[-1,-1],[2,14],[9,14]]},u:{width:19,points:[[4,14],[4,4],[5,1],[7,0],[10,0],[12,1],[15,4],[-1,-1],[15,14],[15,0]]},v:{width:16,points:[[2,14],[8,0],[-1,-1],[14,14],[8,0]]},w:{width:22,points:[[3,14],[7,0],[-1,-1],[11,14],[7,0],[-1,-1],[11,14],[15,0],[-1,-1],[19,14],[15,0]]},x:{width:17,points:[[3,14],[14,0],[-1,-1],[14,14],[3,0]]},y:{width:16,points:[[2,14],[8,0],[-1,-1],[14,14],[8,0],[6,-4],[4,-6],[2,-7],[1,-7]]},z:{width:17,points:[[14,14],[3,0],[-1,-1],[3,14],[14,14],[-1,-1],[3,0],[14,0]]},"{":{width:14,points:[[9,25],[7,24],[6,23],[5,21],[5,19],[6,17],[7,16],[8,14],[8,12],[6,10],[-1,-1],[7,24],[6,22],[6,20],[7,18],[8,17],[9,15],[9,13],[8,11],[4,9],[8,7],[9,5],[9,3],[8,1],[7,0],[6,-2],[6,-4],[7,-6],[-1,-1],[6,8],[8,6],[8,4],[7,2],[6,1],[5,-1],[5,-3],[6,-5],[7,-6],[9,-7]]},"|":{width:8,points:[[4,25],[4,-7]]},"}":{width:14,points:[[5,25],[7,24],[8,23],[9,21],[9,19],[8,17],[7,16],[6,14],[6,12],[8,10],[-1,-1],[7,24],[8,22],[8,20],[7,18],[6,17],[5,15],[5,13],[6,11],[10,9],[6,7],[5,5],[5,3],[6,1],[7,0],[8,-2],[8,-4],[7,-6],[-1,-1],[8,8],[6,6],[6,4],[7,2],[8,1],[9,-1],[9,-3],[8,-5],[7,-6],[5,-7]]},"~":{width:24,points:[[3,6],[3,8],[4,11],[6,12],[8,12],[10,11],[14,8],[16,7],[18,7],[20,8],[21,10],[-1,-1],[3,8],[4,10],[6,11],[8,11],[10,10!
],[14,7],[16,6],[18,6],[20,7],[21,10],[21,12]]}};a.jqplot.CanvasFontRenderer=function(b){b=b||{};if(!b.pt2px){b.pt2px=1.5}a.jqplot.CanvasTextRenderer.call(this,b)};a.jqplot.CanvasFontRenderer.prototype=new a.jqplot.CanvasTextRenderer({});a.jqplot.CanvasFontRenderer.prototype.constructor=a.jqplot.CanvasFontRenderer;a.jqplot.CanvasFontRenderer.prototype.measure=function(c,e){var d=this.fontSize+" "+this.fontFamily;c.save();c.font=d;var b=c.measureText(e).width;c.restore();return b};a.jqplot.CanvasFontRenderer.prototype.draw=function(e,g){var c=0;var h=this.height*0.72;e.save();var d,b;if((-Math.PI/2<=this.angle&&this.angle<=0)||(Math.PI*3/2<=this.angle&&this.angle<=Math.PI*2)){d=0;b=-Math.sin(this.angle)*this.width}else{if((0<this.angle&&this.angle<=Math.PI/2)||(-Math.PI*2<=this.angle&&this.angle<=-Math.PI*3/2)){d=Math.sin(this.angle)*this.height;b=0}else{if((-Math.PI<this.angle&&this.angle<-Math.PI/2)||(Math.PI<=this.angle&&this.angle<=Math.PI*3/2)){d=-Math.cos(this.angle)*this.width;b=-Math.sin(this.angle)*this.width-Math.cos(this.angle)*this.height}else{if((-Math.PI*3/2<this.angle&&this.angle<Math.PI)||(Math.PI/2<this.angle&&this.angle<Math.PI)){d=Math.sin(this.angle)*this.height-Math.cos(this.angle)*this.width;b=-Math.cos(this.angle)*this.height}}}}e.strokeStyle=this.fillStyle;e.fillStyle=this.fillStyle;var f=this.fontSize+" "+this.fontFamily;e.font=f;e.translate(d,b);e.rotate(this.angle);e.fillText(g,c,h);e.restore()}})(jQuery);
\ No newline at end of file
Modified: gnucash/trunk/src/report/jqplot/plugins/jqplot.categoryAxisRenderer.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.categoryAxisRenderer.js 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.categoryAxisRenderer.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -1,18 +1,31 @@
/**
- * Copyright (c) 2009 - 2010 Chris Leonello
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
- * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
- * The author would appreciate an email letting him know of any substantial
- * use of jqPlot. You can reach the author at: chris at jqplot dot com
- * or see http://www.jqplot.com/info.php . This is, of course,
- * not required.
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
- * Thanks for using jqPlot!
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
*
*/
(function($) {
@@ -57,6 +70,7 @@
this._groupLabels = [];
this._grouped = false;
this._barsPerGroup = null;
+ this.reverse = false;
// prop: tickRenderer
// A class of a rendering engine for creating the ticks labels displayed on the plot,
// See <$.jqplot.AxisTickRenderer>.
@@ -247,7 +261,7 @@
var track = 0;
// todo: adjust this so more ticks displayed.
- var maxVisibleTicks = parseInt(3+dim/20, 10);
+ var maxVisibleTicks = parseInt(3+dim/10, 10);
var skip = parseInt(numcats/maxVisibleTicks, 10);
if (this.tickInterval == null) {
@@ -285,7 +299,7 @@
};
// called with scope of axis
- $.jqplot.CategoryAxisRenderer.prototype.draw = function(ctx) {
+ $.jqplot.CategoryAxisRenderer.prototype.draw = function(ctx, plot) {
if (this.show) {
// populate the axis label and value properties.
// createTicks is a method on the renderer, but
@@ -298,9 +312,11 @@
var temp;
// Added for theming.
if (this._elem) {
- this._elem.empty();
+ // this._elem.empty();
+ // Memory Leaks patch
+ this._elem.emptyForce();
}
-
+
this._elem = this._elem || $('<div class="jqplot-axis jqplot-'+this.name+'" style="position:absolute;"></div>');
if (this.name == 'xaxis' || this.name == 'x2axis') {
@@ -314,7 +330,7 @@
this.labelOptions.axis = this.name;
this._label = new this.labelRenderer(this.labelOptions);
if (this._label.show) {
- var elem = this._label.draw(ctx);
+ var elem = this._label.draw(ctx, plot);
elem.appendTo(this._elem);
}
@@ -322,7 +338,7 @@
for (var i=0; i<t.length; i++) {
var tick = t[i];
if (tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) {
- var elem = tick.draw(ctx);
+ var elem = tick.draw(ctx, plot);
elem.appendTo(this._elem);
}
}
@@ -415,7 +431,8 @@
var offmax = offsets.max;
var offmin = offsets.min;
var lshow = (this._label == null) ? false : this._label.show;
-
+ var i;
+
for (var p in pos) {
this._elem.css(p, pos[p]);
}
@@ -425,32 +442,67 @@
var pixellength = offmax - offmin;
var unitlength = max - min;
- // point to unit and unit to point conversions references to Plot DOM element top left corner.
- this.p2u = function(p){
- return (p - offmin) * unitlength / pixellength + min;
- };
-
- this.u2p = function(u){
- return (u - min) * pixellength / unitlength + offmin;
- };
-
- if (this.name == 'xaxis' || this.name == 'x2axis'){
- this.series_u2p = function(u){
- return (u - min) * pixellength / unitlength;
+ if (!this.reverse) {
+ // point to unit and unit to point conversions references to Plot DOM element top left corner.
+
+ this.u2p = function(u){
+ return (u - min) * pixellength / unitlength + offmin;
};
- this.series_p2u = function(p){
- return p * unitlength / pixellength + min;
+
+ this.p2u = function(p){
+ return (p - offmin) * unitlength / pixellength + min;
};
+
+ if (this.name == 'xaxis' || this.name == 'x2axis'){
+ this.series_u2p = function(u){
+ return (u - min) * pixellength / unitlength;
+ };
+ this.series_p2u = function(p){
+ return p * unitlength / pixellength + min;
+ };
+ }
+
+ else {
+ this.series_u2p = function(u){
+ return (u - max) * pixellength / unitlength;
+ };
+ this.series_p2u = function(p){
+ return p * unitlength / pixellength + max;
+ };
+ }
}
-
+
else {
- this.series_u2p = function(u){
- return (u - max) * pixellength / unitlength;
+ // point to unit and unit to point conversions references to Plot DOM element top left corner.
+
+ this.u2p = function(u){
+ return offmin + (max - u) * pixellength / unitlength;
};
- this.series_p2u = function(p){
- return p * unitlength / pixellength + max;
+
+ this.p2u = function(p){
+ return min + (p - offmin) * unitlength / pixellength;
};
+
+ if (this.name == 'xaxis' || this.name == 'x2axis'){
+ this.series_u2p = function(u){
+ return (max - u) * pixellength / unitlength;
+ };
+ this.series_p2u = function(p){
+ return p * unitlength / pixellength + max;
+ };
+ }
+
+ else {
+ this.series_u2p = function(u){
+ return (min - u) * pixellength / unitlength;
+ };
+ this.series_p2u = function(p){
+ return p * unitlength / pixellength + min;
+ };
+ }
+
}
+
if (this.show) {
if (this.name == 'xaxis' || this.name == 'x2axis') {
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.categoryAxisRenderer.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.categoryAxisRenderer.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.categoryAxisRenderer.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(a){a.jqplot.CategoryAxisRenderer=function(b){a.jqplot.LinearAxisRenderer.call(this);this.sortMergedLabels=false};a.jqplot.CategoryAxisRenderer.prototype=new a.jqplot.LinearAxisRenderer();a.jqplot.CategoryAxisRenderer.prototype.constructor=a.jqplot.CategoryAxisRenderer;a.jqplot.CategoryAxisRenderer.prototype.init=function(e){this.groups=1;this.groupLabels=[];this._groupLabels=[];this._grouped=false;this._barsPerGroup=null;this.reverse=false;a.extend(true,this,{tickOptions:{formatString:"%d"}},e);var b=this._dataBounds;for(var f=0;f<this._series.length;f++){var g=this._series[f];if(g.groups){this.groups=g.groups}var h=g.data;for(var c=0;c<h.length;c++){if(this.name=="xaxis"||this.name=="x2axis"){if(h[c][0]<b.min||b.min==null){b.min=h[c][0]}if(h[c][0]>b.max||b.max==null){b.max=h[c][0]}}else{if(h[c][1]<b.min||b.min==null){b.min=h[c][1]}if(h[c][1]>b.max||b.max==null){b.max=h[c][1]}}}}if(this.groupLabels.length){this.groups=this.groupLabels.length}};a.jqplot.CategoryAxisRenderer.prototype.createTicks=function(){var D=this._ticks;var z=this.ticks;var F=this.name;var C=this._dataBounds;var v,A;var q,w;var d,c;var b,x;if(z.length){if(this.groups>1&&!this._grouped){var r=z.length;var p=parseInt(r/this.groups,10);var e=0;for(var x=p;x<r;x+=p){z.splice(x+e,0," ");e++}this._grouped=true}this.min=0.5;this.max=z.length+0.5;var m=this.max-this.min;this.numberTicks=2*z.length+1;for(x=0;x<z.length;x++){b=this.min+2*x*m/(this.numberTicks-1);var h=new this.tickRenderer(this.tickOptions);h.showLabel=false;h.setTick(b,this.name);this._ticks.push(h);var h=new this.tickRenderer(this.tickOptions);h.label=z[x];h.showMark=false;h.showGridline=false;h.setTick(b+0.5,this.name);this._ticks.push(h)}var h=new this.tickRenderer(this.tickOptions);h.showLabel=false;h.setTick(b+1,this.name);this._ticks.push(h)}else{if(F=="xaxis"||F=="x2axis"){v=this._plotDimensions.width}else{v=this._plotDimensions.height}if(this.min!=null&&this.max!=null&&this.numberTicks!=null){this.tickInterval=null}if(this.min!=null&&this.max!=null&&this.!
tickInterval!=null){if(parseInt((this.max-this.min)/this.tickInterval,10)!=(this.max-this.min)/this.tickInterval){this.tickInterval=null}}var y=[];var B=0;var q=0.5;var w,E;var f=false;for(var x=0;x<this._series.length;x++){var k=this._series[x];for(var u=0;u<k.data.length;u++){if(this.name=="xaxis"||this.name=="x2axis"){E=k.data[u][0]}else{E=k.data[u][1]}if(a.inArray(E,y)==-1){f=true;B+=1;y.push(E)}}}if(f&&this.sortMergedLabels){y.sort(function(j,i){return j-i})}this.ticks=y;for(var x=0;x<this._series.length;x++){var k=this._series[x];for(var u=0;u<k.data.length;u++){if(this.name=="xaxis"||this.name=="x2axis"){E=k.data[u][0]}else{E=k.data[u][1]}var n=a.inArray(E,y)+1;if(this.name=="xaxis"||this.name=="x2axis"){k.data[u][0]=n}else{k.data[u][1]=n}}}if(this.groups>1&&!this._grouped){var r=y.length;var p=parseInt(r/this.groups,10);var e=0;for(var x=p;x<r;x+=p+1){y[x]=" "}this._grouped=true}w=B+0.5;if(this.numberTicks==null){this.numberTicks=2*B+1}var m=w-q;this.min=q;this.max=w;var o=0;var g=parseInt(3+v/10,10);var p=parseInt(B/g,10);if(this.tickInterval==null){this.tickInterval=m/(this.numberTicks-1)}for(var x=0;x<this.numberTicks;x++){b=this.min+x*this.tickInterval;var h=new this.tickRenderer(this.tickOptions);if(x/2==parseInt(x/2,10)){h.showLabel=false;h.showMark=true}else{if(p>0&&o<p){h.showLabel=false;o+=1}else{h.showLabel=true;o=0}h.label=h.formatter(h.formatString,y[(x-1)/2]);h.showMark=false;h.showGridline=false}h.setTick(b,this.name);this._ticks.push(h)}}};a.jqplot.CategoryAxisRenderer.prototype.draw=function(b,j){if(this.show){this.renderer.createTicks.call(this);var h=0;var c;if(this._elem){this._elem.emptyForce()}this._elem=this._elem||a('<div class="jqplot-axis jqplot-'+this.name+'" style="position:absolute;"></div>');if(this.name=="xaxis"||this.name=="x2axis"){this._elem.width(this._plotDimensions.width)}else{this._elem.height(this._plotDimensions.height)}this.labelOptions.axis=this.name;this._label=new this.labelRenderer(this.labelOptions);if(this._label.show){var g=this._label.draw(b,j);g.appendTo(t!
his._elem)}var f=this._ticks;for(var e=0;e<f.length;e++){var d=f[e];if(d.showLabel&&(!d.isMinorTick||this.showMinorTicks)){var g=d.draw(b,j);g.appendTo(this._elem)}}this._groupLabels=[];for(var e=0;e<this.groupLabels.length;e++){var g=a('<div style="position:absolute;" class="jqplot-'+this.name+'-groupLabel"></div>');g.html(this.groupLabels[e]);this._groupLabels.push(g);g.appendTo(this._elem)}}return this._elem};a.jqplot.CategoryAxisRenderer.prototype.set=function(){var e=0;var m;var k=0;var f=0;var d=(this._label==null)?false:this._label.show;if(this.show){var n=this._ticks;for(var c=0;c<n.length;c++){var g=n[c];if(g.showLabel&&(!g.isMinorTick||this.showMinorTicks)){if(this.name=="xaxis"||this.name=="x2axis"){m=g._elem.outerHeight(true)}else{m=g._elem.outerWidth(true)}if(m>e){e=m}}}var j=0;for(var c=0;c<this._groupLabels.length;c++){var b=this._groupLabels[c];if(this.name=="xaxis"||this.name=="x2axis"){m=b.outerHeight(true)}else{m=b.outerWidth(true)}if(m>j){j=m}}if(d){k=this._label._elem.outerWidth(true);f=this._label._elem.outerHeight(true)}if(this.name=="xaxis"){e+=j+f;this._elem.css({height:e+"px",left:"0px",bottom:"0px"})}else{if(this.name=="x2axis"){e+=j+f;this._elem.css({height:e+"px",left:"0px",top:"0px"})}else{if(this.name=="yaxis"){e+=j+k;this._elem.css({width:e+"px",left:"0px",top:"0px"});if(d&&this._label.constructor==a.jqplot.AxisLabelRenderer){this._label._elem.css("width",k+"px")}}else{e+=j+k;this._elem.css({width:e+"px",right:"0px",top:"0px"});if(d&&this._label.constructor==a.jqplot.AxisLabelRenderer){this._label._elem.css("width",k+"px")}}}}}};a.jqplot.CategoryAxisRenderer.prototype.pack=function(e,c){var C=this._ticks;var v=this.max;var s=this.min;var n=c.max;var l=c.min;var q=(this._label==null)?false:this._label.show;var x;for(var r in e){this._elem.css(r,e[r])}this._offsets=c;var g=n-l;var k=v-s;if(!this.reverse){this.u2p=function(h){return(h-s)*g/k+l};this.p2u=function(h){return(h-l)*k/g+s};if(this.name=="xaxis"||this.name=="x2axis"){this.series_u2p=function(h){return(h-s)*g/k};this.series_!
p2u=function(h){return h*k/g+s}}else{this.series_u2p=function(h){return(h-v)*g/k};this.series_p2u=function(h){return h*k/g+v}}}else{this.u2p=function(h){return l+(v-h)*g/k};this.p2u=function(h){return s+(h-l)*k/g};if(this.name=="xaxis"||this.name=="x2axis"){this.series_u2p=function(h){return(v-h)*g/k};this.series_p2u=function(h){return h*k/g+v}}else{this.series_u2p=function(h){return(s-h)*g/k};this.series_p2u=function(h){return h*k/g+s}}}if(this.show){if(this.name=="xaxis"||this.name=="x2axis"){for(x=0;x<C.length;x++){var o=C[x];if(o.show&&o.showLabel){var b;if(o.constructor==a.jqplot.CanvasAxisTickRenderer&&o.angle){var A=(this.name=="xaxis")?1:-1;switch(o.labelPosition){case"auto":if(A*o.angle<0){b=-o.getWidth()+o._textRenderer.height*Math.sin(-o._textRenderer.angle)/2}else{b=-o._textRenderer.height*Math.sin(o._textRenderer.angle)/2}break;case"end":b=-o.getWidth()+o._textRenderer.height*Math.sin(-o._textRenderer.angle)/2;break;case"start":b=-o._textRenderer.height*Math.sin(o._textRenderer.angle)/2;break;case"middle":b=-o.getWidth()/2+o._textRenderer.height*Math.sin(-o._textRenderer.angle)/2;break;default:b=-o.getWidth()/2+o._textRenderer.height*Math.sin(-o._textRenderer.angle)/2;break}}else{b=-o.getWidth()/2}var D=this.u2p(o.value)+b+"px";o._elem.css("left",D);o.pack()}}var z=["bottom",0];if(q){var m=this._label._elem.outerWidth(true);this._label._elem.css("left",l+g/2-m/2+"px");if(this.name=="xaxis"){this._label._elem.css("bottom","0px");z=["bottom",this._label._elem.outerHeight(true)]}else{this._label._elem.css("top","0px");z=["top",this._label._elem.outerHeight(true)]}this._label.pack()}var d=parseInt(this._ticks.length/this.groups,10);for(x=0;x<this._groupLabels.length;x++){var B=0;var f=0;for(var u=x*d;u<=(x+1)*d;u++){if(this._ticks[u]._elem&&this._ticks[u].label!=" "){var o=this._ticks[u]._elem;var r=o.position();B+=r.left+o.outerWidth(true)/2;f++}}B=B/f;this._groupLabels[x].css({left:(B-this._groupLabels[x].outerWidth(true)/2)});this._groupLabels[x].css(z[0],z[1])}}else{for(x=0;x<C.length;x++){var o=C[x!
];if(o.show&&o.showLabel){var b;if(o.constructor==a.jqplot.CanvasAxisTickRenderer&&o.angle){var A=(this.name=="yaxis")?1:-1;switch(o.labelPosition){case"auto":case"end":if(A*o.angle<0){b=-o._textRenderer.height*Math.cos(-o._textRenderer.angle)/2}else{b=-o.getHeight()+o._textRenderer.height*Math.cos(o._textRenderer.angle)/2}break;case"start":if(o.angle>0){b=-o._textRenderer.height*Math.cos(-o._textRenderer.angle)/2}else{b=-o.getHeight()+o._textRenderer.height*Math.cos(o._textRenderer.angle)/2}break;case"middle":b=-o.getHeight()/2;break;default:b=-o.getHeight()/2;break}}else{b=-o.getHeight()/2}var D=this.u2p(o.value)+b+"px";o._elem.css("top",D);o.pack()}}var z=["left",0];if(q){var y=this._label._elem.outerHeight(true);this._label._elem.css("top",n-g/2-y/2+"px");if(this.name=="yaxis"){this._label._elem.css("left","0px");z=["left",this._label._elem.outerWidth(true)]}else{this._label._elem.css("right","0px");z=["right",this._label._elem.outerWidth(true)]}this._label.pack()}var d=parseInt(this._ticks.length/this.groups,10);for(x=0;x<this._groupLabels.length;x++){var B=0;var f=0;for(var u=x*d;u<=(x+1)*d;u++){if(this._ticks[u]._elem&&this._ticks[u].label!=" "){var o=this._ticks[u]._elem;var r=o.position();B+=r.top+o.outerHeight()/2;f++}}B=B/f;this._groupLabels[x].css({top:B-this._groupLabels[x].outerHeight()/2});this._groupLabels[x].css(z[0],z[1])}}}}})(jQuery);
\ No newline at end of file
Modified: gnucash/trunk/src/report/jqplot/plugins/jqplot.ciParser.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.ciParser.js 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.ciParser.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -1,25 +1,48 @@
/**
- * Copyright (c) 2009 - 2010 Chris Leonello
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
- * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
- * The author would appreciate an email letting him know of any substantial
- * use of jqPlot. You can reach the author at: chris at jqplot dot com
- * or see http://www.jqplot.com/info.php . This is, of course,
- * not required.
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
- * Thanks for using jqPlot!
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
*
*/
(function($) {
/**
* Class: $.jqplot.ciParser
- * Data Renderer which converts a custom JSON data object into jqPlot data format.
+ * Data Renderer function which converts a custom JSON data object into jqPlot data format.
+ * Set this as a callable on the jqplot dataRenderer plot option:
*
+ * > plot = $.jqplot('mychart', [data], { dataRenderer: $.jqplot.ciParser, ... });
+ *
+ * Where data is an object in JSON format or a JSON encoded string conforming to the
+ * City Index API spec.
+ *
+ * Note that calling the renderer function is handled internally by jqPlot. The
+ * user does not have to call the function. The parameters described below will
+ * automatically be passed to the ciParser function.
+ *
* Parameters:
* data - JSON encoded string or object.
* plot - reference to jqPlot Plot object.
@@ -31,6 +54,7 @@
$.jqplot.ciParser = function (data, plot) {
var ret = [],
line,
+ temp,
i, j, k, kk;
if (typeof(data) == "string") {
@@ -47,7 +71,9 @@
}
}
- else return null;
+ else {
+ return null;
+ }
// function handleStrings
// Checks any JSON encoded strings to see if they are
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.ciParser.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.ciParser.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.ciParser.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(a){a.jqplot.ciParser=function(g,l){var m=[],o,n,h,f,e,c;if(typeof(g)=="string"){g=a.jqplot.JSON.parse(g,d)}else{if(typeof(g)=="object"){for(e in g){for(h=0;h<g[e].length;h++){for(c in g[e][h]){g[e][h][c]=d(c,g[e][h][c])}}}}else{return null}}function d(j,k){var i;if(k!=null){if(k.toString().indexOf("Date")>=0){i=/^\/Date\((-?[0-9]+)\)\/$/.exec(k);if(i){return parseInt(i[1],10)}}return k}}for(var b in g){o=[];n=g[b];switch(b){case"PriceTicks":for(h=0;h<n.length;h++){o.push([n[h]["TickDate"],n[h]["Price"]])}break;case"PriceBars":for(h=0;h<n.length;h++){o.push([n[h]["BarDate"],n[h]["Open"],n[h]["High"],n[h]["Low"],n[h]["Close"]])}break}m.push(o)}return m}})(jQuery);
\ No newline at end of file
Modified: gnucash/trunk/src/report/jqplot/plugins/jqplot.cursor.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.cursor.js 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.cursor.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -1,18 +1,31 @@
/**
- * Copyright (c) 2009 - 2010 Chris Leonello
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
- * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
- * The author would appreciate an email letting him know of any substantial
- * use of jqPlot. You can reach the author at: chris at jqplot dot com
- * or see http://www.jqplot.com/info.php . This is, of course,
- * not required.
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
- * Thanks for using jqPlot!
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
*
*/
(function($) {
@@ -80,6 +93,10 @@
// They Will be set through call to zoomProxy method.
this.zoomProxy = false;
this.zoomTarget = false;
+ // prop: looseZoom
+ // Will expand zoom range to provide more rounded tick values.
+ // Works only with linear, log and date axes.
+ this.looseZoom = true;
// prop: clickReset
// Will reset plot zoom if single click on plot without drag.
this.clickReset = false;
@@ -169,12 +186,19 @@
if (!c.zoomProxy) {
for (var ax in axes) {
axes[ax].reset();
+ axes[ax]._ticks = [];
+ // fake out tick creation algorithm to make sure original auto
+ // computed format string is used if _overrideFormatString is true
+ if (c._zoom.axes[ax] !== undefined) {
+ axes[ax]._autoFormatString = c._zoom.axes[ax].tickFormatString;
+ }
}
this.redraw();
}
else {
var ctx = this.plugins.cursor.zoomCanvas._ctx;
ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height);
+ ctx = null;
}
this.plugins.cursor._zoom.isZoomed = false;
this.target.trigger('jqplotResetZoom', [this, this.plugins.cursor]);
@@ -194,17 +218,49 @@
// called with context of plot
$.jqplot.Cursor.postDraw = function() {
var c = this.plugins.cursor;
- // if (c.zoom) {
- c.zoomCanvas = new $.jqplot.GenericCanvas();
- this.eventCanvas._elem.before(c.zoomCanvas.createElement(this._gridPadding, 'jqplot-zoom-canvas', this._plotDimensions));
- var zctx = c.zoomCanvas.setContext();
- // }
- c._tooltipElem = $('<div class="jqplot-cursor-tooltip" style="position:absolute;display:none"></div>');
- c.zoomCanvas._elem.before(c._tooltipElem);
+
+ // Memory Leaks patch
+ if (c.zoomCanvas) {
+ c.zoomCanvas.resetCanvas();
+ c.zoomCanvas = null;
+ }
+
+ if (c.cursorCanvas) {
+ c.cursorCanvas.resetCanvas();
+ c.cursorCanvas = null;
+ }
+
+ if (c._tooltipElem) {
+ c._tooltipElem.emptyForce();
+ c._tooltipElem = null;
+ }
+
+
+ if (c.zoom) {
+ c.zoomCanvas = new $.jqplot.GenericCanvas();
+ this.eventCanvas._elem.before(c.zoomCanvas.createElement(this._gridPadding, 'jqplot-zoom-canvas', this._plotDimensions, this));
+ c.zoomCanvas.setContext();
+ }
+
+ var elem = document.createElement('div');
+ c._tooltipElem = $(elem);
+ elem = null;
+ c._tooltipElem.addClass('jqplot-cursor-tooltip');
+ c._tooltipElem.css({position:'absolute', display:'none'});
+
+
+ if (c.zoomCanvas) {
+ c.zoomCanvas._elem.before(c._tooltipElem);
+ }
+
+ else {
+ this.eventCanvas._elem.before(c._tooltipElem);
+ }
+
if (c.showVerticalLine || c.showHorizontalLine) {
c.cursorCanvas = new $.jqplot.GenericCanvas();
- this.eventCanvas._elem.before(c.cursorCanvas.createElement(this._gridPadding, 'jqplot-cursor-canvas', this._plotDimensions));
- var zctx = c.cursorCanvas.setContext();
+ this.eventCanvas._elem.before(c.cursorCanvas.createElement(this._gridPadding, 'jqplot-cursor-canvas', this._plotDimensions, this));
+ c.cursorCanvas.setContext();
}
// if we are showing the positions in unit coordinates, and no axes groups
@@ -263,13 +319,18 @@
var cax = cursor._zoom.axes;
if (!plot.plugins.cursor.zoomProxy && cursor._zoom.isZoomed) {
for (var ax in axes) {
+ // axes[ax]._ticks = [];
+ // axes[ax].min = cax[ax].min;
+ // axes[ax].max = cax[ax].max;
+ // axes[ax].numberTicks = cax[ax].numberTicks;
+ // axes[ax].tickInterval = cax[ax].tickInterval;
+ // // for date axes
+ // axes[ax].daTickInterval = cax[ax].daTickInterval;
+ axes[ax].reset();
axes[ax]._ticks = [];
- axes[ax].min = cax[ax].min;
- axes[ax].max = cax[ax].max;
- axes[ax].numberTicks = cax[ax].numberTicks;
- axes[ax].tickInterval = cax[ax].tickInterval;
- // for date axes
- axes[ax].daTickInterval = cax[ax].daTickInterval;
+ // fake out tick creation algorithm to make sure original auto
+ // computed format string is used if _overrideFormatString is true
+ axes[ax]._autoFormatString = cax[ax].tickFormatString;
}
plot.redraw();
cursor._zoom.isZoomed = false;
@@ -277,6 +338,7 @@
else {
var ctx = cursor.zoomCanvas._ctx;
ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height);
+ ctx = null;
}
plot.target.trigger('jqplotResetZoom', [plot, cursor]);
};
@@ -291,9 +353,10 @@
var zaxes = c._zoom.axes;
var start = zaxes.start;
var end = zaxes.end;
- var min, max;
+ var min, max, dp, span,
+ newmin, newmax, curax, _numberTicks, ret;
var ctx = plot.plugins.cursor.zoomCanvas._ctx;
- // don't zoom is zoom area is too small (in pixels)
+ // don't zoom if zoom area is too small (in pixels)
if ((c.constrainZoomTo == 'none' && Math.abs(gridpos.x - c._zoom.start[0]) > 6 && Math.abs(gridpos.y - c._zoom.start[1]) > 6) || (c.constrainZoomTo == 'x' && Math.abs(gridpos.x - c._zoom.start[0]) > 6) || (c.constrainZoomTo == 'y' && Math.abs(gridpos.y - c._zoom.start[1]) > 6)) {
if (!plot.plugins.cursor.zoomProxy) {
for (var ax in datapos) {
@@ -306,22 +369,78 @@
c._zoom.axes[ax].daTickInterval = axes[ax].daTickInterval;
c._zoom.axes[ax].min = axes[ax].min;
c._zoom.axes[ax].max = axes[ax].max;
+ c._zoom.axes[ax].tickFormatString = (axes[ax].tickOptions != null) ? axes[ax].tickOptions.formatString : '';
}
+
+
if ((c.constrainZoomTo == 'none') || (c.constrainZoomTo == 'x' && ax.charAt(0) == 'x') || (c.constrainZoomTo == 'y' && ax.charAt(0) == 'y')) {
dp = datapos[ax];
if (dp != null) {
if (dp > start[ax]) {
- axes[ax].min = start[ax];
- axes[ax].max = dp;
+ newmin = start[ax];
+ newmax = dp;
}
else {
span = start[ax] - dp;
- axes[ax].max = start[ax];
- axes[ax].min = dp;
+ newmin = dp;
+ newmax = start[ax];
}
- axes[ax].tickInterval = null;
- // for date axes...
- axes[ax].daTickInterval = null;
+
+ curax = axes[ax];
+
+ _numberTicks = null;
+
+ // if aligning this axis, use number of ticks from previous axis.
+ // Do I need to reset somehow if alignTicks is changed and then graph is replotted??
+ if (curax.alignTicks) {
+ if (curax.name === 'x2axis' && plot.axes.xaxis.show) {
+ _numberTicks = plot.axes.xaxis.numberTicks;
+ }
+ else if (curax.name.charAt(0) === 'y' && curax.name !== 'yaxis' && curax.name !== 'yMidAxis' && plot.axes.yaxis.show) {
+ _numberTicks = plot.axes.yaxis.numberTicks;
+ }
+ }
+
+ if (this.looseZoom && (axes[ax].renderer.constructor === $.jqplot.LinearAxisRenderer || axes[ax].renderer.constructor === $.jqplot.LogAxisRenderer )) { //} || axes[ax].renderer.constructor === $.jqplot.DateAxisRenderer)) {
+
+ ret = $.jqplot.LinearTickGenerator(newmin, newmax, curax._scalefact, _numberTicks);
+
+ // if new minimum is less than "true" minimum of axis display, adjust it
+ if (axes[ax].tickInset && ret[0] < axes[ax].min + axes[ax].tickInset * axes[ax].tickInterval) {
+ ret[0] += ret[4];
+ ret[2] -= 1;
+ }
+
+ // if new maximum is greater than "true" max of axis display, adjust it
+ if (axes[ax].tickInset && ret[1] > axes[ax].max - axes[ax].tickInset * axes[ax].tickInterval) {
+ ret[1] -= ret[4];
+ ret[2] -= 1;
+ }
+
+ // for log axes, don't fall below current minimum, this will look bad and can't have 0 in range anyway.
+ if (axes[ax].renderer.constructor === $.jqplot.LogAxisRenderer && ret[0] < axes[ax].min) {
+ // remove a tick and shift min up
+ ret[0] += ret[4];
+ ret[2] -= 1;
+ }
+
+ axes[ax].min = ret[0];
+ axes[ax].max = ret[1];
+ axes[ax]._autoFormatString = ret[3];
+ axes[ax].numberTicks = ret[2];
+ axes[ax].tickInterval = ret[4];
+ // for date axes...
+ axes[ax].daTickInterval = [ret[4]/1000, 'seconds'];
+ }
+ else {
+ axes[ax].min = newmin;
+ axes[ax].max = newmax;
+ axes[ax].tickInterval = null;
+ axes[ax].numberTicks = null;
+ // for date axes...
+ axes[ax].daTickInterval = null;
+ }
+
axes[ax]._ticks = [];
}
}
@@ -337,6 +456,7 @@
ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height);
plot.redraw();
c._zoom.isZoomed = true;
+ ctx = null;
}
plot.target.trigger('jqplotZoom', [gridpos, datapos, plot, cursor]);
}
@@ -361,11 +481,14 @@
s += '<br />';
}
if (c.useAxesFormatters) {
- var xf = plot.axes[g[0]]._ticks[0].formatter;
- var yf = plot.axes[g[1]]._ticks[0].formatter;
- var xfstr = plot.axes[g[0]]._ticks[0].formatString;
- var yfstr = plot.axes[g[1]]._ticks[0].formatString;
- s += xf(xfstr, datapos[g[0]]) + ', '+ yf(yfstr, datapos[g[1]]);
+ for (var j=0; j<g.length; j++) {
+ if (j) {
+ s += ', ';
+ }
+ var af = plot.axes[g[j]]._ticks[0].formatter;
+ var afstr = plot.axes[g[j]]._ticks[0].formatString;
+ s += af(afstr, datapos[g[j]]);
+ }
}
else {
s += $.jqplot.sprintf(c.tooltipFormatString, datapos[g[0]], datapos[g[1]]);
@@ -456,11 +579,12 @@
}
}
}
+ ctx = null;
}
function getIntersectingPoints(plot, x, y) {
var ret = {indices:[], data:[]};
- var s, i, d0, d, j, r;
+ var s, i, d0, d, j, r, p;
var threshold;
var c = plot.plugins.cursor;
for (var i=0; i<plot.series.length; i++) {
@@ -528,8 +652,9 @@
break;
}
- c._tooltipElem.css('left', x);
- c._tooltipElem.css('top', y);
+ elem.css('left', x);
+ elem.css('top', y);
+ elem = null;
}
function positionTooltip(plot) {
@@ -586,6 +711,7 @@
elem.css({right:a, bottom:b});
break;
}
+ elem = null;
}
function handleClick (ev, gridpos, datapos, neighbor, plot) {
@@ -630,6 +756,7 @@
if (c.show) {
$(ev.target).css('cursor', c.previousCursor);
if (c.showTooltip && !(c._zoom.zooming && c.showTooltipOutsideZoom && !c.constrainOutsideZoom)) {
+ c._tooltipElem.empty();
c._tooltipElem.hide();
}
if (c.zoom) {
@@ -639,6 +766,7 @@
if (c.showVerticalLine || c.showHorizontalLine) {
var ctx = c.cursorCanvas._ctx;
ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height);
+ ctx = null;
}
if (c.showCursorLegend) {
var cells = $(plot.targetId + ' td.jqplot-cursor-legend-label');
@@ -683,7 +811,6 @@
function handleMouseMove(ev, gridpos, datapos, neighbor, plot) {
var c = plot.plugins.cursor;
- var ctx = c.zoomCanvas._ctx;
if (c.show) {
if (c.showTooltip) {
updateTooltip(gridpos, datapos, plot);
@@ -701,8 +828,11 @@
var plot = ev.data.plot;
var go = plot.eventCanvas._elem.offset();
var gridPos = {x:ev.pageX - go.left, y:ev.pageY - go.top};
- var dataPos = {xaxis:null, yaxis:null, x2axis:null, y2axis:null, y3axis:null, y4axis:null, y5axis:null, y6axis:null, y7axis:null, y8axis:null, y9axis:null};
- var an = ['xaxis', 'yaxis', 'x2axis', 'y2axis', 'y3axis', 'y4axis', 'y5axis', 'y6axis', 'y7axis', 'y8axis', 'y9axis'];
+ //////
+ // TO DO: handle yMidAxis
+ //////
+ var dataPos = {xaxis:null, yaxis:null, x2axis:null, y2axis:null, y3axis:null, y4axis:null, y5axis:null, y6axis:null, y7axis:null, y8axis:null, y9axis:null, yMidAxis:null};
+ var an = ['xaxis', 'yaxis', 'x2axis', 'y2axis', 'y3axis', 'y4axis', 'y5axis', 'y6axis', 'y7axis', 'y8axis', 'y9axis', 'yMidAxis'];
var ax = plot.axes;
var n, axis;
for (n=11; n>0; n--) {
@@ -720,6 +850,7 @@
var c = plot.plugins.cursor;
// don't do anything if not on grid.
if (c.show && c.zoom && c._zoom.started && !c.zoomTarget) {
+ ev.preventDefault();
var ctx = c.zoomCanvas._ctx;
var positions = getEventPosition(ev);
var gridpos = positions.gridPos;
@@ -755,12 +886,17 @@
sel().collapse();
}
drawZoomBox.call(c);
+ ctx = null;
}
}
function handleMouseDown(ev, gridpos, datapos, neighbor, plot) {
var c = plot.plugins.cursor;
- $(document).one('mouseup.jqplot_cursor', {plot:plot}, handleMouseUp);
+ if(plot.plugins.mobile){
+ $(document).one('vmouseup.jqplot_cursor', {plot:plot}, handleMouseUp);
+ } else {
+ $(document).one('mouseup.jqplot_cursor', {plot:plot}, handleMouseUp);
+ }
var axes = plot.axes;
if (document.onselectstart != undefined) {
c._oldHandlers.onselectstart = document.onselectstart;
@@ -778,6 +914,7 @@
if (!c.zoomProxy) {
var ctx = c.zoomCanvas._ctx;
ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height);
+ ctx = null;
}
if (c.constrainZoomTo == 'x') {
c._zoom.start = [gridpos.x, 0];
@@ -793,7 +930,12 @@
// get zoom starting position.
c._zoom.axes.start[ax] = datapos[ax];
}
- $(document).bind('mousemove.jqplotCursor', {plot:plot}, handleZoomMove);
+ if(plot.plugins.mobile){
+ $(document).bind('vmousemove.jqplotCursor', {plot:plot}, handleZoomMove);
+ } else {
+ $(document).bind('mousemove.jqplotCursor', {plot:plot}, handleZoomMove);
+ }
+
}
}
@@ -886,6 +1028,7 @@
ctx.clearRect(l, t, w, h);
// IE won't show transparent fill rect, so stroke a rect also.
ctx.strokeRect(l,t,w,h);
+ ctx = null;
}
$.jqplot.CursorLegendRenderer = function(options) {
@@ -898,15 +1041,23 @@
// called in context of a Legend
$.jqplot.CursorLegendRenderer.prototype.draw = function() {
+ if (this._elem) {
+ this._elem.emptyForce();
+ this._elem = null;
+ }
if (this.show) {
- var series = this._series;
+ var series = this._series, s;
// make a table. one line label per row.
- this._elem = $('<table class="jqplot-legend jqplot-cursor-legend" style="position:absolute"></table>');
+ var elem = document.createElement('div');
+ this._elem = $(elem);
+ elem = null;
+ this._elem.addClass('jqplot-legend jqplot-cursor-legend');
+ this._elem.css('position', 'absolute');
var pad = false;
for (var i = 0; i< series.length; i++) {
s = series[i];
- if (s.show) {
+ if (s.show && s.showLabel) {
var lt = $.jqplot.sprintf(this.formatString, s.label.toString());
if (lt) {
var color = s.color;
@@ -926,6 +1077,9 @@
}
}
}
+ series = s = null;
+ delete series;
+ delete s;
}
function addrow(label, color, pad, idx) {
@@ -945,8 +1099,10 @@
else {
td.html(label);
}
+ tr = null;
+ td = null;
}
return this._elem;
};
-})(jQuery);
\ No newline at end of file
+})(jQuery);
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.cursor.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.cursor.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.cursor.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(j){j.jqplot.Cursor=function(q){this.style="crosshair";this.previousCursor="auto";this.show=j.jqplot.config.enablePlugins;this.showTooltip=true;this.followMouse=false;this.tooltipLocation="se";this.tooltipOffset=6;this.showTooltipGridPosition=false;this.showTooltipUnitPosition=true;this.showTooltipDataPosition=false;this.tooltipFormatString="%.4P, %.4P";this.useAxesFormatters=true;this.tooltipAxisGroups=[];this.zoom=false;this.zoomProxy=false;this.zoomTarget=false;this.looseZoom=true;this.clickReset=false;this.dblClickReset=true;this.showVerticalLine=false;this.showHorizontalLine=false;this.constrainZoomTo="none";this.shapeRenderer=new j.jqplot.ShapeRenderer();this._zoom={start:[],end:[],started:false,zooming:false,isZoomed:false,axes:{start:{},end:{}},gridpos:{},datapos:{}};this._tooltipElem;this.zoomCanvas;this.cursorCanvas;this.intersectionThreshold=2;this.showCursorLegend=false;this.cursorLegendFormatString=j.jqplot.Cursor.cursorLegendFormatString;this._oldHandlers={onselectstart:null,ondrag:null,onmousedown:null};this.constrainOutsideZoom=true;this.showTooltipOutsideZoom=false;this.onGrid=false;j.extend(true,this,q)};j.jqplot.Cursor.cursorLegendFormatString="%s x:%s, y:%s";j.jqplot.Cursor.init=function(t,s,r){var q=r||{};this.plugins.cursor=new j.jqplot.Cursor(q.cursor);var u=this.plugins.cursor;if(u.show){j.jqplot.eventListenerHooks.push(["jqplotMouseEnter",b]);j.jqplot.eventListenerHooks.push(["jqplotMouseLeave",f]);j.jqplot.eventListenerHooks.push(["jqplotMouseMove",i]);if(u.showCursorLegend){r.legend=r.legend||{};r.legend.renderer=j.jqplot.CursorLegendRenderer;r.legend.formatString=this.plugins.cursor.cursorLegendFormatString;r.legend.show=true}if(u.zoom){j.jqplot.eventListenerHooks.push(["jqplotMouseDown",a]);if(u.clickReset){j.jqplot.eventListenerHooks.push(["jqplotClick",k])}if(u.dblClickReset){j.jqplot.eventListenerHooks.push(["jqplotDblClick",c])}}this.resetZoom=function(){var x=this.axes;if(!u.zoomProxy){for(var w in x){x[w].reset();x[w]._ticks=[];if(u._zoom.axes[w]!==undefine!
d){x[w]._autoFormatString=u._zoom.axes[w].tickFormatString}}this.redraw()}else{var v=this.plugins.cursor.zoomCanvas._ctx;v.clearRect(0,0,v.canvas.width,v.canvas.height);v=null}this.plugins.cursor._zoom.isZoomed=false;this.target.trigger("jqplotResetZoom",[this,this.plugins.cursor])};if(u.showTooltipDataPosition){u.showTooltipUnitPosition=false;u.showTooltipGridPosition=false;if(q.cursor.tooltipFormatString==undefined){u.tooltipFormatString=j.jqplot.Cursor.cursorLegendFormatString}}}};j.jqplot.Cursor.postDraw=function(){var x=this.plugins.cursor;if(x.zoomCanvas){x.zoomCanvas.resetCanvas();x.zoomCanvas=null}if(x.cursorCanvas){x.cursorCanvas.resetCanvas();x.cursorCanvas=null}if(x._tooltipElem){x._tooltipElem.emptyForce();x._tooltipElem=null}if(x.zoom){x.zoomCanvas=new j.jqplot.GenericCanvas();this.eventCanvas._elem.before(x.zoomCanvas.createElement(this._gridPadding,"jqplot-zoom-canvas",this._plotDimensions,this));x.zoomCanvas.setContext()}var v=document.createElement("div");x._tooltipElem=j(v);v=null;x._tooltipElem.addClass("jqplot-cursor-tooltip");x._tooltipElem.css({position:"absolute",display:"none"});if(x.zoomCanvas){x.zoomCanvas._elem.before(x._tooltipElem)}else{this.eventCanvas._elem.before(x._tooltipElem)}if(x.showVerticalLine||x.showHorizontalLine){x.cursorCanvas=new j.jqplot.GenericCanvas();this.eventCanvas._elem.before(x.cursorCanvas.createElement(this._gridPadding,"jqplot-cursor-canvas",this._plotDimensions,this));x.cursorCanvas.setContext()}if(x.showTooltipUnitPosition){if(x.tooltipAxisGroups.length===0){var t=this.series;var u;var q=[];for(var r=0;r<t.length;r++){u=t[r];var w=u.xaxis+","+u.yaxis;if(j.inArray(w,q)==-1){q.push(w)}}for(var r=0;r<q.length;r++){x.tooltipAxisGroups.push(q[r].split(","))}}}};j.jqplot.Cursor.zoomProxy=function(v,r){var q=v.plugins.cursor;var u=r.plugins.cursor;q.zoomTarget=true;q.zoom=true;q.style="auto";q.dblClickReset=false;u.zoom=true;u.zoomProxy=true;r.target.bind("jqplotZoom",t);r.target.bind("jqplotResetZoom",s);function t(x,w,z,y,A){q.doZoom(w,z,v,A)}function s(w,x,y){!
v.resetZoom()}};j.jqplot.Cursor.prototype.resetZoom=function(u,v){var t=u.axes;var s=v._zoom.axes;if(!u.plugins.cursor.zoomProxy&&v._zoom.isZoomed){for(var r in t){t[r].reset();t[r]._ticks=[];t[r]._autoFormatString=s[r].tickFormatString}u.redraw();v._zoom.isZoomed=false}else{var q=v.zoomCanvas._ctx;q.clearRect(0,0,q.canvas.width,q.canvas.height);q=null}u.target.trigger("jqplotResetZoom",[u,v])};j.jqplot.Cursor.resetZoom=function(q){q.resetZoom()};j.jqplot.Cursor.prototype.doZoom=function(G,t,C,u){var I=u;var F=C.axes;var r=I._zoom.axes;var w=r.start;var s=r.end;var B,E,z,D,v,x,q,H,J;var A=C.plugins.cursor.zoomCanvas._ctx;if((I.constrainZoomTo=="none"&&Math.abs(G.x-I._zoom.start[0])>6&&Math.abs(G.y-I._zoom.start[1])>6)||(I.constrainZoomTo=="x"&&Math.abs(G.x-I._zoom.start[0])>6)||(I.constrainZoomTo=="y"&&Math.abs(G.y-I._zoom.start[1])>6)){if(!C.plugins.cursor.zoomProxy){for(var y in t){if(I._zoom.axes[y]==undefined){I._zoom.axes[y]={};I._zoom.axes[y].numberTicks=F[y].numberTicks;I._zoom.axes[y].tickInterval=F[y].tickInterval;I._zoom.axes[y].daTickInterval=F[y].daTickInterval;I._zoom.axes[y].min=F[y].min;I._zoom.axes[y].max=F[y].max;I._zoom.axes[y].tickFormatString=(F[y].tickOptions!=null)?F[y].tickOptions.formatString:""}if((I.constrainZoomTo=="none")||(I.constrainZoomTo=="x"&&y.charAt(0)=="x")||(I.constrainZoomTo=="y"&&y.charAt(0)=="y")){z=t[y];if(z!=null){if(z>w[y]){v=w[y];x=z}else{D=w[y]-z;v=z;x=w[y]}q=F[y];H=null;if(q.alignTicks){if(q.name==="x2axis"&&C.axes.xaxis.show){H=C.axes.xaxis.numberTicks}else{if(q.name.charAt(0)==="y"&&q.name!=="yaxis"&&q.name!=="yMidAxis"&&C.axes.yaxis.show){H=C.axes.yaxis.numberTicks}}}if(this.looseZoom&&(F[y].renderer.constructor===j.jqplot.LinearAxisRenderer||F[y].renderer.constructor===j.jqplot.LogAxisRenderer)){J=j.jqplot.LinearTickGenerator(v,x,q._scalefact,H);if(F[y].tickInset&&J[0]<F[y].min+F[y].tickInset*F[y].tickInterval){J[0]+=J[4];J[2]-=1}if(F[y].tickInset&&J[1]>F[y].max-F[y].tickInset*F[y].tickInterval){J[1]-=J[4];J[2]-=1}if(F[y].renderer.constructor===j.jqplot.LogAxisRe!
nderer&&J[0]<F[y].min){J[0]+=J[4];J[2]-=1}F[y].min=J[0];F[y].max=J[1];F[y]._autoFormatString=J[3];F[y].numberTicks=J[2];F[y].tickInterval=J[4];F[y].daTickInterval=[J[4]/1000,"seconds"]}else{F[y].min=v;F[y].max=x;F[y].tickInterval=null;F[y].numberTicks=null;F[y].daTickInterval=null}F[y]._ticks=[]}}}A.clearRect(0,0,A.canvas.width,A.canvas.height);C.redraw();I._zoom.isZoomed=true;A=null}C.target.trigger("jqplotZoom",[G,t,C,u])}};j.jqplot.preInitHooks.push(j.jqplot.Cursor.init);j.jqplot.postDrawHooks.push(j.jqplot.Cursor.postDraw);function e(G,r,C){var J=C.plugins.cursor;var w="";var N=false;if(J.showTooltipGridPosition){w=G.x+", "+G.y;N=true}if(J.showTooltipUnitPosition){var F;for(var E=0;E<J.tooltipAxisGroups.length;E++){F=J.tooltipAxisGroups[E];if(N){w+="<br />"}if(J.useAxesFormatters){for(var D=0;D<F.length;D++){if(D){w+=", "}var H=C.axes[F[D]]._ticks[0].formatter;var B=C.axes[F[D]]._ticks[0].formatString;w+=H(B,r[F[D]])}}else{w+=j.jqplot.sprintf(J.tooltipFormatString,r[F[0]],r[F[1]])}N=true}}if(J.showTooltipDataPosition){var u=C.series;var M=d(C,G.x,G.y);var N=false;for(var E=0;E<u.length;E++){if(u[E].show){var y=u[E].index;var t=u[E].label.toString();var I=j.inArray(y,M.indices);var z=undefined;var x=undefined;if(I!=-1){var L=M.data[I].data;if(J.useAxesFormatters){var A=u[E]._xaxis._ticks[0].formatter;var q=u[E]._yaxis._ticks[0].formatter;var K=u[E]._xaxis._ticks[0].formatString;var v=u[E]._yaxis._ticks[0].formatString;z=A(K,L[0]);x=q(v,L[1])}else{z=L[0];x=L[1]}if(N){w+="<br />"}w+=j.jqplot.sprintf(J.tooltipFormatString,t,z,x);N=true}}}}J._tooltipElem.html(w)}function g(C,A){var E=A.plugins.cursor;var z=E.cursorCanvas._ctx;z.clearRect(0,0,z.canvas.width,z.canvas.height);if(E.showVerticalLine){E.shapeRenderer.draw(z,[[C.x,0],[C.x,z.canvas.height]])}if(E.showHorizontalLine){E.shapeRenderer.draw(z,[[0,C.y],[z.canvas.width,C.y]])}var G=d(A,C.x,C.y);if(E.showCursorLegend){var r=j(A.targetId+" td.jqplot-cursor-legend-label");for(var B=0;B<r.length;B++){var v=j(r[B]).data("seriesIndex");var t=A.series[v];var s=t.labe!
l.toString();var D=j.inArray(v,G.indices);var x=undefined;var w=undefined;if(D!=-1){var H=G.data[D].data;if(E.useAxesFormatters){var y=t._xaxis._ticks[0].formatter;var q=t._yaxis._ticks[0].formatter;var F=t._xaxis._ticks[0].formatString;var u=t._yaxis._ticks[0].formatString;x=y(F,H[0]);w=q(u,H[1])}else{x=H[0];w=H[1]}}if(A.legend.escapeHtml){j(r[B]).text(j.jqplot.sprintf(E.cursorLegendFormatString,s,x,w))}else{j(r[B]).html(j.jqplot.sprintf(E.cursorLegendFormatString,s,x,w))}}}z=null}function d(A,F,E){var B={indices:[],data:[]};var G,w,u,C,v,q,t;var z;var D=A.plugins.cursor;for(var w=0;w<A.series.length;w++){G=A.series[w];q=G.renderer;if(G.show){z=D.intersectionThreshold;if(G.showMarker){z+=G.markerRenderer.size/2}for(var v=0;v<G.gridData.length;v++){t=G.gridData[v];if(D.showVerticalLine){if(Math.abs(F-t[0])<=z){B.indices.push(w);B.data.push({seriesIndex:w,pointIndex:v,gridData:t,data:G.data[v]})}}}}}return B}function n(r,t){var v=t.plugins.cursor;var s=v._tooltipElem;switch(v.tooltipLocation){case"nw":var q=r.x+t._gridPadding.left-s.outerWidth(true)-v.tooltipOffset;var u=r.y+t._gridPadding.top-v.tooltipOffset-s.outerHeight(true);break;case"n":var q=r.x+t._gridPadding.left-s.outerWidth(true)/2;var u=r.y+t._gridPadding.top-v.tooltipOffset-s.outerHeight(true);break;case"ne":var q=r.x+t._gridPadding.left+v.tooltipOffset;var u=r.y+t._gridPadding.top-v.tooltipOffset-s.outerHeight(true);break;case"e":var q=r.x+t._gridPadding.left+v.tooltipOffset;var u=r.y+t._gridPadding.top-s.outerHeight(true)/2;break;case"se":var q=r.x+t._gridPadding.left+v.tooltipOffset;var u=r.y+t._gridPadding.top+v.tooltipOffset;break;case"s":var q=r.x+t._gridPadding.left-s.outerWidth(true)/2;var u=r.y+t._gridPadding.top+v.tooltipOffset;break;case"sw":var q=r.x+t._gridPadding.left-s.outerWidth(true)-v.tooltipOffset;var u=r.y+t._gridPadding.top+v.tooltipOffset;break;case"w":var q=r.x+t._gridPadding.left-s.outerWidth(true)-v.tooltipOffset;var u=r.y+t._gridPadding.top-s.outerHeight(true)/2;break;default:var q=r.x+t._gridPadding.left+v.tooltipOffset;var!
u=r.y+t.._gridPadding.top+v.tooltipOffset;break}s.css("left",q);s.css("top",u);s=null}function m(u){var s=u._gridPadding;var v=u.plugins.cursor;var t=v._tooltipElem;switch(v.tooltipLocation){case"nw":var r=s.left+v.tooltipOffset;var q=s.top+v.tooltipOffset;t.css("left",r);t.css("top",q);break;case"n":var r=(s.left+(u._plotDimensions.width-s.right))/2-t.outerWidth(true)/2;var q=s.top+v.tooltipOffset;t.css("left",r);t.css("top",q);break;case"ne":var r=s.right+v.tooltipOffset;var q=s.top+v.tooltipOffset;t.css({right:r,top:q});break;case"e":var r=s.right+v.tooltipOffset;var q=(s.top+(u._plotDimensions.height-s.bottom))/2-t.outerHeight(true)/2;t.css({right:r,top:q});break;case"se":var r=s.right+v.tooltipOffset;var q=s.bottom+v.tooltipOffset;t.css({right:r,bottom:q});break;case"s":var r=(s.left+(u._plotDimensions.width-s.right))/2-t.outerWidth(true)/2;var q=s.bottom+v.tooltipOffset;t.css({left:r,bottom:q});break;case"sw":var r=s.left+v.tooltipOffset;var q=s.bottom+v.tooltipOffset;t.css({left:r,bottom:q});break;case"w":var r=s.left+v.tooltipOffset;var q=(s.top+(u._plotDimensions.height-s.bottom))/2-t.outerHeight(true)/2;t.css({left:r,top:q});break;default:var r=s.right-v.tooltipOffset;var q=s.bottom+v.tooltipOffset;t.css({right:r,bottom:q});break}t=null}function k(r,q,v,u,t){r.preventDefault();r.stopImmediatePropagation();var w=t.plugins.cursor;if(w.clickReset){w.resetZoom(t,w)}var s=window.getSelection;if(document.selection&&document.selection.empty){document.selection.empty()}else{if(s&&!s().isCollapsed){s().collapse()}}return false}function c(r,q,v,u,t){r.preventDefault();r.stopImmediatePropagation();var w=t.plugins.cursor;if(w.dblClickReset){w.resetZoom(t,w)}var s=window.getSelection;if(document.selection&&document.selection.empty){document.selection.empty()}else{if(s&&!s().isCollapsed){s().collapse()}}return false}function f(w,t,q,z,u){var v=u.plugins.cursor;v.onGrid=false;if(v.show){j(w.target).css("cursor",v.previousCursor);if(v.showTooltip&&!(v._zoom.zooming&&v.showTooltipOutsideZoom&&!v.constrainOutsideZoom)){!
v._tooltipElem.empty();v._tooltipElem.hide()}if(v.zoom){v._zoom.gridpos=t;v._zoom.datapos=q}if(v.showVerticalLine||v.showHorizontalLine){var B=v.cursorCanvas._ctx;B.clearRect(0,0,B.canvas.width,B.canvas.height);B=null}if(v.showCursorLegend){var A=j(u.targetId+" td.jqplot-cursor-legend-label");for(var s=0;s<A.length;s++){var y=j(A[s]).data("seriesIndex");var r=u.series[y];var x=r.label.toString();if(u.legend.escapeHtml){j(A[s]).text(j.jqplot.sprintf(v.cursorLegendFormatString,x,undefined,undefined))}else{j(A[s]).html(j.jqplot.sprintf(v.cursorLegendFormatString,x,undefined,undefined))}}}}}function b(r,q,u,t,s){var v=s.plugins.cursor;v.onGrid=true;if(v.show){v.previousCursor=r.target.style.cursor;r.target.style.cursor=v.style;if(v.showTooltip){e(q,u,s);if(v.followMouse){n(q,s)}else{m(s)}v._tooltipElem.show()}if(v.showVerticalLine||v.showHorizontalLine){g(q,s)}}}function i(r,q,u,t,s){var v=s.plugins.cursor;if(v.show){if(v.showTooltip){e(q,u,s);if(v.followMouse){n(q,s)}}if(v.showVerticalLine||v.showHorizontalLine){g(q,s)}}}function o(y){var x=y.data.plot;var t=x.eventCanvas._elem.offset();var w={x:y.pageX-t.left,y:y.pageY-t.top};var u={xaxis:null,yaxis:null,x2axis:null,y2axis:null,y3axis:null,y4axis:null,y5axis:null,y6axis:null,y7axis:null,y8axis:null,y9axis:null,yMidAxis:null};var v=["xaxis","yaxis","x2axis","y2axis","y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis","yMidAxis"];var q=x.axes;var r,s;for(r=11;r>0;r--){s=v[r-1];if(q[s].show){u[s]=q[s].series_p2u(w[s.charAt(0)])}}return{offsets:t,gridPos:w,dataPos:u}}function h(z){var x=z.data.plot;var y=x.plugins.cursor;if(y.show&&y.zoom&&y._zoom.started&&!y.zoomTarget){z.preventDefault();var B=y.zoomCanvas._ctx;var v=o(z);var w=v.gridPos;var t=v.dataPos;y._zoom.gridpos=w;y._zoom.datapos=t;y._zoom.zooming=true;var u=w.x;var s=w.y;var A=B.canvas.height;var q=B.canvas.width;if(y.showTooltip&&!y.onGrid&&y.showTooltipOutsideZoom){e(w,t,x);if(y.followMouse){n(w,x)}}if(y.constrainZoomTo=="x"){y._zoom.end=[u,A]}else{if(y.constrainZoomTo=="y"){y._zoom.end=[q,s]}el!
se{y._zoom.end=[u,s]}}var r=window.getSelection;if(document.selection&&document.selection.empty){document.selection.empty()}else{if(r&&!r().isCollapsed){r().collapse()}}l.call(y);B=null}}function a(w,s,r,x,t){var v=t.plugins.cursor;if(t.plugins.mobile){j(document).one("vmouseup.jqplot_cursor",{plot:t},p)}else{j(document).one("mouseup.jqplot_cursor",{plot:t},p)}var u=t.axes;if(document.onselectstart!=undefined){v._oldHandlers.onselectstart=document.onselectstart;document.onselectstart=function(){return false}}if(document.ondrag!=undefined){v._oldHandlers.ondrag=document.ondrag;document.ondrag=function(){return false}}if(document.onmousedown!=undefined){v._oldHandlers.onmousedown=document.onmousedown;document.onmousedown=function(){return false}}if(v.zoom){if(!v.zoomProxy){var y=v.zoomCanvas._ctx;y.clearRect(0,0,y.canvas.width,y.canvas.height);y=null}if(v.constrainZoomTo=="x"){v._zoom.start=[s.x,0]}else{if(v.constrainZoomTo=="y"){v._zoom.start=[0,s.y]}else{v._zoom.start=[s.x,s.y]}}v._zoom.started=true;for(var q in r){v._zoom.axes.start[q]=r[q]}if(t.plugins.mobile){j(document).bind("vmousemove.jqplotCursor",{plot:t},h)}else{j(document).bind("mousemove.jqplotCursor",{plot:t},h)}}}function p(y){var v=y.data.plot;var x=v.plugins.cursor;if(x.zoom&&x._zoom.zooming&&!x.zoomTarget){var u=x._zoom.gridpos.x;var r=x._zoom.gridpos.y;var t=x._zoom.datapos;var z=x.zoomCanvas._ctx.canvas.height;var q=x.zoomCanvas._ctx.canvas.width;var w=v.axes;if(x.constrainOutsideZoom&&!x.onGrid){if(u<0){u=0}else{if(u>q){u=q}}if(r<0){r=0}else{if(r>z){r=z}}for(var s in t){if(t[s]){if(s.charAt(0)=="x"){t[s]=w[s].series_p2u(u)}else{t[s]=w[s].series_p2u(r)}}}}if(x.constrainZoomTo=="x"){r=z}else{if(x.constrainZoomTo=="y"){u=q}}x._zoom.end=[u,r];x._zoom.gridpos={x:u,y:r};x.doZoom(x._zoom.gridpos,t,v,x)}x._zoom.started=false;x._zoom.zooming=false;j(document).unbind("mousemove.jqplotCursor",h);if(document.onselectstart!=undefined&&x._oldHandlers.onselectstart!=null){document.onselectstart=x._oldHandlers.onselectstart;x._oldHandlers.onselectstart=null}i!
f(document.ondrag!=undefined&&x._oldHandlers.ondrag!=null){document.ondrag=x._oldHandlers.ondrag;x._oldHandlers.ondrag=null}if(document.onmousedown!=undefined&&x._oldHandlers.onmousedown!=null){document.onmousedown=x._oldHandlers.onmousedown;x._oldHandlers.onmousedown=null}}function l(){var y=this._zoom.start;var u=this._zoom.end;var s=this.zoomCanvas._ctx;var r,v,x,q;if(u[0]>y[0]){r=y[0];q=u[0]-y[0]}else{r=u[0];q=y[0]-u[0]}if(u[1]>y[1]){v=y[1];x=u[1]-y[1]}else{v=u[1];x=y[1]-u[1]}s.fillStyle="rgba(0,0,0,0.2)";s.strokeStyle="#999999";s.lineWidth=1;s.clearRect(0,0,s.canvas.width,s.canvas.height);s.fillRect(0,0,s.canvas.width,s.canvas.height);s.clearRect(r,v,q,x);s.strokeRect(r,v,q,x);s=null}j.jqplot.CursorLegendRenderer=function(q){j.jqplot.TableLegendRenderer.call(this,q);this.formatString="%s"};j.jqplot.CursorLegendRenderer.prototype=new j.jqplot.TableLegendRenderer();j.jqplot.CursorLegendRenderer.prototype.constructor=j.jqplot.CursorLegendRenderer;j.jqplot.CursorLegendRenderer.prototype.draw=function(){if(this._elem){this._elem.emptyForce();this._elem=null}if(this.show){var w=this._series,A;var r=document.createElement("div");this._elem=j(r);r=null;this._elem.addClass("jqplot-legend jqplot-cursor-legend");this._elem.css("position","absolute");var q=false;for(var x=0;x<w.length;x++){A=w[x];if(A.show&&A.showLabel){var v=j.jqplot.sprintf(this.formatString,A.label.toString());if(v){var t=A.color;if(A._stack&&!A.fill){t=""}z.call(this,v,t,q,x);q=true}for(var u=0;u<j.jqplot.addLegendRowHooks.length;u++){var y=j.jqplot.addLegendRowHooks[u].call(this,A);if(y){z.call(this,y.label,y.color,q);q=true}}}}w=A=null;delete w;delete A}function z(D,C,F,s){var B=(F)?this.rowSpacing:"0";var E=j('<tr class="jqplot-legend jqplot-cursor-legend"></tr>').appendTo(this._elem);E.data("seriesIndex",s);j('<td class="jqplot-legend jqplot-cursor-legend-swatch" style="padding-top:'+B+';"><div style="border:1px solid #cccccc;padding:0.2em;"><div class="jqplot-cursor-legend-swatch" style="background-color:'+C+';"></div></div></td>').appendTo(E)!
;var G=j('<td class="jqplot-legend jqplot-cursor-legend-label" style="vertical-align:middle;padding-top:'+B+';"></td>');G.appendTo(E);G.data("seriesIndex",s);if(this.escapeHtml){G.text(D)}else{G.html(D)}E=null;G=null}return this._elem}})(jQuery);
\ No newline at end of file
Modified: gnucash/trunk/src/report/jqplot/plugins/jqplot.dateAxisRenderer.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.dateAxisRenderer.js 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.dateAxisRenderer.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -1,18 +1,31 @@
/**
- * Copyright (c) 2009 - 2010 Chris Leonello
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
- * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
- * The author would appreciate an email letting him know of any substantial
- * use of jqPlot. You can reach the author at: chris at jqplot dot com
- * or see http://www.jqplot.com/info.php . This is, of course,
- * not required.
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
- * Thanks for using jqPlot!
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
*
*/
(function($) {
@@ -94,7 +107,42 @@
*/
$.jqplot.DateAxisRenderer = function() {
$.jqplot.LinearAxisRenderer.call(this);
+ this.date = new $.jsDate();
};
+
+ var second = 1000;
+ var minute = 60 * second;
+ var hour = 60 * minute;
+ var day = 24 * hour;
+ var week = 7 * day;
+
+ // these are less definitive
+ var month = 30.4368499 * day;
+ var year = 365.242199 * day;
+
+ var daysInMonths = [31,28,31,30,31,30,31,30,31,30,31,30];
+ // array of consistent nice intervals. Longer intervals
+ // will depend on days in month, days in year, etc.
+ var niceFormatStrings = ['%M:%S.%#N', '%M:%S.%#N', '%M:%S.%#N', '%M:%S', '%M:%S', '%M:%S', '%M:%S', '%H:%M:%S', '%H:%M:%S', '%H:%M', '%H:%M', '%H:%M', '%H:%M', '%H:%M', '%H:%M', '%a %H:%M', '%a %H:%M', '%b %e %H:%M', '%b %e %H:%M', '%b %e %H:%M', '%b %e %H:%M', '%v', '%v', '%v', '%v', '%v', '%v', '%v'];
+ var niceIntervals = [0.1*second, 0.2*second, 0.5*second, second, 2*second, 5*second, 10*second, 15*second, 30*second, minute, 2*minute, 5*minute, 10*minute, 15*minute, 30*minute, hour, 2*hour, 4*hour, 6*hour, 8*hour, 12*hour, day, 2*day, 3*day, 4*day, 5*day, week, 2*week];
+
+ var niceMonthlyIntervals = [];
+
+ function bestDateInterval(min, max, titarget) {
+ // iterate through niceIntervals to find one closest to titarget
+ var badness = Number.MAX_VALUE;
+ var temp, bestTi, bestfmt;
+ for (var i=0, l=niceIntervals.length; i < l; i++) {
+ temp = Math.abs(titarget - niceIntervals[i]);
+ if (temp < badness) {
+ badness = temp;
+ bestTi = niceIntervals[i];
+ bestfmt = niceFormatStrings[i];
+ }
+ }
+
+ return [bestTi, bestfmt];
+ }
$.jqplot.DateAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer();
$.jqplot.DateAxisRenderer.prototype.constructor = $.jqplot.DateAxisRenderer;
@@ -103,7 +151,7 @@
if (!format) {
format = '%Y/%m/%d';
}
- return Date.create(val).strftime(format);
+ return $.jsDate.strftime(val, format);
};
$.jqplot.DateAxisRenderer.prototype.init = function(options){
@@ -113,77 +161,211 @@
// this.tickRenderer = $.jqplot.AxisTickRenderer;
// this.labelRenderer = $.jqplot.AxisLabelRenderer;
this.tickOptions.formatter = $.jqplot.DateTickFormatter;
+ // prop: tickInset
+ // Controls the amount to inset the first and last ticks from
+ // the edges of the grid, in multiples of the tick interval.
+ // 0 is no inset, 0.5 is one half a tick interval, 1 is a full
+ // tick interval, etc.
+ this.tickInset = 0;
+ // prop: drawBaseline
+ // True to draw the axis baseline.
+ this.drawBaseline = true;
+ // prop: baselineWidth
+ // width of the baseline in pixels.
+ this.baselineWidth = null;
+ // prop: baselineColor
+ // CSS color spec for the baseline.
+ this.baselineColor = null;
this.daTickInterval = null;
this._daTickInterval = null;
+
$.extend(true, this, options);
- var db = this._dataBounds;
+
+ var db = this._dataBounds,
+ stats,
+ sum,
+ s,
+ d,
+ pd,
+ sd,
+ intv;
+
// Go through all the series attached to this axis and find
// the min/max bounds for this axis.
for (var i=0; i<this._series.length; i++) {
- var s = this._series[i];
- var d = s.data;
- var pd = s._plotData;
- var sd = s._stackData;
+ stats = {intervals:[], frequencies:{}, sortedIntervals:[], min:null, max:null, mean:null};
+ sum = 0;
+ s = this._series[i];
+ d = s.data;
+ pd = s._plotData;
+ sd = s._stackData;
+ intv = 0;
for (var j=0; j<d.length; j++) {
if (this.name == 'xaxis' || this.name == 'x2axis') {
- d[j][0] = Date.create(d[j][0]).getTime();
- pd[j][0] = Date.create(d[j][0]).getTime();
- sd[j][0] = Date.create(d[j][0]).getTime();
- if (d[j][0] < db.min || db.min == null) {
+ d[j][0] = new $.jsDate(d[j][0]).getTime();
+ pd[j][0] = new $.jsDate(d[j][0]).getTime();
+ sd[j][0] = new $.jsDate(d[j][0]).getTime();
+ if ((d[j][0] != null && d[j][0] < db.min) || db.min == null) {
db.min = d[j][0];
}
- if (d[j][0] > db.max || db.max == null) {
+ if ((d[j][0] != null && d[j][0] > db.max) || db.max == null) {
db.max = d[j][0];
}
+ if (j>0) {
+ intv = Math.abs(d[j][0] - d[j-1][0]);
+ stats.intervals.push(intv);
+ if (stats.frequencies.hasOwnProperty(intv)) {
+ stats.frequencies[intv] += 1;
+ }
+ else {
+ stats.frequencies[intv] = 1;
+ }
+ }
+ sum += intv;
+
}
else {
- d[j][1] = Date.create(d[j][1]).getTime();
- pd[j][1] = Date.create(d[j][1]).getTime();
- sd[j][1] = Date.create(d[j][1]).getTime();
- if (d[j][1] < db.min || db.min == null) {
+ d[j][1] = new $.jsDate(d[j][1]).getTime();
+ pd[j][1] = new $.jsDate(d[j][1]).getTime();
+ sd[j][1] = new $.jsDate(d[j][1]).getTime();
+ if ((d[j][1] != null && d[j][1] < db.min) || db.min == null) {
db.min = d[j][1];
}
- if (d[j][1] > db.max || db.max == null) {
+ if ((d[j][1] != null && d[j][1] > db.max) || db.max == null) {
db.max = d[j][1];
}
- }
+ if (j>0) {
+ intv = Math.abs(d[j][1] - d[j-1][1]);
+ stats.intervals.push(intv);
+ if (stats.frequencies.hasOwnProperty(intv)) {
+ stats.frequencies[intv] += 1;
+ }
+ else {
+ stats.frequencies[intv] = 1;
+ }
+ }
+ }
+ sum += intv;
}
+
+ if (s.renderer.bands) {
+ if (s.renderer.bands.hiData.length) {
+ var bd = s.renderer.bands.hiData;
+ for (var j=0, l=bd.length; j < l; j++) {
+ if (this.name === 'xaxis' || this.name === 'x2axis') {
+ bd[j][0] = new $.jsDate(bd[j][0]).getTime();
+ if ((bd[j][0] != null && bd[j][0] > db.max) || db.max == null) {
+ db.max = bd[j][0];
+ }
+ }
+ else {
+ bd[j][1] = new $.jsDate(bd[j][1]).getTime();
+ if ((bd[j][1] != null && bd[j][1] > db.max) || db.max == null) {
+ db.max = bd[j][1];
+ }
+ }
+ }
+ }
+ if (s.renderer.bands.lowData.length) {
+ var bd = s.renderer.bands.lowData;
+ for (var j=0, l=bd.length; j < l; j++) {
+ if (this.name === 'xaxis' || this.name === 'x2axis') {
+ bd[j][0] = new $.jsDate(bd[j][0]).getTime();
+ if ((bd[j][0] != null && bd[j][0] < db.min) || db.min == null) {
+ db.min = bd[j][0];
+ }
+ }
+ else {
+ bd[j][1] = new $.jsDate(bd[j][1]).getTime();
+ if ((bd[j][1] != null && bd[j][1] < db.min) || db.min == null) {
+ db.min = bd[j][1];
+ }
+ }
+ }
+ }
+ }
+
+ var tempf = 0,
+ tempn=0;
+ for (var n in stats.frequencies) {
+ stats.sortedIntervals.push({interval:n, frequency:stats.frequencies[n]});
+ }
+ stats.sortedIntervals.sort(function(a, b){
+ return b.frequency - a.frequency;
+ });
+
+ stats.min = $.jqplot.arrayMin(stats.intervals);
+ stats.max = $.jqplot.arrayMax(stats.intervals);
+ stats.mean = sum/d.length;
+ this._intervalStats.push(stats);
+ stats = sum = s = d = pd = sd = null;
}
+ db = null;
+
};
// called with scope of an axis
$.jqplot.DateAxisRenderer.prototype.reset = function() {
- this.min = this._min;
- this.max = this._max;
- this.tickInterval = this._tickInterval;
- this.numberTicks = this._numberTicks;
+ this.min = this._options.min;
+ this.max = this._options.max;
+ this.tickInterval = this._options.tickInterval;
+ this.numberTicks = this._options.numberTicks;
+ this._autoFormatString = '';
+ if (this._overrideFormatString && this.tickOptions && this.tickOptions.formatString) {
+ this.tickOptions.formatString = '';
+ }
this.daTickInterval = this._daTickInterval;
// this._ticks = this.__ticks;
};
- $.jqplot.DateAxisRenderer.prototype.createTicks = function() {
+ $.jqplot.DateAxisRenderer.prototype.createTicks = function(plot) {
// we're are operating on an axis here
var ticks = this._ticks;
var userTicks = this.ticks;
var name = this.name;
// databounds were set on axis initialization.
var db = this._dataBounds;
- var dim, interval;
+ var iv = this._intervalStats;
+ var dim = (this.name.charAt(0) === 'x') ? this._plotDimensions.width : this._plotDimensions.height;
+ var interval;
var min, max;
var pos1, pos2;
var tt, i;
+ var threshold = 30;
+ var insetMult = 1;
+
+ var tickInterval = this.tickInterval;
// if we already have ticks, use them.
// ticks must be in order of increasing value.
+ min = ((this.min != null) ? new $.jsDate(this.min).getTime() : db.min);
+ max = ((this.max != null) ? new $.jsDate(this.max).getTime() : db.max);
+
+ // see if we're zooming. if we are, don't use the min and max we're given,
+ // but compute some nice ones. They will be reset later.
+
+ var cursor = plot.plugins.cursor;
+
+ if (cursor && cursor._zoom && cursor._zoom.zooming) {
+ this.min = null;
+ this.max = null;
+ }
+
+ var range = max - min;
+
+ if (this.tickOptions == null || !this.tickOptions.formatString) {
+ this._overrideFormatString = true;
+ }
+
if (userTicks.length) {
// ticks could be 1D or 2D array of [val, val, ,,,] or [[val, label], [val, label], ...] or mixed
for (i=0; i<userTicks.length; i++){
var ut = userTicks[i];
var t = new this.tickRenderer(this.tickOptions);
if (ut.constructor == Array) {
- t.value = Date.create(ut[0]).getTime();
+ t.value = new $.jsDate(ut[0]).getTime();
t.label = ut[1];
if (!this.showTicks) {
t.showLabel = false;
@@ -197,7 +379,7 @@
}
else {
- t.value = Date.create(ut).getTime();
+ t.value = new $.jsDate(ut).getTime();
if (!this.showTicks) {
t.showLabel = false;
t.showMark = false;
@@ -214,9 +396,238 @@
this.max = this._ticks[this.numberTicks-1].value;
this.daTickInterval = [(this.max - this.min) / (this.numberTicks - 1)/1000, 'seconds'];
}
+
+ ////////
+ // We don't have any ticks yet, let's make some!
+ ////////
+
+ // special case when there is only one point, make three tick marks to center the point
+ else if (this.min == null && this.max == null && db.min == db.max)
+ {
+ var onePointOpts = $.extend(true, {}, this.tickOptions, {name: this.name, value: null});
+ var delta = 300000;
+ this.min = db.min - delta;
+ this.max = db.max + delta;
+ this.numberTicks = 3;
+
+ for(var i=this.min;i<=this.max;i+= delta)
+ {
+ onePointOpts.value = i;
+
+ var t = new this.tickRenderer(onePointOpts);
+
+ if (this._overrideFormatString && this._autoFormatString != '') {
+ t.formatString = this._autoFormatString;
+ }
+
+ t.showLabel = false;
+ t.showMark = false;
+
+ this._ticks.push(t);
+ }
+
+ if(this.showTicks) {
+ this._ticks[1].showLabel = true;
+ }
+ if(this.showTickMarks) {
+ this._ticks[1].showTickMarks = true;
+ }
+ }
+ // if user specified min and max are null, we set those to make best ticks.
+ else if (this.min == null && this.max == null) {
+
+ var opts = $.extend(true, {}, this.tickOptions, {name: this.name, value: null});
+
+ // want to find a nice interval
+ var nttarget,
+ titarget;
+
+ // if no tickInterval or numberTicks options specified, make a good guess.
+ if (!this.tickInterval && !this.numberTicks) {
+ var tdim = Math.max(dim, threshold+1);
+ // how many ticks to put on the axis?
+ // date labels tend to be long. If ticks not rotated,
+ // don't use too many and have a high spacing factor.
+ // If we are rotating ticks, use a lower factor.
+ var spacingFactor = 115;
+ if (this.tickRenderer === $.jqplot.CanvasAxisTickRenderer && this.tickOptions.angle) {
+ spacingFactor = 115 - 40 * Math.abs(Math.sin(this.tickOptions.angle/180*Math.PI));
+ }
+
+ nttarget = Math.ceil((tdim-threshold)/spacingFactor + 1);
+ titarget = (max - min) / (nttarget - 1);
+ }
+
+ // If tickInterval is specified, we'll try to honor it.
+ // Not gauranteed to get this interval, but we'll get as close as
+ // we can.
+ // tickInterval will be used before numberTicks, that is if
+ // both are specified, numberTicks will be ignored.
+ else if (this.tickInterval) {
+ titarget = this.tickInterval;
+ }
+
+ // if numberTicks specified, try to honor it.
+ // Not gauranteed, but will try to get close.
+ else if (this.numberTicks) {
+ nttarget = this.numberTicks;
+ titarget = (max - min) / (nttarget - 1);
+ }
+
+ // If we can use an interval of 2 weeks or less, pick best one
+ if (titarget <= 19*day) {
+ var ret = bestDateInterval(min, max, titarget);
+ var tempti = ret[0];
+ this._autoFormatString = ret[1];
+
+ min = Math.floor(min/tempti) * tempti;
+ min = new $.jsDate(min);
+ min = min.getTime() + min.getUtcOffset();
+
+ nttarget = Math.ceil((max - min) / tempti) + 1;
+ this.min = min;
+ this.max = min + (nttarget - 1) * tempti;
+
+ // if max is less than max, add an interval
+ if (this.max < max) {
+ this.max += tempti;
+ nttarget += 1;
+ }
+ this.tickInterval = tempti;
+ this.numberTicks = nttarget;
+
+ for (var i=0; i<nttarget; i++) {
+ opts.value = this.min + i * tempti;
+ t = new this.tickRenderer(opts);
+
+ if (this._overrideFormatString && this._autoFormatString != '') {
+ t.formatString = this._autoFormatString;
+ }
+ if (!this.showTicks) {
+ t.showLabel = false;
+ t.showMark = false;
+ }
+ else if (!this.showTickMarks) {
+ t.showMark = false;
+ }
+ this._ticks.push(t);
+ }
+
+ insetMult = this.tickInterval;
+ }
+
+ // should we use a monthly interval?
+ else if (titarget <= 9 * month) {
+
+ this._autoFormatString = '%v';
+
+ // how many months in an interval?
+ var intv = Math.round(titarget/month);
+ if (intv < 1) {
+ intv = 1;
+ }
+ else if (intv > 6) {
+ intv = 6;
+ }
+
+ // figure out the starting month and ending month.
+ var mstart = new $.jsDate(min).setDate(1).setHours(0,0,0,0);
+
+ // See if max ends exactly on a month
+ var tempmend = new $.jsDate(max);
+ var mend = new $.jsDate(max).setDate(1).setHours(0,0,0,0);
+
+ if (tempmend.getTime() !== mend.getTime()) {
+ mend = mend.add(1, 'month');
+ }
+
+ var nmonths = mend.diff(mstart, 'month');
+
+ nttarget = Math.ceil(nmonths/intv) + 1;
+
+ this.min = mstart.getTime();
+ this.max = mstart.clone().add((nttarget - 1) * intv, 'month').getTime();
+ this.numberTicks = nttarget;
+
+ for (var i=0; i<nttarget; i++) {
+ if (i === 0) {
+ opts.value = mstart.getTime();
+ }
+ else {
+ opts.value = mstart.add(intv, 'month').getTime();
+ }
+ t = new this.tickRenderer(opts);
+
+ if (this._overrideFormatString && this._autoFormatString != '') {
+ t.formatString = this._autoFormatString;
+ }
+ if (!this.showTicks) {
+ t.showLabel = false;
+ t.showMark = false;
+ }
+ else if (!this.showTickMarks) {
+ t.showMark = false;
+ }
+ this._ticks.push(t);
+ }
+
+ insetMult = intv * month;
+ }
+
+ // use yearly intervals
+ else {
+
+ this._autoFormatString = '%v';
+
+ // how many years in an interval?
+ var intv = Math.round(titarget/year);
+ if (intv < 1) {
+ intv = 1;
+ }
+
+ // figure out the starting and ending years.
+ var mstart = new $.jsDate(min).setMonth(0, 1).setHours(0,0,0,0);
+ var mend = new $.jsDate(max).add(1, 'year').setMonth(0, 1).setHours(0,0,0,0);
+
+ var nyears = mend.diff(mstart, 'year');
+
+ nttarget = Math.ceil(nyears/intv) + 1;
+
+ this.min = mstart.getTime();
+ this.max = mstart.clone().add((nttarget - 1) * intv, 'year').getTime();
+ this.numberTicks = nttarget;
+
+ for (var i=0; i<nttarget; i++) {
+ if (i === 0) {
+ opts.value = mstart.getTime();
+ }
+ else {
+ opts.value = mstart.add(intv, 'year').getTime();
+ }
+ t = new this.tickRenderer(opts);
+
+ if (this._overrideFormatString && this._autoFormatString != '') {
+ t.formatString = this._autoFormatString;
+ }
+ if (!this.showTicks) {
+ t.showLabel = false;
+ t.showMark = false;
+ }
+ else if (!this.showTickMarks) {
+ t.showMark = false;
+ }
+ this._ticks.push(t);
+ }
+
+ insetMult = intv * year;
+ }
+ }
+
+ ////////
+ // Some option(s) specified, work around that.
+ ////////
- // we don't have any ticks yet, let's make some!
- else {
+ else {
if (name == 'xaxis' || name == 'x2axis') {
dim = this._plotDimensions.width;
}
@@ -248,9 +659,6 @@
}
}
}
-
- min = ((this.min != null) ? Date.create(this.min).getTime() : db.min);
- max = ((this.max != null) ? Date.create(this.max).getTime() : db.max);
// if min and max are same, space them out a bit
if (min == max) {
@@ -259,23 +667,27 @@
max += adj;
}
- var range = max - min;
+ range = max - min;
+
+ var optNumTicks = 2 + parseInt(Math.max(0, dim-100)/100, 10);
+
+
var rmin, rmax;
-
- rmin = (this.min != null) ? Date.create(this.min).getTime() : min - range/2*(this.padMin - 1);
- rmax = (this.max != null) ? Date.create(this.max).getTime() : max + range/2*(this.padMax - 1);
+
+ rmin = (this.min != null) ? new $.jsDate(this.min).getTime() : min - range/2*(this.padMin - 1);
+ rmax = (this.max != null) ? new $.jsDate(this.max).getTime() : max + range/2*(this.padMax - 1);
this.min = rmin;
this.max = rmax;
range = this.max - this.min;
-
+
if (this.numberTicks == null){
// if tickInterval is specified by user, we will ignore computed maximum.
// max will be equal or greater to fit even # of ticks.
if (this.daTickInterval != null) {
- var nc = Date.create(this.max).diff(this.min, this.daTickInterval[1], true);
+ var nc = new $.jsDate(this.max).diff(this.min, this.daTickInterval[1], true);
this.numberTicks = Math.ceil(nc/this.daTickInterval[0]) +1;
- // this.max = Date.create(this.min).add(this.numberTicks-1, this.daTickInterval[1]).getTime();
- this.max = Date.create(this.min).add((this.numberTicks-1) * this.daTickInterval[0], this.daTickInterval[1]).getTime();
+ // this.max = new $.jsDate(this.min).add(this.numberTicks-1, this.daTickInterval[1]).getTime();
+ this.max = new $.jsDate(this.min).add((this.numberTicks-1) * this.daTickInterval[0], this.daTickInterval[1]).getTime();
}
else if (dim > 200) {
this.numberTicks = parseInt(3+(dim-200)/100, 10);
@@ -284,12 +696,16 @@
this.numberTicks = 2;
}
}
-
+
+ insetMult = range / (this.numberTicks-1)/1000;
+
if (this.daTickInterval == null) {
- this.daTickInterval = [range / (this.numberTicks-1)/1000, 'seconds'];
+ this.daTickInterval = [insetMult, 'seconds'];
}
+
+
for (var i=0; i<this.numberTicks; i++){
- var min = Date.create(this.min);
+ var min = new $.jsDate(this.min);
tt = min.add(i*this.daTickInterval[0], this.daTickInterval[1]).getTime();
var t = new this.tickRenderer(this.tickOptions);
// var t = new $.jqplot.AxisTickRenderer(this.tickOptions);
@@ -304,9 +720,17 @@
this._ticks.push(t);
}
}
+
+ if (this.tickInset) {
+ this.min = this.min - this.tickInset * insetMult;
+ this.max = this.max + this.tickInset * insetMult;
+ }
+
if (this._daTickInterval == null) {
this._daTickInterval = this.daTickInterval;
}
+
+ ticks = null;
};
})(jQuery);
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.dateAxisRenderer.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.dateAxisRenderer.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.dateAxisRenderer.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(h){h.jqplot.DateAxisRenderer=function(){h.jqplot.LinearAxisRenderer.call(this);this.date=new h.jsDate()};var c=1000;var e=60*c;var f=60*e;var l=24*f;var b=7*l;var j=30.4368499*l;var k=365.242199*l;var g=[31,28,31,30,31,30,31,30,31,30,31,30];var i=["%M:%S.%#N","%M:%S.%#N","%M:%S.%#N","%M:%S","%M:%S","%M:%S","%M:%S","%H:%M:%S","%H:%M:%S","%H:%M","%H:%M","%H:%M","%H:%M","%H:%M","%H:%M","%a %H:%M","%a %H:%M","%b %e %H:%M","%b %e %H:%M","%b %e %H:%M","%b %e %H:%M","%v","%v","%v","%v","%v","%v","%v"];var m=[0.1*c,0.2*c,0.5*c,c,2*c,5*c,10*c,15*c,30*c,e,2*e,5*e,10*e,15*e,30*e,f,2*f,4*f,6*f,8*f,12*f,l,2*l,3*l,4*l,5*l,b,2*b];var d=[];function a(p,s,t){var o=Number.MAX_VALUE;var u,r,v;for(var q=0,n=m.length;q<n;q++){u=Math.abs(t-m[q]);if(u<o){o=u;r=m[q];v=i[q]}}return[r,v]}h.jqplot.DateAxisRenderer.prototype=new h.jqplot.LinearAxisRenderer();h.jqplot.DateAxisRenderer.prototype.constructor=h.jqplot.DateAxisRenderer;h.jqplot.DateTickFormatter=function(n,o){if(!n){n="%Y/%m/%d"}return h.jsDate.strftime(o,n)};h.jqplot.DateAxisRenderer.prototype.init=function(E){this.tickOptions.formatter=h.jqplot.DateTickFormatter;this.tickInset=0;this.drawBaseline=true;this.baselineWidth=null;this.baselineColor=null;this.daTickInterval=null;this._daTickInterval=null;h.extend(true,this,E);var C=this._dataBounds,u,x,D,y,A,z,o;for(var t=0;t<this._series.length;t++){u={intervals:[],frequencies:{},sortedIntervals:[],min:null,max:null,mean:null};x=0;D=this._series[t];y=D.data;A=D._plotData;z=D._stackData;o=0;for(var r=0;r<y.length;r++){if(this.name=="xaxis"||this.name=="x2axis"){y[r][0]=new h.jsDate(y[r][0]).getTime();A[r][0]=new h.jsDate(y[r][0]).getTime();z[r][0]=new h.jsDate(y[r][0]).getTime();if((y[r][0]!=null&&y[r][0]<C.min)||C.min==null){C.min=y[r][0]}if((y[r][0]!=null&&y[r][0]>C.max)||C.max==null){C.max=y[r][0]}if(r>0){o=Math.abs(y[r][0]-y[r-1][0]);u.intervals.push(o);if(u.frequencies.hasOwnProperty(o)){u.frequencies[o]+=1}else{u.frequencies[o]=1}}x+=o}else{y[r][1]=new h.jsDate(y[r][1]).getTime();A[r][1]=new h.jsDate(y[r!
][1]).getTime();z[r][1]=new h.jsDate(y[r][1]).getTime();if((y[r][1]!=null&&y[r][1]<C.min)||C.min==null){C.min=y[r][1]}if((y[r][1]!=null&&y[r][1]>C.max)||C.max==null){C.max=y[r][1]}if(r>0){o=Math.abs(y[r][1]-y[r-1][1]);u.intervals.push(o);if(u.frequencies.hasOwnProperty(o)){u.frequencies[o]+=1}else{u.frequencies[o]=1}}}x+=o}if(D.renderer.bands){if(D.renderer.bands.hiData.length){var w=D.renderer.bands.hiData;for(var r=0,q=w.length;r<q;r++){if(this.name==="xaxis"||this.name==="x2axis"){w[r][0]=new h.jsDate(w[r][0]).getTime();if((w[r][0]!=null&&w[r][0]>C.max)||C.max==null){C.max=w[r][0]}}else{w[r][1]=new h.jsDate(w[r][1]).getTime();if((w[r][1]!=null&&w[r][1]>C.max)||C.max==null){C.max=w[r][1]}}}}if(D.renderer.bands.lowData.length){var w=D.renderer.bands.lowData;for(var r=0,q=w.length;r<q;r++){if(this.name==="xaxis"||this.name==="x2axis"){w[r][0]=new h.jsDate(w[r][0]).getTime();if((w[r][0]!=null&&w[r][0]<C.min)||C.min==null){C.min=w[r][0]}}else{w[r][1]=new h.jsDate(w[r][1]).getTime();if((w[r][1]!=null&&w[r][1]<C.min)||C.min==null){C.min=w[r][1]}}}}}var B=0,v=0;for(var p in u.frequencies){u.sortedIntervals.push({interval:p,frequency:u.frequencies[p]})}u.sortedIntervals.sort(function(s,n){return n.frequency-s.frequency});u.min=h.jqplot.arrayMin(u.intervals);u.max=h.jqplot.arrayMax(u.intervals);u.mean=x/y.length;this._intervalStats.push(u);u=x=D=y=A=z=null}C=null};h.jqplot.DateAxisRenderer.prototype.reset=function(){this.min=this._options.min;this.max=this._options.max;this.tickInterval=this._options.tickInterval;this.numberTicks=this._options.numberTicks;this._autoFormatString="";if(this._overrideFormatString&&this.tickOptions&&this.tickOptions.formatString){this.tickOptions.formatString=""}this.daTickInterval=this._daTickInterval};h.jqplot.DateAxisRenderer.prototype.createTicks=function(p){var W=this._ticks;var L=this.ticks;var F=this.name;var H=this._dataBounds;var M=this._intervalStats;var n=(this.name.charAt(0)==="x")?this._plotDimensions.width:this._plotDimensions.height;var w;var ad,J;var y,x;var ac,Z;var s=30;v!
ar O=1;var v=this.tickInterval;ad=((this.min!=null)?new h.jsDate(this.min).getTime():H.min);J=((this.max!=null)?new h.jsDate(this.max).getTime():H.max);var A=p.plugins.cursor;if(A&&A._zoom&&A._zoom.zooming){this.min=null;this.max=null}var B=J-ad;if(this.tickOptions==null||!this.tickOptions.formatString){this._overrideFormatString=true}if(L.length){for(Z=0;Z<L.length;Z++){var P=L[Z];var X=new this.tickRenderer(this.tickOptions);if(P.constructor==Array){X.value=new h.jsDate(P[0]).getTime();X.label=P[1];if(!this.showTicks){X.showLabel=false;X.showMark=false}else{if(!this.showTickMarks){X.showMark=false}}X.setTick(X.value,this.name);this._ticks.push(X)}else{X.value=new h.jsDate(P).getTime();if(!this.showTicks){X.showLabel=false;X.showMark=false}else{if(!this.showTickMarks){X.showMark=false}}X.setTick(X.value,this.name);this._ticks.push(X)}}this.numberTicks=L.length;this.min=this._ticks[0].value;this.max=this._ticks[this.numberTicks-1].value;this.daTickInterval=[(this.max-this.min)/(this.numberTicks-1)/1000,"seconds"]}else{if(this.min==null&&this.max==null&&H.min==H.max){var E=h.extend(true,{},this.tickOptions,{name:this.name,value:null});var S=300000;this.min=H.min-S;this.max=H.max+S;this.numberTicks=3;for(var Z=this.min;Z<=this.max;Z+=S){E.value=Z;var X=new this.tickRenderer(E);if(this._overrideFormatString&&this._autoFormatString!=""){X.formatString=this._autoFormatString}X.showLabel=false;X.showMark=false;this._ticks.push(X)}if(this.showTicks){this._ticks[1].showLabel=true}if(this.showTickMarks){this._ticks[1].showTickMarks=true}}else{if(this.min==null&&this.max==null){var N=h.extend(true,{},this.tickOptions,{name:this.name,value:null});var ab,I;if(!this.tickInterval&&!this.numberTicks){var R=Math.max(n,s+1);var Y=115;if(this.tickRenderer===h.jqplot.CanvasAxisTickRenderer&&this.tickOptions.angle){Y=115-40*Math.abs(Math.sin(this.tickOptions.angle/180*Math.PI))}ab=Math.ceil((R-s)/Y+1);I=(J-ad)/(ab-1)}else{if(this.tickInterval){I=this.tickInterval}else{if(this.numberTicks){ab=this.numberTicks;I=(J-ad)/(ab-1)}}}if(I<!
=19*l){var Q=a(ad,J,I);var r=Q[0];this._autoFormatString=Q[1];ad=Math.floor(ad/r)*r;ad=new h.jsDate(ad);ad=ad.getTime()+ad.getUtcOffset();ab=Math.ceil((J-ad)/r)+1;this.min=ad;this.max=ad+(ab-1)*r;if(this.max<J){this.max+=r;ab+=1}this.tickInterval=r;this.numberTicks=ab;for(var Z=0;Z<ab;Z++){N.value=this.min+Z*r;X=new this.tickRenderer(N);if(this._overrideFormatString&&this._autoFormatString!=""){X.formatString=this._autoFormatString}if(!this.showTicks){X.showLabel=false;X.showMark=false}else{if(!this.showTickMarks){X.showMark=false}}this._ticks.push(X)}O=this.tickInterval}else{if(I<=9*j){this._autoFormatString="%v";var D=Math.round(I/j);if(D<1){D=1}else{if(D>6){D=6}}var U=new h.jsDate(ad).setDate(1).setHours(0,0,0,0);var q=new h.jsDate(J);var z=new h.jsDate(J).setDate(1).setHours(0,0,0,0);if(q.getTime()!==z.getTime()){z=z.add(1,"month")}var T=z.diff(U,"month");ab=Math.ceil(T/D)+1;this.min=U.getTime();this.max=U.clone().add((ab-1)*D,"month").getTime();this.numberTicks=ab;for(var Z=0;Z<ab;Z++){if(Z===0){N.value=U.getTime()}else{N.value=U.add(D,"month").getTime()}X=new this.tickRenderer(N);if(this._overrideFormatString&&this._autoFormatString!=""){X.formatString=this._autoFormatString}if(!this.showTicks){X.showLabel=false;X.showMark=false}else{if(!this.showTickMarks){X.showMark=false}}this._ticks.push(X)}O=D*j}else{this._autoFormatString="%v";var D=Math.round(I/k);if(D<1){D=1}var U=new h.jsDate(ad).setMonth(0,1).setHours(0,0,0,0);var z=new h.jsDate(J).add(1,"year").setMonth(0,1).setHours(0,0,0,0);var K=z.diff(U,"year");ab=Math.ceil(K/D)+1;this.min=U.getTime();this.max=U.clone().add((ab-1)*D,"year").getTime();this.numberTicks=ab;for(var Z=0;Z<ab;Z++){if(Z===0){N.value=U.getTime()}else{N.value=U.add(D,"year").getTime()}X=new this.tickRenderer(N);if(this._overrideFormatString&&this._autoFormatString!=""){X.formatString=this._autoFormatString}if(!this.showTicks){X.showLabel=false;X.showMark=false}else{if(!this.showTickMarks){X.showMark=false}}this._ticks.push(X)}O=D*k}}}else{if(F=="xaxis"||F=="x2axis"){n=this._plotDimen!
sions.width}else{n=this._plotDimensions.height}if(this.min!=null&&this.max!=null&&this.numberTicks!=null){this.tickInterval=null}if(this.tickInterval!=null){if(Number(this.tickInterval)){this.daTickInterval=[Number(this.tickInterval),"seconds"]}else{if(typeof this.tickInterval=="string"){var aa=this.tickInterval.split(" ");if(aa.length==1){this.daTickInterval=[1,aa[0]]}else{if(aa.length==2){this.daTickInterval=[aa[0],aa[1]]}}}}}if(ad==J){var o=24*60*60*500;ad-=o;J+=o}B=J-ad;var G=2+parseInt(Math.max(0,n-100)/100,10);var V,C;V=(this.min!=null)?new h.jsDate(this.min).getTime():ad-B/2*(this.padMin-1);C=(this.max!=null)?new h.jsDate(this.max).getTime():J+B/2*(this.padMax-1);this.min=V;this.max=C;B=this.max-this.min;if(this.numberTicks==null){if(this.daTickInterval!=null){var u=new h.jsDate(this.max).diff(this.min,this.daTickInterval[1],true);this.numberTicks=Math.ceil(u/this.daTickInterval[0])+1;this.max=new h.jsDate(this.min).add((this.numberTicks-1)*this.daTickInterval[0],this.daTickInterval[1]).getTime()}else{if(n>200){this.numberTicks=parseInt(3+(n-200)/100,10)}else{this.numberTicks=2}}}O=B/(this.numberTicks-1)/1000;if(this.daTickInterval==null){this.daTickInterval=[O,"seconds"]}for(var Z=0;Z<this.numberTicks;Z++){var ad=new h.jsDate(this.min);ac=ad.add(Z*this.daTickInterval[0],this.daTickInterval[1]).getTime();var X=new this.tickRenderer(this.tickOptions);if(!this.showTicks){X.showLabel=false;X.showMark=false}else{if(!this.showTickMarks){X.showMark=false}}X.setTick(ac,this.name);this._ticks.push(X)}}}}if(this.tickInset){this.min=this.min-this.tickInset*O;this.max=this.max+this.tickInset*O}if(this._daTickInterval==null){this._daTickInterval=this.daTickInterval}W=null}})(jQuery);
\ No newline at end of file
Modified: gnucash/trunk/src/report/jqplot/plugins/jqplot.donutRenderer.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.donutRenderer.js 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.donutRenderer.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -1,18 +1,31 @@
/**
- * Copyright (c) 2009 - 2010 Chris Leonello
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
- * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
- * The author would appreciate an email letting him know of any substantial
- * use of jqPlot. You can reach the author at: chris at jqplot dot com
- * or see http://www.jqplot.com/info.php . This is, of course,
- * not required.
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
- * Thanks for using jqPlot!
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
*
*/
(function($) {
@@ -70,7 +83,7 @@
// Outer diameter of the donut, auto computed by default
this.diameter = null;
// prop: innerDiameter
- // Inner diameter of teh donut, auto calculated by default.
+ // Inner diameter of the donut, auto calculated by default.
// If specified will override thickness value.
this.innerDiameter = null;
// prop: thickness
@@ -129,7 +142,7 @@
// prop: dataLabelPositionFactor
// A Multiplier (0-1) of the pie radius which controls position of label on slice.
// Increasing will slide label toward edge of pie, decreasing will slide label toward center of pie.
- this.dataLabelPositionFactor = 0.5;
+ this.dataLabelPositionFactor = 0.4;
// prop: dataLabelNudge
// Number of pixels to slide the label away from (+) or toward (-) the center of the pie.
this.dataLabelNudge = 0;
@@ -144,6 +157,7 @@
this.tickRenderer = $.jqplot.DonutTickRenderer;
// Used as check for conditions where donut shouldn't be drawn.
this._drawData = true;
+ this._type = 'donut';
// if user has passed in highlightMouseDown option and not set highlightMouseOver, disable highlightMouseOver
if (options.highlightMouseDown && options.highlightMouseOver == null) {
@@ -412,7 +426,7 @@
}
else if (this.dataLabels == 'value') {
fstr = this.dataLabelFormatString || '%d';
- label = $.jqplot.sprintf(fstr, gd[i][1]);
+ label = $.jqplot.sprintf(fstr, this.data[i][1]);
}
else if (this.dataLabels == 'percent') {
fstr = this.dataLabelFormatString || '%d%%';
@@ -600,116 +614,6 @@
return this._elem;
};
- // $.jqplot.DonutLegendRenderer.prototype.pack = function(offsets) {
- // if (this.show) {
- // // fake a grid for positioning
- // var grid = {_top:offsets.top, _left:offsets.left, _right:offsets.right, _bottom:this._plotDimensions.height - offsets.bottom};
- // if (this.placement == 'insideGrid') {
- // switch (this.location) {
- // case 'nw':
- // var a = grid._left + this.xoffset;
- // var b = grid._top + this.yoffset;
- // this._elem.css('left', a);
- // this._elem.css('top', b);
- // break;
- // case 'n':
- // var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2;
- // var b = grid._top + this.yoffset;
- // this._elem.css('left', a);
- // this._elem.css('top', b);
- // break;
- // case 'ne':
- // var a = offsets.right + this.xoffset;
- // var b = grid._top + this.yoffset;
- // this._elem.css({right:a, top:b});
- // break;
- // case 'e':
- // var a = offsets.right + this.xoffset;
- // var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2;
- // this._elem.css({right:a, top:b});
- // break;
- // case 'se':
- // var a = offsets.right + this.xoffset;
- // var b = offsets.bottom + this.yoffset;
- // this._elem.css({right:a, bottom:b});
- // break;
- // case 's':
- // var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2;
- // var b = offsets.bottom + this.yoffset;
- // this._elem.css({left:a, bottom:b});
- // break;
- // case 'sw':
- // var a = grid._left + this.xoffset;
- // var b = offsets.bottom + this.yoffset;
- // this._elem.css({left:a, bottom:b});
- // break;
- // case 'w':
- // var a = grid._left + this.xoffset;
- // var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2;
- // this._elem.css({left:a, top:b});
- // break;
- // default: // same as 'se'
- // var a = grid._right - this.xoffset;
- // var b = grid._bottom + this.yoffset;
- // this._elem.css({right:a, bottom:b});
- // break;
- // }
- //
- // }
- // else {
- // switch (this.location) {
- // case 'nw':
- // var a = this._plotDimensions.width - grid._left + this.xoffset;
- // var b = grid._top + this.yoffset;
- // this._elem.css('right', a);
- // this._elem.css('top', b);
- // break;
- // case 'n':
- // var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2;
- // var b = this._plotDimensions.height - grid._top + this.yoffset;
- // this._elem.css('left', a);
- // this._elem.css('bottom', b);
- // break;
- // case 'ne':
- // var a = this._plotDimensions.width - offsets.right + this.xoffset;
- // var b = grid._top + this.yoffset;
- // this._elem.css({left:a, top:b});
- // break;
- // case 'e':
- // var a = this._plotDimensions.width - offsets.right + this.xoffset;
- // var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2;
- // this._elem.css({left:a, top:b});
- // break;
- // case 'se':
- // var a = this._plotDimensions.width - offsets.right + this.xoffset;
- // var b = offsets.bottom + this.yoffset;
- // this._elem.css({left:a, bottom:b});
- // break;
- // case 's':
- // var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2;
- // var b = this._plotDimensions.height - offsets.bottom + this.yoffset;
- // this._elem.css({left:a, top:b});
- // break;
- // case 'sw':
- // var a = this._plotDimensions.width - grid._left + this.xoffset;
- // var b = offsets.bottom + this.yoffset;
- // this._elem.css({right:a, bottom:b});
- // break;
- // case 'w':
- // var a = this._plotDimensions.width - grid._left + this.xoffset;
- // var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2;
- // this._elem.css({right:a, top:b});
- // break;
- // default: // same as 'se'
- // var a = grid._right - this.xoffset;
- // var b = grid._bottom + this.yoffset;
- // this._elem.css({right:a, bottom:b});
- // break;
- // }
- // }
- // }
- // };
-
// setup default renderers for axes and legend so user doesn't have to
// called with scope of plot
function preInit(target, data, options) {
@@ -760,7 +664,6 @@
}
}
}
- this.target.bind('mouseout', {plot:this}, function (ev) { unhighlight(ev.data.plot); });
}
var postParseOptionsRun = false;
@@ -768,7 +671,7 @@
function postParseOptions(options) {
for (var i=0; i<this.series.length; i++) {
this.series[i].seriesColors = this.seriesColors;
- this.series[i].colorGenerator = this.colorGenerator;
+ this.series[i].colorGenerator = $.jqplot.colorGenerator;
}
}
@@ -800,6 +703,7 @@
plot.target.trigger(evt1, ins);
if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.donutRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) {
var evt = jQuery.Event('jqplotDataHighlight');
+ evt.which = ev.which;
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
plot.target.trigger(evt, ins);
@@ -816,6 +720,7 @@
var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
if (plot.series[ins[0]].highlightMouseDown && !(ins[0] == plot.plugins.donutRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) {
var evt = jQuery.Event('jqplotDataHighlight');
+ evt.which = ev.which;
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
plot.target.trigger(evt, ins);
@@ -838,6 +743,7 @@
if (neighbor) {
var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
var evt = jQuery.Event('jqplotDataClick');
+ evt.which = ev.which;
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
plot.target.trigger(evt, ins);
@@ -852,6 +758,7 @@
unhighlight(plot);
}
var evt = jQuery.Event('jqplotDataRightClick');
+ evt.which = ev.which;
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
plot.target.trigger(evt, ins);
@@ -862,19 +769,26 @@
// create a canvas which we can draw on.
// insert it before the eventCanvas, so eventCanvas will still capture events.
function postPlotDraw() {
+ // Memory Leaks patch
+ if (this.plugins.donutRenderer && this.plugins.donutRenderer.highlightCanvas) {
+ this.plugins.donutRenderer.highlightCanvas.resetCanvas();
+ this.plugins.donutRenderer.highlightCanvas = null;
+ }
+
this.plugins.donutRenderer = {highlightedSeriesIndex:null};
this.plugins.donutRenderer.highlightCanvas = new $.jqplot.GenericCanvas();
// do we have any data labels? if so, put highlight canvas before those
// Fix for broken jquery :first selector with canvas (VML) elements.
var labels = $(this.targetId+' .jqplot-data-label');
if (labels.length) {
- $(labels[0]).before(this.plugins.donutRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-donutRenderer-highlight-canvas', this._plotDimensions));
+ $(labels[0]).before(this.plugins.donutRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-donutRenderer-highlight-canvas', this._plotDimensions, this));
}
// else put highlight canvas before event canvas.
else {
- this.eventCanvas._elem.before(this.plugins.donutRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-donutRenderer-highlight-canvas', this._plotDimensions));
+ this.eventCanvas._elem.before(this.plugins.donutRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-donutRenderer-highlight-canvas', this._plotDimensions, this));
}
var hctx = this.plugins.donutRenderer.highlightCanvas.setContext();
+ this.eventCanvas._elem.bind('mouseleave', {plot:this}, function (ev) { unhighlight(ev.data.plot); });
}
$.jqplot.preInitHooks.push(preInit);
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.donutRenderer.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.donutRenderer.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.donutRenderer.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(e){e.jqplot.DonutRenderer=function(){e.jqplot.LineRenderer.call(this)};e.jqplot.DonutRenderer.prototype=new e.jqplot.LineRenderer();e.jqplot.DonutRenderer.prototype.constructor=e.jqplot.DonutRenderer;e.jqplot.DonutRenderer.prototype.init=function(p,t){this.diameter=null;this.innerDiameter=null;this.thickness=null;this.padding=20;this.sliceMargin=0;this.ringMargin=null;this.fill=true;this.shadowOffset=2;this.shadowAlpha=0.07;this.shadowDepth=5;this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColors=[];this.dataLabels="percent";this.showDataLabels=false;this.dataLabelFormatString=null;this.dataLabelThreshold=3;this.dataLabelPositionFactor=0.4;this.dataLabelNudge=0;this.startAngle=0;this.tickRenderer=e.jqplot.DonutTickRenderer;this._drawData=true;this._type="donut";if(p.highlightMouseDown&&p.highlightMouseOver==null){p.highlightMouseOver=false}e.extend(true,this,p);if(this.diameter!=null){this.diameter=this.diameter-this.sliceMargin}this._diameter=null;this._innerDiameter=null;this._radius=null;this._innerRadius=null;this._thickness=null;this._previousSeries=[];this._numberSeries=1;this._sliceAngles=[];this._highlightedPoint=null;if(this.highlightColors.length==0){for(var r=0;r<this.seriesColors.length;r++){var q=e.jqplot.getColorComponents(this.seriesColors[r]);var n=[q[0],q[1],q[2]];var s=n[0]+n[1]+n[2];for(var o=0;o<3;o++){n[o]=(s>570)?n[o]*0.8:n[o]+0.3*(255-n[o]);n[o]=parseInt(n[o],10)}this.highlightColors.push("rgb("+n[0]+","+n[1]+","+n[2]+")")}}t.postParseOptionsHooks.addOnce(l);t.postInitHooks.addOnce(g);t.eventListenerHooks.addOnce("jqplotMouseMove",b);t.eventListenerHooks.addOnce("jqplotMouseDown",a);t.eventListenerHooks.addOnce("jqplotMouseUp",j);t.eventListenerHooks.addOnce("jqplotClick",f);t.eventListenerHooks.addOnce("jqplotRightClick",m);t.postDrawHooks.addOnce(h)};e.jqplot.DonutRenderer.prototype.setGridData=function(s){var o=[];var t=[];var n=this.startAngle/180*Math.PI;var r=0;this._drawData=false;for(var q=0;q<this.data.length;q++){if(this.data[q][1]!=!
0){this._drawData=true}o.push(this.data[q][1]);t.push([this.data[q][0]]);if(q>0){o[q]+=o[q-1]}r+=this.data[q][1]}var p=Math.PI*2/o[o.length-1];for(var q=0;q<o.length;q++){t[q][1]=o[q]*p;t[q][2]=this.data[q][1]/r}this.gridData=t};e.jqplot.DonutRenderer.prototype.makeGridData=function(s,t){var o=[];var u=[];var r=0;var n=this.startAngle/180*Math.PI;this._drawData=false;for(var q=0;q<s.length;q++){if(this.data[q][1]!=0){this._drawData=true}o.push(s[q][1]);u.push([s[q][0]]);if(q>0){o[q]+=o[q-1]}r+=s[q][1]}var p=Math.PI*2/o[o.length-1];for(var q=0;q<o.length;q++){u[q][1]=o[q]*p;u[q][2]=s[q][1]/r}return u};e.jqplot.DonutRenderer.prototype.drawSlice=function(x,u,t,p,s){var n=this._diameter/2;var v=n-this._thickness;var w=this.fill;x.save();x.translate(this._center[0],this._center[1]);if(s){for(var q=0;q<this.shadowDepth;q++){x.save();x.translate(this.shadowOffset*Math.cos(this.shadowAngle/180*Math.PI),this.shadowOffset*Math.sin(this.shadowAngle/180*Math.PI));o()}}else{o()}function o(){if(t>6.282+this.startAngle){t=6.282+this.startAngle;if(u>t){u=6.281+this.startAngle}}if(u>=t){return}x.beginPath();x.fillStyle=p;x.strokeStyle=p;x.arc(0,0,n,u,t,false);x.lineTo(v*Math.cos(t),v*Math.sin(t));x.arc(0,0,v,t,u,true);x.closePath();if(w){x.fill()}else{x.stroke()}}if(s){for(var q=0;q<this.shadowDepth;q++){x.restore()}}x.restore()};e.jqplot.DonutRenderer.prototype.draw=function(N,V,t,P){var Q;var J=(t!=undefined)?t:{};var q=0;var p=0;var u=1;if(t.legendInfo&&t.legendInfo.placement=="insideGrid"){var I=t.legendInfo;switch(I.location){case"nw":q=I.width+I.xoffset;break;case"w":q=I.width+I.xoffset;break;case"sw":q=I.width+I.xoffset;break;case"ne":q=I.width+I.xoffset;u=-1;break;case"e":q=I.width+I.xoffset;u=-1;break;case"se":q=I.width+I.xoffset;u=-1;break;case"n":p=I.height+I.yoffset;break;case"s":p=I.height+I.yoffset;u=-1;break;default:break}}var B=(J.shadow!=undefined)?J.shadow:this.shadow;var W=(J.showLine!=undefined)?J.showLine:this.showLine;var O=(J.fill!=undefined)?J.fill:this.fill;var s=N.canvas.width;var H=N.canvas.height;var !
G=s-q-2*this.padding;var R=H-p-2*this.padding;var v=Math.min(G,R);var T=v;var X=(this.ringMargin==null)?this.sliceMargin*2:this.ringMargin;for(var Q=0;Q<this._previousSeries.length;Q++){T-=2*this._previousSeries[Q]._thickness+2*X}this._diameter=this.diameter||T;if(this.innerDiameter!=null){var M=(this._numberSeries>1&&this.index>0)?this._previousSeries[0]._diameter:this._diameter;this._thickness=this.thickness||(M-this.innerDiameter-2*X*this._numberSeries)/this._numberSeries/2}else{this._thickness=this.thickness||v/2/(this._numberSeries+1)*0.85}var K=this._radius=this._diameter/2;this._innerRadius=this._radius-this._thickness;var o=this.startAngle/180*Math.PI;this._center=[(s-u*q)/2+u*q,(H-u*p)/2+u*p];if(this.shadow){var L="rgba(0,0,0,"+this.shadowAlpha+")";for(var Q=0;Q<V.length;Q++){var A=(Q==0)?o:V[Q-1][1]+o;A+=this.sliceMargin/180*Math.PI;this.renderer.drawSlice.call(this,N,A,V[Q][1]+o,L,true)}}for(var Q=0;Q<V.length;Q++){var A=(Q==0)?o:V[Q-1][1]+o;A+=this.sliceMargin/180*Math.PI;var z=V[Q][1]+o;this._sliceAngles.push([A,z]);this.renderer.drawSlice.call(this,N,A,z,this.seriesColors[Q],false);if(this.showDataLabels&&V[Q][2]*100>=this.dataLabelThreshold){var S,U=(A+z)/2,C;if(this.dataLabels=="label"){S=this.dataLabelFormatString||"%s";C=e.jqplot.sprintf(S,V[Q][0])}else{if(this.dataLabels=="value"){S=this.dataLabelFormatString||"%d";C=e.jqplot.sprintf(S,this.data[Q][1])}else{if(this.dataLabels=="percent"){S=this.dataLabelFormatString||"%d%%";C=e.jqplot.sprintf(S,V[Q][2]*100)}else{if(this.dataLabels.constructor==Array){S=this.dataLabelFormatString||"%s";C=e.jqplot.sprintf(S,this.dataLabels[Q])}}}}var n=this._innerRadius+this._thickness*this.dataLabelPositionFactor+this.sliceMargin+this.dataLabelNudge;var F=this._center[0]+Math.cos(U)*n+this.canvas._offsets.left;var E=this._center[1]+Math.sin(U)*n+this.canvas._offsets.top;var D=e('<span class="jqplot-donut-series jqplot-data-label" style="position:absolute;">'+C+"</span>").insertBefore(P.eventCanvas._elem);F-=D.width()/2;E-=D.height()/2;F=Math.round(F);E=Math.rou!
nd(E);D.css({left:F,top:E})}}};e.jqplot.DonutAxisRenderer=function(){e.jqplot.LinearAxisRenderer.call(this)};e.jqplot.DonutAxisRenderer.prototype=new e.jqplot.LinearAxisRenderer();e.jqplot.DonutAxisRenderer.prototype.constructor=e.jqplot.DonutAxisRenderer;e.jqplot.DonutAxisRenderer.prototype.init=function(n){this.tickRenderer=e.jqplot.DonutTickRenderer;e.extend(true,this,n);this._dataBounds={min:0,max:100};this.min=0;this.max=100;this.showTicks=false;this.ticks=[];this.showMark=false;this.show=false};e.jqplot.DonutLegendRenderer=function(){e.jqplot.TableLegendRenderer.call(this)};e.jqplot.DonutLegendRenderer.prototype=new e.jqplot.TableLegendRenderer();e.jqplot.DonutLegendRenderer.prototype.constructor=e.jqplot.DonutLegendRenderer;e.jqplot.DonutLegendRenderer.prototype.init=function(n){this.numberRows=null;this.numberColumns=null;e.extend(true,this,n)};e.jqplot.DonutLegendRenderer.prototype.draw=function(){var q=this;if(this.show){var y=this._series;var B="position:absolute;";B+=(this.background)?"background:"+this.background+";":"";B+=(this.border)?"border:"+this.border+";":"";B+=(this.fontSize)?"font-size:"+this.fontSize+";":"";B+=(this.fontFamily)?"font-family:"+this.fontFamily+";":"";B+=(this.textColor)?"color:"+this.textColor+";":"";B+=(this.marginTop!=null)?"margin-top:"+this.marginTop+";":"";B+=(this.marginBottom!=null)?"margin-bottom:"+this.marginBottom+";":"";B+=(this.marginLeft!=null)?"margin-left:"+this.marginLeft+";":"";B+=(this.marginRight!=null)?"margin-right:"+this.marginRight+";":"";this._elem=e('<table class="jqplot-table-legend" style="'+B+'"></table>');var F=false,x=false,n,v;var z=y[0];var o=new e.jqplot.ColorGenerator(z.seriesColors);if(z.show){var G=z.data;if(this.numberRows){n=this.numberRows;if(!this.numberColumns){v=Math.ceil(G.length/n)}else{v=this.numberColumns}}else{if(this.numberColumns){v=this.numberColumns;n=Math.ceil(G.length/this.numberColumns)}else{n=G.length;v=1}}var E,D,p,t,r,u,w,C;var A=0;for(E=0;E<n;E++){if(x){p=e('<tr class="jqplot-table-legend"></tr>').prependTo(this._elem!
)}else{p=e('<tr class="jqplot-table-legend"></tr>').appendTo(this._elem)}for(D=0;D<v;D++){if(A<G.length){u=this.labels[A]||G[A][0].toString();C=o.next();if(!x){if(E>0){F=true}else{F=false}}else{if(E==n-1){F=false}else{F=true}}w=(F)?this.rowSpacing:"0";t=e('<td class="jqplot-table-legend" style="text-align:center;padding-top:'+w+';"><div><div class="jqplot-table-legend-swatch" style="border-color:'+C+';"></div></div></td>');r=e('<td class="jqplot-table-legend" style="padding-top:'+w+';"></td>');if(this.escapeHtml){r.text(u)}else{r.html(u)}if(x){r.prependTo(p);t.prependTo(p)}else{t.appendTo(p);r.appendTo(p)}F=true}A++}}}}return this._elem};function c(r,q,o){o=o||{};o.axesDefaults=o.axesDefaults||{};o.legend=o.legend||{};o.seriesDefaults=o.seriesDefaults||{};var n=false;if(o.seriesDefaults.renderer==e.jqplot.DonutRenderer){n=true}else{if(o.series){for(var p=0;p<o.series.length;p++){if(o.series[p].renderer==e.jqplot.DonutRenderer){n=true}}}}if(n){o.axesDefaults.renderer=e.jqplot.DonutAxisRenderer;o.legend.renderer=e.jqplot.DonutLegendRenderer;o.legend.preDraw=true;o.seriesDefaults.pointLabels={show:false}}}function g(r,q,o){for(var p=1;p<this.series.length;p++){if(!this.series[p]._previousSeries.length){for(var n=0;n<p;n++){if(this.series[p].renderer.constructor==e.jqplot.DonutRenderer&&this.series[n].renderer.constructor==e.jqplot.DonutRenderer){this.series[p]._previousSeries.push(this.series[n])}}}}for(p=0;p<this.series.length;p++){if(this.series[p].renderer.constructor==e.jqplot.DonutRenderer){this.series[p]._numberSeries=this.series.length;if(this.series[p].highlightMouseOver){this.series[p].highlightMouseDown=false}}}}var k=false;function l(n){for(var o=0;o<this.series.length;o++){this.series[o].seriesColors=this.seriesColors;this.series[o].colorGenerator=e.jqplot.colorGenerator}}function d(r,q,p){var o=r.series[q];var n=r.plugins.donutRenderer.highlightCanvas;n._ctx.clearRect(0,0,n._ctx.canvas.width,n._ctx.canvas.height);o._highlightedPoint=p;r.plugins.donutRenderer.highlightedSeriesIndex=q;o.renderer.drawSlic!
e.call(o,n._ctx,o._sliceAngles[p][0],o._sliceAngles[p][1],o.highlightColors[p],false)}function i(p){var n=p.plugins.donutRenderer.highlightCanvas;n._ctx.clearRect(0,0,n._ctx.canvas.width,n._ctx.canvas.height);for(var o=0;o<p.series.length;o++){p.series[o]._highlightedPoint=null}p.plugins.donutRenderer.highlightedSeriesIndex=null;p.target.trigger("jqplotDataUnhighlight")}function b(r,q,u,t,s){if(t){var p=[t.seriesIndex,t.pointIndex,t.data];var o=jQuery.Event("jqplotDataMouseOver");o.pageX=r.pageX;o.pageY=r.pageY;s.target.trigger(o,p);if(s.series[p[0]].highlightMouseOver&&!(p[0]==s.plugins.donutRenderer.highlightedSeriesIndex&&p[1]==s.series[p[0]]._highlightedPoint)){var n=jQuery.Event("jqplotDataHighlight");n.which=r.which;n.pageX=r.pageX;n.pageY=r.pageY;s.target.trigger(n,p);d(s,p[0],p[1])}}else{if(t==null){i(s)}}}function a(q,p,t,s,r){if(s){var o=[s.seriesIndex,s.pointIndex,s.data];if(r.series[o[0]].highlightMouseDown&&!(o[0]==r.plugins.donutRenderer.highlightedSeriesIndex&&o[1]==r.series[o[0]]._highlightedPoint)){var n=jQuery.Event("jqplotDataHighlight");n.which=q.which;n.pageX=q.pageX;n.pageY=q.pageY;r.target.trigger(n,o);d(r,o[0],o[1])}}else{if(s==null){i(r)}}}function j(p,o,s,r,q){var n=q.plugins.donutRenderer.highlightedSeriesIndex;if(n!=null&&q.series[n].highlightMouseDown){i(q)}}function f(q,p,t,s,r){if(s){var o=[s.seriesIndex,s.pointIndex,s.data];var n=jQuery.Event("jqplotDataClick");n.which=q.which;n.pageX=q.pageX;n.pageY=q.pageY;r.target.trigger(n,o)}}function m(r,q,u,t,s){if(t){var p=[t.seriesIndex,t.pointIndex,t.data];var n=s.plugins.donutRenderer.highlightedSeriesIndex;if(n!=null&&s.series[n].highlightMouseDown){i(s)}var o=jQuery.Event("jqplotDataRightClick");o.which=r.which;o.pageX=r.pageX;o.pageY=r.pageY;s.target.trigger(o,p)}}function h(){if(this.plugins.donutRenderer&&this.plugins.donutRenderer.highlightCanvas){this.plugins.donutRenderer.highlightCanvas.resetCanvas();this.plugins.donutRenderer.highlightCanvas=null}this.plugins.donutRenderer={highlightedSeriesIndex:null};this.plugins.donutRender!
er.highlightCanvas=new e.jqplot.GenericCanvas();var o=e(this.targetId+" .jqplot-data-label");if(o.length){e(o[0]).before(this.plugins.donutRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-donutRenderer-highlight-canvas",this._plotDimensions,this))}else{this.eventCanvas._elem.before(this.plugins.donutRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-donutRenderer-highlight-canvas",this._plotDimensions,this))}var n=this.plugins.donutRenderer.highlightCanvas.setContext();this.eventCanvas._elem.bind("mouseleave",{plot:this},function(p){i(p.data.plot)})}e.jqplot.preInitHooks.push(c);e.jqplot.DonutTickRenderer=function(){e.jqplot.AxisTickRenderer.call(this)};e.jqplot.DonutTickRenderer.prototype=new e.jqplot.AxisTickRenderer();e.jqplot.DonutTickRenderer.prototype.constructor=e.jqplot.DonutTickRenderer})(jQuery);
\ No newline at end of file
Modified: gnucash/trunk/src/report/jqplot/plugins/jqplot.dragable.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.dragable.js 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.dragable.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -1,18 +1,31 @@
/**
- * Copyright (c) 2009 - 2010 Chris Leonello
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
- * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
- * The author would appreciate an email letting him know of any substantial
- * use of jqPlot. You can reach the author at: chris at jqplot dot com
- * or see http://www.jqplot.com/info.php . This is, of course,
- * not required.
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
- * Thanks for using jqPlot!
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
*
*/
(function($) {
@@ -67,10 +80,16 @@
// insert it before the eventCanvas, so eventCanvas will still capture events.
// add a new DragCanvas object to the plot plugins to handle drawing on this new canvas.
$.jqplot.Dragable.postPlotDraw = function() {
+ // Memory Leaks patch
+ if (this.plugins.dragable && this.plugins.dragable.highlightCanvas) {
+ this.plugins.dragable.highlightCanvas.resetCanvas();
+ this.plugins.dragable.highlightCanvas = null;
+ }
+
this.plugins.dragable = {previousCursor:'auto', isOver:false};
this.plugins.dragable.dragCanvas = new DragCanvas();
- this.eventCanvas._elem.before(this.plugins.dragable.dragCanvas.createElement(this._gridPadding, 'jqplot-dragable-canvas', this._plotDimensions));
+ this.eventCanvas._elem.before(this.plugins.dragable.dragCanvas.createElement(this._gridPadding, 'jqplot-dragable-canvas', this._plotDimensions, this));
var dctx = this.plugins.dragable.dragCanvas.setContext();
};
@@ -168,7 +187,7 @@
initDragPoint(plot, neighbor);
drag.markerRenderer.draw(s.gridData[neighbor.pointIndex][0], s.gridData[neighbor.pointIndex][1], dc._ctx);
ev.target.style.cursor = "move";
- plot.target.trigger('jqlotDragStart', [neighbor.seriesIndex, neighbor.pointIndex, gridpos, datapos]);
+ plot.target.trigger('jqplotDragStart', [neighbor.seriesIndex, neighbor.pointIndex, gridpos, datapos]);
}
}
// Just in case of a hickup, we'll clear the drag canvas and reset.
@@ -200,7 +219,7 @@
plot.drawSeries({preventJqPlotSeriesDrawTrigger:true}, dp.seriesIndex);
dc._neighbor = null;
ev.target.style.cursor = dc._cursors.pop();
- plot.target.trigger('jqlotDragStop', [gridpos, datapos]);
+ plot.target.trigger('jqplotDragStop', [gridpos, datapos]);
}
}
})(jQuery);
\ No newline at end of file
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.dragable.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.dragable.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.dragable.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(d){d.jqplot.Dragable=function(g){this.markerRenderer=new d.jqplot.MarkerRenderer({shadow:false});this.shapeRenderer=new d.jqplot.ShapeRenderer();this.isDragging=false;this.isOver=false;this._ctx;this._elem;this._point;this._gridData;this.color;this.constrainTo="none";d.extend(true,this,g)};function b(){d.jqplot.GenericCanvas.call(this);this.isDragging=false;this.isOver=false;this._neighbor;this._cursors=[]}b.prototype=new d.jqplot.GenericCanvas();b.prototype.constructor=b;d.jqplot.Dragable.parseOptions=function(i,h){var g=h||{};this.plugins.dragable=new d.jqplot.Dragable(g.dragable);this.isDragable=d.jqplot.config.enablePlugins};d.jqplot.Dragable.postPlotDraw=function(){if(this.plugins.dragable&&this.plugins.dragable.highlightCanvas){this.plugins.dragable.highlightCanvas.resetCanvas();this.plugins.dragable.highlightCanvas=null}this.plugins.dragable={previousCursor:"auto",isOver:false};this.plugins.dragable.dragCanvas=new b();this.eventCanvas._elem.before(this.plugins.dragable.dragCanvas.createElement(this._gridPadding,"jqplot-dragable-canvas",this._plotDimensions,this));var g=this.plugins.dragable.dragCanvas.setContext()};d.jqplot.preParseSeriesOptionsHooks.push(d.jqplot.Dragable.parseOptions);d.jqplot.postDrawHooks.push(d.jqplot.Dragable.postPlotDraw);d.jqplot.eventListenerHooks.push(["jqplotMouseMove",e]);d.jqplot.eventListenerHooks.push(["jqplotMouseDown",c]);d.jqplot.eventListenerHooks.push(["jqplotMouseUp",a]);function f(n,p){var q=n.series[p.seriesIndex];var m=q.plugins.dragable;var h=q.markerRenderer;var i=m.markerRenderer;i.style=h.style;i.lineWidth=h.lineWidth+2.5;i.size=h.size+5;if(!m.color){var l=d.jqplot.getColorComponents(h.color);var o=[l[0],l[1],l[2]];var k=(l[3]>=0.6)?l[3]*0.6:l[3]*(2-l[3]);m.color="rgba("+o[0]+","+o[1]+","+o[2]+","+k+")"}i.color=m.color;i.init();var g=(p.pointIndex>0)?p.pointIndex-1:0;var j=p.pointIndex+2;m._gridData=q.gridData.slice(g,j)}function e(o,l,h,t,m){if(m.plugins.dragable.dragCanvas.isDragging){var u=m.plugins.dragable.dragCanvas;var i=u._neighbor!
;var w=m.series[i.seriesIndex];var k=w.plugins.dragable;var r=w.gridData;var p=(k.constrainTo=="y")?i.gridData[0]:l.x;var n=(k.constrainTo=="x")?i.gridData[1]:l.y;var g=w._xaxis.series_p2u(p);var q=w._yaxis.series_p2u(n);var v=u._ctx;v.clearRect(0,0,v.canvas.width,v.canvas.height);if(i.pointIndex>0){k._gridData[1]=[p,n]}else{k._gridData[0]=[p,n]}m.series[i.seriesIndex].draw(u._ctx,{gridData:k._gridData,shadow:false,preventJqPlotSeriesDrawTrigger:true,color:k.color,markerOptions:{color:k.color,shadow:false},trendline:{show:false}});m.target.trigger("jqplotSeriesPointChange",[i.seriesIndex,i.pointIndex,[g,q],[p,n]])}else{if(t!=null){var j=m.series[t.seriesIndex];if(j.isDragable){var u=m.plugins.dragable.dragCanvas;if(!u.isOver){u._cursors.push(o.target.style.cursor);o.target.style.cursor="pointer"}u.isOver=true}}else{if(t==null){var u=m.plugins.dragable.dragCanvas;if(u.isOver){o.target.style.cursor=u._cursors.pop();u.isOver=false}}}}}function c(k,i,g,l,j){var m=j.plugins.dragable.dragCanvas;m._cursors.push(k.target.style.cursor);if(l!=null){var o=j.series[l.seriesIndex];var h=o.plugins.dragable;if(o.isDragable&&!m.isDragging){m._neighbor=l;m.isDragging=true;f(j,l);h.markerRenderer.draw(o.gridData[l.pointIndex][0],o.gridData[l.pointIndex][1],m._ctx);k.target.style.cursor="move";j.target.trigger("jqplotDragStart",[l.seriesIndex,l.pointIndex,i,g])}}else{var n=m._ctx;n.clearRect(0,0,n.canvas.width,n.canvas.height);m.isDragging=false}}function a(m,j,g,o,k){if(k.plugins.dragable.dragCanvas.isDragging){var p=k.plugins.dragable.dragCanvas;var q=p._ctx;q.clearRect(0,0,q.canvas.width,q.canvas.height);p.isDragging=false;var h=p._neighbor;var r=k.series[h.seriesIndex];var i=r.plugins.dragable;var n=(i.constrainTo=="y")?h.data[0]:g[r.xaxis];var l=(i.constrainTo=="x")?h.data[1]:g[r.yaxis];r.data[h.pointIndex][0]=n;r.data[h.pointIndex][1]=l;k.drawSeries({preventJqPlotSeriesDrawTrigger:true},h.seriesIndex);p._neighbor=null;m.target.style.cursor=p._cursors.pop();k.target.trigger("jqplotDragStop",[j,g])}}})(jQuery);
\ No newline at end of file
Modified: gnucash/trunk/src/report/jqplot/plugins/jqplot.enhancedLegendRenderer.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.enhancedLegendRenderer.js 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.enhancedLegendRenderer.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -1,18 +1,31 @@
/**
- * Copyright (c) 2009 - 2010 Chris Leonello
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
- * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
- * The author would appreciate an email letting him know of any substantial
- * use of jqPlot. You can reach the author at: chris at jqplot dot com
- * or see http://www.jqplot.com/info.php . This is, of course,
- * not required.
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
- * Thanks for using jqPlot!
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
*
*/
(function($) {
@@ -38,6 +51,12 @@
// true or a fadein/fadeout speed (number of milliseconds or 'fast', 'normal', 'slow')
// to enable show/hide of series on click of legend item.
this.seriesToggle = 'normal';
+ // prop: seriesToggleReplot
+ // True to replot the chart after toggling series on/off.
+ // This will set the series show property to false.
+ // This allows for rescaling or other maniplation of chart.
+ // Set to an options object (e.g. {resetAxes: true}) for replot options.
+ this.seriesToggleReplot = false;
// prop: disableIEFading
// true to toggle series with a show/hide method only and not allow fading in/out.
// This is to overcome poor performance of fade in some versions of IE.
@@ -50,10 +69,11 @@
};
// called with scope of legend
- $.jqplot.EnhancedLegendRenderer.prototype.draw = function() {
+ $.jqplot.EnhancedLegendRenderer.prototype.draw = function(offsets, plot) {
var legend = this;
if (this.show) {
var series = this._series;
+ var s;
var ss = 'position:absolute;';
ss += (this.background) ? 'background:'+this.background+';' : '';
ss += (this.border) ? 'border:'+this.border+';' : '';
@@ -90,24 +110,26 @@
nc = 1;
}
- var i, j, tr, td1, td2, lt, rs;
+ var i, j, tr, td1, td2, lt, rs, div, div0, div1;
var idx = 0;
// check to see if we need to reverse
for (i=series.length-1; i>=0; i--) {
- if (series[i]._stack || series[i].renderer.constructor == $.jqplot.BezierCurveRenderer){
+ if (nc == 1 && series[i]._stack || series[i].renderer.constructor == $.jqplot.BezierCurveRenderer){
reverse = true;
}
}
for (i=0; i<nr; i++) {
+ tr = $(document.createElement('tr'));
+ tr.addClass('jqplot-table-legend');
if (reverse){
- tr = $('<tr class="jqplot-table-legend"></tr>').prependTo(this._elem);
+ tr.prependTo(this._elem);
}
else{
- tr = $('<tr class="jqplot-table-legend"></tr>').appendTo(this._elem);
+ tr.appendTo(this._elem);
}
for (j=0; j<nc; j++) {
- if (idx < series.length && series[idx].show && series[idx].showLabel){
+ if (idx < series.length && (series[idx].show || series[idx].showLabel)){
s = series[idx];
lt = this.labels[idx] || s.label.toString();
if (lt) {
@@ -129,11 +151,27 @@
}
}
rs = (pad) ? this.rowSpacing : '0';
+
+ td1 = $(document.createElement('td'));
+ td1.addClass('jqplot-table-legend jqplot-table-legend-swatch');
+ td1.css({textAlign: 'center', paddingTop: rs});
+
+ div0 = $(document.createElement('div'));
+ div0.addClass('jqplot-table-legend-swatch-outline');
+ div1 = $(document.createElement('div'));
+ div1.addClass('jqplot-table-legend-swatch');
+ div1.css({backgroundColor: color, borderColor: color});
+
+ td1.append(div0.append(div1));
+
+ td2 = $(document.createElement('td'));
+ td2.addClass('jqplot-table-legend jqplot-table-legend-label');
+ td2.css('paddingTop', rs);
- td1 = $('<td class="jqplot-table-legend" style="text-align:center;padding-top:'+rs+';">'+
- '<div><div class="jqplot-table-legend-swatch" style="background-color:'+color+';border-color:'+color+';"></div>'+
- '</div></td>');
- td2 = $('<td class="jqplot-table-legend" style="padding-top:'+rs+';"></td>');
+ // td1 = $('<td class="jqplot-table-legend" style="text-align:center;padding-top:'+rs+';">'+
+ // '<div><div class="jqplot-table-legend-swatch" style="background-color:'+color+';border-color:'+color+';"></div>'+
+ // '</div></td>');
+ // td2 = $('<td class="jqplot-table-legend" style="padding-top:'+rs+';"></td>');
if (this.escapeHtml){
td2.text(lt);
}
@@ -150,37 +188,118 @@
}
if (this.seriesToggle) {
+
+ // add an overlay for clicking series on/off
+ // div0 = $(document.createElement('div'));
+ // div0.addClass('jqplot-table-legend-overlay');
+ // div0.css({position:'relative', left:0, top:0, height:'100%', width:'100%'});
+ // tr.append(div0);
+
var speed;
- if (typeof(this.seriesToggle) == 'string' || typeof(this.seriesToggle) == 'number') {
- if (!$.browser.msie || !this.disableIEFading) {
+ if (typeof(this.seriesToggle) === 'string' || typeof(this.seriesToggle) === 'number') {
+ if (!$.jqplot.use_excanvas || !this.disableIEFading) {
speed = this.seriesToggle;
}
}
if (this.showSwatches) {
- td1.bind('click', {series:s, speed:speed}, s.toggleDisplay);
+ td1.bind('click', {series:s, speed:speed, plot: plot, replot:this.seriesToggleReplot}, handleToggle);
td1.addClass('jqplot-seriesToggle');
}
if (this.showLabels) {
- td2.bind('click', {series:s, speed:speed}, s.toggleDisplay);
+ td2.bind('click', {series:s, speed:speed, plot: plot, replot:this.seriesToggleReplot}, handleToggle);
td2.addClass('jqplot-seriesToggle');
}
+
+ // for series that are already hidden, add the hidden class
+ if (!s.show && s.showLabel) {
+ td1.addClass('jqplot-series-hidden');
+ td2.addClass('jqplot-series-hidden');
+ }
}
pad = true;
}
}
idx++;
- }
+ }
+
+ td1 = td2 = div0 = div1 = null;
}
}
return this._elem;
};
+
+ var handleToggle = function (ev) {
+ var d = ev.data,
+ s = d.series,
+ replot = d.replot,
+ plot = d.plot,
+ speed = d.speed,
+ sidx = s.index,
+ showing = false;
+
+ if (s.canvas._elem.is(':hidden') || !s.show) {
+ showing = true;
+ }
+
+ var doLegendToggle = function() {
+
+ if (replot) {
+ var opts = {};
+
+ if ($.isPlainObject(replot)) {
+ $.extend(true, opts, replot);
+ }
+
+ plot.replot(opts);
+ // if showing, there was no canvas element to fade in, so hide here
+ // and then do a fade in.
+ if (showing && speed) {
+ var s = plot.series[sidx];
+
+ if (s.shadowCanvas._elem) {
+ s.shadowCanvas._elem.hide().fadeIn(speed);
+ }
+ s.canvas._elem.hide().fadeIn(speed);
+ s.canvas._elem.nextAll('.jqplot-point-label.jqplot-series-'+s.index).hide().fadeIn(speed);
+ }
+
+ }
+
+ else {
+ var s = plot.series[sidx];
+
+ if (s.canvas._elem.is(':hidden') || !s.show) {
+ // Not sure if there is a better way to check for showSwatches and showLabels === true.
+ // Test for "undefined" since default values for both showSwatches and showLables is true.
+ if (typeof plot.options.legend.showSwatches === 'undefined' || plot.options.legend.showSwatches === true) {
+ plot.legend._elem.find('td').eq(sidx * 2).addClass('jqplot-series-hidden');
+ }
+ if (typeof plot.options.legend.showLabels === 'undefined' || plot.options.legend.showLabels === true) {
+ plot.legend._elem.find('td').eq((sidx * 2) + 1).addClass('jqplot-series-hidden');
+ }
+ }
+ else {
+ if (typeof plot.options.legend.showSwatches === 'undefined' || plot.options.legend.showSwatches === true) {
+ plot.legend._elem.find('td').eq(sidx * 2).removeClass('jqplot-series-hidden');
+ }
+ if (typeof plot.options.legend.showLabels === 'undefined' || plot.options.legend.showLabels === true) {
+ plot.legend._elem.find('td').eq((sidx * 2) + 1).removeClass('jqplot-series-hidden');
+ }
+ }
+
+ }
+
+ };
+
+ s.toggleDisplay(ev, doLegendToggle);
+ };
// called with scope of plot.
- postDraw = function () {
+ var postDraw = function () {
if (this.legend.renderer.constructor == $.jqplot.EnhancedLegendRenderer && this.legend.seriesToggle){
var e = this.legend._elem.detach();
this.eventCanvas._elem.after(e);
}
};
-})(jQuery);
\ No newline at end of file
+})(jQuery);
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.enhancedLegendRenderer.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.enhancedLegendRenderer.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.enhancedLegendRenderer.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(c){c.jqplot.EnhancedLegendRenderer=function(){c.jqplot.TableLegendRenderer.call(this)};c.jqplot.EnhancedLegendRenderer.prototype=new c.jqplot.TableLegendRenderer();c.jqplot.EnhancedLegendRenderer.prototype.constructor=c.jqplot.EnhancedLegendRenderer;c.jqplot.EnhancedLegendRenderer.prototype.init=function(d){this.numberRows=null;this.numberColumns=null;this.seriesToggle="normal";this.seriesToggleReplot=false;this.disableIEFading=true;c.extend(true,this,d);if(this.seriesToggle){c.jqplot.postDrawHooks.push(b)}};c.jqplot.EnhancedLegendRenderer.prototype.draw=function(m,y){var f=this;if(this.show){var r=this._series;var u;var w="position:absolute;";w+=(this.background)?"background:"+this.background+";":"";w+=(this.border)?"border:"+this.border+";":"";w+=(this.fontSize)?"font-size:"+this.fontSize+";":"";w+=(this.fontFamily)?"font-family:"+this.fontFamily+";":"";w+=(this.textColor)?"color:"+this.textColor+";":"";w+=(this.marginTop!=null)?"margin-top:"+this.marginTop+";":"";w+=(this.marginBottom!=null)?"margin-bottom:"+this.marginBottom+";":"";w+=(this.marginLeft!=null)?"margin-left:"+this.marginLeft+";":"";w+=(this.marginRight!=null)?"margin-right:"+this.marginRight+";":"";this._elem=c('<table class="jqplot-table-legend" style="'+w+'"></table>');if(this.seriesToggle){this._elem.css("z-index","3")}var C=false,q=false,d,o;if(this.numberRows){d=this.numberRows;if(!this.numberColumns){o=Math.ceil(r.length/d)}else{o=this.numberColumns}}else{if(this.numberColumns){o=this.numberColumns;d=Math.ceil(r.length/this.numberColumns)}else{d=r.length;o=1}}var B,z,e,l,k,n,p,t,h,g;var v=0;for(B=r.length-1;B>=0;B--){if(o==1&&r[B]._stack||r[B].renderer.constructor==c.jqplot.BezierCurveRenderer){q=true}}for(B=0;B<d;B++){e=c(document.createElement("tr"));e.addClass("jqplot-table-legend");if(q){e.prependTo(this._elem)}else{e.appendTo(this._elem)}for(z=0;z<o;z++){if(v<r.length&&(r[v].show||r[v].showLabel)){u=r[v];n=this.labels[v]||u.label.toString();if(n){var x=u.color;if(!q){if(B>0){C=true}else{C=false}}else{if(B==d-1){!
C=false}else{C=true}}p=(C)?this.rowSpacing:"0";l=c(document.createElement("td"));l.addClass("jqplot-table-legend jqplot-table-legend-swatch");l.css({textAlign:"center",paddingTop:p});h=c(document.createElement("div"));h.addClass("jqplot-table-legend-swatch-outline");g=c(document.createElement("div"));g.addClass("jqplot-table-legend-swatch");g.css({backgroundColor:x,borderColor:x});l.append(h.append(g));k=c(document.createElement("td"));k.addClass("jqplot-table-legend jqplot-table-legend-label");k.css("paddingTop",p);if(this.escapeHtml){k.text(n)}else{k.html(n)}if(q){if(this.showLabels){k.prependTo(e)}if(this.showSwatches){l.prependTo(e)}}else{if(this.showSwatches){l.appendTo(e)}if(this.showLabels){k.appendTo(e)}}if(this.seriesToggle){var A;if(typeof(this.seriesToggle)==="string"||typeof(this.seriesToggle)==="number"){if(!c.jqplot.use_excanvas||!this.disableIEFading){A=this.seriesToggle}}if(this.showSwatches){l.bind("click",{series:u,speed:A,plot:y,replot:this.seriesToggleReplot},a);l.addClass("jqplot-seriesToggle")}if(this.showLabels){k.bind("click",{series:u,speed:A,plot:y,replot:this.seriesToggleReplot},a);k.addClass("jqplot-seriesToggle")}if(!u.show&&u.showLabel){l.addClass("jqplot-series-hidden");k.addClass("jqplot-series-hidden")}}C=true}}v++}l=k=h=g=null}}return this._elem};var a=function(j){var i=j.data,m=i.series,k=i.replot,h=i.plot,f=i.speed,l=m.index,g=false;if(m.canvas._elem.is(":hidden")||!m.show){g=true}var e=function(){if(k){var n={};if(c.isPlainObject(k)){c.extend(true,n,k)}h.replot(n);if(g&&f){var d=h.series[l];if(d.shadowCanvas._elem){d.shadowCanvas._elem.hide().fadeIn(f)}d.canvas._elem.hide().fadeIn(f);d.canvas._elem.nextAll(".jqplot-point-label.jqplot-series-"+d.index).hide().fadeIn(f)}}else{var d=h.series[l];if(d.canvas._elem.is(":hidden")||!d.show){if(typeof h.options.legend.showSwatches==="undefined"||h.options.legend.showSwatches===true){h.legend._elem.find("td").eq(l*2).addClass("jqplot-series-hidden")}if(typeof h.options.legend.showLabels==="undefined"||h.options.legend.showLabels===true!
){h.legend._elem.find("td").eq((l*2)+1).addClass("jqplot-series-hidden")}}else{if(typeof h.options.legend.showSwatches==="undefined"||h.options.legend.showSwatches===true){h.legend._elem.find("td").eq(l*2).removeClass("jqplot-series-hidden")}if(typeof h.options.legend.showLabels==="undefined"||h.options.legend.showLabels===true){h.legend._elem.find("td").eq((l*2)+1).removeClass("jqplot-series-hidden")}}}};m.toggleDisplay(j,e)};var b=function(){if(this.legend.renderer.constructor==c.jqplot.EnhancedLegendRenderer&&this.legend.seriesToggle){var d=this.legend._elem.detach();this.eventCanvas._elem.after(d)}}})(jQuery);
\ No newline at end of file
Modified: gnucash/trunk/src/report/jqplot/plugins/jqplot.funnelRenderer.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.funnelRenderer.js 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.funnelRenderer.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -1,18 +1,31 @@
/**
- * Copyright (c) 2009 - 2010 Chris Leonello
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
- * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
- * The author would appreciate an email letting him know of any substantial
- * use of jqPlot. You can reach the author at: chris at jqplot dot com
- * or see http://www.jqplot.com/info.php . This is, of course,
- * not required.
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
- * Thanks for using jqPlot!
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
*
*/
(function($) {
@@ -134,6 +147,7 @@
// Threshhold in percentage (0 - 100) of pie area, below which no label will be displayed.
// This applies to all label types, not just to percentage labels.
this.dataLabelThreshold = 3;
+ this._type = 'funnel';
this.tickRenderer = $.jqplot.FunnelTickRenderer;
@@ -781,7 +795,7 @@
function postInit(target, data, options) {
// if multiple series, add a reference to the previous one so that
// funnel rings can nest.
- for (i=0; i<this.series.length; i++) {
+ for (var i=0; i<this.series.length; i++) {
if (this.series[i].renderer.constructor == $.jqplot.FunnelRenderer) {
// don't allow mouseover and mousedown at same time.
if (this.series[i].highlightMouseOver) {
@@ -789,14 +803,13 @@
}
}
}
- this.target.bind('mouseout', {plot:this}, function (ev) { unhighlight(ev.data.plot); });
}
// called with scope of plot
function postParseOptions(options) {
for (var i=0; i<this.series.length; i++) {
this.series[i].seriesColors = this.seriesColors;
- this.series[i].colorGenerator = this.colorGenerator;
+ this.series[i].colorGenerator = $.jqplot.colorGenerator;
}
}
@@ -828,6 +841,7 @@
plot.target.trigger(evt1, ins);
if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.funnelRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) {
var evt = jQuery.Event('jqplotDataHighlight');
+ evt.which = ev.which;
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
plot.target.trigger(evt, ins);
@@ -844,6 +858,7 @@
var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
if (plot.series[ins[0]].highlightMouseDown && !(ins[0] == plot.plugins.funnelRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) {
var evt = jQuery.Event('jqplotDataHighlight');
+ evt.which = ev.which;
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
plot.target.trigger(evt, ins);
@@ -866,6 +881,7 @@
if (neighbor) {
var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
var evt = jQuery.Event('jqplotDataClick');
+ evt.which = ev.which;
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
plot.target.trigger(evt, ins);
@@ -880,6 +896,7 @@
unhighlight(plot);
}
var evt = jQuery.Event('jqplotDataRightClick');
+ evt.which = ev.which;
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
plot.target.trigger(evt, ins);
@@ -890,19 +907,26 @@
// create a canvas which we can draw on.
// insert it before the eventCanvas, so eventCanvas will still capture events.
function postPlotDraw() {
+ // Memory Leaks patch
+ if (this.plugins.funnelRenderer && this.plugins.funnelRenderer.highlightCanvas) {
+ this.plugins.funnelRenderer.highlightCanvas.resetCanvas();
+ this.plugins.funnelRenderer.highlightCanvas = null;
+ }
+
this.plugins.funnelRenderer = {};
this.plugins.funnelRenderer.highlightCanvas = new $.jqplot.GenericCanvas();
// do we have any data labels? if so, put highlight canvas before those
var labels = $(this.targetId+' .jqplot-data-label');
if (labels.length) {
- $(labels[0]).before(this.plugins.funnelRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-funnelRenderer-highlight-canvas', this._plotDimensions));
+ $(labels[0]).before(this.plugins.funnelRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-funnelRenderer-highlight-canvas', this._plotDimensions, this));
}
// else put highlight canvas before event canvas.
else {
- this.eventCanvas._elem.before(this.plugins.funnelRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-funnelRenderer-highlight-canvas', this._plotDimensions));
+ this.eventCanvas._elem.before(this.plugins.funnelRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-funnelRenderer-highlight-canvas', this._plotDimensions, this));
}
var hctx = this.plugins.funnelRenderer.highlightCanvas.setContext();
+ this.eventCanvas._elem.bind('mouseleave', {plot:this}, function (ev) { unhighlight(ev.data.plot); });
}
$.jqplot.preInitHooks.push(preInit);
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.funnelRenderer.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.funnelRenderer.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.funnelRenderer.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(e){e.jqplot.FunnelRenderer=function(){e.jqplot.LineRenderer.call(this)};e.jqplot.FunnelRenderer.prototype=new e.jqplot.LineRenderer();e.jqplot.FunnelRenderer.prototype.constructor=e.jqplot.FunnelRenderer;e.jqplot.FunnelRenderer.prototype.init=function(p,t){this.padding={top:20,right:20,bottom:20,left:20};this.sectionMargin=6;this.fill=true;this.shadowOffset=2;this.shadowAlpha=0.07;this.shadowDepth=5;this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColors=[];this.widthRatio=0.2;this.lineWidth=2;this.dataLabels="percent";this.showDataLabels=false;this.dataLabelFormatString=null;this.dataLabelThreshold=3;this._type="funnel";this.tickRenderer=e.jqplot.FunnelTickRenderer;if(p.highlightMouseDown&&p.highlightMouseOver==null){p.highlightMouseOver=false}e.extend(true,this,p);this._highlightedPoint=null;this._bases=[];this._atot;this._areas=[];this._lengths=[];this._angle;this._dataIndices=[];this._unorderedData=e.extend(true,[],this.data);var o=e.extend(true,[],this.data);for(var r=0;r<o.length;r++){o[r].push(r)}this.data.sort(function(v,u){return u[1]-v[1]});o.sort(function(v,u){return u[1]-v[1]});for(var r=0;r<o.length;r++){this._dataIndices.push(o[r][2])}if(this.highlightColors.length==0){for(var r=0;r<this.seriesColors.length;r++){var q=e.jqplot.getColorComponents(this.seriesColors[r]);var m=[q[0],q[1],q[2]];var s=m[0]+m[1]+m[2];for(var n=0;n<3;n++){m[n]=(s>570)?m[n]*0.8:m[n]+0.4*(255-m[n]);m[n]=parseInt(m[n],10)}this.highlightColors.push("rgb("+m[0]+","+m[1]+","+m[2]+")")}}t.postParseOptionsHooks.addOnce(k);t.postInitHooks.addOnce(g);t.eventListenerHooks.addOnce("jqplotMouseMove",a);t.eventListenerHooks.addOnce("jqplotMouseDown",b);t.eventListenerHooks.addOnce("jqplotMouseUp",j);t.eventListenerHooks.addOnce("jqplotClick",f);t.eventListenerHooks.addOnce("jqplotRightClick",l);t.postDrawHooks.addOnce(h)};e.jqplot.FunnelRenderer.prototype.setGridData=function(o){var n=0;var p=[];for(var m=0;m<this.data.length;m++){n+=this.data[m][1];p.push([this.data[m][0],this.data[m][1]])}!
for(var m=0;m<p.length;m++){p[m][1]=p[m][1]/n}this._bases=new Array(p.length+1);this._lengths=new Array(p.length);this.gridData=p};e.jqplot.FunnelRenderer.prototype.makeGridData=function(o,p){var n=0;var q=[];for(var m=0;m<this.data.length;m++){n+=this.data[m][1];q.push([this.data[m][0],this.data[m][1]])}for(var m=0;m<q.length;m++){q[m][1]=q[m][1]/n}this._bases=new Array(q.length+1);this._lengths=new Array(q.length);return q};e.jqplot.FunnelRenderer.prototype.drawSection=function(n,p,o,s){var t=this.fill;var m=this.lineWidth;n.save();if(s){for(var r=0;r<this.shadowDepth;r++){n.save();n.translate(this.shadowOffset*Math.cos(this.shadowAngle/180*Math.PI),this.shadowOffset*Math.sin(this.shadowAngle/180*Math.PI));q()}}else{q()}function q(){n.beginPath();n.fillStyle=o;n.strokeStyle=o;n.lineWidth=m;n.moveTo(p[0][0],p[0][1]);for(var u=1;u<4;u++){n.lineTo(p[u][0],p[u][1])}n.closePath();if(t){n.fill()}else{n.stroke()}}if(s){for(var r=0;r<this.shadowDepth;r++){n.restore()}}n.restore()};e.jqplot.FunnelRenderer.prototype.draw=function(G,B,J,p){var Y;var L=(J!=undefined)?J:{};var w=0;var u=0;var R=1;this._areas=[];if(J.legendInfo&&J.legendInfo.placement=="insideGrid"){var O=J.legendInfo;switch(O.location){case"nw":w=O.width+O.xoffset;break;case"w":w=O.width+O.xoffset;break;case"sw":w=O.width+O.xoffset;break;case"ne":w=O.width+O.xoffset;R=-1;break;case"e":w=O.width+O.xoffset;R=-1;break;case"se":w=O.width+O.xoffset;R=-1;break;case"n":u=O.height+O.yoffset;break;case"s":u=O.height+O.yoffset;R=-1;break;default:break}}var t=(R==1)?this.padding.left+w:this.padding.left;var F=(R==1)?this.padding.top+u:this.padding.top;var M=(R==-1)?this.padding.right+w:this.padding.right;var o=(R==-1)?this.padding.bottom+u:this.padding.bottom;var P=(L.shadow!=undefined)?L.shadow:this.shadow;var q=(L.showLine!=undefined)?L.showLine:this.showLine;var C=(L.fill!=undefined)?L.fill:this.fill;var H=G.canvas.width;var N=G.canvas.height;this._bases[0]=H-t-M;var I=this._length=N-F-o;var r=this._bases[0]*this.widthRatio;this._atot=I/2*(this._bases[0]+this._bas!
es[0]*this.widthRatio);this._angle=Math.atan((this._bases[0]-r)/2/I);for(Y=0;Y<B.length;Y++){this._areas.push(B[Y][1]*this._atot)}var E,aa,W,Q=0;var n=0.0001;for(Y=0;Y<this._areas.length;Y++){E=this._areas[Y]/this._bases[Y];aa=999999;this._lengths[Y]=E;W=0;while(aa>this._lengths[Y]*n&&W<100){this._lengths[Y]=this._areas[Y]/(this._bases[Y]-this._lengths[Y]*Math.tan(this._angle));aa=Math.abs(this._lengths[Y]-E);this._bases[Y+1]=this._bases[Y]-(2*this._lengths[Y]*Math.tan(this._angle));E=this._lengths[Y];W++}Q+=this._lengths[Y]}this._vertices=new Array(B.length);var ae=[t,F],ad=[t+this._bases[0],F],ac=[t+(this._bases[0]-this._bases[this._bases.length-1])/2,F+this._length],ab=[ac[0]+this._bases[this._bases.length-1],ac[1]];function V(ag){var x=(ae[1]-ac[1])/(ae[0]-ac[0]);var v=ae[1]-x*ae[0];var ah=ag+ae[1];return[(ah-v)/x,ah]}function D(ag){var x=(ad[1]-ab[1])/(ad[0]-ab[0]);var v=ad[1]-x*ad[0];var ah=ag+ad[1];return[(ah-v)/x,ah]}var T=w,S=u;var Z=0,m=0;for(Y=0;Y<B.length;Y++){this._vertices[Y]=new Array();var U=this._vertices[Y];var A=this.sectionMargin;if(Y==0){m=0}if(Y==1){m=A/3}else{if(Y>0&&Y<B.length-1){m=A/2}else{if(Y==B.length-1){m=2*A/3}}}U.push(V(Z+m));U.push(D(Z+m));Z+=this._lengths[Y];if(Y==0){m=-2*A/3}else{if(Y>0&&Y<B.length-1){m=-A/2}else{if(Y==B.length-1){m=0}}}U.push(D(Z+m));U.push(V(Z+m))}if(this.shadow){var af="rgba(0,0,0,"+this.shadowAlpha+")";for(var Y=0;Y<B.length;Y++){this.renderer.drawSection.call(this,G,this._vertices[Y],af,true)}}for(var Y=0;Y<B.length;Y++){var U=this._vertices[Y];this.renderer.drawSection.call(this,G,U,this.seriesColors[Y]);if(this.showDataLabels&&B[Y][1]*100>=this.dataLabelThreshold){var K,X;if(this.dataLabels=="label"){K=this.dataLabelFormatString||"%s";X=e.jqplot.sprintf(K,B[Y][0])}else{if(this.dataLabels=="value"){K=this.dataLabelFormatString||"%d";X=e.jqplot.sprintf(K,this.data[Y][1])}else{if(this.dataLabels=="percent"){K=this.dataLabelFormatString||"%d%%";X=e.jqplot.sprintf(K,B[Y][1]*100)}else{if(this.dataLabels.constructor==Array){K=this.dataLabelFormatString||"%s";X=e!
.jqplot.sprintf(K,this.dataLabels[this._dataIndices[Y]])}}}}var s=(this._radius)*this.dataLabelPositionFactor+this.sliceMargin+this.dataLabelNudge;var T=(U[0][0]+U[1][0])/2+this.canvas._offsets.left;var S=(U[1][1]+U[2][1])/2+this.canvas._offsets.top;var z=e('<span class="jqplot-funnel-series jqplot-data-label" style="position:absolute;">'+X+"</span>").insertBefore(p.eventCanvas._elem);T-=z.width()/2;S-=z.height()/2;T=Math.round(T);S=Math.round(S);z.css({left:T,top:S})}}};e.jqplot.FunnelAxisRenderer=function(){e.jqplot.LinearAxisRenderer.call(this)};e.jqplot.FunnelAxisRenderer.prototype=new e.jqplot.LinearAxisRenderer();e.jqplot.FunnelAxisRenderer.prototype.constructor=e.jqplot.FunnelAxisRenderer;e.jqplot.FunnelAxisRenderer.prototype.init=function(m){this.tickRenderer=e.jqplot.FunnelTickRenderer;e.extend(true,this,m);this._dataBounds={min:0,max:100};this.min=0;this.max=100;this.showTicks=false;this.ticks=[];this.showMark=false;this.show=false};e.jqplot.FunnelLegendRenderer=function(){e.jqplot.TableLegendRenderer.call(this)};e.jqplot.FunnelLegendRenderer.prototype=new e.jqplot.TableLegendRenderer();e.jqplot.FunnelLegendRenderer.prototype.constructor=e.jqplot.FunnelLegendRenderer;e.jqplot.FunnelLegendRenderer.prototype.init=function(m){this.numberRows=null;this.numberColumns=null;e.extend(true,this,m)};e.jqplot.FunnelLegendRenderer.prototype.draw=function(){var p=this;if(this.show){var x=this._series;var A="position:absolute;";A+=(this.background)?"background:"+this.background+";":"";A+=(this.border)?"border:"+this.border+";":"";A+=(this.fontSize)?"font-size:"+this.fontSize+";":"";A+=(this.fontFamily)?"font-family:"+this.fontFamily+";":"";A+=(this.textColor)?"color:"+this.textColor+";":"";A+=(this.marginTop!=null)?"margin-top:"+this.marginTop+";":"";A+=(this.marginBottom!=null)?"margin-bottom:"+this.marginBottom+";":"";A+=(this.marginLeft!=null)?"margin-left:"+this.marginLeft+";":"";A+=(this.marginRight!=null)?"margin-right:"+this.marginRight+";":"";this._elem=e('<table class="jqplot-table-legend" style="'+A+'"></t!
able>');var E=false,w=false,m,u;var y=x[0];var n=new e.jqplot.ColorGenerator(y.seriesColors);if(y.show){var F=y.data;if(this.numberRows){m=this.numberRows;if(!this.numberColumns){u=Math.ceil(F.length/m)}else{u=this.numberColumns}}else{if(this.numberColumns){u=this.numberColumns;m=Math.ceil(F.length/this.numberColumns)}else{m=F.length;u=1}}var D,C,o,r,q,t,v,B;var z=0;for(D=0;D<m;D++){if(w){o=e('<tr class="jqplot-table-legend"></tr>').prependTo(this._elem)}else{o=e('<tr class="jqplot-table-legend"></tr>').appendTo(this._elem)}for(C=0;C<u;C++){if(z<F.length){t=this.labels[z]||F[z][0].toString();B=n.next();if(!w){if(D>0){E=true}else{E=false}}else{if(D==m-1){E=false}else{E=true}}v=(E)?this.rowSpacing:"0";r=e('<td class="jqplot-table-legend" style="text-align:center;padding-top:'+v+';"><div><div class="jqplot-table-legend-swatch" style="border-color:'+B+';"></div></div></td>');q=e('<td class="jqplot-table-legend" style="padding-top:'+v+';"></td>');if(this.escapeHtml){q.text(t)}else{q.html(t)}if(w){q.prependTo(o);r.prependTo(o)}else{r.appendTo(o);q.appendTo(o)}E=true}z++}}}}return this._elem};function c(q,p,n){n=n||{};n.axesDefaults=n.axesDefaults||{};n.legend=n.legend||{};n.seriesDefaults=n.seriesDefaults||{};var m=false;if(n.seriesDefaults.renderer==e.jqplot.FunnelRenderer){m=true}else{if(n.series){for(var o=0;o<n.series.length;o++){if(n.series[o].renderer==e.jqplot.FunnelRenderer){m=true}}}}if(m){n.axesDefaults.renderer=e.jqplot.FunnelAxisRenderer;n.legend.renderer=e.jqplot.FunnelLegendRenderer;n.legend.preDraw=true;n.sortData=false;n.seriesDefaults.pointLabels={show:false}}}function g(p,o,m){for(var n=0;n<this.series.length;n++){if(this.series[n].renderer.constructor==e.jqplot.FunnelRenderer){if(this.series[n].highlightMouseOver){this.series[n].highlightMouseDown=false}}}}function k(m){for(var n=0;n<this.series.length;n++){this.series[n].seriesColors=this.seriesColors;this.series[n].colorGenerator=e.jqplot.colorGenerator}}function d(q,p,o){var n=q.series[p];var m=q.plugins.funnelRenderer.highlightCanvas;m._ctx.clea!
rRect(0,0,m._ctx.canvas.width,m._ctx.canvas.height);n._highlightedPoint=o;q.plugins.funnelRenderer.highlightedSeriesIndex=p;n.renderer.drawSection.call(n,m._ctx,n._vertices[o],n.highlightColors[o],false)}function i(o){var m=o.plugins.funnelRenderer.highlightCanvas;m._ctx.clearRect(0,0,m._ctx.canvas.width,m._ctx.canvas.height);for(var n=0;n<o.series.length;n++){o.series[n]._highlightedPoint=null}o.plugins.funnelRenderer.highlightedSeriesIndex=null;o.target.trigger("jqplotDataUnhighlight")}function a(q,p,t,s,r){if(s){var o=[s.seriesIndex,s.pointIndex,s.data];var n=jQuery.Event("jqplotDataMouseOver");n.pageX=q.pageX;n.pageY=q.pageY;r.target.trigger(n,o);if(r.series[o[0]].highlightMouseOver&&!(o[0]==r.plugins.funnelRenderer.highlightedSeriesIndex&&o[1]==r.series[o[0]]._highlightedPoint)){var m=jQuery.Event("jqplotDataHighlight");m.which=q.which;m.pageX=q.pageX;m.pageY=q.pageY;r.target.trigger(m,o);d(r,o[0],o[1])}}else{if(s==null){i(r)}}}function b(p,o,s,r,q){if(r){var n=[r.seriesIndex,r.pointIndex,r.data];if(q.series[n[0]].highlightMouseDown&&!(n[0]==q.plugins.funnelRenderer.highlightedSeriesIndex&&n[1]==q.series[n[0]]._highlightedPoint)){var m=jQuery.Event("jqplotDataHighlight");m.which=p.which;m.pageX=p.pageX;m.pageY=p.pageY;q.target.trigger(m,n);d(q,n[0],n[1])}}else{if(r==null){i(q)}}}function j(o,n,r,q,p){var m=p.plugins.funnelRenderer.highlightedSeriesIndex;if(m!=null&&p.series[m].highlightMouseDown){i(p)}}function f(p,o,s,r,q){if(r){var n=[r.seriesIndex,r.pointIndex,r.data];var m=jQuery.Event("jqplotDataClick");m.which=p.which;m.pageX=p.pageX;m.pageY=p.pageY;q.target.trigger(m,n)}}function l(q,p,t,s,r){if(s){var o=[s.seriesIndex,s.pointIndex,s.data];var m=r.plugins.funnelRenderer.highlightedSeriesIndex;if(m!=null&&r.series[m].highlightMouseDown){i(r)}var n=jQuery.Event("jqplotDataRightClick");n.which=q.which;n.pageX=q.pageX;n.pageY=q.pageY;r.target.trigger(n,o)}}function h(){if(this.plugins.funnelRenderer&&this.plugins.funnelRenderer.highlightCanvas){this.plugins.funnelRenderer.highlightCanvas.resetCanvas();th!
is.plugins.funnelRenderer.highlightCanvas=null}this.plugins.funnelRenderer={};this.plugins.funnelRenderer.highlightCanvas=new e.jqplot.GenericCanvas();var n=e(this.targetId+" .jqplot-data-label");if(n.length){e(n[0]).before(this.plugins.funnelRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-funnelRenderer-highlight-canvas",this._plotDimensions,this))}else{this.eventCanvas._elem.before(this.plugins.funnelRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-funnelRenderer-highlight-canvas",this._plotDimensions,this))}var m=this.plugins.funnelRenderer.highlightCanvas.setContext();this.eventCanvas._elem.bind("mouseleave",{plot:this},function(o){i(o.data.plot)})}e.jqplot.preInitHooks.push(c);e.jqplot.FunnelTickRenderer=function(){e.jqplot.AxisTickRenderer.call(this)};e.jqplot.FunnelTickRenderer.prototype=new e.jqplot.AxisTickRenderer();e.jqplot.FunnelTickRenderer.prototype.constructor=e.jqplot.FunnelTickRenderer})(jQuery);
\ No newline at end of file
Modified: gnucash/trunk/src/report/jqplot/plugins/jqplot.highlighter.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.highlighter.js 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.highlighter.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -1,18 +1,31 @@
/**
- * Copyright (c) 2009 - 2010 Chris Leonello
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
- * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
- * The author would appreciate an email letting him know of any substantial
- * use of jqPlot. You can reach the author at: chris at jqplot dot com
- * or see http://www.jqplot.com/info.php . This is, of course,
- * not required.
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
- * Thanks for using jqPlot!
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
*
*/
(function($) {
@@ -102,6 +115,12 @@
// prop; tooltipSeparator
// String to use to separate x and y axes in tooltip.
this.tooltipSeparator = ', ';
+ // prop; tooltipContentEditor
+ // Function used to edit/augment/replace the formatted tooltip contents.
+ // Called as str = tooltipContentEditor(str, seriesIndex, pointIndex)
+ // where str is the generated tooltip html and seriesIndex and pointIndex identify
+ // the data point being highlighted. Should return the html for the tooltip contents.
+ this.tooltipContentEditor = null;
// prop: useAxesFormatters
// Use the x and y axes formatters to format the text in the tooltip.
this.useAxesFormatters = true;
@@ -133,10 +152,15 @@
this.bringSeriesToFront = false;
this._tooltipElem;
this.isHighlighting = false;
+ this.currentNeighbor = null;
$.extend(true, this, options);
};
+ var locations = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w'];
+ var locationIndicies = {'nw':0, 'n':1, 'ne':2, 'e':3, 'se':4, 's':5, 'sw':6, 'w':7};
+ var oppositeLocations = ['se', 's', 'sw', 'w', 'nw', 'n', 'ne', 'e'];
+
// axis.renderer.tickrenderer.formatter
// called with scope of plot
@@ -157,14 +181,29 @@
// create a canvas which we can draw on.
// insert it before the eventCanvas, so eventCanvas will still capture events.
$.jqplot.Highlighter.postPlotDraw = function() {
+ // Memory Leaks patch
+ if (this.plugins.highlighter && this.plugins.highlighter.highlightCanvas) {
+ this.plugins.highlighter.highlightCanvas.resetCanvas();
+ this.plugins.highlighter.highlightCanvas = null;
+ }
+
+ if (this.plugins.highlighter && this.plugins.highlighter._tooltipElem) {
+ this.plugins.highlighter._tooltipElem.emptyForce();
+ this.plugins.highlighter._tooltipElem = null;
+ }
+
this.plugins.highlighter.highlightCanvas = new $.jqplot.GenericCanvas();
- this.eventCanvas._elem.before(this.plugins.highlighter.highlightCanvas.createElement(this._gridPadding, 'jqplot-highlight-canvas', this._plotDimensions));
- var hctx = this.plugins.highlighter.highlightCanvas.setContext();
+ this.eventCanvas._elem.before(this.plugins.highlighter.highlightCanvas.createElement(this._gridPadding, 'jqplot-highlight-canvas', this._plotDimensions, this));
+ this.plugins.highlighter.highlightCanvas.setContext();
+
+ var elem = document.createElement('div');
+ this.plugins.highlighter._tooltipElem = $(elem);
+ elem = null;
+ this.plugins.highlighter._tooltipElem.addClass('jqplot-highlighter-tooltip');
+ this.plugins.highlighter._tooltipElem.css({position:'absolute', display:'none'});
- var p = this.plugins.highlighter;
- p._tooltipElem = $('<div class="jqplot-highlighter-tooltip" style="position:absolute;display:none"></div>');
- this.eventCanvas._elem.before(p._tooltipElem);
+ this.eventCanvas._elem.before(this.plugins.highlighter._tooltipElem);
};
$.jqplot.preInitHooks.push($.jqplot.Highlighter.init);
@@ -193,7 +232,11 @@
// add the plot._gridPadding to that to get x,y in the target.
var hl = plot.plugins.highlighter;
var elem = hl._tooltipElem;
- if (hl.useAxesFormatters) {
+ var serieshl = series.highlighter || {};
+
+ var opts = $.extend(true, {}, hl, serieshl);
+
+ if (opts.useAxesFormatters) {
var xf = series._xaxis._ticks[0].formatter;
var yf = series._yaxis._ticks[0].formatter;
var xfstr = series._xaxis._ticks[0].formatString;
@@ -201,49 +244,49 @@
var str;
var xstr = xf(xfstr, neighbor.data[0]);
var ystrs = [];
- for (var i=1; i<hl.yvalues+1; i++) {
+ for (var i=1; i<opts.yvalues+1; i++) {
ystrs.push(yf(yfstr, neighbor.data[i]));
}
- if (hl.formatString) {
- switch (hl.tooltipAxes) {
+ if (typeof opts.formatString === 'string') {
+ switch (opts.tooltipAxes) {
case 'both':
case 'xy':
ystrs.unshift(xstr);
- ystrs.unshift(hl.formatString);
+ ystrs.unshift(opts.formatString);
str = $.jqplot.sprintf.apply($.jqplot.sprintf, ystrs);
break;
case 'yx':
ystrs.push(xstr);
- ystrs.unshift(hl.formatString);
+ ystrs.unshift(opts.formatString);
str = $.jqplot.sprintf.apply($.jqplot.sprintf, ystrs);
break;
case 'x':
- str = $.jqplot.sprintf.apply($.jqplot.sprintf, [hl.formatString, xstr]);
+ str = $.jqplot.sprintf.apply($.jqplot.sprintf, [opts.formatString, xstr]);
break;
case 'y':
- ystrs.unshift(hl.formatString);
+ ystrs.unshift(opts.formatString);
str = $.jqplot.sprintf.apply($.jqplot.sprintf, ystrs);
break;
default: // same as xy
ystrs.unshift(xstr);
- ystrs.unshift(hl.formatString);
+ ystrs.unshift(opts.formatString);
str = $.jqplot.sprintf.apply($.jqplot.sprintf, ystrs);
break;
}
}
else {
- switch (hl.tooltipAxes) {
+ switch (opts.tooltipAxes) {
case 'both':
case 'xy':
str = xstr;
for (var i=0; i<ystrs.length; i++) {
- str += hl.tooltipSeparator + ystrs[i];
+ str += opts.tooltipSeparator + ystrs[i];
}
break;
case 'yx':
str = '';
for (var i=0; i<ystrs.length; i++) {
- str += ystrs[i] + hl.tooltipSeparator;
+ str += ystrs[i] + opts.tooltipSeparator;
}
str += xstr;
break;
@@ -251,15 +294,12 @@
str = xstr;
break;
case 'y':
- str = '';
- for (var i=0; i<ystrs.length; i++) {
- str += ystrs[i] + hl.tooltipSeparator;
- }
+ str = ystrs.join(opts.tooltipSeparator);
break;
default: // same as 'xy'
str = xstr;
for (var i=0; i<ystrs.length; i++) {
- str += hl.tooltipSeparator + ystrs[i];
+ str += opts.tooltipSeparator + ystrs[i];
}
break;
@@ -268,73 +308,91 @@
}
else {
var str;
- if (hl.tooltipAxes == 'both' || hl.tooltipAxes == 'xy') {
- str = $.jqplot.sprintf(hl.tooltipFormatString, neighbor.data[0]) + hl.tooltipSeparator + $.jqplot.sprintf(hl.tooltipFormatString, neighbor.data[1]);
+ if (typeof opts.formatString === 'string') {
+ str = $.jqplot.sprintf.apply($.jqplot.sprintf, [opts.formatString].concat(neighbor.data));
}
- else if (hl.tooltipAxes == 'yx') {
- str = $.jqplot.sprintf(hl.tooltipFormatString, neighbor.data[1]) + hl.tooltipSeparator + $.jqplot.sprintf(hl.tooltipFormatString, neighbor.data[0]);
+
+ else {
+ if (opts.tooltipAxes == 'both' || opts.tooltipAxes == 'xy') {
+ str = $.jqplot.sprintf(opts.tooltipFormatString, neighbor.data[0]) + opts.tooltipSeparator + $.jqplot.sprintf(opts.tooltipFormatString, neighbor.data[1]);
+ }
+ else if (opts.tooltipAxes == 'yx') {
+ str = $.jqplot.sprintf(opts.tooltipFormatString, neighbor.data[1]) + opts.tooltipSeparator + $.jqplot.sprintf(opts.tooltipFormatString, neighbor.data[0]);
+ }
+ else if (opts.tooltipAxes == 'x') {
+ str = $.jqplot.sprintf(opts.tooltipFormatString, neighbor.data[0]);
+ }
+ else if (opts.tooltipAxes == 'y') {
+ str = $.jqplot.sprintf(opts.tooltipFormatString, neighbor.data[1]);
+ }
}
- else if (hl.tooltipAxes == 'x') {
- str = $.jqplot.sprintf(hl.tooltipFormatString, neighbor.data[0]);
- }
- else if (hl.tooltipAxes == 'y') {
- str = $.jqplot.sprintf(hl.tooltipFormatString, neighbor.data[1]);
- }
}
+ if ($.isFunction(opts.tooltipContentEditor)) {
+ // args str, seriesIndex, pointIndex are essential so the hook can look up
+ // extra data for the point.
+ str = opts.tooltipContentEditor(str, neighbor.seriesIndex, neighbor.pointIndex, plot);
+ }
elem.html(str);
var gridpos = {x:neighbor.gridData[0], y:neighbor.gridData[1]};
var ms = 0;
var fact = 0.707;
if (series.markerRenderer.show == true) {
- ms = (series.markerRenderer.size + hl.sizeAdjust)/2;
+ ms = (series.markerRenderer.size + opts.sizeAdjust)/2;
}
- switch (hl.tooltipLocation) {
+
+ var loc = locations;
+ if (series.fillToZero && series.fill && neighbor.data[1] < 0) {
+ loc = oppositeLocations;
+ }
+
+ switch (loc[locationIndicies[opts.tooltipLocation]]) {
case 'nw':
- var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true) - hl.tooltipOffset - fact * ms;
- var y = gridpos.y + plot._gridPadding.top - hl.tooltipOffset - elem.outerHeight(true) - fact * ms;
+ var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset - fact * ms;
+ var y = gridpos.y + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true) - fact * ms;
break;
case 'n':
var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true)/2;
- var y = gridpos.y + plot._gridPadding.top - hl.tooltipOffset - elem.outerHeight(true) - ms;
+ var y = gridpos.y + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true) - ms;
break;
case 'ne':
- var x = gridpos.x + plot._gridPadding.left + hl.tooltipOffset + fact * ms;
- var y = gridpos.y + plot._gridPadding.top - hl.tooltipOffset - elem.outerHeight(true) - fact * ms;
+ var x = gridpos.x + plot._gridPadding.left + opts.tooltipOffset + fact * ms;
+ var y = gridpos.y + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true) - fact * ms;
break;
case 'e':
- var x = gridpos.x + plot._gridPadding.left + hl.tooltipOffset + ms;
+ var x = gridpos.x + plot._gridPadding.left + opts.tooltipOffset + ms;
var y = gridpos.y + plot._gridPadding.top - elem.outerHeight(true)/2;
break;
case 'se':
- var x = gridpos.x + plot._gridPadding.left + hl.tooltipOffset + fact * ms;
- var y = gridpos.y + plot._gridPadding.top + hl.tooltipOffset + fact * ms;
+ var x = gridpos.x + plot._gridPadding.left + opts.tooltipOffset + fact * ms;
+ var y = gridpos.y + plot._gridPadding.top + opts.tooltipOffset + fact * ms;
break;
case 's':
var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true)/2;
- var y = gridpos.y + plot._gridPadding.top + hl.tooltipOffset + ms;
+ var y = gridpos.y + plot._gridPadding.top + opts.tooltipOffset + ms;
break;
case 'sw':
- var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true) - hl.tooltipOffset - fact * ms;
- var y = gridpos.y + plot._gridPadding.top + hl.tooltipOffset + fact * ms;
+ var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset - fact * ms;
+ var y = gridpos.y + plot._gridPadding.top + opts.tooltipOffset + fact * ms;
break;
case 'w':
- var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true) - hl.tooltipOffset - ms;
+ var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset - ms;
var y = gridpos.y + plot._gridPadding.top - elem.outerHeight(true)/2;
break;
default: // same as 'nw'
- var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true) - hl.tooltipOffset - fact * ms;
- var y = gridpos.y + plot._gridPadding.top - hl.tooltipOffset - elem.outerHeight(true) - fact * ms;
+ var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset - fact * ms;
+ var y = gridpos.y + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true) - fact * ms;
break;
}
elem.css('left', x);
elem.css('top', y);
- if (hl.fadeTooltip) {
+ if (opts.fadeTooltip) {
// Fix for stacked up animations. Thnanks Trevor!
- elem.stop(true,true).fadeIn(hl.tooltipFadeSpeed);
+ elem.stop(true,true).fadeIn(opts.tooltipFadeSpeed);
}
else {
elem.show();
}
+ elem = null;
}
@@ -343,8 +401,11 @@
var c = plot.plugins.cursor;
if (hl.show) {
if (neighbor == null && hl.isHighlighting) {
- var ctx = hl.highlightCanvas._ctx;
- ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
+ var evt = jQuery.Event('jqplotHighlighterUnhighlight');
+ plot.target.trigger(evt);
+
+ var ctx = hl.highlightCanvas._ctx;
+ ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
if (hl.fadeTooltip) {
hl._tooltipElem.fadeOut(hl.tooltipFadeSpeed);
}
@@ -354,11 +415,20 @@
if (hl.bringSeriesToFront) {
plot.restorePreviousSeriesOrder();
}
- hl.isHighlighting = false;
-
+ hl.isHighlighting = false;
+ hl.currentNeighbor = null;
+ ctx = null;
}
- if (neighbor != null && plot.series[neighbor.seriesIndex].showHighlight && !hl.isHighlighting) {
+ else if (neighbor != null && plot.series[neighbor.seriesIndex].showHighlight && !hl.isHighlighting) {
+ var evt = jQuery.Event('jqplotHighlighterHighlight');
+ evt.which = ev.which;
+ evt.pageX = ev.pageX;
+ evt.pageY = ev.pageY;
+ var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data, plot];
+ plot.target.trigger(evt, ins);
+
hl.isHighlighting = true;
+ hl.currentNeighbor = neighbor;
if (hl.showMarker) {
draw(plot, neighbor);
}
@@ -369,6 +439,27 @@
plot.moveSeriesToFront(neighbor.seriesIndex);
}
}
+ // check to see if we're highlighting the wrong point.
+ else if (neighbor != null && hl.isHighlighting && hl.currentNeighbor != neighbor) {
+ // highlighting the wrong point.
+
+ // if new series allows highlighting, highlight new point.
+ if (plot.series[neighbor.seriesIndex].showHighlight) {
+ var ctx = hl.highlightCanvas._ctx;
+ ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
+ hl.isHighlighting = true;
+ hl.currentNeighbor = neighbor;
+ if (hl.showMarker) {
+ draw(plot, neighbor);
+ }
+ if (hl.showTooltip && (!c || !c._zoom.started)) {
+ showTooltip(plot, plot.series[neighbor.seriesIndex], neighbor);
+ }
+ if (hl.bringSeriesToFront) {
+ plot.moveSeriesToFront(neighbor.seriesIndex);
+ }
+ }
+ }
}
}
})(jQuery);
\ No newline at end of file
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.highlighter.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.highlighter.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.highlighter.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(d){d.jqplot.eventListenerHooks.push(["jqplotMouseMove",f]);d.jqplot.Highlighter=function(h){this.show=d.jqplot.config.enablePlugins;this.markerRenderer=new d.jqplot.MarkerRenderer({shadow:false});this.showMarker=true;this.lineWidthAdjust=2.5;this.sizeAdjust=5;this.showTooltip=true;this.tooltipLocation="nw";this.fadeTooltip=true;this.tooltipFadeSpeed="fast";this.tooltipOffset=2;this.tooltipAxes="both";this.tooltipSeparator=", ";this.tooltipContentEditor=null;this.useAxesFormatters=true;this.tooltipFormatString="%.5P";this.formatString=null;this.yvalues=1;this.bringSeriesToFront=false;this._tooltipElem;this.isHighlighting=false;this.currentNeighbor=null;d.extend(true,this,h)};var b=["nw","n","ne","e","se","s","sw","w"];var e={nw:0,n:1,ne:2,e:3,se:4,s:5,sw:6,w:7};var c=["se","s","sw","w","nw","n","ne","e"];d.jqplot.Highlighter.init=function(k,j,i){var h=i||{};this.plugins.highlighter=new d.jqplot.Highlighter(h.highlighter)};d.jqplot.Highlighter.parseOptions=function(i,h){this.showHighlight=true};d.jqplot.Highlighter.postPlotDraw=function(){if(this.plugins.highlighter&&this.plugins.highlighter.highlightCanvas){this.plugins.highlighter.highlightCanvas.resetCanvas();this.plugins.highlighter.highlightCanvas=null}if(this.plugins.highlighter&&this.plugins.highlighter._tooltipElem){this.plugins.highlighter._tooltipElem.emptyForce();this.plugins.highlighter._tooltipElem=null}this.plugins.highlighter.highlightCanvas=new d.jqplot.GenericCanvas();this.eventCanvas._elem.before(this.plugins.highlighter.highlightCanvas.createElement(this._gridPadding,"jqplot-highlight-canvas",this._plotDimensions,this));this.plugins.highlighter.highlightCanvas.setContext();var h=document.createElement("div");this.plugins.highlighter._tooltipElem=d(h);h=null;this.plugins.highlighter._tooltipElem.addClass("jqplot-highlighter-tooltip");this.plugins.highlighter._tooltipElem.css({position:"absolute",display:"none"});this.eventCanvas._elem.before(this.plugins.highlighter._tooltipElem)};d.jqplot.preInitHooks.push(d.jqplot.Highligh!
ter.init);d.jqplot.preParseSeriesOptionsHooks.push(d.jqplot.Highlighter.parseOptions);d.jqplot.postDrawHooks.push(d.jqplot.Highlighter.postPlotDraw);function a(m,o){var j=m.plugins.highlighter;var p=m.series[o.seriesIndex];var h=p.markerRenderer;var i=j.markerRenderer;i.style=h.style;i.lineWidth=h.lineWidth+j.lineWidthAdjust;i.size=h.size+j.sizeAdjust;var l=d.jqplot.getColorComponents(h.color);var n=[l[0],l[1],l[2]];var k=(l[3]>=0.6)?l[3]*0.6:l[3]*(2-l[3]);i.color="rgba("+n[0]+","+n[1]+","+n[2]+","+k+")";i.init();i.draw(p.gridData[o.pointIndex][0],p.gridData[o.pointIndex][1],j.highlightCanvas._ctx)}function g(A,q,m){var k=A.plugins.highlighter;var D=k._tooltipElem;var r=q.highlighter||{};var t=d.extend(true,{},k,r);if(t.useAxesFormatters){var w=q._xaxis._ticks[0].formatter;var h=q._yaxis._ticks[0].formatter;var E=q._xaxis._ticks[0].formatString;var s=q._yaxis._ticks[0].formatString;var z;var u=w(E,m.data[0]);var l=[];for(var B=1;B<t.yvalues+1;B++){l.push(h(s,m.data[B]))}if(typeof t.formatString==="string"){switch(t.tooltipAxes){case"both":case"xy":l.unshift(u);l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break;case"yx":l.push(u);l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break;case"x":z=d.jqplot.sprintf.apply(d.jqplot.sprintf,[t.formatString,u]);break;case"y":l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break;default:l.unshift(u);l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break}}else{switch(t.tooltipAxes){case"both":case"xy":z=u;for(var B=0;B<l.length;B++){z+=t.tooltipSeparator+l[B]}break;case"yx":z="";for(var B=0;B<l.length;B++){z+=l[B]+t.tooltipSeparator}z+=u;break;case"x":z=u;break;case"y":z=l.join(t.tooltipSeparator);break;default:z=u;for(var B=0;B<l.length;B++){z+=t.tooltipSeparator+l[B]}break}}}else{var z;if(typeof t.formatString==="string"){z=d.jqplot.sprintf.apply(d.jqplot.sprintf,[t.formatString].concat(m.data))}else{if(t.tooltipAxes=="both"||t.tooltipAxes=="xy"){z=d.jqplot.sprintf(t.tooltipFormat!
String,m..data[0])+t.tooltipSeparator+d.jqplot.sprintf(t.tooltipFormatString,m.data[1])}else{if(t.tooltipAxes=="yx"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[1])+t.tooltipSeparator+d.jqplot.sprintf(t.tooltipFormatString,m.data[0])}else{if(t.tooltipAxes=="x"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[0])}else{if(t.tooltipAxes=="y"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[1])}}}}}}if(d.isFunction(t.tooltipContentEditor)){z=t.tooltipContentEditor(z,m.seriesIndex,m.pointIndex,A)}D.html(z);var C={x:m.gridData[0],y:m.gridData[1]};var v=0;var j=0.707;if(q.markerRenderer.show==true){v=(q.markerRenderer.size+t.sizeAdjust)/2}var o=b;if(q.fillToZero&&q.fill&&m.data[1]<0){o=c}switch(o[e[t.tooltipLocation]]){case"nw":var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-j*v;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-j*v;break;case"n":var p=C.x+A._gridPadding.left-D.outerWidth(true)/2;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-v;break;case"ne":var p=C.x+A._gridPadding.left+t.tooltipOffset+j*v;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-j*v;break;case"e":var p=C.x+A._gridPadding.left+t.tooltipOffset+v;var n=C.y+A._gridPadding.top-D.outerHeight(true)/2;break;case"se":var p=C.x+A._gridPadding.left+t.tooltipOffset+j*v;var n=C.y+A._gridPadding.top+t.tooltipOffset+j*v;break;case"s":var p=C.x+A._gridPadding.left-D.outerWidth(true)/2;var n=C.y+A._gridPadding.top+t.tooltipOffset+v;break;case"sw":var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-j*v;var n=C.y+A._gridPadding.top+t.tooltipOffset+j*v;break;case"w":var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-v;var n=C.y+A._gridPadding.top-D.outerHeight(true)/2;break;default:var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-j*v;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-j*v;break}D.css("left",p);D.css("top",n);if(t.fadeTooltip){D.stop(true,true).fadeIn(t.tooltipFadeSpeed)}else{D.show()}D=null}function f(n,j,i,p,l){var h=l.pl!
ugins.highlighter;var m=l.plugins.cursor;if(h.show){if(p==null&&h.isHighlighting){var o=jQuery.Event("jqplotHighlighterUnhighlight");l.target.trigger(o);var q=h.highlightCanvas._ctx;q.clearRect(0,0,q.canvas.width,q.canvas.height);if(h.fadeTooltip){h._tooltipElem.fadeOut(h.tooltipFadeSpeed)}else{h._tooltipElem.hide()}if(h.bringSeriesToFront){l.restorePreviousSeriesOrder()}h.isHighlighting=false;h.currentNeighbor=null;q=null}else{if(p!=null&&l.series[p.seriesIndex].showHighlight&&!h.isHighlighting){var o=jQuery.Event("jqplotHighlighterHighlight");o.which=n.which;o.pageX=n.pageX;o.pageY=n.pageY;var k=[p.seriesIndex,p.pointIndex,p.data,l];l.target.trigger(o,k);h.isHighlighting=true;h.currentNeighbor=p;if(h.showMarker){a(l,p)}if(h.showTooltip&&(!m||!m._zoom.started)){g(l,l.series[p.seriesIndex],p)}if(h.bringSeriesToFront){l.moveSeriesToFront(p.seriesIndex)}}else{if(p!=null&&h.isHighlighting&&h.currentNeighbor!=p){if(l.series[p.seriesIndex].showHighlight){var q=h.highlightCanvas._ctx;q.clearRect(0,0,q.canvas.width,q.canvas.height);h.isHighlighting=true;h.currentNeighbor=p;if(h.showMarker){a(l,p)}if(h.showTooltip&&(!m||!m._zoom.started)){g(l,l.series[p.seriesIndex],p)}if(h.bringSeriesToFront){l.moveSeriesToFront(p.seriesIndex)}}}}}}}})(jQuery);
\ No newline at end of file
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.json2.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.json2.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.json2.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function($){$.jqplot.JSON=window.JSON;if(!window.JSON){$.jqplot.JSON={}}function f(n){return n<10?"0"+n:n}if(typeof Date.prototype.toJSON!=="function"){Date.prototype.toJSON=function(key){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf()}}var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==="string"?c:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+string+'"'}function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==="object"&&typeof value.toJSON==="function"){value=value.toJSON(key)}if(typeof rep==="function"){value=rep.call(holder,key,value)}switch(typeof value){case"string":return quote(value);case"number":return isFinite(value)?String(value):"null";case"boolean":case"null":return String(value);case"object":if(!value){return"null"}gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==="[object Array]"){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||"null"}v=partial.length===0?"[]":gap?"[\n"+gap+partial.join(",\n"+gap)+"\n"+mind+"]":"["+partial.join(",")+"]";gap=mind;return v}if(rep&&typeof rep==="object"){length=rep.length;for(i=0;i<length;i+=1){k=rep[i];if(typeof k==="string"){v=str(k,value);if(v){partial.push(quote(k)+(gap?": ":":")+v)}}}}else{for(k in value){if(Object.hasOwnProperty.call(value,k)){v=str(k,value);if(v)!
{partial.push(quote(k)+(gap?": ":":")+v)}}}}v=partial.length===0?"{}":gap?"{\n"+gap+partial.join(",\n"+gap)+"\n"+mind+"}":"{"+partial.join(",")+"}";gap=mind;return v}}if(typeof $.jqplot.JSON.stringify!=="function"){$.jqplot.JSON.stringify=function(value,replacer,space){var i;gap="";indent="";if(typeof space==="number"){for(i=0;i<space;i+=1){indent+=" "}}else{if(typeof space==="string"){indent=space}}rep=replacer;if(replacer&&typeof replacer!=="function"&&(typeof replacer!=="object"||typeof replacer.length!=="number")){throw new Error("$.jqplot.JSON.stringify")}return str("",{"":value})}}if(typeof $.jqplot.JSON.parse!=="function"){$.jqplot.JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==="object"){for(k in value){if(Object.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v}else{delete value[k]}}}}return reviver.call(holder,key,value)}text=String(text);cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})}if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,""))){j=eval("("+text+")");return typeof reviver==="function"?walk({"":j},""):j}throw new SyntaxError("$.jqplot.JSON.parse")}}})(jQuery);
\ No newline at end of file
Modified: gnucash/trunk/src/report/jqplot/plugins/jqplot.logAxisRenderer.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.logAxisRenderer.js 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.logAxisRenderer.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -1,20 +1,33 @@
/**
- * Copyright (c) 2009 - 2010 Chris Leonello
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
- * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
- * The author would appreciate an email letting him know of any substantial
- * use of jqPlot. You can reach the author at: chris at jqplot dot com
- * or see http://www.jqplot.com/info.php . This is, of course,
- * not required.
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
- * Thanks for using jqPlot!
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
*
- */
+ */
(function($) {
/**
* class: $.jqplot.LogAxisRenderer
@@ -36,13 +49,12 @@
//
// Properties
//
- /// base - the logarithmic base, commonly 2, 10 or Math.E
- // tickDistribution - 'even' or 'power'. 'even' gives equal pixel
- // spacing of the ticks on the plot. 'power' gives ticks in powers
- // of 10.
+ // base - the logarithmic base, commonly 2, 10 or Math.E
+ // tickDistribution - Deprecated. "power" distribution of ticks
+ // always used. Option has no effect.
this.axisDefaults = {
base : 10,
- tickDistribution :'even'
+ tickDistribution :'power'
};
};
@@ -50,56 +62,46 @@
$.jqplot.LogAxisRenderer.prototype.constructor = $.jqplot.LogAxisRenderer;
$.jqplot.LogAxisRenderer.prototype.init = function(options) {
- // prop: tickRenderer
- // A class of a rendering engine for creating the ticks labels displayed on the plot,
- // See <$.jqplot.AxisTickRenderer>.
- // this.tickRenderer = $.jqplot.AxisTickRenderer;
- // this.labelRenderer = $.jqplot.AxisLabelRenderer;
- $.extend(true, this.renderer, options);
+ // prop: drawBaseline
+ // True to draw the axis baseline.
+ this.drawBaseline = true;
+ // prop: minorTicks
+ // Number of ticks to add between "major" ticks.
+ // Major ticks are ticks supplied by user or auto computed.
+ // Minor ticks cannot be created by user.
+ this.minorTicks = 'auto';
+ this._scalefact = 1.0;
+
+ $.extend(true, this, options);
+
+ this._autoFormatString = '%d';
+ this._overrideFormatString = false;
+
for (var d in this.renderer.axisDefaults) {
if (this[d] == null) {
this[d] = this.renderer.axisDefaults[d];
}
}
- var db = this._dataBounds;
- // Go through all the series attached to this axis and find
- // the min/max bounds for this axis.
- for (var i=0; i<this._series.length; i++) {
- var s = this._series[i];
- var d = s.data;
-
- for (var j=0; j<d.length; j++) {
- if (this.name == 'xaxis' || this.name == 'x2axis') {
- if (d[j][0] > db.max || db.max == null) {
- db.max = d[j][0];
- }
- if (d[j][0] > db.max || db.max == null) {
- db.max = d[j][0];
- }
- }
- else {
- if (d[j][1] < db.min || db.min == null) {
- db.min = d[j][1];
- }
- if (d[j][1] > db.max || db.max == null) {
- db.max = d[j][1];
- }
- }
- }
- }
+
+ this.resetDataBounds();
};
- $.jqplot.LogAxisRenderer.prototype.createTicks = function() {
+ $.jqplot.LogAxisRenderer.prototype.createTicks = function(plot) {
// we're are operating on an axis here
var ticks = this._ticks;
var userTicks = this.ticks;
var name = this.name;
var db = this._dataBounds;
- var dim, interval;
+ var dim = (this.name.charAt(0) === 'x') ? this._plotDimensions.width : this._plotDimensions.height;
+ var interval;
var min, max;
var pos1, pos2;
var tt, i;
+ var threshold = 30;
+ // For some reason scalefactor is screwing up ticks.
+ this._scalefact = (Math.max(dim, threshold+1) - threshold)/300;
+
// if we already have ticks, use them.
// ticks must be in order of increasing value.
if (userTicks.length) {
@@ -120,6 +122,12 @@
t.setTick(ut[0], this.name);
this._ticks.push(t);
}
+
+ else if ($.isPlainObject(ut)) {
+ $.extend(true, t, ut);
+ t.axis = this.name;
+ this._ticks.push(t);
+ }
else {
t.value = ut;
@@ -140,16 +148,9 @@
}
// we don't have any ticks yet, let's make some!
- else {
- if (name == 'xaxis' || name == 'x2axis') {
- dim = this._plotDimensions.width;
- }
- else {
- dim = this._plotDimensions.height;
- }
-
- min = ((this.min != null) ? this.min : db.min);
- max = ((this.max != null) ? this.max : db.max);
+ else if (this.min == null && this.max == null) {
+ min = db.min * (2 - this.padMin);
+ max = db.max * this.padMax;
// if min and max are same, space them out a bit
if (min == max) {
@@ -165,30 +166,169 @@
if (this.max != null && this.max <= 0) {
throw('log axis maximum must be greater than 0');
}
- // if (this.pad >1.99) this.pad = 1.99;
- var range = max - min;
+
+ function findCeil (val) {
+ var order = Math.pow(10, Math.floor(Math.log(val)/Math.LN10));
+ return Math.ceil(val/order) * order;
+ }
+
+ function findFloor(val) {
+ var order = Math.pow(10, Math.floor(Math.log(val)/Math.LN10));
+ return Math.floor(val/order) * order;
+ }
+
+ // var range = max - min;
var rmin, rmax;
- if (this.tickDistribution == 'even') {
- rmin = (this.min != null) ? this.min : min - min*((this.padMin-1)/2);
- rmax = (this.max != null) ? this.max : max + max*((this.padMax-1)/2);
- this.min = rmin;
- this.max = rmax;
- range = this.max - this.min;
-
- if (this.numberTicks == null){
- if (dim > 100) {
- this.numberTicks = parseInt(3+(dim-100)/75, 10);
+ // for power distribution, open up range to get a nice power of axis.renderer.base.
+ // power distribution won't respect the user's min/max settings.
+ rmin = Math.pow(this.base, Math.floor(Math.log(min)/Math.log(this.base)));
+ rmax = Math.pow(this.base, Math.ceil(Math.log(max)/Math.log(this.base)));
+
+ // // if min and max are same, space them out a bit
+ // if (rmin === rmax) {
+ // var adj = 0.05;
+ // rmin = rmin*(1-adj);
+ // rmax = rmax*(1+adj);
+ // }
+
+ var order = Math.round(Math.log(rmin)/Math.LN10);
+
+ if (this.tickOptions == null || !this.tickOptions.formatString) {
+ this._overrideFormatString = true;
+ }
+
+ this.min = rmin;
+ this.max = rmax;
+ var range = this.max - this.min;
+
+ var minorTicks = (this.minorTicks === 'auto') ? 0 : this.minorTicks;
+ var numberTicks;
+ if (this.numberTicks == null){
+ if (dim > 140) {
+ numberTicks = Math.round(Math.log(this.max/this.min)/Math.log(this.base) + 1);
+ if (numberTicks < 2) {
+ numberTicks = 2;
}
- else {
- this.numberTicks = 2;
+ if (minorTicks === 0) {
+ var temp = dim/(numberTicks - 1);
+ if (temp < 100) {
+ minorTicks = 0;
+ }
+ else if (temp < 190) {
+ minorTicks = 1;
+ }
+ else if (temp < 250) {
+ minorTicks = 3;
+ }
+ else if (temp < 600) {
+ minorTicks = 4;
+ }
+ else {
+ minorTicks = 9;
+ }
}
}
-
- var u = Math.pow(this.base, (1/(this.numberTicks-1)*Math.log(this.max/this.min)/Math.log(this.base)));
- for (var i=0; i<this.numberTicks; i++){
- tt = this.min * Math.pow(u, i);
- var t = new this.tickRenderer(this.tickOptions);
+ else {
+ numberTicks = 2;
+ if (minorTicks === 0) {
+ minorTicks = 1;
+ }
+ minorTicks = 0;
+ }
+ }
+ else {
+ numberTicks = this.numberTicks;
+ }
+
+ if (order >= 0 && minorTicks !== 3) {
+ this._autoFormatString = '%d';
+ }
+ // Adjust format string for case with 3 ticks where we'll have like 1, 2.5, 5, 7.5, 10
+ else if (order <= 0 && minorTicks === 3) {
+ var temp = -(order - 1);
+ this._autoFormatString = '%.'+ Math.abs(order-1) + 'f';
+ }
+
+ // Adjust format string for values less than 1.
+ else if (order < 0) {
+ var temp = -order;
+ this._autoFormatString = '%.'+ Math.abs(order) + 'f';
+ }
+
+ else {
+ this._autoFormatString = '%d';
+ }
+
+ var to, t, val, tt1, spread, interval;
+ for (var i=0; i<numberTicks; i++){
+ tt = Math.pow(this.base, i - numberTicks + 1) * this.max;
+
+ t = new this.tickRenderer(this.tickOptions);
+
+ if (this._overrideFormatString) {
+ t.formatString = this._autoFormatString;
+ }
+
+ if (!this.showTicks) {
+ t.showLabel = false;
+ t.showMark = false;
+ }
+ else if (!this.showTickMarks) {
+ t.showMark = false;
+ }
+ t.setTick(tt, this.name);
+ this._ticks.push(t);
+
+ if (minorTicks && i<numberTicks-1) {
+ tt1 = Math.pow(this.base, i - numberTicks + 2) * this.max;
+ spread = tt1 - tt;
+ interval = tt1 / (minorTicks+1);
+ for (var j=minorTicks-1; j>=0; j--) {
+ val = tt1-interval*(j+1);
+ t = new this.tickRenderer(this.tickOptions);
+
+ if (this._overrideFormatString && this._autoFormatString != '') {
+ t.formatString = this._autoFormatString;
+ }
+ if (!this.showTicks) {
+ t.showLabel = false;
+ t.showMark = false;
+ }
+ else if (!this.showTickMarks) {
+ t.showMark = false;
+ }
+ t.setTick(val, this.name);
+ this._ticks.push(t);
+ }
+ }
+ }
+ }
+
+ // min and max are set as would be the case with zooming
+ else if (this.min != null && this.max != null) {
+ var opts = $.extend(true, {}, this.tickOptions, {name: this.name, value: null});
+ var nt, ti;
+ // don't have an interval yet, pick one that gives the most
+ // "round" ticks we can get.
+ if (this.numberTicks == null && this.tickInterval == null) {
+ // var threshold = 30;
+ var tdim = Math.max(dim, threshold+1);
+ var nttarget = Math.ceil((tdim-threshold)/35 + 1);
+
+ var ret = $.jqplot.LinearTickGenerator.bestConstrainedInterval(this.min, this.max, nttarget);
+
+ this._autoFormatString = ret[3];
+ nt = ret[2];
+ ti = ret[4];
+
+ for (var i=0; i<nt; i++) {
+ opts.value = this.min + i * ti;
+ t = new this.tickRenderer(opts);
+
+ if (this._overrideFormatString && this._autoFormatString != '') {
+ t.formatString = this._autoFormatString;
+ }
if (!this.showTicks) {
t.showLabel = false;
t.showMark = false;
@@ -196,45 +336,20 @@
else if (!this.showTickMarks) {
t.showMark = false;
}
- t.setTick(tt, this.name);
this._ticks.push(t);
}
-
}
-
- else if (this.tickDistribution == 'power'){
- // for power distribution, open up range to get a nice power of axis.renderer.base.
- // power distribution won't respect the user's min/max settings.
- rmin = Math.pow(this.base, Math.ceil(Math.log(min*(2-this.padMin))/Math.log(this.base))-1);
- rmax = Math.pow(this.base, Math.floor(Math.log(max*this.padMax)/Math.log(this.base))+1);
- this.min = rmin;
- this.max = rmax;
- range = this.max - this.min;
-
- var fittedTicks = 0;
- var minorTicks = 0;
- if (this.numberTicks == null){
- if (dim > 100) {
- this.numberTicks = Math.round(Math.log(this.max/this.min)/Math.log(this.base) + 1);
- if (this.numberTicks < 2) {
- this.numberTicks = 2;
- }
- fittedTicks = parseInt(3+(dim-100)/75, 10);
+
+ // for loose zoom, number ticks and interval are also set.
+ else if (this.numberTicks != null && this.tickInterval != null) {
+ nt = this.numberTicks;
+ for (var i=0; i<nt; i++) {
+ opts.value = this.min + i * this.tickInterval;
+ t = new this.tickRenderer(opts);
+
+ if (this._overrideFormatString && this._autoFormatString != '') {
+ t.formatString = this._autoFormatString;
}
- else {
- this.numberTicks = 2;
- fittedTicks = 2;
- }
- // if we don't have enough ticks, add some intermediate ticks
- // how many to have between major ticks.
- if (this.numberTicks < fittedTicks-1) {
- minorTicks = Math.floor(fittedTicks/this.numberTicks);
- }
- }
-
- for (var i=0; i<this.numberTicks; i++){
- tt = Math.pow(this.base, i - this.numberTicks + 1) * this.max;
- var t = new this.tickRenderer(this.tickOptions);
if (!this.showTicks) {
t.showLabel = false;
t.showMark = false;
@@ -242,29 +357,9 @@
else if (!this.showTickMarks) {
t.showMark = false;
}
- t.setTick(tt, this.name);
this._ticks.push(t);
-
- if (minorTicks && i<this.numberTicks-1) {
- var tt1 = Math.pow(this.base, i - this.numberTicks + 2) * this.max;
- var spread = tt1 - tt;
- var interval = tt1 / (minorTicks+1);
- for (var j=minorTicks-1; j>=0; j--) {
- var val = tt1-interval*(j+1);
- var t = new this.tickRenderer(this.tickOptions);
- if (!this.showTicks) {
- t.showLabel = false;
- t.showMark = false;
- }
- else if (!this.showTickMarks) {
- t.showMark = false;
- }
- t.setTick(val, this.name);
- this._ticks.push(t);
- }
- }
- }
- }
+ }
+ }
}
};
@@ -273,8 +368,8 @@
var ticks = this._ticks;
var trans = function (v) { return Math.log(v)/Math.log(lb); };
var invtrans = function (v) { return Math.pow(Math.E, (Math.log(lb)*v)); };
- max = trans(this.max);
- min = trans(this.min);
+ var max = trans(this.max);
+ var min = trans(this.min);
var offmax = offsets.max;
var offmin = offsets.min;
var lshow = (this._label == null) ? false : this._label.show;
@@ -317,7 +412,7 @@
if (this.show) {
if (this.name == 'xaxis' || this.name == 'x2axis') {
- for (i=0; i<ticks.length; i++) {
+ for (var i=0; i<ticks.length; i++) {
var t = ticks[i];
if (t.show && t.showLabel) {
var shim;
@@ -370,7 +465,7 @@
}
}
else {
- for (i=0; i<ticks.length; i++) {
+ for (var i=0; i<ticks.length; i++) {
var t = ticks[i];
if (t.show && t.showLabel) {
var shim;
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.logAxisRenderer.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.logAxisRenderer.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.logAxisRenderer.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(a){a.jqplot.LogAxisRenderer=function(){a.jqplot.LinearAxisRenderer.call(this);this.axisDefaults={base:10,tickDistribution:"power"}};a.jqplot.LogAxisRenderer.prototype=new a.jqplot.LinearAxisRenderer();a.jqplot.LogAxisRenderer.prototype.constructor=a.jqplot.LogAxisRenderer;a.jqplot.LogAxisRenderer.prototype.init=function(b){this.drawBaseline=true;this.minorTicks="auto";this._scalefact=1;a.extend(true,this,b);this._autoFormatString="%d";this._overrideFormatString=false;for(var c in this.renderer.axisDefaults){if(this[c]==null){this[c]=this.renderer.axisDefaults[c]}}this.resetDataBounds()};a.jqplot.LogAxisRenderer.prototype.createTicks=function(d){var G=this._ticks;var w=this.ticks;var s=this.name;var u=this._dataBounds;var b=(this.name.charAt(0)==="x")?this._plotDimensions.width:this._plotDimensions.height;var k;var N,v;var m,l;var M,K;var g=30;this._scalefact=(Math.max(b,g+1)-g)/300;if(w.length){for(K=0;K<w.length;K++){var A=w[K];var H=new this.tickRenderer(this.tickOptions);if(A.constructor==Array){H.value=A[0];H.label=A[1];if(!this.showTicks){H.showLabel=false;H.showMark=false}else{if(!this.showTickMarks){H.showMark=false}}H.setTick(A[0],this.name);this._ticks.push(H)}else{if(a.isPlainObject(A)){a.extend(true,H,A);H.axis=this.name;this._ticks.push(H)}else{H.value=A;if(!this.showTicks){H.showLabel=false;H.showMark=false}else{if(!this.showTickMarks){H.showMark=false}}H.setTick(A,this.name);this._ticks.push(H)}}}this.numberTicks=w.length;this.min=this._ticks[0].value;this.max=this._ticks[this.numberTicks-1].value}else{if(this.min==null&&this.max==null){N=u.min*(2-this.padMin);v=u.max*this.padMax;if(N==v){var c=0.05;N=N*(1-c);v=v*(1+c)}if(this.min!=null&&this.min<=0){throw ("log axis minimum must be greater than 0")}if(this.max!=null&&this.max<=0){throw ("log axis maximum must be greater than 0")}function f(j){var i=Math.pow(10,Math.floor(Math.log(j)/Math.LN10));return Math.ceil(j/i)*i}function x(j){var i=Math.pow(10,Math.floor(Math.log(j)/Math.LN10));return Math.floor(j/i)*i}var F,r;F=Math.po!
w(this.base,Math.floor(Math.log(N)/Math.log(this.base)));r=Math.pow(this.base,Math.ceil(Math.log(v)/Math.log(this.base)));var E=Math.round(Math.log(F)/Math.LN10);if(this.tickOptions==null||!this.tickOptions.formatString){this._overrideFormatString=true}this.min=F;this.max=r;var q=this.max-this.min;var C=(this.minorTicks==="auto")?0:this.minorTicks;var h;if(this.numberTicks==null){if(b>140){h=Math.round(Math.log(this.max/this.min)/Math.log(this.base)+1);if(h<2){h=2}if(C===0){var o=b/(h-1);if(o<100){C=0}else{if(o<190){C=1}else{if(o<250){C=3}else{if(o<600){C=4}else{C=9}}}}}}else{h=2;if(C===0){C=1}C=0}}else{h=this.numberTicks}if(E>=0&&C!==3){this._autoFormatString="%d"}else{if(E<=0&&C===3){var o=-(E-1);this._autoFormatString="%."+Math.abs(E-1)+"f"}else{if(E<0){var o=-E;this._autoFormatString="%."+Math.abs(E)+"f"}else{this._autoFormatString="%d"}}}var O,H,z,p,n,k;for(var K=0;K<h;K++){M=Math.pow(this.base,K-h+1)*this.max;H=new this.tickRenderer(this.tickOptions);if(this._overrideFormatString){H.formatString=this._autoFormatString}if(!this.showTicks){H.showLabel=false;H.showMark=false}else{if(!this.showTickMarks){H.showMark=false}}H.setTick(M,this.name);this._ticks.push(H);if(C&&K<h-1){p=Math.pow(this.base,K-h+2)*this.max;n=p-M;k=p/(C+1);for(var J=C-1;J>=0;J--){z=p-k*(J+1);H=new this.tickRenderer(this.tickOptions);if(this._overrideFormatString&&this._autoFormatString!=""){H.formatString=this._autoFormatString}if(!this.showTicks){H.showLabel=false;H.showMark=false}else{if(!this.showTickMarks){H.showMark=false}}H.setTick(z,this.name);this._ticks.push(H)}}}}else{if(this.min!=null&&this.max!=null){var y=a.extend(true,{},this.tickOptions,{name:this.name,value:null});var I,e;if(this.numberTicks==null&&this.tickInterval==null){var D=Math.max(b,g+1);var L=Math.ceil((D-g)/35+1);var B=a.jqplot.LinearTickGenerator.bestConstrainedInterval(this.min,this.max,L);this._autoFormatString=B[3];I=B[2];e=B[4];for(var K=0;K<I;K++){y.value=this.min+K*e;H=new this.tickRenderer(y);if(this._overrideFormatString&&this._autoFormatString!=""){H.fo!
rmatString=this._autoFormatString}if(!this.showTicks){H.showLabel=false;H.showMark=false}else{if(!this.showTickMarks){H.showMark=false}}this._ticks.push(H)}}else{if(this.numberTicks!=null&&this.tickInterval!=null){I=this.numberTicks;for(var K=0;K<I;K++){y.value=this.min+K*this.tickInterval;H=new this.tickRenderer(y);if(this._overrideFormatString&&this._autoFormatString!=""){H.formatString=this._autoFormatString}if(!this.showTicks){H.showLabel=false;H.showMark=false}else{if(!this.showTickMarks){H.showMark=false}}this._ticks.push(H)}}}}}}};a.jqplot.LogAxisRenderer.prototype.pack=function(f,e){var r=parseInt(this.base,10);var y=this._ticks;var d=function(h){return Math.log(h)/Math.log(r)};var b=function(h){return Math.pow(Math.E,(Math.log(r)*h))};var u=d(this.max);var s=d(this.min);var m=e.max;var k=e.min;var o=(this._label==null)?false:this._label.show;for(var q in f){this._elem.css(q,f[q])}this._offsets=e;var g=m-k;var j=u-s;this.p2u=function(h){return b((h-k)*j/g+s)};this.u2p=function(h){return(d(h)-s)*g/j+k};if(this.name=="xaxis"||this.name=="x2axis"){this.series_u2p=function(h){return(d(h)-s)*g/j};this.series_p2u=function(h){return b(h*j/g+s)}}else{this.series_u2p=function(h){return(d(h)-u)*g/j};this.series_p2u=function(h){return b(h*j/g+u)}}if(this.show){if(this.name=="xaxis"||this.name=="x2axis"){for(var v=0;v<y.length;v++){var n=y[v];if(n.show&&n.showLabel){var c;if(n.constructor==a.jqplot.CanvasAxisTickRenderer&&n.angle){switch(n.labelPosition){case"auto":if(n.angle<0){c=-n.getWidth()+n._textRenderer.height*Math.sin(-n._textRenderer.angle)/2}else{c=-n._textRenderer.height*Math.sin(n._textRenderer.angle)/2}break;case"end":c=-n.getWidth()+n._textRenderer.height*Math.sin(-n._textRenderer.angle)/2;break;case"start":c=-n._textRenderer.height*Math.sin(n._textRenderer.angle)/2;break;case"middle":c=-n.getWidth()/2+n._textRenderer.height*Math.sin(-n._textRenderer.angle)/2;break;default:c=-n.getWidth()/2+n._textRenderer.height*Math.sin(-n._textRenderer.angle)/2;break}}else{c=-n.getWidth()/2}var z=this.u2p(n.value)+c!
+"px";n._elem.css("left",z);n.pack()}}if(o){var l=this._label._elem.outerWidth(true);this._label._elem.css("left",k+g/2-l/2+"px");if(this.name=="xaxis"){this._label._elem.css("bottom","0px")}else{this._label._elem.css("top","0px")}this._label.pack()}}else{for(var v=0;v<y.length;v++){var n=y[v];if(n.show&&n.showLabel){var c;if(n.constructor==a.jqplot.CanvasAxisTickRenderer&&n.angle){switch(n.labelPosition){case"auto":case"end":if(n.angle<0){c=-n._textRenderer.height*Math.cos(-n._textRenderer.angle)/2}else{c=-n.getHeight()+n._textRenderer.height*Math.cos(n._textRenderer.angle)/2}break;case"start":if(n.angle>0){c=-n._textRenderer.height*Math.cos(-n._textRenderer.angle)/2}else{c=-n.getHeight()+n._textRenderer.height*Math.cos(n._textRenderer.angle)/2}break;case"middle":c=-n.getHeight()/2;break;default:c=-n.getHeight()/2;break}}else{c=-n.getHeight()/2}var z=this.u2p(n.value)+c+"px";n._elem.css("top",z);n.pack()}}if(o){var x=this._label._elem.outerHeight(true);this._label._elem.css("top",m-g/2-x/2+"px");if(this.name=="yaxis"){this._label._elem.css("left","0px")}else{this._label._elem.css("right","0px")}this._label.pack()}}}}})(jQuery);
\ No newline at end of file
Modified: gnucash/trunk/src/report/jqplot/plugins/jqplot.mekkoAxisRenderer.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.mekkoAxisRenderer.js 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.mekkoAxisRenderer.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -1,18 +1,31 @@
/**
- * Copyright (c) 2009 - 2010 Chris Leonello
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
- * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
- * The author would appreciate an email letting him know of any substantial
- * use of jqPlot. You can reach the author at: chris at jqplot dot com
- * or see http://www.jqplot.com/info.php . This is, of course,
- * not required.
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
- * Thanks for using jqPlot!
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
*
*/
(function($) {
@@ -71,7 +84,7 @@
};
// called with scope of axis
- $.jqplot.MekkoAxisRenderer.prototype.draw = function(ctx) {
+ $.jqplot.MekkoAxisRenderer.prototype.draw = function(ctx, plot) {
if (this.show) {
// populate the axis label and value properties.
// createTicks is a method on the renderer, but
@@ -83,7 +96,11 @@
var dim=0;
var temp;
- this._elem = $('<div class="jqplot-axis jqplot-'+this.name+'" style="position:absolute;"></div>');
+ var elem = document.createElement('div');
+ this._elem = $(elem);
+ this._elem.addClass('jqplot-axis jqplot-'+this.name);
+ this._elem.css('position', 'absolute');
+ elem = null;
if (this.name == 'xaxis' || this.name == 'x2axis') {
this._elem.width(this._plotDimensions.width);
@@ -97,8 +114,7 @@
this.labelOptions.axis = this.name;
this._label = new this.labelRenderer(this.labelOptions);
if (this._label.show) {
- var elem = this._label.draw(ctx);
- elem.appendTo(this._elem);
+ this._elem.append(this._label.draw(ctx));
}
var t, tick, elem;
@@ -107,8 +123,7 @@
for (var i=0; i<t.length; i++) {
tick = t[i];
if (tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) {
- elem = tick.draw(ctx);
- elem.appendTo(this._elem);
+ this._elem.append(tick.draw(ctx));
}
}
}
@@ -122,11 +137,12 @@
this._barLabels[i].show = false;
}
if (this._barLabels[i].show) {
- var elem = this._barLabels[i].draw(ctx);
+ var elem = this._barLabels[i].draw(ctx, plot);
elem.removeClass('jqplot-'+this.name+'-label');
elem.addClass('jqplot-'+this.name+'-tick');
elem.addClass('jqplot-mekko-barLabel');
elem.appendTo(this._elem);
+ elem = null;
}
}
@@ -467,7 +483,7 @@
if (this.show) {
if (this.name == 'xaxis' || this.name == 'x2axis') {
- for (i=0; i<ticks.length; i++) {
+ for (var i=0; i<ticks.length; i++) {
var t = ticks[i];
if (t.show && t.showLabel) {
var shim;
@@ -522,7 +538,7 @@
}
// now show the labels under the bars.
var b, l, r;
- for (i=0; i<this.barLabels.length; i++) {
+ for (var i=0; i<this.barLabels.length; i++) {
b = this._barLabels[i];
if (b.show) {
w = b.getWidth();
@@ -535,7 +551,7 @@
}
}
else {
- for (i=0; i<ticks.length; i++) {
+ for (var i=0; i<ticks.length; i++) {
var t = ticks[i];
if (t.show && t.showLabel) {
var shim;
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.mekkoAxisRenderer.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.mekkoAxisRenderer.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.mekkoAxisRenderer.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(a){a.jqplot.MekkoAxisRenderer=function(){};a.jqplot.MekkoAxisRenderer.prototype.init=function(c){this.tickMode;this.barLabelRenderer=a.jqplot.AxisLabelRenderer;this.barLabels=this.barLabels||[];this.barLabelOptions={};this.tickOptions=a.extend(true,{showGridline:false},this.tickOptions);this._barLabels=[];a.extend(true,this,c);if(this.name=="yaxis"){this.tickOptions.formatString=this.tickOptions.formatString||"%d%"}var b=this._dataBounds;b.min=0;if(this.name=="yaxis"||this.name=="y2axis"){b.max=100;this.tickMode="even"}else{if(this.name=="xaxis"){this.tickMode=(this.tickMode==null)?"bar":this.tickMode;for(var d=0;d<this._series.length;d++){b.max+=this._series[d]._sumy}}else{if(this.name=="x2axis"){this.tickMode=(this.tickMode==null)?"even":this.tickMode;for(var d=0;d<this._series.length;d++){b.max+=this._series[d]._sumy}}}}};a.jqplot.MekkoAxisRenderer.prototype.draw=function(b,j){if(this.show){this.renderer.createTicks.call(this);var h=0;var c;var g=document.createElement("div");this._elem=a(g);this._elem.addClass("jqplot-axis jqplot-"+this.name);this._elem.css("position","absolute");g=null;if(this.name=="xaxis"||this.name=="x2axis"){this._elem.width(this._plotDimensions.width)}else{this._elem.height(this._plotDimensions.height)}this.labelOptions.axis=this.name;this._label=new this.labelRenderer(this.labelOptions);if(this._label.show){this._elem.append(this._label.draw(b))}var f,e,g;if(this.showTicks){f=this._ticks;for(var d=0;d<f.length;d++){e=f[d];if(e.showLabel&&(!e.isMinorTick||this.showMinorTicks)){this._elem.append(e.draw(b))}}}for(d=0;d<this.barLabels.length;d++){this.barLabelOptions.axis=this.name;this.barLabelOptions.label=this.barLabels[d];this._barLabels.push(new this.barLabelRenderer(this.barLabelOptions));if(this.tickMode!="bar"){this._barLabels[d].show=false}if(this._barLabels[d].show){var g=this._barLabels[d].draw(b,j);g.removeClass("jqplot-"+this.name+"-label");g.addClass("jqplot-"+this.name+"-tick");g.addClass("jqplot-mekko-barLabel");g.appendTo(this._elem);g=null}}}return !
this._elem};a.jqplot.MekkoAxisRenderer.prototype.reset=function(){this.min=this._min;this.max=this._max;this.tickInterval=this._tickInterval;this.numberTicks=this._numberTicks};a.jqplot.MekkoAxisRenderer.prototype.set=function(){var k=0;var d;var c=0;var j=0;var b=(this._label==null)?false:this._label.show;if(this.show&&this.showTicks){var g=this._ticks;for(var f=0;f<g.length;f++){var e=g[f];if(e.showLabel&&(!e.isMinorTick||this.showMinorTicks)){if(this.name=="xaxis"||this.name=="x2axis"){d=e._elem.outerHeight(true)}else{d=e._elem.outerWidth(true)}if(d>k){k=d}}}if(b){c=this._label._elem.outerWidth(true);j=this._label._elem.outerHeight(true)}if(this.name=="xaxis"){k=k+j;this._elem.css({height:k+"px",left:"0px",bottom:"0px"})}else{if(this.name=="x2axis"){k=k+j;this._elem.css({height:k+"px",left:"0px",top:"0px"})}else{if(this.name=="yaxis"){k=k+c;this._elem.css({width:k+"px",left:"0px",top:"0px"});if(b&&this._label.constructor==a.jqplot.AxisLabelRenderer){this._label._elem.css("width",c+"px")}}else{k=k+c;this._elem.css({width:k+"px",right:"0px",top:"0px"});if(b&&this._label.constructor==a.jqplot.AxisLabelRenderer){this._label._elem.css("width",c+"px")}}}}}};a.jqplot.MekkoAxisRenderer.prototype.createTicks=function(){var z=this._ticks;var w=this.ticks;var B=this.name;var y=this._dataBounds;var p,x;var n,r;var d,c;var h,b,s,q;if(w.length){for(s=0;s<w.length;s++){var e=w[s];var h=new this.tickRenderer(this.tickOptions);if(e.constructor==Array){h.value=e[0];h.label=e[1];if(!this.showTicks){h.showLabel=false;h.showMark=false}else{if(!this.showTickMarks){h.showMark=false}}h.setTick(e[0],this.name);this._ticks.push(h)}else{h.value=e;if(!this.showTicks){h.showLabel=false;h.showMark=false}else{if(!this.showTickMarks){h.showMark=false}}h.setTick(e,this.name);this._ticks.push(h)}}this.numberTicks=w.length;this.min=this._ticks[0].value;this.max=this._ticks[this.numberTicks-1].value;this.tickInterval=(this.max-this.min)/(this.numberTicks-1)}else{if(B=="xaxis"||B=="x2axis"){p=this._plotDimensions.width}else{p=this._plotDimension!
s.height}if(this.min!=null&&this.max!=null&&this.numberTicks!=null){this.tickInterval=null}n=(this.min!=null)?this.min:y.min;r=(this.max!=null)?this.max:y.max;if(n==r){var g=0.05;if(n>0){g=Math.max(Math.log(n)/Math.LN10,0.05)}n-=g;r+=g}var k=r-n;var m,o;var v,l,u;var f=[3,5,6,11,21];if(this.name=="yaxis"||this.name=="y2axis"){this.min=0;this.max=100;if(!this.numberTicks){if(this.tickInterval){this.numberTicks=3+Math.ceil(k/this.tickInterval)}else{v=2+Math.ceil((p-(this.tickSpacing-1))/this.tickSpacing);for(s=0;s<f.length;s++){u=v/f[s];if(u==1){this.numberTicks=f[s];break}else{if(u>1){l=u;continue}else{if(u<1){if(Math.abs(l-1)<Math.abs(u-1)){this.numberTicks=f[s-1];break}else{this.numberTicks=f[s];break}}else{if(s==f.length-1){this.numberTicks=f[s]}}}}}this.tickInterval=k/(this.numberTicks-1)}}else{this.tickInterval=k/(this.numberTicks-1)}for(var s=0;s<this.numberTicks;s++){b=this.min+s*this.tickInterval;h=new this.tickRenderer(this.tickOptions);if(!this.showTicks){h.showLabel=false;h.showMark=false}else{if(!this.showTickMarks){h.showMark=false}}h.setTick(b,this.name);this._ticks.push(h)}}else{if(this.tickMode=="bar"){this.min=0;this.numberTicks=this._series.length+1;h=new this.tickRenderer(this.tickOptions);if(!this.showTicks){h.showLabel=false;h.showMark=false}else{if(!this.showTickMarks){h.showMark=false}}h.setTick(0,this.name);this._ticks.push(h);v=0;for(s=1;s<this.numberTicks;s++){v+=this._series[s-1]._sumy;h=new this.tickRenderer(this.tickOptions);if(!this.showTicks){h.showLabel=false;h.showMark=false}else{if(!this.showTickMarks){h.showMark=false}}h.setTick(v,this.name);this._ticks.push(h)}this.max=this.max||v;if(this.max>v){h=new this.tickRenderer(this.tickOptions);if(!this.showTicks){h.showLabel=false;h.showMark=false}else{if(!this.showTickMarks){h.showMark=false}}h.setTick(this.max,this.name);this._ticks.push(h)}}else{if(this.tickMode=="even"){this.min=0;this.max=this.max||y.max;var A=2+Math.ceil((p-(this.tickSpacing-1))/this.tickSpacing);k=this.max-this.min;this.numberTicks=A;this.tickInterval=k/(this.n!
umberTicks-1);for(s=0;s<this.numberTicks;s++){b=this.min+s*this.tickInterval;h=new this.tickRenderer(this.tickOptions);if(!this.showTicks){h.showLabel=false;h.showMark=false}else{if(!this.showTickMarks){h.showMark=false}}h.setTick(b,this.name);this._ticks.push(h)}}}}}};a.jqplot.MekkoAxisRenderer.prototype.pack=function(e,d){var C=this._ticks;var x=this.max;var v=this.min;var m=d.max;var j=d.min;var o=(this._label==null)?false:this._label.show;for(var s in e){this._elem.css(s,e[s])}this._offsets=d;var f=m-j;var g=x-v;this.p2u=function(b){return(b-j)*g/f+v};this.u2p=function(b){return(b-v)*f/g+j};if(this.name=="xaxis"||this.name=="x2axis"){this.series_u2p=function(b){return(b-v)*f/g};this.series_p2u=function(b){return b*g/f+v}}else{this.series_u2p=function(b){return(b-x)*f/g};this.series_p2u=function(b){return b*g/f+x}}if(this.show){if(this.name=="xaxis"||this.name=="x2axis"){for(var y=0;y<C.length;y++){var n=C[y];if(n.show&&n.showLabel){var c;if(n.constructor==a.jqplot.CanvasAxisTickRenderer&&n.angle){var A=(this.name=="xaxis")?1:-1;switch(n.labelPosition){case"auto":if(A*n.angle<0){c=-n.getWidth()+n._textRenderer.height*Math.sin(-n._textRenderer.angle)/2}else{c=-n._textRenderer.height*Math.sin(n._textRenderer.angle)/2}break;case"end":c=-n.getWidth()+n._textRenderer.height*Math.sin(-n._textRenderer.angle)/2;break;case"start":c=-n._textRenderer.height*Math.sin(n._textRenderer.angle)/2;break;case"middle":c=-n.getWidth()/2+n._textRenderer.height*Math.sin(-n._textRenderer.angle)/2;break;default:c=-n.getWidth()/2+n._textRenderer.height*Math.sin(-n._textRenderer.angle)/2;break}}else{c=-n.getWidth()/2}var D=this.u2p(n.value)+c+"px";n._elem.css("left",D);n.pack()}}var k;if(o){k=this._label._elem.outerWidth(true);this._label._elem.css("left",j+f/2-k/2+"px");if(this.name=="xaxis"){this._label._elem.css("bottom","0px")}else{this._label._elem.css("top","0px")}this._label.pack()}var B,u,q;for(var y=0;y<this.barLabels.length;y++){B=this._barLabels[y];if(B.show){k=B.getWidth();u=this._ticks[y].getLeft()+this._ticks[y].getWidth(!
);q=this._ticks[y+1].getLeft();B._elem.css("left",(q+u-k)/2+"px");B._elem.css("top",this._ticks[y]._elem.css("top"));B.pack()}}}else{for(var y=0;y<C.length;y++){var n=C[y];if(n.show&&n.showLabel){var c;if(n.constructor==a.jqplot.CanvasAxisTickRenderer&&n.angle){var A=(this.name=="yaxis")?1:-1;switch(n.labelPosition){case"auto":case"end":if(A*n.angle<0){c=-n._textRenderer.height*Math.cos(-n._textRenderer.angle)/2}else{c=-n.getHeight()+n._textRenderer.height*Math.cos(n._textRenderer.angle)/2}break;case"start":if(n.angle>0){c=-n._textRenderer.height*Math.cos(-n._textRenderer.angle)/2}else{c=-n.getHeight()+n._textRenderer.height*Math.cos(n._textRenderer.angle)/2}break;case"middle":c=-n.getHeight()/2;break;default:c=-n.getHeight()/2;break}}else{c=-n.getHeight()/2}var D=this.u2p(n.value)+c+"px";n._elem.css("top",D);n.pack()}}if(o){var z=this._label._elem.outerHeight(true);this._label._elem.css("top",m-f/2-z/2+"px");if(this.name=="yaxis"){this._label._elem.css("left","0px")}else{this._label._elem.css("right","0px")}this._label.pack()}}}}})(jQuery);
\ No newline at end of file
Modified: gnucash/trunk/src/report/jqplot/plugins/jqplot.mekkoRenderer.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.mekkoRenderer.js 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.mekkoRenderer.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -1,18 +1,31 @@
/**
- * Copyright (c) 2009 - 2010 Chris Leonello
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
- * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
- * The author would appreciate an email letting him know of any substantial
- * use of jqPlot. You can reach the author at: chris at jqplot dot com
- * or see http://www.jqplot.com/info.php . This is, of course,
- * not required.
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
- * Thanks for using jqPlot!
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
*
*/
(function($) {
@@ -65,6 +78,7 @@
var opts = {lineJoin:'miter', lineCap:'butt', isarc:false, fillRect:this.fillRect, strokeRect:this.strokeRect};
this.renderer.shapeRenderer.init(opts);
plot.axes.x2axis._series.push(this);
+ this._type = 'mekko';
};
// Method: setGridData
@@ -273,6 +287,10 @@
idx++;
}
}
+
+ tr = null;
+ td1 = null;
+ td2 = null;
}
}
return this._elem;
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.mekkoRenderer.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.mekkoRenderer.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.mekkoRenderer.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(b){b.jqplot.MekkoRenderer=function(){this.shapeRenderer=new b.jqplot.ShapeRenderer();this.borderColor=null;this.showBorders=true};b.jqplot.MekkoRenderer.prototype.init=function(c,e){this.fill=false;this.fillRect=true;this.strokeRect=true;this.shadow=false;this._xwidth=0;this._xstart=0;b.extend(true,this.renderer,c);var d={lineJoin:"miter",lineCap:"butt",isarc:false,fillRect:this.fillRect,strokeRect:this.strokeRect};this.renderer.shapeRenderer.init(d);e.axes.x2axis._series.push(this);this._type="mekko"};b.jqplot.MekkoRenderer.prototype.setGridData=function(h){var e=this._xaxis.series_u2p;var c=this._yaxis.series_u2p;var g=this._plotData;this.gridData=[];this._xwidth=e(this._sumy)-e(0);if(this.index>0){this._xstart=h.series[this.index-1]._xstart+h.series[this.index-1]._xwidth}var l=this.canvas.getHeight();var d=0;var k;var j;for(var f=0;f<g.length;f++){if(g[f]!=null){d+=g[f][1];k=l-(d/this._sumy*l);j=g[f][1]/this._sumy*l;this.gridData.push([this._xstart,k,this._xwidth,j])}}};b.jqplot.MekkoRenderer.prototype.makeGridData=function(f,g){var d=this._xaxis.series_u2p;var l=this.canvas.getHeight();var c=0;var j;var h;var k=[];for(var e=0;e<f.length;e++){if(f[e]!=null){c+=f[e][1];j=l-(c/this._sumy*l);h=f[e][1]/this._sumy*l;k.push([this._xstart,j,this._xwidth,h])}}return k};b.jqplot.MekkoRenderer.prototype.draw=function(c,h,d){var e;var g=(d!=undefined)?d:{};var f=(g.showLine!=undefined)?g.showLine:this.showLine;var j=new b.jqplot.ColorGenerator(this.seriesColors);c.save();if(h.length){if(f){for(e=0;e<h.length;e++){g.fillStyle=j.next();if(this.renderer.showBorders){g.strokeStyle=this.renderer.borderColor}else{g.strokeStyle=g.fillStyle}this.renderer.shapeRenderer.draw(c,h[e],g)}}}c.restore()};b.jqplot.MekkoRenderer.prototype.drawShadow=function(c,e,d){};b.jqplot.MekkoLegendRenderer=function(){};b.jqplot.MekkoLegendRenderer.prototype.init=function(c){this.numberRows=null;this.numberColumns=null;this.placement="outside";b.extend(true,this,c)};b.jqplot.MekkoLegendRenderer.prototype.draw=function(){var f=!
this;if(this.show){var o=this._series;var r="position:absolute;";r+=(this.background)?"background:"+this.background+";":"";r+=(this.border)?"border:"+this.border+";":"";r+=(this.fontSize)?"font-size:"+this.fontSize+";":"";r+=(this.fontFamily)?"font-family:"+this.fontFamily+";":"";r+=(this.textColor)?"color:"+this.textColor+";":"";this._elem=b('<table class="jqplot-table-legend" style="'+r+'"></table>');var w=false,n=true,c,l;var p=o[0];var d=new b.jqplot.ColorGenerator(p.seriesColors);if(p.show){var x=p.data;if(this.numberRows){c=this.numberRows;if(!this.numberColumns){l=Math.ceil(x.length/c)}else{l=this.numberColumns}}else{if(this.numberColumns){l=this.numberColumns;c=Math.ceil(x.length/this.numberColumns)}else{c=x.length;l=1}}var v,u,e,h,g,k,m,t;var q=0;for(v=0;v<c;v++){if(n){e=b('<tr class="jqplot-table-legend"></tr>').prependTo(this._elem)}else{e=b('<tr class="jqplot-table-legend"></tr>').appendTo(this._elem)}for(u=0;u<l;u++){if(q<x.length){k=this.labels[q]||x[q][0].toString();t=d.next();if(!n){if(v>0){w=true}else{w=false}}else{if(v==c-1){w=false}else{w=true}}m=(w)?this.rowSpacing:"0";h=b('<td class="jqplot-table-legend" style="text-align:center;padding-top:'+m+';"><div><div class="jqplot-table-legend-swatch" style="border-color:'+t+';"></div></div></td>');g=b('<td class="jqplot-table-legend" style="padding-top:'+m+';"></td>');if(this.escapeHtml){g.text(k)}else{g.html(k)}if(n){g.prependTo(e);h.prependTo(e)}else{h.appendTo(e);g.appendTo(e)}w=true}q++}}e=null;h=null;g=null}}return this._elem};b.jqplot.MekkoLegendRenderer.prototype.pack=function(f){if(this.show){var e={_top:f.top,_left:f.left,_right:f.right,_bottom:this._plotDimensions.height-f.bottom};if(this.placement=="insideGrid"){switch(this.location){case"nw":var d=e._left+this.xoffset;var c=e._top+this.yoffset;this._elem.css("left",d);this._elem.css("top",c);break;case"n":var d=(f.left+(this._plotDimensions.width-f.right))/2-this.getWidth()/2;var c=e._top+this.yoffset;this._elem.css("left",d);this._elem.css("top",c);break;case"ne":var d=f.right+this.xoff!
set;var c=e._top+this.yoffset;this._elem.css({right:d,top:c});break;case"e":var d=f.right+this.xoffset;var c=(f.top+(this._plotDimensions.height-f.bottom))/2-this.getHeight()/2;this._elem.css({right:d,top:c});break;case"se":var d=f.right+this.xoffset;var c=f.bottom+this.yoffset;this._elem.css({right:d,bottom:c});break;case"s":var d=(f.left+(this._plotDimensions.width-f.right))/2-this.getWidth()/2;var c=f.bottom+this.yoffset;this._elem.css({left:d,bottom:c});break;case"sw":var d=e._left+this.xoffset;var c=f.bottom+this.yoffset;this._elem.css({left:d,bottom:c});break;case"w":var d=e._left+this.xoffset;var c=(f.top+(this._plotDimensions.height-f.bottom))/2-this.getHeight()/2;this._elem.css({left:d,top:c});break;default:var d=e._right-this.xoffset;var c=e._bottom+this.yoffset;this._elem.css({right:d,bottom:c});break}}else{switch(this.location){case"nw":var d=this._plotDimensions.width-e._left+this.xoffset;var c=e._top+this.yoffset;this._elem.css("right",d);this._elem.css("top",c);break;case"n":var d=(f.left+(this._plotDimensions.width-f.right))/2-this.getWidth()/2;var c=this._plotDimensions.height-e._top+this.yoffset;this._elem.css("left",d);this._elem.css("bottom",c);break;case"ne":var d=this._plotDimensions.width-f.right+this.xoffset;var c=e._top+this.yoffset;this._elem.css({left:d,top:c});break;case"e":var d=this._plotDimensions.width-f.right+this.xoffset;var c=(f.top+(this._plotDimensions.height-f.bottom))/2-this.getHeight()/2;this._elem.css({left:d,top:c});break;case"se":var d=this._plotDimensions.width-f.right+this.xoffset;var c=f.bottom+this.yoffset;this._elem.css({left:d,bottom:c});break;case"s":var d=(f.left+(this._plotDimensions.width-f.right))/2-this.getWidth()/2;var c=this._plotDimensions.height-f.bottom+this.yoffset;this._elem.css({left:d,top:c});break;case"sw":var d=this._plotDimensions.width-e._left+this.xoffset;var c=f.bottom+this.yoffset;this._elem.css({right:d,bottom:c});break;case"w":var d=this._plotDimensions.width-e._left+this.xoffset;var c=(f.top+(this._plotDimensions.height-f.bottom))/2-this.g!
etHeight()/2;this._elem.css({right:d,top:c});break;default:var d=e._right-this.xoffset;var c=e._bottom+this.yoffset;this._elem.css({right:d,bottom:c});break}}}};function a(g,f,d){d=d||{};d.axesDefaults=d.axesDefaults||{};d.legend=d.legend||{};d.seriesDefaults=d.seriesDefaults||{};var c=false;if(d.seriesDefaults.renderer==b.jqplot.MekkoRenderer){c=true}else{if(d.series){for(var e=0;e<d.series.length;e++){if(d.series[e].renderer==b.jqplot.MekkoRenderer){c=true}}}}if(c){d.axesDefaults.renderer=b.jqplot.MekkoAxisRenderer;d.legend.renderer=b.jqplot.MekkoLegendRenderer;d.legend.preDraw=true}}b.jqplot.preInitHooks.push(a)})(jQuery);
\ No newline at end of file
Modified: gnucash/trunk/src/report/jqplot/plugins/jqplot.meterGaugeRenderer.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.meterGaugeRenderer.js 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.meterGaugeRenderer.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -1,18 +1,31 @@
/**
- * Copyright (c) 2009 - 2010 Chris Leonello
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
- * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
- * The author would appreciate an email letting him know of any substantial
- * use of jqPlot. You can reach the author at: chris at jqplot dot com
- * or see http://www.jqplot.com/info.php . This is, of course,
- * not required.
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
- * Thanks for using jqPlot!
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
*
*/
(function($) {
@@ -81,7 +94,7 @@
this.needleColor = "#C3D3E5";
// prop: tickColor
// color of the tick marks around the gauge.
- this.tickColor = "989898";
+ this.tickColor = "#989898";
// prop: ringWidth
// width of the ring around the gauge. Auto computed by default.
this.ringWidth = null;
@@ -151,6 +164,7 @@
// True will stop needle just below/above the min/max values if data is below/above min/max,
// as if the meter is "pegged".
this.pegNeedle = true;
+ this._type = 'meterGauge';
$.extend(true, this, options);
this.type = null;
@@ -172,7 +186,7 @@
}
this._tickPoints = [];
// reference to label element.
- this._labelElm = null;
+ this._labelElem = null;
// start the gauge at the beginning of the span
this.startAngle = (90 + (360 - this.span)/2) * Math.PI/180;
@@ -289,7 +303,7 @@
function getnmt(pos, interval, fact) {
var temp;
- for (i=pos.length-1; i>=0; i--) {
+ for (var i=pos.length-1; i>=0; i--) {
temp = interval/(pos[i] * Math.pow(10, fact));
if (temp == 4 || temp == 5) {
return temp - 1;
@@ -382,7 +396,7 @@
}
this.needleThickness = this.needleThickness || 2+Math.pow(this.ringWidth, 0.8);
this.innerPad = this.ringWidth/2 + this.needleThickness/2 + this.needlePad;
- this.diameter = w - 2*this.innerPad;
+ this.diameter = w - 2*this.innerPad - this.ringWidth - this.padding;
}
// center taking into account legend and over draw for gauge bottom below hub.
// this will be center of hub.
@@ -400,6 +414,7 @@
this._center = [(cw-trans*offx)/2 + trans * offx, (ch-trans*offy)/2 + trans * offy];
}
}
+
if (this._labelElem && this.labelPosition == 'bottom') {
this._center[1] -= this._labelElem.outerHeight(true);
@@ -573,8 +588,8 @@
this.numberMinorTicks = 1;
var nums = [4, 5, 3, 6, 2];
for (i=0; i<5; i++) {
- temp = this.tickInterval/nums[i];
- if (temp == parseInt(temp)) {
+ var temp = this.tickInterval/nums[i];
+ if (temp == parseInt(temp, 10)) {
this.numberMinorTicks = nums[i]-1;
break;
}
@@ -694,7 +709,7 @@
// draw the tick labels
if (this.showTickLabels) {
- var elem, l, t, ew, dim, maxdim=0;
+ var elem, l, t, ew, eh, dim, maxdim=0;
var tp = this.tickPadding * (1 - 1/(this.diameter/80+1));
for (i=0; i<this.ticks.length; i++) {
elem = $('<div class="jqplot-meterGauge-tick" style="position:absolute;">'+this.ticks[i][1]+'</div>');
@@ -704,7 +719,7 @@
l = this._tickPoints[i][0] - ew * (this._tickPoints[i][2]-Math.PI)/Math.PI - tp * Math.cos(this._tickPoints[i][2]);
t = this._tickPoints[i][1] - eh/2 + eh/2 * Math.pow(Math.abs((Math.sin(this._tickPoints[i][2]))), 0.5) + tp/3 * Math.pow(Math.abs((Math.sin(this._tickPoints[i][2]))), 0.5) ;
// t = this._tickPoints[i][1] - eh/2 - eh/2 * Math.sin(this._tickPoints[i][2]) - tp/2 * Math.sin(this._tickPoints[i][2]);
- elem.css({left:l, top:t});
+ elem.css({left:l, top:t, color: this.tickColor});
dim = ew*Math.cos(this._tickPoints[i][2]) + eh*Math.sin(Math.PI/2+this._tickPoints[i][2]/2);
maxdim = (dim > maxdim) ? dim : maxdim;
}
@@ -849,7 +864,6 @@
*Meter gauges don't typically have a legend, this overrides the default legend renderer.
*/
$.jqplot.MeterGaugeLegendRenderer.prototype.init = function(options) {
-
// Maximum number of rows in the legend. 0 or null for unlimited.
this.numberRows = null;
// Maximum number of columns in the legend. 0 or null for unlimited.
@@ -859,7 +873,6 @@
// called with context of legend
$.jqplot.MeterGaugeLegendRenderer.prototype.draw = function() {
- var legend = this;
if (this.show) {
var series = this._series;
var ss = 'position:absolute;';
@@ -913,8 +926,9 @@
}
for (j=0; j<nc; j++) {
if (idx < pd.length){
+ // debugger
lt = this.labels[idx] || pd[idx][0].toString();
- color = colorGenerator.next();
+ color = s.color;
if (!reverse){
if (i>0){
pad = true;
@@ -961,125 +975,16 @@
return this._elem;
};
- // $.jqplot.MeterGaugeLegendRenderer.prototype.pack = function(offsets) {
- // if (this.show) {
- // // fake a grid for positioning
- // var grid = {_top:offsets.top, _left:offsets.left, _right:offsets.right, _bottom:this._plotDimensions.height - offsets.bottom};
- // if (this.placement == 'insideGrid') {
- // switch (this.location) {
- // case 'nw':
- // var a = grid._left + this.xoffset;
- // var b = grid._top + this.yoffset;
- // this._elem.css('left', a);
- // this._elem.css('top', b);
- // break;
- // case 'n':
- // var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2;
- // var b = grid._top + this.yoffset;
- // this._elem.css('left', a);
- // this._elem.css('top', b);
- // break;
- // case 'ne':
- // var a = offsets.right + this.xoffset;
- // var b = grid._top + this.yoffset;
- // this._elem.css({right:a, top:b});
- // break;
- // case 'e':
- // var a = offsets.right + this.xoffset;
- // var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2;
- // this._elem.css({right:a, top:b});
- // break;
- // case 'se':
- // var a = offsets.right + this.xoffset;
- // var b = offsets.bottom + this.yoffset;
- // this._elem.css({right:a, bottom:b});
- // break;
- // case 's':
- // var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2;
- // var b = offsets.bottom + this.yoffset;
- // this._elem.css({left:a, bottom:b});
- // break;
- // case 'sw':
- // var a = grid._left + this.xoffset;
- // var b = offsets.bottom + this.yoffset;
- // this._elem.css({left:a, bottom:b});
- // break;
- // case 'w':
- // var a = grid._left + this.xoffset;
- // var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2;
- // this._elem.css({left:a, top:b});
- // break;
- // default: // same as 'se'
- // var a = grid._right - this.xoffset;
- // var b = grid._bottom + this.yoffset;
- // this._elem.css({right:a, bottom:b});
- // break;
- // }
- //
- // }
- // else {
- // switch (this.location) {
- // case 'nw':
- // var a = this._plotDimensions.width - grid._left + this.xoffset;
- // var b = grid._top + this.yoffset;
- // this._elem.css('right', a);
- // this._elem.css('top', b);
- // break;
- // case 'n':
- // var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2;
- // var b = this._plotDimensions.height - grid._top + this.yoffset;
- // this._elem.css('left', a);
- // this._elem.css('bottom', b);
- // break;
- // case 'ne':
- // var a = this._plotDimensions.width - offsets.right + this.xoffset;
- // var b = grid._top + this.yoffset;
- // this._elem.css({left:a, top:b});
- // break;
- // case 'e':
- // var a = this._plotDimensions.width - offsets.right + this.xoffset;
- // var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2;
- // this._elem.css({left:a, top:b});
- // break;
- // case 'se':
- // var a = this._plotDimensions.width - offsets.right + this.xoffset;
- // var b = offsets.bottom + this.yoffset;
- // this._elem.css({left:a, bottom:b});
- // break;
- // case 's':
- // var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2;
- // var b = this._plotDimensions.height - offsets.bottom + this.yoffset;
- // this._elem.css({left:a, top:b});
- // break;
- // case 'sw':
- // var a = this._plotDimensions.width - grid._left + this.xoffset;
- // var b = offsets.bottom + this.yoffset;
- // this._elem.css({right:a, bottom:b});
- // break;
- // case 'w':
- // var a = this._plotDimensions.width - grid._left + this.xoffset;
- // var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2;
- // this._elem.css({right:a, top:b});
- // break;
- // default: // same as 'se'
- // var a = grid._right - this.xoffset;
- // var b = grid._bottom + this.yoffset;
- // this._elem.css({right:a, bottom:b});
- // break;
- // }
- // }
- // }
- // };
// setup default renderers for axes and legend so user doesn't have to
// called with scope of plot
function preInit(target, data, options) {
+ // debugger
options = options || {};
options.axesDefaults = options.axesDefaults || {};
options.legend = options.legend || {};
options.seriesDefaults = options.seriesDefaults || {};
options.grid = options.grid || {};
- options.gridPadding = options.gridPadding || {};
// only set these if there is a gauge series
var setopts = false;
@@ -1102,10 +1007,6 @@
options.grid.drawGridlines = false;
options.grid.borderWidth = (options.grid.borderWidth != null) ? options.grid.borderWidth : 0;
options.grid.shadow = (options.grid.shadow != null) ? options.grid.shadow : false;
- options.gridPadding.top = (options.gridPadding.top != null) ? options.gridPadding.top : 0;
- options.gridPadding.bottom = (options.gridPadding.bottom != null) ? options.gridPadding.bottom : 0;
- options.gridPadding.left = (options.gridPadding.left != null) ? options.gridPadding.left : 0;
- options.gridPadding.right = (options.gridPadding.right != null) ? options.gridPadding.right : 0;
}
}
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.meterGaugeRenderer.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.meterGaugeRenderer.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.meterGaugeRenderer.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(c){c.jqplot.MeterGaugeRenderer=function(){c.jqplot.LineRenderer.call(this)};c.jqplot.MeterGaugeRenderer.prototype=new c.jqplot.LineRenderer();c.jqplot.MeterGaugeRenderer.prototype.constructor=c.jqplot.MeterGaugeRenderer;c.jqplot.MeterGaugeRenderer.prototype.init=function(e){this.diameter=null;this.padding=null;this.shadowOffset=2;this.shadowAlpha=0.07;this.shadowDepth=4;this.background="#efefef";this.ringColor="#BBC6D0";this.needleColor="#C3D3E5";this.tickColor="#989898";this.ringWidth=null;this.min;this.max;this.ticks=[];this.showTicks=true;this.showTickLabels=true;this.label=null;this.labelHeightAdjust=0;this.labelPosition="inside";this.intervals=[];this.intervalColors=["#4bb2c5","#EAA228","#c5b47f","#579575","#839557","#958c12","#953579","#4b5de4","#d8b83f","#ff5800","#0085cc","#c747a3","#cddf54","#FBD178","#26B4E3","#bd70c7"];this.intervalInnerRadius=null;this.intervalOuterRadius=null;this.tickRenderer=c.jqplot.MeterGaugeTickRenderer;this.tickPositions=[1,2,2.5,5,10];this.tickSpacing=30;this.numberMinorTicks=null;this.hubRadius=null;this.tickPadding=null;this.needleThickness=null;this.needlePad=6;this.pegNeedle=true;this._type="meterGauge";c.extend(true,this,e);this.type=null;this.numberTicks=null;this.tickInterval=null;this.span=180;if(this.type=="circular"){this.semiCircular=false}else{if(this.type!="circular"){this.semiCircular=true}else{this.semiCircular=(this.span<=180)?true:false}}this._tickPoints=[];this._labelElem=null;this.startAngle=(90+(360-this.span)/2)*Math.PI/180;this.endAngle=(90-(360-this.span)/2)*Math.PI/180;this.setmin=!!(this.min==null);this.setmax=!!(this.max==null);if(this.intervals.length){if(this.intervals[0].length==null||this.intervals.length==1){for(var f=0;f<this.intervals.length;f++){this.intervals[f]=[this.intervals[f],this.intervals[f],this.intervalColors[f]]}}else{if(this.intervals[0].length==2){for(f=0;f<this.intervals.length;f++){this.intervals[f]=[this.intervals[f][0],this.intervals[f][1],this.intervalColors[f]]}}}}if(this.ticks.length){if(this.ticks[0]!
.length==null||this.ticks[0].length==1){for(var f=0;f<this.ticks.length;f++){this.ticks[f]=[this.ticks[f],this.ticks[f]]}}this.min=(this.min==null)?this.ticks[0][0]:this.min;this.max=(this.max==null)?this.ticks[this.ticks.length-1][0]:this.max;this.setmin=false;this.setmax=false;this.numberTicks=this.ticks.length;this.tickInterval=this.ticks[1][0]-this.ticks[0][0];this.tickFactor=Math.floor(parseFloat((Math.log(this.tickInterval)/Math.log(10)).toFixed(11)));this.numberMinorTicks=b(this.tickPositions,this.tickInterval,this.tickFactor);if(!this.numberMinorTicks){this.numberMinorTicks=b(this.tickPositions,this.tickInterval,this.tickFactor-1)}if(!this.numberMinorTicks){this.numberMinorTicks=1}}else{if(this.intervals.length){this.min=(this.min==null)?0:this.min;this.setmin=false;if(this.max==null){if(this.intervals[this.intervals.length-1][0]>=this.data[0][1]){this.max=this.intervals[this.intervals.length-1][0];this.setmax=false}}else{this.setmax=false}}else{this.min=(this.min==null)?0:this.min;this.setmin=false;if(this.max==null){this.max=this.data[0][1]*1.25;this.setmax=true}else{this.setmax=false}}}};c.jqplot.MeterGaugeRenderer.prototype.setGridData=function(j){var f=[];var k=[];var e=this.startAngle;for(var h=0;h<this.data.length;h++){f.push(this.data[h][1]);k.push([this.data[h][0]]);if(h>0){f[h]+=f[h-1]}}var g=Math.PI*2/f[f.length-1];for(var h=0;h<f.length;h++){k[h][1]=f[h]*g}this.gridData=k};c.jqplot.MeterGaugeRenderer.prototype.makeGridData=function(j,k){var f=[];var l=[];var e=this.startAngle;for(var h=0;h<j.length;h++){f.push(j[h][1]);l.push([j[h][0]]);if(h>0){f[h]+=f[h-1]}}var g=Math.PI*2/f[f.length-1];for(var h=0;h<f.length;h++){l[h][1]=f[h]*g}return l};function b(j,f,g){var e;for(var h=j.length-1;h>=0;h--){e=f/(j[h]*Math.pow(10,g));if(e==4||e==5){return e-1}}return null}c.jqplot.MeterGaugeRenderer.prototype.draw=function(X,aC,ap){var aa;var aM=(ap!=undefined)?ap:{};var ai=0;var ah=0;var at=1;if(ap.legendInfo&&ap.legendInfo.placement=="inside"){var aI=ap.legendInfo;switch(aI.location){case"nw":ai=aI.width+!
aI.xoffset;break;case"w":ai=aI.width+aI.xoffset;break;case"sw":ai=aI.width+aI.xoffset;break;case"ne":ai=aI.width+aI.xoffset;at=-1;break;case"e":ai=aI.width+aI.xoffset;at=-1;break;case"se":ai=aI.width+aI.xoffset;at=-1;break;case"n":ah=aI.height+aI.yoffset;break;case"s":ah=aI.height+aI.yoffset;at=-1;break;default:break}}if(this.label){this._labelElem=c('<div class="jqplot-meterGauge-label" style="position:absolute;">'+this.label+"</div>");this.canvas._elem.after(this._labelElem)}var m=(aM.shadow!=undefined)?aM.shadow:this.shadow;var N=(aM.showLine!=undefined)?aM.showLine:this.showLine;var I=(aM.fill!=undefined)?aM.fill:this.fill;var K=X.canvas.width;var S=X.canvas.height;if(this.padding==null){this.padding=Math.round(Math.min(K,S)/30)}var Q=K-ai-2*this.padding;var ab=S-ah-2*this.padding;if(this.labelPosition=="bottom"&&this.label){ab-=this._labelElem.outerHeight(true)}var L=Math.min(Q,ab);var ad=L;if(!this.diameter){if(this.semiCircular){if(Q>=2*ab){if(!this.ringWidth){this.ringWidth=2*ab/35}this.needleThickness=this.needleThickness||2+Math.pow(this.ringWidth,0.8);this.innerPad=this.ringWidth/2+this.needleThickness/2+this.needlePad;this.diameter=2*(ab-2*this.innerPad)}else{if(!this.ringWidth){this.ringWidth=Q/35}this.needleThickness=this.needleThickness||2+Math.pow(this.ringWidth,0.8);this.innerPad=this.ringWidth/2+this.needleThickness/2+this.needlePad;this.diameter=Q-2*this.innerPad-this.ringWidth-this.padding}this._center=[(K-at*ai)/2+at*ai,(S+at*ah-this.padding-this.ringWidth-this.innerPad)]}else{if(!this.ringWidth){this.ringWidth=ad/35}this.needleThickness=this.needleThickness||2+Math.pow(this.ringWidth,0.8);this.innerPad=0;this.diameter=ad-this.ringWidth;this._center=[(K-at*ai)/2+at*ai,(S-at*ah)/2+at*ah]}}if(this._labelElem&&this.labelPosition=="bottom"){this._center[1]-=this._labelElem.outerHeight(true)}this._radius=this.diameter/2;this.tickSpacing=6000/this.diameter;if(!this.hubRadius){this.hubRadius=this.diameter/18}this.shadowOffset=0.5+this.ringWidth/9;this.shadowWidth=this.ringWidth*1;this.tickPadding=3!
+Math.pow(this.diameter/20,0.7);this.tickOuterRadius=this._radius-this.ringWidth/2-this.tickPadding;this.tickLength=(this.showTicks)?this._radius/13:0;if(this.ticks.length==0){var A=this.max,aL=this.min,q=this.setmax,aG=this.setmin,au=(A-aL)*this.tickSpacing/this.span;var aw=Math.floor(parseFloat((Math.log(au)/Math.log(10)).toFixed(11)));var an=(au/Math.pow(10,aw));(an>2&&an<=2.5)?an=2.5:an=Math.ceil(an);var T=this.tickPositions;var aA,ak;for(aa=0;aa<T.length;aa++){if(an==T[aa]||aa&&T[aa-1]<an&&an<T[aa]){au=T[aa]*Math.pow(10,aw);aA=aa}}for(aa=0;aa<T.length;aa++){if(an==T[aa]||aa&&T[aa-1]<an&&an<T[aa]){au=T[aa]*Math.pow(10,aw);ak=Math.ceil((A-aL)/au)}}if(q&&aG){var aP=(aL>0)?aL-aL%au:aL-aL%au-au;if(!this.forceZero){var D=Math.min(aL-aP,0.8*au);var o=Math.floor(D/T[aA]);if(o>1){aP=aP+T[aA]*(o-1);if(parseInt(aP,10)!=aP&&parseInt(aP-T[aA],10)==aP-T[aA]){aP=aP-T[aA]}}}if(aL==aP){aL-=au}else{if(aL-aP>0.23*au){aL=aP}else{aL=aP-au;ak+=1}}ak+=1;var E=aL+(ak-1)*au;if(A>=E){E+=au;ak+=1}if(E-A<0.23*au){E+=au;ak+=1}this.max=A=E;this.min=aL;this.tickInterval=au;this.numberTicks=ak;var O;for(aa=0;aa<ak;aa++){O=parseFloat((aL+aa*au).toFixed(11));this.ticks.push([O,O])}this.max=this.ticks[ak-1][1];this.tickFactor=aw;this.numberMinorTicks=b(this.tickPositions,this.tickInterval,this.tickFactor);if(!this.numberMinorTicks){this.numberMinorTicks=b(this.tickPositions,this.tickInterval,this.tickFactor-1)}}else{if(q){var E=aL+(ak-1)*au;if(A>=E){A=E+au;ak+=1}else{A=E}this.tickInterval=this.tickInterval||au;this.numberTicks=this.numberTicks||ak;var O;for(aa=0;aa<this.numberTicks;aa++){O=parseFloat((aL+aa*this.tickInterval).toFixed(11));this.ticks.push([O,O])}this.max=this.ticks[this.numberTicks-1][1];this.tickFactor=aw;this.numberMinorTicks=b(this.tickPositions,this.tickInterval,this.tickFactor);if(!this.numberMinorTicks){this.numberMinorTicks=b(this.tickPositions,this.tickInterval,this.tickFactor-1)}}}if(!q&&!aG){var P=this.max-this.min;aw=Math.floor(parseFloat((Math.log(P)/Math.log(10)).toFixed(11)))-1;var aN=[5,6,4,7,3,8,9,10,2],V,C,av!
=0,M;if(P>1){var aJ=String(P);if(aJ.search(/\./)==-1){var aF=aJ.search(/0+$/);av=(aF>0)?aJ.length-aF-1:0}}M=P/Math.pow(10,av);for(aa=0;aa<aN.length;aa++){V=M/(aN[aa]-1);if(V==parseInt(V,10)){this.numberTicks=aN[aa];this.tickInterval=P/(this.numberTicks-1);this.tickFactor=aw+1;break}}var O;for(aa=0;aa<this.numberTicks;aa++){O=parseFloat((this.min+aa*this.tickInterval).toFixed(11));this.ticks.push([O,O])}this.numberMinorTicks=b(this.tickPositions,this.tickInterval,this.tickFactor);if(!this.numberMinorTicks){this.numberMinorTicks=b(this.tickPositions,this.tickInterval,this.tickFactor-1)}if(!this.numberMinorTicks){this.numberMinorTicks=1;var aH=[4,5,3,6,2];for(aa=0;aa<5;aa++){var ao=this.tickInterval/aH[aa];if(ao==parseInt(ao,10)){this.numberMinorTicks=aH[aa]-1;break}}}}}var U=this._radius,aE=this.startAngle,k=this.endAngle,H=Math.PI,e=Math.PI/2;if(this.semiCircular){var z=Math.atan(this.innerPad/U),ac=this.outerStartAngle=aE-z,aB=this.outerEndAngle=k+z,B=this.hubStartAngle=aE-Math.atan(this.innerPad/this.hubRadius*2),af=this.hubEndAngle=k+Math.atan(this.innerPad/this.hubRadius*2);X.save();X.translate(this._center[0],this._center[1]);X.lineJoin="round";X.lineCap="round";X.save();X.beginPath();X.fillStyle=this.background;X.arc(0,0,U,ac,aB,false);X.closePath();X.fill();X.restore();var aj="rgba(0,0,0,"+this.shadowAlpha+")";X.save();for(var aa=0;aa<this.shadowDepth;aa++){X.translate(this.shadowOffset*Math.cos(this.shadowAngle/180*Math.PI),this.shadowOffset*Math.sin(this.shadowAngle/180*Math.PI));X.beginPath();X.strokeStyle=aj;X.lineWidth=this.shadowWidth;X.arc(0,0,U,ac,aB,false);X.closePath();X.stroke()}X.restore();X.save();var az=parseInt((this.shadowDepth+1)/2,10);for(var aa=0;aa<az;aa++){X.translate(this.shadowOffset*Math.cos(this.shadowAngle/180*Math.PI),this.shadowOffset*Math.sin(this.shadowAngle/180*Math.PI));X.beginPath();X.fillStyle=aj;X.arc(0,0,this.hubRadius,B,af,false);X.closePath();X.fill()}X.restore();X.save();X.beginPath();X.strokeStyle=this.ringColor;X.lineWidth=this.ringWidth;X.arc(0,0,U,ac,aB,false);X.c!
losePath();X.stroke();X.restore();X.save();X.beginPath();X.fillStyle=this.ringColor;X.arc(0,0,this.hubRadius,B,af,false);X.closePath();X.fill();X.restore();if(this.showTicks){X.save();var f=this.tickOuterRadius,aq=this.tickLength,v=aq/2,F=this.numberMinorTicks,am=this.span*Math.PI/180/(this.ticks.length-1),p=am/(F+1);for(aa=0;aa<this.ticks.length;aa++){X.beginPath();X.lineWidth=1.5+this.diameter/360;X.strokeStyle=this.ringColor;var ae=am*aa+aE;X.moveTo(-f*Math.cos(am*aa+aE),f*Math.sin(am*aa+aE));X.lineTo(-(f-aq)*Math.cos(am*aa+aE),(f-aq)*Math.sin(am*aa+aE));this._tickPoints.push([(f-aq)*Math.cos(am*aa+aE)+this._center[0]+this.canvas._offsets.left,(f-aq)*Math.sin(am*aa+aE)+this._center[1]+this.canvas._offsets.top,am*aa+aE]);X.stroke();X.lineWidth=1+this.diameter/440;if(aa<this.ticks.length-1){for(var Y=1;Y<=F;Y++){X.beginPath();X.moveTo(-f*Math.cos(am*aa+p*Y+aE),f*Math.sin(am*aa+p*Y+aE));X.lineTo(-(f-v)*Math.cos(am*aa+p*Y+aE),(f-v)*Math.sin(am*aa+p*Y+aE));X.stroke()}}}X.restore()}if(this.showTickLabels){var J,W,T,aO,g,G,n=0;var an=this.tickPadding*(1-1/(this.diameter/80+1));for(aa=0;aa<this.ticks.length;aa++){J=c('<div class="jqplot-meterGauge-tick" style="position:absolute;">'+this.ticks[aa][1]+"</div>");this.canvas._elem.after(J);aO=J.outerWidth(true);g=J.outerHeight(true);W=this._tickPoints[aa][0]-aO*(this._tickPoints[aa][2]-Math.PI)/Math.PI-an*Math.cos(this._tickPoints[aa][2]);T=this._tickPoints[aa][1]-g/2+g/2*Math.pow(Math.abs((Math.sin(this._tickPoints[aa][2]))),0.5)+an/3*Math.pow(Math.abs((Math.sin(this._tickPoints[aa][2]))),0.5);J.css({left:W,top:T,color:this.tickColor});G=aO*Math.cos(this._tickPoints[aa][2])+g*Math.sin(Math.PI/2+this._tickPoints[aa][2]/2);n=(G>n)?G:n}}if(this.label&&this.labelPosition=="inside"){var W=this._center[0]+this.canvas._offsets.left;var an=this.tickPadding*(1-1/(this.diameter/80+1));var T=0.5*(this._center[1]+this.canvas._offsets.top-this.hubRadius)+0.5*(this._center[1]+this.canvas._offsets.top-this.tickOuterRadius+this.tickLength+an)+this.labelHeightAdjust;W-=this._labelElem.o!
uterWidth(true)/2;T-=this._labelElem.outerHeight(true)/2;this._labelElem.css({left:W,top:T})}else{if(this.label&&this.labelPosition=="bottom"){var W=this._center[0]+this.canvas._offsets.left-this._labelElem.outerWidth(true)/2;var T=this._center[1]+this.canvas._offsets.top+this.innerPad+ +this.ringWidth+this.padding+this.labelHeightAdjust;this._labelElem.css({left:W,top:T})}}X.save();var ax=this.intervalInnerRadius||this.hubRadius*1.5;if(this.intervalOuterRadius==null){if(this.showTickLabels){var ag=(this.tickOuterRadius-this.tickLength-this.tickPadding-this.diameter/8)}else{var ag=(this.tickOuterRadius-this.tickLength-this.diameter/16)}}else{var ag=this.intervalOuterRadius}var P=this.max-this.min;var aD=this.intervals[this.intervals.length-1]-this.min;var y,Z,u=this.span*Math.PI/180;for(aa=0;aa<this.intervals.length;aa++){y=(aa==0)?aE:aE+(this.intervals[aa-1][0]-this.min)*u/P;if(y<0){y=0}Z=aE+(this.intervals[aa][0]-this.min)*u/P;if(Z<0){Z=0}X.beginPath();X.fillStyle=this.intervals[aa][2];X.arc(0,0,ax,y,Z,false);X.lineTo(ag*Math.cos(Z),ag*Math.sin(Z));X.arc(0,0,ag,Z,y,true);X.lineTo(ax*Math.cos(y),ax*Math.sin(y));X.closePath();X.fill()}X.restore();var ay=this.data[0][1];var R=this.max-this.min;if(this.pegNeedle){if(this.data[0][1]>this.max+R*3/this.span){ay=this.max+R*3/this.span}if(this.data[0][1]<this.min-R*3/this.span){ay=this.min-R*3/this.span}}var al=(ay-this.min)/R*this.span*Math.PI/180+this.startAngle;X.save();X.beginPath();X.fillStyle=this.ringColor;X.strokeStyle=this.ringColor;this.needleLength=(this.tickOuterRadius-this.tickLength)*0.85;this.needleThickness=(this.needleThickness<2)?2:this.needleThickness;var aK=this.needleThickness*0.4;var x=this.needleLength/10;var s=(this.needleThickness-aK)/10;var ar;for(var aa=0;aa<10;aa++){ar=this.needleThickness-aa*s;X.moveTo(x*aa*Math.cos(al),x*aa*Math.sin(al));X.lineWidth=ar;X.lineTo(x*(aa+1)*Math.cos(al),x*(aa+1)*Math.sin(al));X.stroke()}X.restore()}else{this._center=[(K-at*ai)/2+at*ai,(S-at*ah)/2+at*ah]}};c.jqplot.MeterGaugeAxisRenderer=function(){c.jqplot.Lin!
earAxisRenderer.call(this)};c.jqplot.MeterGaugeAxisRenderer.prototype=new c.jqplot.LinearAxisRenderer();c.jqplot.MeterGaugeAxisRenderer.prototype.constructor=c.jqplot.MeterGaugeAxisRenderer;c.jqplot.MeterGaugeAxisRenderer.prototype.init=function(e){this.tickRenderer=c.jqplot.MeterGaugeTickRenderer;c.extend(true,this,e);this._dataBounds={min:0,max:100};this.min=0;this.max=100;this.showTicks=false;this.ticks=[];this.showMark=false;this.show=false};c.jqplot.MeterGaugeLegendRenderer=function(){c.jqplot.TableLegendRenderer.call(this)};c.jqplot.MeterGaugeLegendRenderer.prototype=new c.jqplot.TableLegendRenderer();c.jqplot.MeterGaugeLegendRenderer.prototype.constructor=c.jqplot.MeterGaugeLegendRenderer;c.jqplot.MeterGaugeLegendRenderer.prototype.init=function(e){this.numberRows=null;this.numberColumns=null;c.extend(true,this,e)};c.jqplot.MeterGaugeLegendRenderer.prototype.draw=function(){if(this.show){var p=this._series;var x="position:absolute;";x+=(this.background)?"background:"+this.background+";":"";x+=(this.border)?"border:"+this.border+";":"";x+=(this.fontSize)?"font-size:"+this.fontSize+";":"";x+=(this.fontFamily)?"font-family:"+this.fontFamily+";":"";x+=(this.textColor)?"color:"+this.textColor+";":"";x+=(this.marginTop!=null)?"margin-top:"+this.marginTop+";":"";x+=(this.marginBottom!=null)?"margin-bottom:"+this.marginBottom+";":"";x+=(this.marginLeft!=null)?"margin-left:"+this.marginLeft+";":"";x+=(this.marginRight!=null)?"margin-right:"+this.marginRight+";":"";this._elem=c('<table class="jqplot-table-legend" style="'+x+'"></table>');var f=false,q=false,u,o;var w=p[0];if(w.show){var t=w.data;if(this.numberRows){u=this.numberRows;if(!this.numberColumns){o=Math.ceil(t.length/u)}else{o=this.numberColumns}}else{if(this.numberColumns){o=this.numberColumns;u=Math.ceil(t.length/this.numberColumns)}else{u=t.length;o=1}}var n,m,r,g,e,l,k,h;var v=0;for(n=0;n<u;n++){if(q){r=c('<tr class="jqplot-table-legend"></tr>').prependTo(this._elem)}else{r=c('<tr class="jqplot-table-legend"></tr>').appendTo(this._elem)}for(m=0;m<o;m+!
+){if(v<t.length){l=this.labels[v]||t[v][0].toString();h=w.color;if(!q){if(n>0){f=true}else{f=false}}else{if(n==u-1){f=false}else{f=true}}k=(f)?this.rowSpacing:"0";g=c('<td class="jqplot-table-legend" style="text-align:center;padding-top:'+k+';"><div><div class="jqplot-table-legend-swatch" style="border-color:'+h+';"></div></div></td>');e=c('<td class="jqplot-table-legend" style="padding-top:'+k+';"></td>');if(this.escapeHtml){e.text(l)}else{e.html(l)}if(q){e.prependTo(r);g.prependTo(r)}else{g.appendTo(r);e.appendTo(r)}f=true}v++}}}}return this._elem};function a(j,h,f){f=f||{};f.axesDefaults=f.axesDefaults||{};f.legend=f.legend||{};f.seriesDefaults=f.seriesDefaults||{};f.grid=f.grid||{};var e=false;if(f.seriesDefaults.renderer==c.jqplot.MeterGaugeRenderer){e=true}else{if(f.series){for(var g=0;g<f.series.length;g++){if(f.series[g].renderer==c.jqplot.MeterGaugeRenderer){e=true}}}}if(e){f.axesDefaults.renderer=c.jqplot.MeterGaugeAxisRenderer;f.legend.renderer=c.jqplot.MeterGaugeLegendRenderer;f.legend.preDraw=true;f.grid.background=f.grid.background||"white";f.grid.drawGridlines=false;f.grid.borderWidth=(f.grid.borderWidth!=null)?f.grid.borderWidth:0;f.grid.shadow=(f.grid.shadow!=null)?f.grid.shadow:false}}function d(e){}c.jqplot.preInitHooks.push(a);c.jqplot.postParseOptionsHooks.push(d);c.jqplot.MeterGaugeTickRenderer=function(){c.jqplot.AxisTickRenderer.call(this)};c.jqplot.MeterGaugeTickRenderer.prototype=new c.jqplot.AxisTickRenderer();c.jqplot.MeterGaugeTickRenderer.prototype.constructor=c.jqplot.MeterGaugeTickRenderer})(jQuery);
\ No newline at end of file
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.mobile.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.mobile.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.mobile.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,45 @@
+/**
+ * jqplot.jquerymobile plugin
+ * jQuery Mobile virtual event support.
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2011 Takashi Okamoto
+ * jqPlot is currently available for use in all personal or commercial projects
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
+ * choose the license that best suits your project and use it accordingly.
+ *
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
+ *
+ * If you are feeling kind and generous, consider supporting the project by
+ * making a donation at: http://www.jqplot.com/donate.php .
+ *
+ */
+(function($) {
+ function postInit(target, data, options){
+ this.bindCustomEvents = function() {
+ this.eventCanvas._elem.bind('vclick', {plot:this}, this.onClick);
+ this.eventCanvas._elem.bind('dblclick', {plot:this}, this.onDblClick);
+ this.eventCanvas._elem.bind('taphold', {plot:this}, this.onDblClick);
+ this.eventCanvas._elem.bind('vmousedown', {plot:this}, this.onMouseDown);
+ this.eventCanvas._elem.bind('vmousemove', {plot:this}, this.onMouseMove);
+ this.eventCanvas._elem.bind('mouseenter', {plot:this}, this.onMouseEnter);
+ this.eventCanvas._elem.bind('mouseleave', {plot:this}, this.onMouseLeave);
+ if (this.captureRightClick) {
+ this.eventCanvas._elem.bind('vmouseup', {plot:this}, this.onRightClick);
+ this.eventCanvas._elem.get(0).oncontextmenu = function() {
+ return false;
+ };
+ }
+ else {
+ this.eventCanvas._elem.bind('vmouseup', {plot:this}, this.onMouseUp);
+ }
+ };
+ this.plugins.mobile = true;
+ }
+ $.jqplot.postInitHooks.push(postInit);
+})(jQuery);
\ No newline at end of file
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.mobile.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.mobile.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.mobile.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(b){function a(e,d,c){this.bindCustomEvents=function(){this.eventCanvas._elem.bind("vclick",{plot:this},this.onClick);this.eventCanvas._elem.bind("dblclick",{plot:this},this.onDblClick);this.eventCanvas._elem.bind("taphold",{plot:this},this.onDblClick);this.eventCanvas._elem.bind("vmousedown",{plot:this},this.onMouseDown);this.eventCanvas._elem.bind("vmousemove",{plot:this},this.onMouseMove);this.eventCanvas._elem.bind("mouseenter",{plot:this},this.onMouseEnter);this.eventCanvas._elem.bind("mouseleave",{plot:this},this.onMouseLeave);if(this.captureRightClick){this.eventCanvas._elem.bind("vmouseup",{plot:this},this.onRightClick);this.eventCanvas._elem.get(0).oncontextmenu=function(){return false}}else{this.eventCanvas._elem.bind("vmouseup",{plot:this},this.onMouseUp)}};this.plugins.mobile=true}b.jqplot.postInitHooks.push(a)})(jQuery);
\ No newline at end of file
Modified: gnucash/trunk/src/report/jqplot/plugins/jqplot.ohlcRenderer.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.ohlcRenderer.js 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.ohlcRenderer.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -1,18 +1,31 @@
/**
- * Copyright (c) 2009 - 2010 Chris Leonello
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
- * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
- * The author would appreciate an email letting him know of any substantial
- * use of jqPlot. You can reach the author at: chris at jqplot dot com
- * or see http://www.jqplot.com/info.php . This is, of course,
- * not required.
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
- * Thanks for using jqPlot!
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
*
*/
(function($) {
@@ -95,6 +108,10 @@
// true if is a hi-low-close chart (no open price).
// This is determined automatically from the series data.
this.hlc = false;
+ // prop: lineWidth
+ // Width of the hi-low line and open/close ticks.
+ // Must be set in the rendererOptions for the series.
+ this.lineWidth = 1.5;
this._tickLength;
this._bodyWidth;
};
@@ -104,10 +121,13 @@
// called with scope of series.
$.jqplot.OHLCRenderer.prototype.init = function(options) {
- // prop: lineWidth
- // Width of the hi-low line and open/close ticks.
- this.lineWidth = 1.5;
+ options = options || {};
+ // lineWidth has to be set on the series, changes in renderer
+ // constructor have no effect. set the default here
+ // if no renderer option for lineWidth is specified.
+ this.lineWidth = options.lineWidth || 1.5;
$.jqplot.LineRenderer.prototype.init.call(this, options);
+ this._type = 'ohlc';
// set the yaxis data bounds here to account for hi and low values
var db = this._yaxis._dataBounds;
var d = this._plotData;
@@ -171,13 +191,23 @@
xmaxidx = i+1;
}
}
+
+ var dwidth = this.gridData[xmaxidx-1][0] - this.gridData[xminidx][0];
+ var nvisiblePoints = xmaxidx - xminidx;
+ try {
+ var dinterval = Math.abs(this._xaxis.series_u2p(parseInt(this._xaxis._intervalStats[0].sortedIntervals[0].interval, 10)) - this._xaxis.series_u2p(0));
+ }
+
+ catch (e) {
+ var dinterval = dwidth / nvisiblePoints;
+ }
if (r.candleStick) {
if (typeof(r.bodyWidth) == 'number') {
r._bodyWidth = r.bodyWidth;
}
else {
- r._bodyWidth = Math.min(20, ctx.canvas.width/(xmaxidx - xminidx)/2);
+ r._bodyWidth = Math.min(20, dinterval/1.65);
}
}
else {
@@ -185,7 +215,7 @@
r._tickLength = r.tickLength;
}
else {
- r._tickLength = Math.min(10, ctx.canvas.width/(xmaxidx - xminidx)/4);
+ r._tickLength = Math.min(10, dinterval/3.5);
}
}
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.ohlcRenderer.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.ohlcRenderer.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.ohlcRenderer.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(a){a.jqplot.OHLCRenderer=function(){a.jqplot.LineRenderer.call(this);this.candleStick=false;this.tickLength="auto";this.bodyWidth="auto";this.openColor=null;this.closeColor=null;this.wickColor=null;this.fillUpBody=false;this.fillDownBody=true;this.upBodyColor=null;this.downBodyColor=null;this.hlc=false;this.lineWidth=1.5;this._tickLength;this._bodyWidth};a.jqplot.OHLCRenderer.prototype=new a.jqplot.LineRenderer();a.jqplot.OHLCRenderer.prototype.constructor=a.jqplot.OHLCRenderer;a.jqplot.OHLCRenderer.prototype.init=function(e){e=e||{};this.lineWidth=e.lineWidth||1.5;a.jqplot.LineRenderer.prototype.init.call(this,e);this._type="ohlc";var b=this._yaxis._dataBounds;var f=this._plotData;if(f[0].length<5){this.renderer.hlc=true;for(var c=0;c<f.length;c++){if(f[c][2]<b.min||b.min==null){b.min=f[c][2]}if(f[c][1]>b.max||b.max==null){b.max=f[c][1]}}}else{for(var c=0;c<f.length;c++){if(f[c][3]<b.min||b.min==null){b.min=f[c][3]}if(f[c][2]>b.max||b.max==null){b.max=f[c][2]}}}};a.jqplot.OHLCRenderer.prototype.draw=function(A,N,j){var J=this.data;var v=this._xaxis.min;var z=this._xaxis.max;var l=0;var K=J.length;var p=this._xaxis.series_u2p;var G=this._yaxis.series_u2p;var D,E,f,M,F,n,O,C;var y;var u=this.renderer;var s=(j!=undefined)?j:{};var k=(s.shadow!=undefined)?s.shadow:this.shadow;var B=(s.fill!=undefined)?s.fill:this.fill;var c=(s.fillAndStroke!=undefined)?s.fillAndStroke:this.fillAndStroke;u.bodyWidth=(s.bodyWidth!=undefined)?s.bodyWidth:u.bodyWidth;u.tickLength=(s.tickLength!=undefined)?s.tickLength:u.tickLength;A.save();if(this.show){var m,q,g,Q,t;for(var D=0;D<J.length;D++){if(J[D][0]<v){l=D}else{if(J[D][0]<z){K=D+1}}}var I=this.gridData[K-1][0]-this.gridData[l][0];var L=K-l;try{var P=Math.abs(this._xaxis.series_u2p(parseInt(this._xaxis._intervalStats[0].sortedIntervals[0].interval,10))-this._xaxis.series_u2p(0))}catch(H){var P=I/L}if(u.candleStick){if(typeof(u.bodyWidth)=="number"){u._bodyWidth=u.bodyWidth}else{u._bodyWidth=Math.min(20,P/1.65)}}else{if(typeof(u.tickLength)=="number"){u._tickL!
ength=u.tickLength}else{u._tickLength=Math.min(10,P/3.5)}}for(var D=l;D<K;D++){m=p(J[D][0]);if(u.hlc){q=null;g=G(J[D][1]);Q=G(J[D][2]);t=G(J[D][3])}else{q=G(J[D][1]);g=G(J[D][2]);Q=G(J[D][3]);t=G(J[D][4])}y={};if(u.candleStick&&!u.hlc){n=u._bodyWidth;O=m-n/2;if(t<q){if(u.wickColor){y.color=u.wickColor}else{if(u.downBodyColor){y.color=u.upBodyColor}}f=a.extend(true,{},s,y);u.shapeRenderer.draw(A,[[m,g],[m,t]],f);u.shapeRenderer.draw(A,[[m,q],[m,Q]],f);y={};M=t;F=q-t;if(u.fillUpBody){y.fillRect=true}else{y.strokeRect=true;n=n-this.lineWidth;O=m-n/2}if(u.upBodyColor){y.color=u.upBodyColor;y.fillStyle=u.upBodyColor}C=[O,M,n,F]}else{if(t>q){if(u.wickColor){y.color=u.wickColor}else{if(u.downBodyColor){y.color=u.downBodyColor}}f=a.extend(true,{},s,y);u.shapeRenderer.draw(A,[[m,g],[m,q]],f);u.shapeRenderer.draw(A,[[m,t],[m,Q]],f);y={};M=q;F=t-q;if(u.fillDownBody){y.fillRect=true}else{y.strokeRect=true;n=n-this.lineWidth;O=m-n/2}if(u.downBodyColor){y.color=u.downBodyColor;y.fillStyle=u.downBodyColor}C=[O,M,n,F]}else{if(u.wickColor){y.color=u.wickColor}f=a.extend(true,{},s,y);u.shapeRenderer.draw(A,[[m,g],[m,Q]],f);y={};y.fillRect=false;y.strokeRect=false;O=[m-n/2,q];M=[m+n/2,t];n=null;F=null;C=[O,M]}}f=a.extend(true,{},s,y);u.shapeRenderer.draw(A,C,f)}else{E=s.color;if(u.openColor){s.color=u.openColor}if(!u.hlc){u.shapeRenderer.draw(A,[[m-u._tickLength,q],[m,q]],s)}s.color=E;if(u.wickColor){s.color=u.wickColor}u.shapeRenderer.draw(A,[[m,g],[m,Q]],s);s.color=E;if(u.closeColor){s.color=u.closeColor}u.shapeRenderer.draw(A,[[m,t],[m+u._tickLength,t]],s);s.color=E}}}A.restore()};a.jqplot.OHLCRenderer.prototype.drawShadow=function(b,d,c){};a.jqplot.OHLCRenderer.checkOptions=function(d,c,b){if(!b.highlighter){b.highlighter={showMarker:false,tooltipAxes:"y",yvalues:4,formatString:'<table class="jqplot-highlighter"><tr><td>date:</td><td>%s</td></tr><tr><td>open:</td><td>%s</td></tr><tr><td>hi:</td><td>%s</td></tr><tr><td>low:</td><td>%s</td></tr><tr><td>close:</td><td>%s</td></tr></table>'}}}})(jQuery);
\ No newline at end of file
Modified: gnucash/trunk/src/report/jqplot/plugins/jqplot.pieRenderer.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.pieRenderer.js 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.pieRenderer.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -1,18 +1,31 @@
/**
- * Copyright (c) 2009 - 2010 Chris Leonello
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
- * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
- * The author would appreciate an email letting him know of any substantial
- * use of jqPlot. You can reach the author at: chris at jqplot dot com
- * or see http://www.jqplot.com/info.php . This is, of course,
- * not required.
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
- * Thanks for using jqPlot!
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
*
*/
(function($) {
@@ -110,7 +123,7 @@
// Format string for data labels. If none, '%s' is used for "label" and for arrays, '%d' for value and '%d%%' for percentage.
this.dataLabelFormatString = null;
// prop: dataLabelThreshold
- // Threshhold in percentage (0 - 100) of pie area, below which no label will be displayed.
+ // Threshhold in percentage (0-100) of pie area, below which no label will be displayed.
// This applies to all label types, not just to percentage labels.
this.dataLabelThreshold = 3;
// prop: dataLabelPositionFactor
@@ -135,6 +148,7 @@
this.tickRenderer = $.jqplot.PieTickRenderer;
// Used as check for conditions where pie shouldn't be drawn.
this._drawData = true;
+ this._type = 'pie';
// if user has passed in highlightMouseDown option and not set highlightMouseOver, disable highlightMouseOver
if (options.highlightMouseDown && options.highlightMouseOver == null) {
@@ -142,9 +156,11 @@
}
$.extend(true, this, options);
- if (this.diameter != null) {
- this.diameter = this.diameter - this.sliceMargin;
+
+ if (this.sliceMargin < 0) {
+ this.sliceMargin = 0;
}
+
this._diameter = null;
this._radius = null;
// array of [start,end] angles arrays, one for each slice. In radians.
@@ -235,32 +251,74 @@
}
return td;
};
+
+ function calcRadiusAdjustment(ang) {
+ return Math.sin((ang - (ang-Math.PI) / 8 / Math.PI )/2.0);
+ }
+
+ function calcRPrime(ang1, ang2, sliceMargin, fill, lineWidth) {
+ var rprime = 0;
+ var ang = ang2 - ang1;
+ var absang = Math.abs(ang);
+ var sm = sliceMargin;
+ if (fill == false) {
+ sm += lineWidth;
+ }
+
+ if (sm > 0 && absang > 0.01 && absang < 6.282) {
+ rprime = parseFloat(sm) / 2.0 / calcRadiusAdjustment(ang);
+ }
+
+ return rprime;
+ }
$.jqplot.PieRenderer.prototype.drawSlice = function (ctx, ang1, ang2, color, isShadow) {
if (this._drawData) {
- var r = this._diameter / 2;
+ var r = this._radius;
var fill = this.fill;
var lineWidth = this.lineWidth;
+ var sm = this.sliceMargin;
+ if (this.fill == false) {
+ sm += this.lineWidth;
+ }
ctx.save();
ctx.translate(this._center[0], this._center[1]);
- ctx.translate(this.sliceMargin*Math.cos((ang1+ang2)/2), this.sliceMargin*Math.sin((ang1+ang2)/2));
-
+
+ var rprime = calcRPrime(ang1, ang2, this.sliceMargin, this.fill, this.lineWidth);
+
+ var transx = rprime * Math.cos((ang1 + ang2) / 2.0);
+ var transy = rprime * Math.sin((ang1 + ang2) / 2.0);
+
+ if ((ang2 - ang1) <= Math.PI) {
+ r -= rprime;
+ }
+ else {
+ r += rprime;
+ }
+
+ ctx.translate(transx, transy);
+
if (isShadow) {
- for (var i=0; i<this.shadowDepth; i++) {
+ for (var i=0, l=this.shadowDepth; i<l; i++) {
ctx.save();
ctx.translate(this.shadowOffset*Math.cos(this.shadowAngle/180*Math.PI), this.shadowOffset*Math.sin(this.shadowAngle/180*Math.PI));
- doDraw();
+ doDraw(r);
}
+ for (var i=0, l=this.shadowDepth; i<l; i++) {
+ ctx.restore();
+ }
}
else {
- doDraw();
+ doDraw(r);
}
+ ctx.restore();
}
- function doDraw () {
+ function doDraw (rad) {
// Fix for IE and Chrome that can't seem to draw circles correctly.
// ang2 should always be <= 2 pi since that is the way the data is converted.
+ // 2Pi = 6.2831853, Pi = 3.1415927
if (ang2 > 6.282 + this.startAngle) {
ang2 = 6.282 + this.startAngle;
if (ang1 > ang2) {
@@ -277,7 +335,7 @@
ctx.fillStyle = color;
ctx.strokeStyle = color;
ctx.lineWidth = lineWidth;
- ctx.arc(0, 0, r, ang1, ang2, false);
+ ctx.arc(0, 0, rad, ang1, ang2, false);
ctx.lineTo(0,0);
ctx.closePath();
@@ -288,14 +346,6 @@
ctx.stroke();
}
}
-
- if (isShadow) {
- for (var i=0; i<this.shadowDepth; i++) {
- ctx.restore();
- }
- }
-
- ctx.restore();
};
// called with scope of series
@@ -344,7 +394,6 @@
}
var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow;
- var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine;
var fill = (opts.fill != undefined) ? opts.fill : this.fill;
var cw = ctx.canvas.width;
var ch = ctx.canvas.height;
@@ -352,34 +401,67 @@
var h = ch - offy - 2 * this.padding;
var mindim = Math.min(w,h);
var d = mindim;
- // this._diameter = this.diameter || d;
- this._diameter = this.diameter || d - this.sliceMargin;
+
+ // Fixes issue #272. Thanks hugwijst!
+ // reset slice angles array.
+ this._sliceAngles = [];
+ var sm = this.sliceMargin;
+ if (this.fill == false) {
+ sm += this.lineWidth;
+ }
+
+ var rprime;
+ var maxrprime = 0;
+
+ var ang, ang1, ang2, shadowColor;
+ var sa = this.startAngle / 180 * Math.PI;
+
+ // have to pre-draw shadows, so loop throgh here and calculate some values also.
+ for (var i=0, l=gd.length; i<l; i++) {
+ ang1 = (i == 0) ? sa : gd[i-1][1] + sa;
+ ang2 = gd[i][1] + sa;
+
+ this._sliceAngles.push([ang1, ang2]);
+
+ rprime = calcRPrime(ang1, ang2, this.sliceMargin, this.fill, this.lineWidth);
+
+ if (Math.abs(ang2-ang1) > Math.PI) {
+ maxrprime = Math.max(rprime, maxrprime);
+ }
+ }
+
+ if (this.diameter != null && this.diameter > 0) {
+ this._diameter = this.diameter - 2*maxrprime;
+ }
+ else {
+ this._diameter = d - 2*maxrprime;
+ }
+
+ // Need to check for undersized pie. This can happen if
+ // plot area too small and legend is too big.
+ if (this._diameter < 6) {
+ $.jqplot.log('Diameter of pie too small, not rendering.');
+ return;
+ }
+
var r = this._radius = this._diameter/2;
- var sa = this.startAngle / 180 * Math.PI;
- this._center = [(cw - trans * offx)/2 + trans * offx, (ch - trans*offy)/2 + trans * offy];
-
+
+ this._center = [(cw - trans * offx)/2 + trans * offx + maxrprime * Math.cos(sa), (ch - trans*offy)/2 + trans * offy + maxrprime * Math.sin(sa)];
+
if (this.shadow) {
- var shadowColor = 'rgba(0,0,0,'+this.shadowAlpha+')';
- for (var i=0; i<gd.length; i++) {
- var ang1 = (i == 0) ? sa : gd[i-1][1] + sa;
- // Adjust ang1 and ang2 for sliceMargin
- ang1 += this.sliceMargin/180*Math.PI;
- this.renderer.drawSlice.call (this, ctx, ang1, gd[i][1]+sa, shadowColor, true);
+ for (var i=0, l=gd.length; i<l; i++) {
+ shadowColor = 'rgba(0,0,0,'+this.shadowAlpha+')';
+ this.renderer.drawSlice.call (this, ctx, this._sliceAngles[i][0], this._sliceAngles[i][1], shadowColor, true);
}
-
}
+
for (var i=0; i<gd.length; i++) {
- var ang1 = (i == 0) ? sa : gd[i-1][1] + sa;
- // Adjust ang1 and ang2 for sliceMargin
- ang1 += this.sliceMargin/180*Math.PI;
- var ang2 = gd[i][1] + sa;
- this._sliceAngles.push([ang1, ang2]);
- this.renderer.drawSlice.call (this, ctx, ang1, ang2, colorGenerator.next(), false);
+ this.renderer.drawSlice.call (this, ctx, this._sliceAngles[i][0], this._sliceAngles[i][1], colorGenerator.next(), false);
if (this.showDataLabels && gd[i][2]*100 >= this.dataLabelThreshold) {
- var fstr, avgang = (ang1+ang2)/2, label;
+ var fstr, avgang = (this._sliceAngles[i][0] + this._sliceAngles[i][1])/2, label;
if (this.dataLabels == 'label') {
fstr = this.dataLabelFormatString || '%s';
@@ -416,8 +498,7 @@
y = Math.round(y);
labelelem.css({left: x, top: y});
}
- }
-
+ }
};
$.jqplot.PieAxisRenderer = function() {
@@ -481,23 +562,49 @@
var legend = this;
if (this.show) {
var series = this._series;
- var ss = 'position:absolute;';
- ss += (this.background) ? 'background:'+this.background+';' : '';
- ss += (this.border) ? 'border:'+this.border+';' : '';
- ss += (this.fontSize) ? 'font-size:'+this.fontSize+';' : '';
- ss += (this.fontFamily) ? 'font-family:'+this.fontFamily+';' : '';
- ss += (this.textColor) ? 'color:'+this.textColor+';' : '';
- ss += (this.marginTop != null) ? 'margin-top:'+this.marginTop+';' : '';
- ss += (this.marginBottom != null) ? 'margin-bottom:'+this.marginBottom+';' : '';
- ss += (this.marginLeft != null) ? 'margin-left:'+this.marginLeft+';' : '';
- ss += (this.marginRight != null) ? 'margin-right:'+this.marginRight+';' : '';
- this._elem = $('<table class="jqplot-table-legend" style="'+ss+'"></table>');
+
+
+ this._elem = $(document.createElement('table'));
+ this._elem.addClass('jqplot-table-legend');
+
+ var ss = {position:'absolute'};
+ if (this.background) {
+ ss['background'] = this.background;
+ }
+ if (this.border) {
+ ss['border'] = this.border;
+ }
+ if (this.fontSize) {
+ ss['fontSize'] = this.fontSize;
+ }
+ if (this.fontFamily) {
+ ss['fontFamily'] = this.fontFamily;
+ }
+ if (this.textColor) {
+ ss['textColor'] = this.textColor;
+ }
+ if (this.marginTop != null) {
+ ss['marginTop'] = this.marginTop;
+ }
+ if (this.marginBottom != null) {
+ ss['marginBottom'] = this.marginBottom;
+ }
+ if (this.marginLeft != null) {
+ ss['marginLeft'] = this.marginLeft;
+ }
+ if (this.marginRight != null) {
+ ss['marginRight'] = this.marginRight;
+ }
+
+ this._elem.css(ss);
+
// Pie charts legends don't go by number of series, but by number of data points
// in the series. Refactor things here for that.
var pad = false,
reverse = false,
- nr, nc;
+ nr,
+ nc;
var s = series[0];
var colorGenerator = new $.jqplot.ColorGenerator(s.seriesColors);
@@ -521,16 +628,24 @@
nc = 1;
}
- var i, j, tr, td1, td2, lt, rs, color;
- var idx = 0;
+ var i, j;
+ var tr, td1, td2;
+ var lt, rs, color;
+ var idx = 0;
+ var div0, div1;
for (i=0; i<nr; i++) {
+ tr = $(document.createElement('tr'));
+ tr.addClass('jqplot-table-legend');
+
if (reverse){
- tr = $('<tr class="jqplot-table-legend"></tr>').prependTo(this._elem);
+ tr.prependTo(this._elem);
}
+
else{
- tr = $('<tr class="jqplot-table-legend"></tr>').appendTo(this._elem);
+ tr.appendTo(this._elem);
}
+
for (j=0; j<nc; j++) {
if (idx < pd.length){
lt = this.labels[idx] || pd[idx][0].toString();
@@ -552,11 +667,24 @@
}
}
rs = (pad) ? this.rowSpacing : '0';
-
- td1 = $('<td class="jqplot-table-legend" style="text-align:center;padding-top:'+rs+';">'+
- '<div><div class="jqplot-table-legend-swatch" style="border-color:'+color+';"></div>'+
- '</div></td>');
- td2 = $('<td class="jqplot-table-legend" style="padding-top:'+rs+';"></td>');
+
+
+
+ td1 = $(document.createElement('td'));
+ td1.addClass('jqplot-table-legend jqplot-table-legend-swatch');
+ td1.css({textAlign: 'center', paddingTop: rs});
+
+ div0 = $(document.createElement('div'));
+ div0.addClass('jqplot-table-legend-swatch-outline');
+ div1 = $(document.createElement('div'));
+ div1.addClass('jqplot-table-legend-swatch');
+ div1.css({backgroundColor: color, borderColor: color});
+ td1.append(div0.append(div1));
+
+ td2 = $(document.createElement('td'));
+ td2.addClass('jqplot-table-legend jqplot-table-legend-label');
+ td2.css('paddingTop', rs);
+
if (this.escapeHtml){
td2.text(lt);
}
@@ -627,7 +755,7 @@
}
function postInit(target, data, options) {
- for (i=0; i<this.series.length; i++) {
+ for (var i=0; i<this.series.length; i++) {
if (this.series[i].renderer.constructor == $.jqplot.PieRenderer) {
// don't allow mouseover and mousedown at same time.
if (this.series[i].highlightMouseOver) {
@@ -635,14 +763,13 @@
}
}
}
- this.target.bind('mouseout', {plot:this}, function (ev) { unhighlight(ev.data.plot); });
}
// called with scope of plot
function postParseOptions(options) {
for (var i=0; i<this.series.length; i++) {
this.series[i].seriesColors = this.seriesColors;
- this.series[i].colorGenerator = this.colorGenerator;
+ this.series[i].colorGenerator = $.jqplot.colorGenerator;
}
}
@@ -674,6 +801,7 @@
plot.target.trigger(evt1, ins);
if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.pieRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) {
var evt = jQuery.Event('jqplotDataHighlight');
+ evt.which = ev.which;
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
plot.target.trigger(evt, ins);
@@ -690,6 +818,7 @@
var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
if (plot.series[ins[0]].highlightMouseDown && !(ins[0] == plot.plugins.pieRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) {
var evt = jQuery.Event('jqplotDataHighlight');
+ evt.which = ev.which;
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
plot.target.trigger(evt, ins);
@@ -712,6 +841,7 @@
if (neighbor) {
var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
var evt = jQuery.Event('jqplotDataClick');
+ evt.which = ev.which;
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
plot.target.trigger(evt, ins);
@@ -726,6 +856,7 @@
unhighlight(plot);
}
var evt = jQuery.Event('jqplotDataRightClick');
+ evt.which = ev.which;
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
plot.target.trigger(evt, ins);
@@ -736,20 +867,27 @@
// create a canvas which we can draw on.
// insert it before the eventCanvas, so eventCanvas will still capture events.
function postPlotDraw() {
+ // Memory Leaks patch
+ if (this.plugins.pieRenderer && this.plugins.pieRenderer.highlightCanvas) {
+ this.plugins.pieRenderer.highlightCanvas.resetCanvas();
+ this.plugins.pieRenderer.highlightCanvas = null;
+ }
+
this.plugins.pieRenderer = {highlightedSeriesIndex:null};
this.plugins.pieRenderer.highlightCanvas = new $.jqplot.GenericCanvas();
// do we have any data labels? if so, put highlight canvas before those
var labels = $(this.targetId+' .jqplot-data-label');
if (labels.length) {
- $(labels[0]).before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-pieRenderer-highlight-canvas', this._plotDimensions));
+ $(labels[0]).before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-pieRenderer-highlight-canvas', this._plotDimensions, this));
}
// else put highlight canvas before event canvas.
else {
- this.eventCanvas._elem.before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-pieRenderer-highlight-canvas', this._plotDimensions));
+ this.eventCanvas._elem.before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-pieRenderer-highlight-canvas', this._plotDimensions, this));
}
var hctx = this.plugins.pieRenderer.highlightCanvas.setContext();
+ this.eventCanvas._elem.bind('mouseleave', {plot:this}, function (ev) { unhighlight(ev.data.plot); });
}
$.jqplot.preInitHooks.push(preInit);
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.pieRenderer.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.pieRenderer.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.pieRenderer.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(e){e.jqplot.PieRenderer=function(){e.jqplot.LineRenderer.call(this)};e.jqplot.PieRenderer.prototype=new e.jqplot.LineRenderer();e.jqplot.PieRenderer.prototype.constructor=e.jqplot.PieRenderer;e.jqplot.PieRenderer.prototype.init=function(q,u){this.diameter=null;this.padding=20;this.sliceMargin=0;this.fill=true;this.shadowOffset=2;this.shadowAlpha=0.07;this.shadowDepth=5;this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColors=[];this.dataLabels="percent";this.showDataLabels=false;this.dataLabelFormatString=null;this.dataLabelThreshold=3;this.dataLabelPositionFactor=0.52;this.dataLabelNudge=2;this.dataLabelCenterOn=true;this.startAngle=0;this.tickRenderer=e.jqplot.PieTickRenderer;this._drawData=true;this._type="pie";if(q.highlightMouseDown&&q.highlightMouseOver==null){q.highlightMouseOver=false}e.extend(true,this,q);if(this.sliceMargin<0){this.sliceMargin=0}this._diameter=null;this._radius=null;this._sliceAngles=[];this._highlightedPoint=null;if(this.highlightColors.length==0){for(var s=0;s<this.seriesColors.length;s++){var r=e.jqplot.getColorComponents(this.seriesColors[s]);var o=[r[0],r[1],r[2]];var t=o[0]+o[1]+o[2];for(var p=0;p<3;p++){o[p]=(t>570)?o[p]*0.8:o[p]+0.3*(255-o[p]);o[p]=parseInt(o[p],10)}this.highlightColors.push("rgb("+o[0]+","+o[1]+","+o[2]+")")}}this.highlightColorGenerator=new e.jqplot.ColorGenerator(this.highlightColors);u.postParseOptionsHooks.addOnce(m);u.postInitHooks.addOnce(g);u.eventListenerHooks.addOnce("jqplotMouseMove",b);u.eventListenerHooks.addOnce("jqplotMouseDown",a);u.eventListenerHooks.addOnce("jqplotMouseUp",l);u.eventListenerHooks.addOnce("jqplotClick",f);u.eventListenerHooks.addOnce("jqplotRightClick",n);u.postDrawHooks.addOnce(i)};e.jqplot.PieRenderer.prototype.setGridData=function(t){var p=[];var u=[];var o=this.startAngle/180*Math.PI;var s=0;this._drawData=false;for(var r=0;r<this.data.length;r++){if(this.data[r][1]!=0){this._drawData=true}p.push(this.data[r][1]);u.push([this.data[r][0]]);if(r>0){p[r]+=p[r-1]}s+=this.data[r][1]}v!
ar q=Math.PI*2/p[p.length-1];for(var r=0;r<p.length;r++){u[r][1]=p[r]*q;u[r][2]=this.data[r][1]/s}this.gridData=u};e.jqplot.PieRenderer.prototype.makeGridData=function(t,u){var p=[];var v=[];var s=0;var o=this.startAngle/180*Math.PI;this._drawData=false;for(var r=0;r<t.length;r++){if(this.data[r][1]!=0){this._drawData=true}p.push(t[r][1]);v.push([t[r][0]]);if(r>0){p[r]+=p[r-1]}s+=t[r][1]}var q=Math.PI*2/p[p.length-1];for(var r=0;r<p.length;r++){v[r][1]=p[r]*q;v[r][2]=t[r][1]/s}return v};function h(o){return Math.sin((o-(o-Math.PI)/8/Math.PI)/2)}function j(u,t,o,v,r){var w=0;var q=t-u;var s=Math.abs(q);var p=o;if(v==false){p+=r}if(p>0&&s>0.01&&s<6.282){w=parseFloat(p)/2/h(q)}return w}e.jqplot.PieRenderer.prototype.drawSlice=function(B,z,y,u,w){if(this._drawData){var p=this._radius;var A=this.fill;var x=this.lineWidth;var s=this.sliceMargin;if(this.fill==false){s+=this.lineWidth}B.save();B.translate(this._center[0],this._center[1]);var D=j(z,y,this.sliceMargin,this.fill,this.lineWidth);var o=D*Math.cos((z+y)/2);var C=D*Math.sin((z+y)/2);if((y-z)<=Math.PI){p-=D}else{p+=D}B.translate(o,C);if(w){for(var v=0,t=this.shadowDepth;v<t;v++){B.save();B.translate(this.shadowOffset*Math.cos(this.shadowAngle/180*Math.PI),this.shadowOffset*Math.sin(this.shadowAngle/180*Math.PI));q(p)}for(var v=0,t=this.shadowDepth;v<t;v++){B.restore()}}else{q(p)}B.restore()}function q(r){if(y>6.282+this.startAngle){y=6.282+this.startAngle;if(z>y){z=6.281+this.startAngle}}if(z>=y){return}B.beginPath();B.fillStyle=u;B.strokeStyle=u;B.lineWidth=x;B.arc(0,0,r,z,y,false);B.lineTo(0,0);B.closePath();if(A){B.fill()}else{B.stroke()}}};e.jqplot.PieRenderer.prototype.draw=function(B,z,E,o){var W;var H=(E!=undefined)?E:{};var t=0;var s=0;var N=1;var L=new e.jqplot.ColorGenerator(this.seriesColors);if(E.legendInfo&&E.legendInfo.placement=="insideGrid"){var J=E.legendInfo;switch(J.location){case"nw":t=J.width+J.xoffset;break;case"w":t=J.width+J.xoffset;break;case"sw":t=J.width+J.xoffset;break;case"ne":t=J.width+J.xoffset;N=-1;break;case"e":t=J.width+J.xoffs!
et;N=-1;break;case"se":t=J.width+J.xoffset;N=-1;break;case"n":s=J.height+J.yoffset;break;case"s":s=J.height+J.yoffset;N=-1;break;default:break}}var K=(H.shadow!=undefined)?H.shadow:this.shadow;var A=(H.fill!=undefined)?H.fill:this.fill;var C=B.canvas.width;var I=B.canvas.height;var Q=C-t-2*this.padding;var X=I-s-2*this.padding;var M=Math.min(Q,X);var Y=M;this._sliceAngles=[];var v=this.sliceMargin;if(this.fill==false){v+=this.lineWidth}var q;var G=0;var R,aa,Z,ab;var D=this.startAngle/180*Math.PI;for(var W=0,V=z.length;W<V;W++){aa=(W==0)?D:z[W-1][1]+D;Z=z[W][1]+D;this._sliceAngles.push([aa,Z]);q=j(aa,Z,this.sliceMargin,this.fill,this.lineWidth);if(Math.abs(Z-aa)>Math.PI){G=Math.max(q,G)}}if(this.diameter!=null&&this.diameter>0){this._diameter=this.diameter-2*G}else{this._diameter=Y-2*G}if(this._diameter<6){e.jqplot.log("Diameter of pie too small, not rendering.");return}var S=this._radius=this._diameter/2;this._center=[(C-N*t)/2+N*t+G*Math.cos(D),(I-N*s)/2+N*s+G*Math.sin(D)];if(this.shadow){for(var W=0,V=z.length;W<V;W++){ab="rgba(0,0,0,"+this.shadowAlpha+")";this.renderer.drawSlice.call(this,B,this._sliceAngles[W][0],this._sliceAngles[W][1],ab,true)}}for(var W=0;W<z.length;W++){this.renderer.drawSlice.call(this,B,this._sliceAngles[W][0],this._sliceAngles[W][1],L.next(),false);if(this.showDataLabels&&z[W][2]*100>=this.dataLabelThreshold){var F,U=(this._sliceAngles[W][0]+this._sliceAngles[W][1])/2,T;if(this.dataLabels=="label"){F=this.dataLabelFormatString||"%s";T=e.jqplot.sprintf(F,z[W][0])}else{if(this.dataLabels=="value"){F=this.dataLabelFormatString||"%d";T=e.jqplot.sprintf(F,this.data[W][1])}else{if(this.dataLabels=="percent"){F=this.dataLabelFormatString||"%d%%";T=e.jqplot.sprintf(F,z[W][2]*100)}else{if(this.dataLabels.constructor==Array){F=this.dataLabelFormatString||"%s";T=e.jqplot.sprintf(F,this.dataLabels[W])}}}}var p=(this._radius)*this.dataLabelPositionFactor+this.sliceMargin+this.dataLabelNudge;var P=this._center[0]+Math.cos(U)*p+this.canvas._offsets.left;var O=this._center[1]+Math.sin(U)*p+this.canv!
as._offsets.top;var u=e('<div class="jqplot-pie-series jqplot-data-label" style="position:absolute;">'+T+"</div>").insertBefore(o.eventCanvas._elem);if(this.dataLabelCenterOn){P-=u.width()/2;O-=u.height()/2}else{P-=u.width()*Math.sin(U/2);O-=u.height()/2}P=Math.round(P);O=Math.round(O);u.css({left:P,top:O})}}};e.jqplot.PieAxisRenderer=function(){e.jqplot.LinearAxisRenderer.call(this)};e.jqplot.PieAxisRenderer.prototype=new e.jqplot.LinearAxisRenderer();e.jqplot.PieAxisRenderer.prototype.constructor=e.jqplot.PieAxisRenderer;e.jqplot.PieAxisRenderer.prototype.init=function(o){this.tickRenderer=e.jqplot.PieTickRenderer;e.extend(true,this,o);this._dataBounds={min:0,max:100};this.min=0;this.max=100;this.showTicks=false;this.ticks=[];this.showMark=false;this.show=false};e.jqplot.PieLegendRenderer=function(){e.jqplot.TableLegendRenderer.call(this)};e.jqplot.PieLegendRenderer.prototype=new e.jqplot.TableLegendRenderer();e.jqplot.PieLegendRenderer.prototype.constructor=e.jqplot.PieLegendRenderer;e.jqplot.PieLegendRenderer.prototype.init=function(o){this.numberRows=null;this.numberColumns=null;e.extend(true,this,o)};e.jqplot.PieLegendRenderer.prototype.draw=function(){var r=this;if(this.show){var B=this._series;this._elem=e(document.createElement("table"));this._elem.addClass("jqplot-table-legend");var E={position:"absolute"};if(this.background){E.background=this.background}if(this.border){E.border=this.border}if(this.fontSize){E.fontSize=this.fontSize}if(this.fontFamily){E.fontFamily=this.fontFamily}if(this.textColor){E.textColor=this.textColor}if(this.marginTop!=null){E.marginTop=this.marginTop}if(this.marginBottom!=null){E.marginBottom=this.marginBottom}if(this.marginLeft!=null){E.marginLeft=this.marginLeft}if(this.marginRight!=null){E.marginRight=this.marginRight}this._elem.css(E);var I=false,A=false,o,y;var C=B[0];var p=new e.jqplot.ColorGenerator(C.seriesColors);if(C.show){var J=C.data;if(this.numberRows){o=this.numberRows;if(!this.numberColumns){y=Math.ceil(J.length/o)}else{y=this.numberColumns}}else{if(this.number!
Columns){y=this.numberColumns;o=Math.ceil(J.length/this.numberColumns)}else{o=J.length;y=1}}var H,G;var q,w,v;var x,z,F;var D=0;var u,t;for(H=0;H<o;H++){q=e(document.createElement("tr"));q.addClass("jqplot-table-legend");if(A){q.prependTo(this._elem)}else{q.appendTo(this._elem)}for(G=0;G<y;G++){if(D<J.length){x=this.labels[D]||J[D][0].toString();F=p.next();if(!A){if(H>0){I=true}else{I=false}}else{if(H==o-1){I=false}else{I=true}}z=(I)?this.rowSpacing:"0";w=e(document.createElement("td"));w.addClass("jqplot-table-legend jqplot-table-legend-swatch");w.css({textAlign:"center",paddingTop:z});u=e(document.createElement("div"));u.addClass("jqplot-table-legend-swatch-outline");t=e(document.createElement("div"));t.addClass("jqplot-table-legend-swatch");t.css({backgroundColor:F,borderColor:F});w.append(u.append(t));v=e(document.createElement("td"));v.addClass("jqplot-table-legend jqplot-table-legend-label");v.css("paddingTop",z);if(this.escapeHtml){v.text(x)}else{v.html(x)}if(A){v.prependTo(q);w.prependTo(q)}else{w.appendTo(q);v.appendTo(q)}I=true}D++}}}}return this._elem};e.jqplot.PieRenderer.prototype.handleMove=function(q,p,t,s,r){if(s){var o=[s.seriesIndex,s.pointIndex,s.data];r.target.trigger("jqplotDataMouseOver",o);if(r.series[o[0]].highlightMouseOver&&!(o[0]==r.plugins.pieRenderer.highlightedSeriesIndex&&o[1]==r.series[o[0]]._highlightedPoint)){r.target.trigger("jqplotDataHighlight",o);d(r,o[0],o[1])}}else{if(s==null){k(r)}}};function c(s,r,p){p=p||{};p.axesDefaults=p.axesDefaults||{};p.legend=p.legend||{};p.seriesDefaults=p.seriesDefaults||{};var o=false;if(p.seriesDefaults.renderer==e.jqplot.PieRenderer){o=true}else{if(p.series){for(var q=0;q<p.series.length;q++){if(p.series[q].renderer==e.jqplot.PieRenderer){o=true}}}}if(o){p.axesDefaults.renderer=e.jqplot.PieAxisRenderer;p.legend.renderer=e.jqplot.PieLegendRenderer;p.legend.preDraw=true;p.seriesDefaults.pointLabels={show:false}}}function g(r,q,o){for(var p=0;p<this.series.length;p++){if(this.series[p].renderer.constructor==e.jqplot.PieRenderer){if(this.series[!
p].highlightMouseOver){this.series[p].highlightMouseDown=false}}}}function m(o){for(var p=0;p<this.series.length;p++){this.series[p].seriesColors=this.seriesColors;this.series[p].colorGenerator=e.jqplot.colorGenerator}}function d(t,r,q){var p=t.series[r];var o=t.plugins.pieRenderer.highlightCanvas;o._ctx.clearRect(0,0,o._ctx.canvas.width,o._ctx.canvas.height);p._highlightedPoint=q;t.plugins.pieRenderer.highlightedSeriesIndex=r;p.renderer.drawSlice.call(p,o._ctx,p._sliceAngles[q][0],p._sliceAngles[q][1],p.highlightColorGenerator.get(q),false)}function k(q){var o=q.plugins.pieRenderer.highlightCanvas;o._ctx.clearRect(0,0,o._ctx.canvas.width,o._ctx.canvas.height);for(var p=0;p<q.series.length;p++){q.series[p]._highlightedPoint=null}q.plugins.pieRenderer.highlightedSeriesIndex=null;q.target.trigger("jqplotDataUnhighlight")}function b(s,r,v,u,t){if(u){var q=[u.seriesIndex,u.pointIndex,u.data];var p=jQuery.Event("jqplotDataMouseOver");p.pageX=s.pageX;p.pageY=s.pageY;t.target.trigger(p,q);if(t.series[q[0]].highlightMouseOver&&!(q[0]==t.plugins.pieRenderer.highlightedSeriesIndex&&q[1]==t.series[q[0]]._highlightedPoint)){var o=jQuery.Event("jqplotDataHighlight");o.which=s.which;o.pageX=s.pageX;o.pageY=s.pageY;t.target.trigger(o,q);d(t,q[0],q[1])}}else{if(u==null){k(t)}}}function a(r,q,u,t,s){if(t){var p=[t.seriesIndex,t.pointIndex,t.data];if(s.series[p[0]].highlightMouseDown&&!(p[0]==s.plugins.pieRenderer.highlightedSeriesIndex&&p[1]==s.series[p[0]]._highlightedPoint)){var o=jQuery.Event("jqplotDataHighlight");o.which=r.which;o.pageX=r.pageX;o.pageY=r.pageY;s.target.trigger(o,p);d(s,p[0],p[1])}}else{if(t==null){k(s)}}}function l(q,p,t,s,r){var o=r.plugins.pieRenderer.highlightedSeriesIndex;if(o!=null&&r.series[o].highlightMouseDown){k(r)}}function f(r,q,u,t,s){if(t){var p=[t.seriesIndex,t.pointIndex,t.data];var o=jQuery.Event("jqplotDataClick");o.which=r.which;o.pageX=r.pageX;o.pageY=r.pageY;s.target.trigger(o,p)}}function n(s,r,v,u,t){if(u){var q=[u.seriesIndex,u.pointIndex,u.data];var o=t.plugins.pieRenderer.highlighte!
dSeriesIndex;if(o!=null&&t.series[o].highlightMouseDown){k(t)}var p=jQuery.Event("jqplotDataRightClick");p.which=s.which;p.pageX=s.pageX;p.pageY=s.pageY;t.target.trigger(p,q)}}function i(){if(this.plugins.pieRenderer&&this.plugins.pieRenderer.highlightCanvas){this.plugins.pieRenderer.highlightCanvas.resetCanvas();this.plugins.pieRenderer.highlightCanvas=null}this.plugins.pieRenderer={highlightedSeriesIndex:null};this.plugins.pieRenderer.highlightCanvas=new e.jqplot.GenericCanvas();var p=e(this.targetId+" .jqplot-data-label");if(p.length){e(p[0]).before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-pieRenderer-highlight-canvas",this._plotDimensions,this))}else{this.eventCanvas._elem.before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-pieRenderer-highlight-canvas",this._plotDimensions,this))}var o=this.plugins.pieRenderer.highlightCanvas.setContext();this.eventCanvas._elem.bind("mouseleave",{plot:this},function(q){k(q.data.plot)})}e.jqplot.preInitHooks.push(c);e.jqplot.PieTickRenderer=function(){e.jqplot.AxisTickRenderer.call(this)};e.jqplot.PieTickRenderer.prototype=new e.jqplot.AxisTickRenderer();e.jqplot.PieTickRenderer.prototype.constructor=e.jqplot.PieTickRenderer})(jQuery);
\ No newline at end of file
Modified: gnucash/trunk/src/report/jqplot/plugins/jqplot.pointLabels.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.pointLabels.js 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.pointLabels.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -1,18 +1,31 @@
/**
- * Copyright (c) 2009 - 2010 Chris Leonello
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
- * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
- * The author would appreciate an email letting him know of any substantial
- * use of jqPlot. You can reach the author at: chris at jqplot dot com
- * or see http://www.jqplot.com/info.php . This is, of course,
- * not required.
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
- * Thanks for using jqPlot!
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
*
*/
(function($) {
@@ -123,10 +136,10 @@
var oppositeLocations = ['se', 's', 'sw', 'w', 'nw', 'n', 'ne', 'e'];
// called with scope of a series
- $.jqplot.PointLabels.init = function (target, data, seriesDefaults, opts){
+ $.jqplot.PointLabels.init = function (target, data, seriesDefaults, opts, plot){
var options = $.extend(true, {}, seriesDefaults, opts);
options.pointLabels = options.pointLabels || {};
- if (this.renderer.constructor == $.jqplot.BarRenderer && this.barDirection == 'horizontal' && !options.pointLabels.location) {
+ if (this.renderer.constructor === $.jqplot.BarRenderer && this.barDirection === 'horizontal' && !options.pointLabels.location) {
options.pointLabels.location = 'e';
}
// add a pointLabels attribute to the series plugins
@@ -141,14 +154,14 @@
if (p.seriesLabelIndex != null) {
labelIdx = p.seriesLabelIndex;
}
- else if (this.renderer.constructor == $.jqplot.BarRenderer && this.barDirection == 'horizontal') {
- labelIdx = 0;
+ else if (this.renderer.constructor === $.jqplot.BarRenderer && this.barDirection === 'horizontal') {
+ labelIdx = (this._plotData[0].length < 3) ? 0 : this._plotData[0].length -1;
}
else {
- labelIdx = this._plotData[0].length -1;
+ labelIdx = (this._plotData.length === 0) ? 0 : this._plotData[0].length -1;
}
p._labels = [];
- if (p.labels.length == 0 || p.labelsFromSeries) {
+ if (p.labels.length === 0 || p.labelsFromSeries) {
if (p.stackedValue) {
if (this._plotData.length && this._plotData[0].length){
// var idx = p.seriesLabelIndex || this._plotData[0].length -1;
@@ -158,8 +171,9 @@
}
}
else {
+ // var d = this._plotData;
var d = this.data;
- if (this.renderer.constructor == $.jqplot.BarRenderer && this.waterfall) {
+ if (this.renderer.constructor === $.jqplot.BarRenderer && this.waterfall) {
d = this._data;
}
if (d.length && d[0].length) {
@@ -168,6 +182,7 @@
p._labels.push(d[i][labelIdx]);
}
}
+ d = null;
}
}
else if (p.labels.length){
@@ -250,14 +265,18 @@
};
// called with scope of series
- $.jqplot.PointLabels.draw = function (sctx, options) {
+ $.jqplot.PointLabels.draw = function (sctx, options, plot) {
var p = this.plugins.pointLabels;
// set labels again in case they have changed.
p.setLabels.call(this);
// remove any previous labels
for (var i=0; i<p._elems.length; i++) {
- p._elems[i].remove();
+ // Memory Leaks patch
+ // p._elems[i].remove();
+ p._elems[i].emptyForce();
}
+ p._elems.splice(0, p._elems.length);
+
if (p.show) {
var ax = '_'+this._stackAxis+'axis';
@@ -267,10 +286,12 @@
}
var pd = this._plotData;
+ var ppd = this._prevPlotData;
var xax = this._xaxis;
var yax = this._yaxis;
+ var elem, helem;
- for (var i=p._labels.length-1; i>=0; i--) {
+ for (var i=0, l=p._labels.length; i < l; i++) {
var label = p._labels[i];
if (p.hideZeros && parseInt(p._labels[i], 10) == 0) {
@@ -280,9 +301,17 @@
if (label != null) {
label = p.formatter(p.formatString, label);
}
- var elem = $('<div class="jqplot-point-label jqplot-series-'+this.index+' jqplot-point-'+i+'" style="position:absolute"></div>');
+
+ helem = document.createElement('div');
+ p._elems[i] = $(helem);
+
+ elem = p._elems[i];
+
+
+ elem.addClass('jqplot-point-label jqplot-series-'+this.index+' jqplot-point-'+i);
+ elem.css('position', 'absolute');
elem.insertAfter(sctx.canvas);
- p._elems.push(elem);
+
if (p.escapeHTML) {
elem.text(label);
}
@@ -290,11 +319,25 @@
elem.html(label);
}
var location = p.location;
- if (this.waterfall && parseInt(label, 10) < 0) {
+ if ((this.fillToZero && pd[i][1] < 0) || (this.fillToZero && this._type === 'bar' && this.barDirection === 'horizontal' && pd[i][0] < 0) || (this.waterfall && parseInt(label, 10)) < 0) {
location = oppositeLocations[locationIndicies[location]];
}
+
+
var ell = xax.u2p(pd[i][0]) + p.xOffset(elem, location);
var elt = yax.u2p(pd[i][1]) + p.yOffset(elem, location);
+
+ // we have stacked chart but are not showing stacked values,
+ // place labels in center.
+ if (this._stack && !p.stackedValue) {
+ if (this.barDirection === "vertical") {
+ elt = (this._barPoints[i][0][1] + this._barPoints[i][1][1]) / 2 + plot._gridPadding.top - 0.5 * elem.outerHeight(true);
+ }
+ else {
+ ell = (this._barPoints[i][2][0] + this._barPoints[i][0][0]) / 2 + plot._gridPadding.left - 0.5 * elem.outerWidth(true);
+ }
+ }
+
if (this.renderer.constructor == $.jqplot.BarRenderer) {
if (this.barDirection == "vertical") {
ell += this._barNudge;
@@ -305,8 +348,8 @@
}
elem.css('left', ell);
elem.css('top', elt);
- var elr = ell + $(elem).width();
- var elb = elt + $(elem).height();
+ var elr = ell + elem.width();
+ var elb = elt + elem.height();
var et = p.edgeTolerance;
var scl = $(sctx.canvas).position().left;
var sct = $(sctx.canvas).position().top;
@@ -314,9 +357,20 @@
var scb = sctx.canvas.height + sct;
// if label is outside of allowed area, remove it
if (ell - et < scl || elt - et < sct || elr + et > scr || elb + et > scb) {
- $(elem).detach();
+ elem.remove();
}
+
+ elem = null;
+ helem = null;
}
+
+ // finally, animate them if the series is animated
+ // if (this.renderer.animation && this.renderer.animation._supported && this.renderer.animation.show && plot._drawCount < 2) {
+ // var sel = '.jqplot-point-label.jqplot-series-'+this.index;
+ // $(sel).hide();
+ // $(sel).fadeIn(1000);
+ // }
+
}
};
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.pointLabels.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.pointLabels.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.pointLabels.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(c){c.jqplot.PointLabels=function(e){this.show=c.jqplot.config.enablePlugins;this.location="n";this.labelsFromSeries=false;this.seriesLabelIndex=null;this.labels=[];this._labels=[];this.stackedValue=false;this.ypadding=6;this.xpadding=6;this.escapeHTML=true;this.edgeTolerance=-5;this.formatter=c.jqplot.DefaultTickFormatter;this.formatString="";this.hideZeros=false;this._elems=[];c.extend(true,this,e)};var a=["nw","n","ne","e","se","s","sw","w"];var d={nw:0,n:1,ne:2,e:3,se:4,s:5,sw:6,w:7};var b=["se","s","sw","w","nw","n","ne","e"];c.jqplot.PointLabels.init=function(j,h,f,g,i){var e=c.extend(true,{},f,g);e.pointLabels=e.pointLabels||{};if(this.renderer.constructor===c.jqplot.BarRenderer&&this.barDirection==="horizontal"&&!e.pointLabels.location){e.pointLabels.location="e"}this.plugins.pointLabels=new c.jqplot.PointLabels(e.pointLabels);this.plugins.pointLabels.setLabels.call(this)};c.jqplot.PointLabels.prototype.setLabels=function(){var f=this.plugins.pointLabels;var h;if(f.seriesLabelIndex!=null){h=f.seriesLabelIndex}else{if(this.renderer.constructor===c.jqplot.BarRenderer&&this.barDirection==="horizontal"){h=(this._plotData[0].length<3)?0:this._plotData[0].length-1}else{h=(this._plotData.length===0)?0:this._plotData[0].length-1}}f._labels=[];if(f.labels.length===0||f.labelsFromSeries){if(f.stackedValue){if(this._plotData.length&&this._plotData[0].length){for(var e=0;e<this._plotData.length;e++){f._labels.push(this._plotData[e][h])}}}else{var g=this.data;if(this.renderer.constructor===c.jqplot.BarRenderer&&this.waterfall){g=this._data}if(g.length&&g[0].length){for(var e=0;e<g.length;e++){f._labels.push(g[e][h])}}g=null}}else{if(f.labels.length){f._labels=f.labels}}};c.jqplot.PointLabels.prototype.xOffset=function(f,e,g){e=e||this.location;g=g||this.xpadding;var h;switch(e){case"nw":h=-f.outerWidth(true)-this.xpadding;break;case"n":h=-f.outerWidth(true)/2;break;case"ne":h=this.xpadding;break;case"e":h=this.xpadding;break;case"se":h=this.xpadding;break;case"s":h=-f.outerWidth(true)/2;break;cas!
e"sw":h=-f.outerWidth(true)-this.xpadding;break;case"w":h=-f.outerWidth(true)-this.xpadding;break;default:h=-f.outerWidth(true)-this.xpadding;break}return h};c.jqplot.PointLabels.prototype.yOffset=function(f,e,g){e=e||this.location;g=g||this.xpadding;var h;switch(e){case"nw":h=-f.outerHeight(true)-this.ypadding;break;case"n":h=-f.outerHeight(true)-this.ypadding;break;case"ne":h=-f.outerHeight(true)-this.ypadding;break;case"e":h=-f.outerHeight(true)/2;break;case"se":h=this.ypadding;break;case"s":h=this.ypadding;break;case"sw":h=this.ypadding;break;case"w":h=-f.outerHeight(true)/2;break;default:h=-f.outerHeight(true)-this.ypadding;break}return h};c.jqplot.PointLabels.draw=function(x,j,v){var t=this.plugins.pointLabels;t.setLabels.call(this);for(var w=0;w<t._elems.length;w++){t._elems[w].emptyForce()}t._elems.splice(0,t._elems.length);if(t.show){var r="_"+this._stackAxis+"axis";if(!t.formatString){t.formatString=this[r]._ticks[0].formatString;t.formatter=this[r]._ticks[0].formatter}var E=this._plotData;var D=this._prevPlotData;var A=this._xaxis;var q=this._yaxis;var z,f;for(var w=0,u=t._labels.length;w<u;w++){var o=t._labels[w];if(t.hideZeros&&parseInt(t._labels[w],10)==0){o=""}if(o!=null){o=t.formatter(t.formatString,o)}f=document.createElement("div");t._elems[w]=c(f);z=t._elems[w];z.addClass("jqplot-point-label jqplot-series-"+this.index+" jqplot-point-"+w);z.css("position","absolute");z.insertAfter(x.canvas);if(t.escapeHTML){z.text(o)}else{z.html(o)}var g=t.location;if((this.fillToZero&&E[w][1]<0)||(this.fillToZero&&this._type==="bar"&&this.barDirection==="horizontal"&&E[w][0]<0)||(this.waterfall&&parseInt(o,10))<0){g=b[d[g]]}var n=A.u2p(E[w][0])+t.xOffset(z,g);var h=q.u2p(E[w][1])+t.yOffset(z,g);if(this._stack&&!t.stackedValue){if(this.barDirection==="vertical"){h=(this._barPoints[w][0][1]+this._barPoints[w][1][1])/2+v._gridPadding.top-0.5*z.outerHeight(true)}else{n=(this._barPoints[w][2][0]+this._barPoints[w][0][0])/2+v._gridPadding.left-0.5*z.outerWidth(true)}}if(this.renderer.constructor==c.jqplot.BarRendere!
r){if(this.barDirection=="vertical"){n+=this._barNudge}else{h-=this._barNudge}}z.css("left",n);z.css("top",h);var k=n+z.width();var s=h+z.height();var C=t.edgeTolerance;var e=c(x.canvas).position().left;var y=c(x.canvas).position().top;var B=x.canvas.width+e;var m=x.canvas.height+y;if(n-C<e||h-C<y||k+C>B||s+C>m){z.remove()}z=null;f=null}}};c.jqplot.postSeriesInitHooks.push(c.jqplot.PointLabels.init);c.jqplot.postDrawSeriesHooks.push(c.jqplot.PointLabels.draw)})(jQuery);
\ No newline at end of file
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.pyramidAxisRenderer.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.pyramidAxisRenderer.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.pyramidAxisRenderer.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,728 @@
+/**
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
+ * jqPlot is currently available for use in all personal or commercial projects
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
+ * choose the license that best suits your project and use it accordingly.
+ *
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
+ *
+ * If you are feeling kind and generous, consider supporting the project by
+ * making a donation at: http://www.jqplot.com/donate.php .
+ *
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
+ *
+ */
+(function($) {
+ $.jqplot.PyramidAxisRenderer = function() {
+ $.jqplot.LinearAxisRenderer.call(this);
+ };
+
+ $.jqplot.PyramidAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer();
+ $.jqplot.PyramidAxisRenderer.prototype.constructor = $.jqplot.PyramidAxisRenderer;
+
+ // called with scope of axis
+ $.jqplot.PyramidAxisRenderer.prototype.init = function(options){
+ // Group: Properties
+ //
+ // prop: position
+ // Position of axis. Values are: top, bottom , left, center, right.
+ // By default, x and x2 axes are bottom, y axis is center.
+ this.position = null;
+ // prop: drawBaseline
+ // True to draw the axis baseline.
+ this.drawBaseline = true;
+ // prop: baselineWidth
+ // width of the baseline in pixels.
+ this.baselineWidth = null;
+ // prop: baselineColor
+ // CSS color spec for the baseline.
+ this.baselineColor = null;
+ this.tickSpacingFactor = 25;
+ this._type = 'pyramid';
+ this._splitAxis = false;
+ this._splitLength = null;
+ this.category = false;
+ this._autoFormatString = '';
+ this._overrideFormatString = false;
+
+ $.extend(true, this, options);
+ this.renderer.options = options;
+
+ this.resetDataBounds = this.renderer.resetDataBounds;
+ this.resetDataBounds();
+
+ };
+
+ $.jqplot.PyramidAxisRenderer.prototype.resetDataBounds = function() {
+ // Go through all the series attached to this axis and find
+ // the min/max bounds for this axis.
+ var db = this._dataBounds;
+ db.min = null;
+ db.max = null;
+ var temp;
+ for (var i=0; i<this._series.length; i++) {
+ var s = this._series[i];
+ var d = s._plotData;
+
+ for (var j=0, l=d.length; j<l; j++) {
+ if (this.name.charAt(0) === 'x') {
+ temp = d[j][1];
+ if ((temp !== null && temp < db.min) || db.min === null) {
+ db.min = temp;
+ }
+ if ((temp !== null && temp > db.max) || db.max === null) {
+ db.max = temp;
+ }
+ }
+ else {
+ temp = d[j][0];
+ if ((temp !== null && temp < db.min) || db.min === null) {
+ db.min = temp;
+ }
+ if ((temp !== null && temp > db.max) || db.max === null) {
+ db.max = temp;
+ }
+ }
+ }
+ }
+ };
+
+ // called with scope of axis
+ $.jqplot.PyramidAxisRenderer.prototype.draw = function(ctx, plot) {
+ if (this.show) {
+ // populate the axis label and value properties.
+ // createTicks is a method on the renderer, but
+ // call it within the scope of the axis.
+ this.renderer.createTicks.call(this, plot);
+ // fill a div with axes labels in the right direction.
+ // Need to pregenerate each axis to get it's bounds and
+ // position it and the labels correctly on the plot.
+ var dim=0;
+ var temp;
+ // Added for theming.
+ if (this._elem) {
+ // Memory Leaks patch
+ //this._elem.empty();
+ this._elem.emptyForce();
+ this._elem = null;
+ }
+
+ this._elem = $(document.createElement('div'));
+ this._elem.addClass('jqplot-axis jqplot-'+this.name);
+ this._elem.css('position', 'absolute');
+
+
+ if (this.name == 'xaxis' || this.name == 'x2axis') {
+ this._elem.width(this._plotDimensions.width);
+ }
+ else {
+ this._elem.height(this._plotDimensions.height);
+ }
+
+ // create a _label object.
+ this.labelOptions.axis = this.name;
+ this._label = new this.labelRenderer(this.labelOptions);
+ if (this._label.show) {
+ var elem = this._label.draw(ctx, plot);
+ elem.appendTo(this._elem);
+ elem = null;
+ }
+
+ var t = this._ticks;
+ var tick;
+ for (var i=0; i<t.length; i++) {
+ tick = t[i];
+ if (tick.show && tick.showLabel && (!tick.isMinorTick)) {
+ this._elem.append(tick.draw(ctx, plot));
+ }
+ }
+ tick = null;
+ t = null;
+ }
+ return this._elem;
+ };
+
+ // Note, primes can be found on http://primes.utm.edu/
+ var _primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997];
+
+
+ var _primesHash = {};
+
+ for (var i =0, l = _primes.length; i < l; i++) {
+ _primesHash[_primes[i]] = _primes[i];
+ }
+
+ // called with scope of axis
+ $.jqplot.PyramidAxisRenderer.prototype.createTicks = function(plot) {
+ // we're are operating on an axis here
+ var userTicks = this.ticks;
+ // databounds were set on axis initialization.
+ var db = this._dataBounds;
+ var dim;
+ var interval;
+ var min;
+ var max;
+ var range;
+ var pos1;
+ var pos2;
+ var tt;
+ var i;
+ var l;
+ var s;
+ // get a copy of user's settings for min/max.
+ var userMin = this.min;
+ var userMax = this.max;
+ var ut;
+ var t;
+ var threshold;
+ var tdim;
+ var scalefact;
+ var ret;
+ var tumin;
+ var tumax;
+ var maxVisibleTicks;
+ var val;
+ var skip = null;
+ var temp;
+
+ // if we already have ticks, use them.
+ // ticks must be in order of increasing value.
+
+ if (userTicks.length) {
+ // ticks could be 1D or 2D array of [val, val, ,,,] or [[val, label], [val, label], ...] or mixed
+ for (i=0, l=userTicks.length; i<l; i++){
+ ut = userTicks[i];
+ t = new this.tickRenderer(this.tickOptions);
+ if ($.isArray(ut)) {
+ t.value = ut[0];
+ t.label = ut[1];
+ t.setTick(ut[0], this.name);
+ this._ticks.push(t);
+ }
+
+ else if ($.isPlainObject(ut)) {
+ $.extend(true, t, ut);
+ t.axis = this.name;
+ this._ticks.push(t);
+ }
+
+ else {
+ if (typeof ut === 'string') {
+ val = i + plot.defaultAxisStart;
+ }
+ else {
+ val = ut;
+ }
+ t.value = val;
+ t.label = ut;
+ t.axis = this.name;
+ this._ticks.push(t);
+ }
+ }
+ this.numberTicks = userTicks.length;
+ this.min = this._ticks[0].value;
+ this.max = this._ticks[this.numberTicks-1].value;
+ this.tickInterval = (this.max - this.min) / (this.numberTicks - 1);
+
+ // use user specified tickInterval if there is one
+ if (this._options.tickInterval) {
+ // hide every tick except for ticks on interval
+ var ti = this._options.tickInterval;
+ for (i=0; i<this.numberTicks; i++) {
+ if (i%ti !== 0) {
+ // this._ticks[i].show = false;
+ this._ticks[i].isMinorTick = true;
+ }
+ }
+ }
+
+ else {
+ // check if we have too many ticks
+ dim = (this.name.charAt(0) === 'x') ? this._plotDimensions.width : this._plotDimensions.height;
+ maxVisibleTicks = Math.round(2.0 + dim/this.tickSpacingFactor);
+
+ if (this.numberTicks > maxVisibleTicks) {
+ // check for number of ticks we can skip
+ temp = this.numberTicks - 1;
+ for (i=2; i<temp; i++) {
+ if (temp % i === 0 && temp/i < maxVisibleTicks) {
+ skip = i-1;
+ break;
+ }
+ }
+
+ if (skip !== null) {
+ var count = 1;
+ for (i=1, l=this._ticks.length; i<l; i++) {
+ if (count <= skip) {
+ this._ticks[i].show = false;
+ count += 1;
+ }
+ else {
+ count = 1;
+ }
+ }
+ }
+ }
+ }
+
+ // if category style, add minor ticks in between
+ temp = [];
+ if (this.category) {
+ // turn off gridline and mark on first tick
+ this._ticks[0].showGridline = false;
+ this._ticks[0].showMark = false;
+
+ for (i=this._ticks.length-1; i>0; i--) {
+ t = new this.tickRenderer(this.tickOptions);
+ t.value = this._ticks[i-1].value + this.tickInterval/2.0;
+ t.label = '';
+ t.showLabel = false;
+ t.axis = this.name;
+ this._ticks[i].showGridline = false;
+ this._ticks[i].showMark = false;
+ this._ticks.splice(i, 0, t);
+ // temp.push(t);
+ }
+
+ // merge in the new ticks
+ // for (i=1, l=temp.length; i<l; i++) {
+ // this._ticks.splice(i, 0, temp[i]);
+ // }
+
+ // now add a tick at beginning and end
+ t = new this.tickRenderer(this.tickOptions);
+ t.value = this._ticks[0].value - this.tickInterval/2.0;
+ t.label = '';
+ t.showLabel = false;
+ t.axis = this.name;
+ this._ticks.unshift(t);
+
+ t = new this.tickRenderer(this.tickOptions);
+ t.value = this._ticks[this._ticks.length-1].value + this.tickInterval/2.0;
+ t.label = '';
+ t.showLabel = false;
+ t.axis = this.name;
+ this._ticks.push(t);
+
+ this.tickInterval = this.tickInterval / 2.0;
+ this.numberTicks = this._ticks.length;
+ this.min = this._ticks[0].value;
+ this.max = this._ticks[this._ticks.length-1].value;
+ }
+ }
+
+ // we don't have any ticks yet, let's make some!
+ else {
+ if (this.name.charAt(0) === 'x') {
+ dim = this._plotDimensions.width;
+ // make sure x axis is symetric about 0.
+ var tempmax = Math.max(db.max, Math.abs(db.min));
+ var tempmin = Math.min(db.min, -tempmax);
+ // min = ((this.min != null) ? this.min : tempmin);
+ // max = ((this.max != null) ? this.max : tempmax);
+ min = tempmin;
+ max = tempmax;
+ range = max - min;
+
+ if (this.tickOptions == null || !this.tickOptions.formatString) {
+ this._overrideFormatString = true;
+ }
+
+ threshold = 30;
+ tdim = Math.max(dim, threshold+1);
+ scalefact = (tdim-threshold)/300.0;
+ ret = $.jqplot.LinearTickGenerator(min, max, scalefact);
+ // calculate a padded max and min, points should be less than these
+ // so that they aren't too close to the edges of the plot.
+ // User can adjust how much padding is allowed with pad, padMin and PadMax options.
+ tumin = min + range*(this.padMin - 1);
+ tumax = max - range*(this.padMax - 1);
+
+ if (min < tumin || max > tumax) {
+ tumin = min - range*(this.padMin - 1);
+ tumax = max + range*(this.padMax - 1);
+ ret = $.jqplot.LinearTickGenerator(tumin, tumax, scalefact);
+ }
+
+ this.min = ret[0];
+ this.max = ret[1];
+ this.numberTicks = ret[2];
+ this._autoFormatString = ret[3];
+ this.tickInterval = ret[4];
+ }
+ else {
+ dim = this._plotDimensions.height;
+
+ // ticks will be on whole integers like 1, 2, 3, ... or 1, 4, 7, ...
+ min = db.min;
+ max = db.max;
+ s = this._series[0];
+ this._ticks = [];
+
+ range = max - min;
+
+ // if range is a prime, will get only 2 ticks, expand range in that case.
+ if (_primesHash[range]) {
+ range += 1;
+ max += 1;
+ }
+
+ this.max = max;
+ this.min = min;
+
+ maxVisibleTicks = Math.round(2.0 + dim/this.tickSpacingFactor);
+
+ if (range + 1 <= maxVisibleTicks) {
+ this.numberTicks = range + 1;
+ this.tickInterval = 1.0;
+ }
+
+ else {
+ // figure out a round number of ticks to skip in every interval
+ // range / ti + 1 = nt
+ // ti = range / (nt - 1)
+ for (var i=maxVisibleTicks; i>1; i--) {
+ if (range/(i - 1) === Math.round(range/(i - 1))) {
+ this.numberTicks = i;
+ this.tickInterval = range/(i - 1);
+ break;
+ }
+
+ }
+ }
+ }
+
+ if (this._overrideFormatString && this._autoFormatString != '') {
+ this.tickOptions = this.tickOptions || {};
+ this.tickOptions.formatString = this._autoFormatString;
+ }
+
+ var labelval;
+ for (i=0; i<this.numberTicks; i++) {
+ this.tickOptions.axis = this.name;
+ labelval = this.min + this.tickInterval * i;
+ if (this.name.charAt(0) === 'x') {
+ labelval = Math.abs(labelval);
+ }
+ // this.tickOptions.label = String (labelval);
+ this.tickOptions.value = this.min + this.tickInterval * i;
+ t = new this.tickRenderer(this.tickOptions);
+
+ t.label = t.prefix + t.formatter(t.formatString, labelval);
+
+ this._ticks.push(t);
+ // for x axis, if y axis is in middle, add a symetrical 0 tick
+ if (this.name.charAt(0) === 'x' && plot.axes.yMidAxis.show && this.tickOptions.value === 0) {
+ this._splitAxis = true;
+ this._splitLength = plot.axes.yMidAxis.getWidth();
+ // t.value = -this.max/2000.0;
+ t = new this.tickRenderer(this.tickOptions);
+ this._ticks.push(t);
+ t.value = this.max/2000.0;
+ }
+ }
+ t = null;
+ }
+ };
+
+ // called with scope of axis
+ $.jqplot.PyramidAxisRenderer.prototype.set = function() {
+ var dim = 0;
+ var temp;
+ var w = 0;
+ var h = 0;
+ var i;
+ var t;
+ var tick;
+ var lshow = (this._label == null) ? false : this._label.show;
+ if (this.show) {
+ t = this._ticks;
+ l = t.length;
+ for (i=0; i<l; i++) {
+ tick = t[i];
+ if (!tick._breakTick && tick.show && tick.showLabel && !tick.isMinorTick) {
+ if (this.name.charAt(0) === 'x') {
+ temp = tick._elem.outerHeight(true);
+ }
+ else {
+ temp = tick._elem.outerWidth(true);
+ }
+ if (temp > dim) {
+ dim = temp;
+ }
+ }
+ }
+
+ if (this.name === 'yMidAxis') {
+ for (i=0; i<l; i++) {
+ tick = t[i];
+ if (tick._elem) {
+ temp = (dim - tick._elem.outerWidth(true))/2.0;
+ tick._elem.css('left', temp);
+ }
+ }
+ }
+ tick = null;
+ t = null;
+
+ if (lshow) {
+ w = this._label._elem.outerWidth(true);
+ h = this._label._elem.outerHeight(true);
+ }
+ if (this.name === 'xaxis') {
+ dim = dim + h;
+ this._elem.css({'height':dim+'px', left:'0px', bottom:'0px'});
+ }
+ else if (this.name === 'x2axis') {
+ dim = dim + h;
+ this._elem.css({'height':dim+'px', left:'0px', top:'0px'});
+ }
+ else if (this.name === 'yaxis') {
+ dim = dim + w;
+ this._elem.css({'width':dim+'px', left:'0px', top:'0px'});
+ if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) {
+ this._label._elem.css('width', w+'px');
+ }
+ }
+ else if (this.name === 'yMidAxis') {
+ // don't include width of label at all in width of axis?
+ // dim = (dim > w) ? dim : w;
+ var temp = dim/2.0 - w/2.0;
+ this._elem.css({'width':dim+'px', top:'0px'});
+ if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) {
+ this._label._elem.css({width: w, left: temp, top: 0});
+ }
+ }
+ else {
+ dim = dim + w;
+ this._elem.css({'width':dim+'px', right:'0px', top:'0px'});
+ if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) {
+ this._label._elem.css('width', w+'px');
+ }
+ }
+ }
+ };
+
+ $.jqplot.PyramidAxisRenderer.prototype.pack = function(pos, offsets) {
+ // Add defaults for repacking from resetTickValues function.
+ pos = pos || {};
+ offsets = offsets || this._offsets;
+
+ var ticks = this._ticks;
+ var max = this.max;
+ var min = this.min;
+ var offmax = offsets.max;
+ var offmin = offsets.min;
+ var lshow = (this._label == null) ? false : this._label.show;
+
+ for (var p in pos) {
+ this._elem.css(p, pos[p]);
+ }
+
+ this._offsets = offsets;
+ // pixellength will be + for x axes and - for y axes becasue pixels always measured from top left.
+ var pixellength = offmax - offmin;
+ var unitlength = max - min;
+ var sl = this._splitLength;
+
+ // point to unit and unit to point conversions references to Plot DOM element top left corner.
+ if (this._splitAxis) {
+ pixellength -= this._splitLength;
+
+ // don't know that this one is correct.
+ this.p2u = function(p){
+ return (p - offmin) * unitlength / pixellength + min;
+ };
+
+ this.u2p = function(u){
+ if (u <= 0) {
+ return (u - min) * pixellength / unitlength + offmin;
+ }
+ else {
+ return (u - min) * pixellength / unitlength + offmin + sl;
+ }
+ };
+
+ this.series_u2p = function(u){
+ if (u <= 0) {
+ return (u - min) * pixellength / unitlength;
+ }
+ else {
+ return (u - min) * pixellength / unitlength + sl;
+ }
+ };
+
+ // don't know that this one is correct.
+ this.series_p2u = function(p){
+ return p * unitlength / pixellength + min;
+ };
+ }
+ else {
+ this.p2u = function(p){
+ return (p - offmin) * unitlength / pixellength + min;
+ };
+
+ this.u2p = function(u){
+ return (u - min) * pixellength / unitlength + offmin;
+ };
+
+ if (this.name.charAt(0) === 'x'){
+ this.series_u2p = function(u){
+ return (u - min) * pixellength / unitlength;
+ };
+ this.series_p2u = function(p){
+ return p * unitlength / pixellength + min;
+ };
+ }
+
+ else {
+ this.series_u2p = function(u){
+ return (u - max) * pixellength / unitlength;
+ };
+ this.series_p2u = function(p){
+ return p * unitlength / pixellength + max;
+ };
+ }
+ }
+
+ if (this.show) {
+ if (this.name.charAt(0) === 'x') {
+ for (var i=0; i<ticks.length; i++) {
+ var t = ticks[i];
+ if (t.show && t.showLabel) {
+ var shim;
+
+ if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) {
+ // will need to adjust auto positioning based on which axis this is.
+ var temp = (this.name == 'xaxis') ? 1 : -1;
+ switch (t.labelPosition) {
+ case 'auto':
+ // position at end
+ if (temp * t.angle < 0) {
+ shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
+ }
+ // position at start
+ else {
+ shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2;
+ }
+ break;
+ case 'end':
+ shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
+ break;
+ case 'start':
+ shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2;
+ break;
+ case 'middle':
+ shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
+ break;
+ default:
+ shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
+ break;
+ }
+ }
+ else {
+ shim = -t.getWidth()/2;
+ }
+ var val = this.u2p(t.value) + shim + 'px';
+ t._elem.css('left', val);
+ t.pack();
+ }
+ }
+ if (lshow) {
+ var w = this._label._elem.outerWidth(true);
+ this._label._elem.css('left', offmin + pixellength/2 - w/2 + 'px');
+ if (this.name == 'xaxis') {
+ this._label._elem.css('bottom', '0px');
+ }
+ else {
+ this._label._elem.css('top', '0px');
+ }
+ this._label.pack();
+ }
+ }
+ else {
+ for (var i=0; i<ticks.length; i++) {
+ var t = ticks[i];
+ if (t.show && t.showLabel && !t.isMinorTick) {
+ var shim;
+ if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) {
+ // will need to adjust auto positioning based on which axis this is.
+ var temp = (this.name == 'yaxis') ? 1 : -1;
+ switch (t.labelPosition) {
+ case 'auto':
+ // position at end
+ case 'end':
+ if (temp * t.angle < 0) {
+ shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2;
+ }
+ else {
+ shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2;
+ }
+ break;
+ case 'start':
+ if (t.angle > 0) {
+ shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2;
+ }
+ else {
+ shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2;
+ }
+ break;
+ case 'middle':
+ // if (t.angle > 0) {
+ // shim = -t.getHeight()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
+ // }
+ // else {
+ // shim = -t.getHeight()/2 - t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2;
+ // }
+ shim = -t.getHeight()/2;
+ break;
+ default:
+ shim = -t.getHeight()/2;
+ break;
+ }
+ }
+ else {
+ shim = -t.getHeight()/2;
+ }
+
+ var val = this.u2p(t.value) + shim + 'px';
+ t._elem.css('top', val);
+ t.pack();
+ }
+ }
+ if (lshow) {
+ var h = this._label._elem.outerHeight(true);
+ if (this.name !== 'yMidAxis') {
+ this._label._elem.css('top', offmax - pixellength/2 - h/2 + 'px');
+ }
+ if (this.name == 'yaxis') {
+ this._label._elem.css('left', '0px');
+ }
+ else if (this.name !== 'yMidAxis') {
+ this._label._elem.css('right', '0px');
+ }
+ this._label.pack();
+ }
+ }
+ }
+
+ ticks = null;
+ };
+})(jQuery);
\ No newline at end of file
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.pyramidAxisRenderer.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.pyramidAxisRenderer.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.pyramidAxisRenderer.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(e){e.jqplot.PyramidAxisRenderer=function(){e.jqplot.LinearAxisRenderer.call(this)};e.jqplot.PyramidAxisRenderer.prototype=new e.jqplot.LinearAxisRenderer();e.jqplot.PyramidAxisRenderer.prototype.constructor=e.jqplot.PyramidAxisRenderer;e.jqplot.PyramidAxisRenderer.prototype.init=function(f){this.position=null;this.drawBaseline=true;this.baselineWidth=null;this.baselineColor=null;this.tickSpacingFactor=25;this._type="pyramid";this._splitAxis=false;this._splitLength=null;this.category=false;this._autoFormatString="";this._overrideFormatString=false;e.extend(true,this,f);this.renderer.options=f;this.resetDataBounds=this.renderer.resetDataBounds;this.resetDataBounds()};e.jqplot.PyramidAxisRenderer.prototype.resetDataBounds=function(){var h=this._dataBounds;h.min=null;h.max=null;var g;for(var m=0;m<this._series.length;m++){var n=this._series[m];var o=n._plotData;for(var k=0,f=o.length;k<f;k++){if(this.name.charAt(0)==="x"){g=o[k][1];if((g!==null&&g<h.min)||h.min===null){h.min=g}if((g!==null&&g>h.max)||h.max===null){h.max=g}}else{g=o[k][0];if((g!==null&&g<h.min)||h.min===null){h.min=g}if((g!==null&&g>h.max)||h.max===null){h.max=g}}}}};e.jqplot.PyramidAxisRenderer.prototype.draw=function(f,n){if(this.show){this.renderer.createTicks.call(this,n);var m=0;var g;if(this._elem){this._elem.emptyForce();this._elem=null}this._elem=e(document.createElement("div"));this._elem.addClass("jqplot-axis jqplot-"+this.name);this._elem.css("position","absolute");if(this.name=="xaxis"||this.name=="x2axis"){this._elem.width(this._plotDimensions.width)}else{this._elem.height(this._plotDimensions.height)}this.labelOptions.axis=this.name;this._label=new this.labelRenderer(this.labelOptions);if(this._label.show){var l=this._label.draw(f,n);l.appendTo(this._elem);l=null}var k=this._ticks;var j;for(var h=0;h<k.length;h++){j=k[h];if(j.show&&j.showLabel&&(!j.isMinorTick)){this._elem.append(j.draw(f,n))}}j=null;k=null}return this._elem};var b=[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,!
109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997];var d={};for(var c=0,a=b.length;c<a;c++){d[b[c]]=b[c]}e.jqplot.PyramidAxisRenderer.prototype.createTicks=function(D){var J=this.ticks;var M=this._dataBounds;var E;var K;var B;var G;var y;var n;var k;var h;var H;var C;var x;var L=this.min;var N=this.max;var q;var v;var m;var g;var j;var O;var A;var F;var r;var P;var z=null;var I;if(J.length){for(H=0,C=J.length;H<C;H++){q=J[H];v=new this.tickRenderer(this.tickOptions);if(e.isArray(q)){v.value=q[0];v.label=q[1];v.setTick(q[0],this.name);this._ticks.push(v)}else{if(e.isPlainObject(q)){e.extend(true,v,q);v.axis=this.name;this._ticks.push(v)}else{if(typeof q==="string"){P=H+D.defaultAxisStart}else{P=q}v.value=P;v.label=q;v.axis=this.name;this._ticks.push(v)}}}this.numberTicks=J.length;this.min=this._ticks[0].value;this.max=this._ticks[this.numberTicks-1].value;this.tickInterval=(this.max-this.min)/(this.numberTicks-1);if(this._options.tickInterval){var o=this._options.tickInterval;for(H=0;H<this.numberTicks;H++){if(H%o!==0){this._ticks[H].isMinorTick=true}}}else{E=(this.name.charAt(0)==="x")?this._plotDimensions.width:this._plotDimensions.height;r=Math.round(2+E/this.tickSpacingFactor);if(this.numberTicks>r){I=this.numberTicks-1;for(H=2;H<I;H++){if(I%H===0&&I/H<r){z=H-1;break}}if(z!==null){var p=1;for(H=1,C=this._ticks.length;H<C;H++){if(p<=z){this._ticks[H].show=false;p+=1}else{p=1}}}}}I=[];if(this.category){this._ticks[0].showGridline=false;this._ticks[0].showMark=false;for(H=this._ticks.length-1;H>0;H--){v=new this!
.tickRenderer(this.tickOptions);v.value=this._ticks[H-1].value+this.tickInterval/2;v.label="";v.showLabel=false;v.axis=this.name;this._ticks[H].showGridline=false;this._ticks[H].showMark=false;this._ticks.splice(H,0,v)}v=new this.tickRenderer(this.tickOptions);v.value=this._ticks[0].value-this.tickInterval/2;v.label="";v.showLabel=false;v.axis=this.name;this._ticks.unshift(v);v=new this.tickRenderer(this.tickOptions);v.value=this._ticks[this._ticks.length-1].value+this.tickInterval/2;v.label="";v.showLabel=false;v.axis=this.name;this._ticks.push(v);this.tickInterval=this.tickInterval/2;this.numberTicks=this._ticks.length;this.min=this._ticks[0].value;this.max=this._ticks[this._ticks.length-1].value}}else{if(this.name.charAt(0)==="x"){E=this._plotDimensions.width;var w=Math.max(M.max,Math.abs(M.min));var u=Math.min(M.min,-w);B=u;G=w;y=G-B;if(this.tickOptions==null||!this.tickOptions.formatString){this._overrideFormatString=true}m=30;g=Math.max(E,m+1);j=(g-m)/300;O=e.jqplot.LinearTickGenerator(B,G,j);A=B+y*(this.padMin-1);F=G-y*(this.padMax-1);if(B<A||G>F){A=B-y*(this.padMin-1);F=G+y*(this.padMax-1);O=e.jqplot.LinearTickGenerator(A,F,j)}this.min=O[0];this.max=O[1];this.numberTicks=O[2];this._autoFormatString=O[3];this.tickInterval=O[4]}else{E=this._plotDimensions.height;B=M.min;G=M.max;x=this._series[0];this._ticks=[];y=G-B;if(d[y]){y+=1;G+=1}this.max=G;this.min=B;r=Math.round(2+E/this.tickSpacingFactor);if(y+1<=r){this.numberTicks=y+1;this.tickInterval=1}else{for(var H=r;H>1;H--){if(y/(H-1)===Math.round(y/(H-1))){this.numberTicks=H;this.tickInterval=y/(H-1);break}}}}if(this._overrideFormatString&&this._autoFormatString!=""){this.tickOptions=this.tickOptions||{};this.tickOptions.formatString=this._autoFormatString}var f;for(H=0;H<this.numberTicks;H++){this.tickOptions.axis=this.name;f=this.min+this.tickInterval*H;if(this.name.charAt(0)==="x"){f=Math.abs(f)}this.tickOptions.value=this.min+this.tickInterval*H;v=new this.tickRenderer(this.tickOptions);v.label=v.prefix+v.formatter(v.formatString,f);this._ticks.push(v)!
;if(this..name.charAt(0)==="x"&&D.axes.yMidAxis.show&&this.tickOptions.value===0){this._splitAxis=true;this._splitLength=D.axes.yMidAxis.getWidth();v=new this.tickRenderer(this.tickOptions);this._ticks.push(v);v.value=this.max/2000}}v=null}};e.jqplot.PyramidAxisRenderer.prototype.set=function(){var o=0;var j;var g=0;var n=0;var m;var l;var k;var f=(this._label==null)?false:this._label.show;if(this.show){l=this._ticks;a=l.length;for(m=0;m<a;m++){k=l[m];if(!k._breakTick&&k.show&&k.showLabel&&!k.isMinorTick){if(this.name.charAt(0)==="x"){j=k._elem.outerHeight(true)}else{j=k._elem.outerWidth(true)}if(j>o){o=j}}}if(this.name==="yMidAxis"){for(m=0;m<a;m++){k=l[m];if(k._elem){j=(o-k._elem.outerWidth(true))/2;k._elem.css("left",j)}}}k=null;l=null;if(f){g=this._label._elem.outerWidth(true);n=this._label._elem.outerHeight(true)}if(this.name==="xaxis"){o=o+n;this._elem.css({height:o+"px",left:"0px",bottom:"0px"})}else{if(this.name==="x2axis"){o=o+n;this._elem.css({height:o+"px",left:"0px",top:"0px"})}else{if(this.name==="yaxis"){o=o+g;this._elem.css({width:o+"px",left:"0px",top:"0px"});if(f&&this._label.constructor==e.jqplot.AxisLabelRenderer){this._label._elem.css("width",g+"px")}}else{if(this.name==="yMidAxis"){var j=o/2-g/2;this._elem.css({width:o+"px",top:"0px"});if(f&&this._label.constructor==e.jqplot.AxisLabelRenderer){this._label._elem.css({width:g,left:j,top:0})}}else{o=o+g;this._elem.css({width:o+"px",right:"0px",top:"0px"});if(f&&this._label.constructor==e.jqplot.AxisLabelRenderer){this._label._elem.css("width",g+"px")}}}}}}};e.jqplot.PyramidAxisRenderer.prototype.pack=function(j,g){j=j||{};g=g||this._offsets;var B=this._ticks;var v=this.max;var u=this.min;var o=g.max;var m=g.min;var r=(this._label==null)?false:this._label.show;for(var s in j){this._elem.css(s,j[s])}this._offsets=g;var k=o-m;var l=v-u;var z=this._splitLength;if(this._splitAxis){k-=this._splitLength;this.p2u=function(h){return(h-m)*l/k+u};this.u2p=function(h){if(h<=0){return(h-u)*k/l+m}else{return(h-u)*k/l+m+z}};this.series_u2p=function(h){if(h<=0)!
{return(h-u)*k/l}else{return(h-u)*k/l+z}};this.series_p2u=function(h){return h*l/k+u}}else{this.p2u=function(h){return(h-m)*l/k+u};this.u2p=function(h){return(h-u)*k/l+m};if(this.name.charAt(0)==="x"){this.series_u2p=function(h){return(h-u)*k/l};this.series_p2u=function(h){return h*l/k+u}}else{this.series_u2p=function(h){return(h-v)*k/l};this.series_p2u=function(h){return h*l/k+v}}}if(this.show){if(this.name.charAt(0)==="x"){for(var x=0;x<B.length;x++){var q=B[x];if(q.show&&q.showLabel){var f;if(q.constructor==e.jqplot.CanvasAxisTickRenderer&&q.angle){var A=(this.name=="xaxis")?1:-1;switch(q.labelPosition){case"auto":if(A*q.angle<0){f=-q.getWidth()+q._textRenderer.height*Math.sin(-q._textRenderer.angle)/2}else{f=-q._textRenderer.height*Math.sin(q._textRenderer.angle)/2}break;case"end":f=-q.getWidth()+q._textRenderer.height*Math.sin(-q._textRenderer.angle)/2;break;case"start":f=-q._textRenderer.height*Math.sin(q._textRenderer.angle)/2;break;case"middle":f=-q.getWidth()/2+q._textRenderer.height*Math.sin(-q._textRenderer.angle)/2;break;default:f=-q.getWidth()/2+q._textRenderer.height*Math.sin(-q._textRenderer.angle)/2;break}}else{f=-q.getWidth()/2}var C=this.u2p(q.value)+f+"px";q._elem.css("left",C);q.pack()}}if(r){var n=this._label._elem.outerWidth(true);this._label._elem.css("left",m+k/2-n/2+"px");if(this.name=="xaxis"){this._label._elem.css("bottom","0px")}else{this._label._elem.css("top","0px")}this._label.pack()}}else{for(var x=0;x<B.length;x++){var q=B[x];if(q.show&&q.showLabel&&!q.isMinorTick){var f;if(q.constructor==e.jqplot.CanvasAxisTickRenderer&&q.angle){var A=(this.name=="yaxis")?1:-1;switch(q.labelPosition){case"auto":case"end":if(A*q.angle<0){f=-q._textRenderer.height*Math.cos(-q._textRenderer.angle)/2}else{f=-q.getHeight()+q._textRenderer.height*Math.cos(q._textRenderer.angle)/2}break;case"start":if(q.angle>0){f=-q._textRenderer.height*Math.cos(-q._textRenderer.angle)/2}else{f=-q.getHeight()+q._textRenderer.height*Math.cos(q._textRenderer.angle)/2}break;case"middle":f=-q.getHeight()/2;break;default:f!
=-q.getHeight()/2;break}}else{f=-q.getHeight()/2}var C=this.u2p(q.value)+f+"px";q._elem.css("top",C);q.pack()}}if(r){var y=this._label._elem.outerHeight(true);if(this.name!=="yMidAxis"){this._label._elem.css("top",o-k/2-y/2+"px")}if(this.name=="yaxis"){this._label._elem.css("left","0px")}else{if(this.name!=="yMidAxis"){this._label._elem.css("right","0px")}}this._label.pack()}}}B=null}})(jQuery);
\ No newline at end of file
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.pyramidGridRenderer.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.pyramidGridRenderer.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.pyramidGridRenderer.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,429 @@
+/**
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
+ * jqPlot is currently available for use in all personal or commercial projects
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
+ * choose the license that best suits your project and use it accordingly.
+ *
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
+ *
+ * If you are feeling kind and generous, consider supporting the project by
+ * making a donation at: http://www.jqplot.com/donate.php .
+ *
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
+ *
+ */
+(function($) {
+ // Class: $.jqplot.CanvasGridRenderer
+ // The default jqPlot grid renderer, creating a grid on a canvas element.
+ // The renderer has no additional options beyond the <Grid> class.
+ $.jqplot.PyramidGridRenderer = function(){
+ $.jqplot.CanvasGridRenderer.call(this);
+ };
+
+ $.jqplot.PyramidGridRenderer.prototype = new $.jqplot.CanvasGridRenderer();
+ $.jqplot.PyramidGridRenderer.prototype.constructor = $.jqplot.PyramidGridRenderer;
+
+ // called with context of Grid object
+ $.jqplot.CanvasGridRenderer.prototype.init = function(options) {
+ this._ctx;
+ this.plotBands = {
+ show: false,
+ color: 'rgb(230, 219, 179)',
+ axis: 'y',
+ start: null,
+ interval: 10
+ };
+ $.extend(true, this, options);
+ // set the shadow renderer options
+ var sopts = {lineJoin:'miter', lineCap:'round', fill:false, isarc:false, angle:this.shadowAngle, offset:this.shadowOffset, alpha:this.shadowAlpha, depth:this.shadowDepth, lineWidth:this.shadowWidth, closePath:false, strokeStyle:this.shadowColor};
+ this.renderer.shadowRenderer.init(sopts);
+ };
+
+ $.jqplot.PyramidGridRenderer.prototype.draw = function() {
+ this._ctx = this._elem.get(0).getContext("2d");
+ var ctx = this._ctx;
+ var axes = this._axes;
+ var xp = axes.xaxis.u2p;
+ var yp = axes.yMidAxis.u2p;
+ var xnudge = axes.xaxis.max/1000.0;
+ var xp0 = xp(0);
+ var xpn = xp(xnudge);
+ var ax = ['xaxis', 'yaxis', 'x2axis', 'y2axis','yMidAxis'];
+ // Add the grid onto the grid canvas. This is the bottom most layer.
+ ctx.save();
+ ctx.clearRect(0, 0, this._plotDimensions.width, this._plotDimensions.height);
+ ctx.fillStyle = this.backgroundColor || this.background;
+
+ ctx.fillRect(this._left, this._top, this._width, this._height);
+
+ if (this.plotBands.show) {
+ ctx.save();
+ var pb = this.plotBands;
+ ctx.fillStyle = pb.color;
+ var axis;
+ var x, y, w, h;
+ // find axis to work with
+ if (pb.axis.charAt(0) === 'x') {
+ if (axes.xaxis.show) {
+ axis = axes.xaxis;
+ }
+ }
+ else if (pb.axis.charAt(0) === 'y') {
+ if (axes.yaxis.show) {
+ axis = axes.yaxis;
+ }
+ else if (axes.y2axis.show) {
+ axis = axes.y2axis;
+ }
+ else if (axes.yMidAxis.show) {
+ axis = axes.yMidAxis;
+ }
+ }
+
+ if (axis !== undefined) {
+ // draw some rectangles
+ var start = pb.start;
+ if (start === null) {
+ start = axis.min;
+ }
+ for (var i = start; i < axis.max; i += 2 * pb.interval) {
+ if (axis.name.charAt(0) === 'y') {
+ x = this._left;
+ if ((i + pb.interval) < axis.max) {
+ y = axis.series_u2p(i + pb.interval) + this._top;
+ }
+ else {
+ y = axis.series_u2p(axis.max) + this._top;
+ }
+ w = this._right - this._left;
+ h = axis.series_u2p(start) - axis.series_u2p(start + pb.interval);
+ ctx.fillRect(x, y, w, h);
+ }
+ // else {
+ // y = 0;
+ // x = axis.series_u2p(i);
+ // h = this._height;
+ // w = axis.series_u2p(start + pb.interval) - axis.series_u2p(start);
+ // }
+
+ }
+ }
+ ctx.restore();
+ }
+
+ ctx.save();
+ ctx.lineJoin = 'miter';
+ ctx.lineCap = 'butt';
+ ctx.lineWidth = this.gridLineWidth;
+ ctx.strokeStyle = this.gridLineColor;
+ var b, e, s, m;
+ for (var i=5; i>0; i--) {
+ var name = ax[i-1];
+ var axis = axes[name];
+ var ticks = axis._ticks;
+ var numticks = ticks.length;
+ if (axis.show) {
+ if (axis.drawBaseline) {
+ var bopts = {};
+ if (axis.baselineWidth !== null) {
+ bopts.lineWidth = axis.baselineWidth;
+ }
+ if (axis.baselineColor !== null) {
+ bopts.strokeStyle = axis.baselineColor;
+ }
+ switch (name) {
+ case 'xaxis':
+ if (axes.yMidAxis.show) {
+ drawLine (this._left, this._bottom, xp0, this._bottom, bopts);
+ drawLine (xpn, this._bottom, this._right, this._bottom, bopts);
+ }
+ else {
+ drawLine (this._left, this._bottom, this._right, this._bottom, bopts);
+ }
+ break;
+ case 'yaxis':
+ drawLine (this._left, this._bottom, this._left, this._top, bopts);
+ break;
+ case 'yMidAxis':
+ drawLine(xp0, this._bottom, xp0, this._top, bopts);
+ drawLine(xpn, this._bottom, xpn, this._top, bopts);
+ break;
+ case 'x2axis':
+ if (axes.yMidAxis.show) {
+ drawLine (this._left, this._top, xp0, this._top, bopts);
+ drawLine (xpn, this._top, this._right, this._top, bopts);
+ }
+ else {
+ drawLine (this._left, this._bottom, this._right, this._bottom, bopts);
+ }
+ break;
+ case 'y2axis':
+ drawLine (this._right, this._bottom, this._right, this._top, bopts);
+ break;
+
+ }
+ }
+ for (var j=numticks; j>0; j--) {
+ var t = ticks[j-1];
+ if (t.show) {
+ var pos = Math.round(axis.u2p(t.value)) + 0.5;
+ switch (name) {
+ case 'xaxis':
+ // draw the grid line if we should
+ if (t.showGridline && this.drawGridlines && (!t.isMinorTick || axis.showMinorTicks)) {
+ drawLine(pos, this._top, pos, this._bottom);
+ }
+
+ // draw the mark
+ if (t.showMark && t.mark && (!t.isMinorTick || axis.showMinorTicks)) {
+ s = t.markSize;
+ m = t.mark;
+ var pos = Math.round(axis.u2p(t.value)) + 0.5;
+ switch (m) {
+ case 'outside':
+ b = this._bottom;
+ e = this._bottom+s;
+ break;
+ case 'inside':
+ b = this._bottom-s;
+ e = this._bottom;
+ break;
+ case 'cross':
+ b = this._bottom-s;
+ e = this._bottom+s;
+ break;
+ default:
+ b = this._bottom;
+ e = this._bottom+s;
+ break;
+ }
+ // draw the shadow
+ if (this.shadow) {
+ this.renderer.shadowRenderer.draw(ctx, [[pos,b],[pos,e]], {lineCap:'butt', lineWidth:this.gridLineWidth, offset:this.gridLineWidth*0.75, depth:2, fill:false, closePath:false});
+ }
+ // draw the line
+ drawLine(pos, b, pos, e);
+ }
+ break;
+ case 'yaxis':
+ // draw the grid line
+ if (t.showGridline && this.drawGridlines && (!t.isMinorTick || axis.showMinorTicks)) {
+ drawLine(this._right, pos, this._left, pos);
+ }
+
+ // draw the mark
+ if (t.showMark && t.mark && (!t.isMinorTick || axis.showMinorTicks)) {
+ s = t.markSize;
+ m = t.mark;
+ var pos = Math.round(axis.u2p(t.value)) + 0.5;
+ switch (m) {
+ case 'outside':
+ b = this._left-s;
+ e = this._left;
+ break;
+ case 'inside':
+ b = this._left;
+ e = this._left+s;
+ break;
+ case 'cross':
+ b = this._left-s;
+ e = this._left+s;
+ break;
+ default:
+ b = this._left-s;
+ e = this._left;
+ break;
+ }
+ // draw the shadow
+ if (this.shadow) {
+ this.renderer.shadowRenderer.draw(ctx, [[b, pos], [e, pos]], {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false});
+ }
+ drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor});
+ }
+ break;
+ case 'yMidAxis':
+ // draw the grid line
+ if (t.showGridline && this.drawGridlines && (!t.isMinorTick || axis.showMinorTicks)) {
+ drawLine(this._left, pos, xp0, pos);
+ drawLine(xpn, pos, this._right, pos);
+ }
+ // draw the mark
+ if (t.showMark && t.mark && (!t.isMinorTick || axis.showMinorTicks)) {
+ s = t.markSize;
+ m = t.mark;
+ var pos = Math.round(axis.u2p(t.value)) + 0.5;
+
+ b = xp0;
+ e = xp0 + s;
+ // draw the shadow
+ if (this.shadow) {
+ this.renderer.shadowRenderer.draw(ctx, [[b, pos], [e, pos]], {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false});
+ }
+ drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor});
+
+ b = xpn - s;
+ e = xpn;
+ // draw the shadow
+ if (this.shadow) {
+ this.renderer.shadowRenderer.draw(ctx, [[b, pos], [e, pos]], {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false});
+ }
+ drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor});
+ }
+ break;
+ case 'x2axis':
+ // draw the grid line
+ if (t.showGridline && this.drawGridlines && (!t.isMinorTick || axis.showMinorTicks)) {
+ drawLine(pos, this._bottom, pos, this._top);
+ }
+
+ // draw the mark
+ if (t.showMark && t.mark && (!t.isMinorTick || axis.showMinorTicks)) {
+ s = t.markSize;
+ m = t.mark;
+ var pos = Math.round(axis.u2p(t.value)) + 0.5;
+ switch (m) {
+ case 'outside':
+ b = this._top-s;
+ e = this._top;
+ break;
+ case 'inside':
+ b = this._top;
+ e = this._top+s;
+ break;
+ case 'cross':
+ b = this._top-s;
+ e = this._top+s;
+ break;
+ default:
+ b = this._top-s;
+ e = this._top;
+ break;
+ }
+ // draw the shadow
+ if (this.shadow) {
+ this.renderer.shadowRenderer.draw(ctx, [[pos,b],[pos,e]], {lineCap:'butt', lineWidth:this.gridLineWidth, offset:this.gridLineWidth*0.75, depth:2, fill:false, closePath:false});
+ }
+ drawLine(pos, b, pos, e);
+ }
+ break;
+ case 'y2axis':
+ // draw the grid line
+ if (t.showGridline && this.drawGridlines && (!t.isMinorTick || axis.showMinorTicks)) {
+ drawLine(this._left, pos, this._right, pos);
+ }
+
+ // draw the mark
+ if (t.showMark && t.mark && (!t.isMinorTick || axis.showMinorTicks)) {
+ s = t.markSize;
+ m = t.mark;
+ var pos = Math.round(axis.u2p(t.value)) + 0.5;
+ switch (m) {
+ case 'outside':
+ b = this._right;
+ e = this._right+s;
+ break;
+ case 'inside':
+ b = this._right-s;
+ e = this._right;
+ break;
+ case 'cross':
+ b = this._right-s;
+ e = this._right+s;
+ break;
+ default:
+ b = this._right;
+ e = this._right+s;
+ break;
+ }
+ // draw the shadow
+ if (this.shadow) {
+ this.renderer.shadowRenderer.draw(ctx, [[b, pos], [e, pos]], {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false});
+ }
+ drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor});
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ t = null;
+ }
+ axis = null;
+ ticks = null;
+ }
+
+ ctx.restore();
+
+ function drawLine(bx, by, ex, ey, opts) {
+ ctx.save();
+ opts = opts || {};
+ if (opts.lineWidth == null || opts.lineWidth != 0){
+ $.extend(true, ctx, opts);
+ ctx.beginPath();
+ ctx.moveTo(bx, by);
+ ctx.lineTo(ex, ey);
+ ctx.stroke();
+ }
+ ctx.restore();
+ }
+
+ if (this.shadow) {
+ if (axes.yMidAxis.show) {
+ var points = [[this._left, this._bottom], [xp0, this._bottom]];
+ this.renderer.shadowRenderer.draw(ctx, points);
+ var points = [[xpn, this._bottom], [this._right, this._bottom], [this._right, this._top]];
+ this.renderer.shadowRenderer.draw(ctx, points);
+ var points = [[xp0, this._bottom], [xp0, this._top]];
+ this.renderer.shadowRenderer.draw(ctx, points);
+ }
+ else {
+ var points = [[this._left, this._bottom], [this._right, this._bottom], [this._right, this._top]];
+ this.renderer.shadowRenderer.draw(ctx, points);
+ }
+ }
+ // Now draw border around grid. Use axis border definitions. start at
+ // upper left and go clockwise.
+ if (this.borderWidth != 0 && this.drawBorder) {
+ if (axes.yMidAxis.show) {
+ drawLine (this._left, this._top, xp0, this._top, {lineCap:'round', strokeStyle:axes.x2axis.borderColor, lineWidth:axes.x2axis.borderWidth});
+ drawLine (xpn, this._top, this._right, this._top, {lineCap:'round', strokeStyle:axes.x2axis.borderColor, lineWidth:axes.x2axis.borderWidth});
+ drawLine (this._right, this._top, this._right, this._bottom, {lineCap:'round', strokeStyle:axes.y2axis.borderColor, lineWidth:axes.y2axis.borderWidth});
+ drawLine (this._right, this._bottom, xpn, this._bottom, {lineCap:'round', strokeStyle:axes.xaxis.borderColor, lineWidth:axes.xaxis.borderWidth});
+ drawLine (xp0, this._bottom, this._left, this._bottom, {lineCap:'round', strokeStyle:axes.xaxis.borderColor, lineWidth:axes.xaxis.borderWidth});
+ drawLine (this._left, this._bottom, this._left, this._top, {lineCap:'round', strokeStyle:axes.yaxis.borderColor, lineWidth:axes.yaxis.borderWidth});
+ drawLine (xp0, this._bottom, xp0, this._top, {lineCap:'round', strokeStyle:axes.yaxis.borderColor, lineWidth:axes.yaxis.borderWidth});
+ drawLine (xpn, this._bottom, xpn, this._top, {lineCap:'round', strokeStyle:axes.yaxis.borderColor, lineWidth:axes.yaxis.borderWidth});
+ }
+ else {
+ drawLine (this._left, this._top, this._right, this._top, {lineCap:'round', strokeStyle:axes.x2axis.borderColor, lineWidth:axes.x2axis.borderWidth});
+ drawLine (this._right, this._top, this._right, this._bottom, {lineCap:'round', strokeStyle:axes.y2axis.borderColor, lineWidth:axes.y2axis.borderWidth});
+ drawLine (this._right, this._bottom, this._left, this._bottom, {lineCap:'round', strokeStyle:axes.xaxis.borderColor, lineWidth:axes.xaxis.borderWidth});
+ drawLine (this._left, this._bottom, this._left, this._top, {lineCap:'round', strokeStyle:axes.yaxis.borderColor, lineWidth:axes.yaxis.borderWidth});
+ }
+ }
+ // ctx.lineWidth = this.borderWidth;
+ // ctx.strokeStyle = this.borderColor;
+ // ctx.strokeRect(this._left, this._top, this._width, this._height);
+
+ ctx.restore();
+ ctx = null;
+ axes = null;
+ };
+})(jQuery);
\ No newline at end of file
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.pyramidGridRenderer.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.pyramidGridRenderer.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.pyramidGridRenderer.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(a){a.jqplot.PyramidGridRenderer=function(){a.jqplot.CanvasGridRenderer.call(this)};a.jqplot.PyramidGridRenderer.prototype=new a.jqplot.CanvasGridRenderer();a.jqplot.PyramidGridRenderer.prototype.constructor=a.jqplot.PyramidGridRenderer;a.jqplot.CanvasGridRenderer.prototype.init=function(c){this._ctx;this.plotBands={show:false,color:"rgb(230, 219, 179)",axis:"y",start:null,interval:10};a.extend(true,this,c);var b={lineJoin:"miter",lineCap:"round",fill:false,isarc:false,angle:this.shadowAngle,offset:this.shadowOffset,alpha:this.shadowAlpha,depth:this.shadowDepth,lineWidth:this.shadowWidth,closePath:false,strokeStyle:this.shadowColor};this.renderer.shadowRenderer.init(b)};a.jqplot.PyramidGridRenderer.prototype.draw=function(){this._ctx=this._elem.get(0).getContext("2d");var D=this._ctx;var G=this._axes;var q=G.xaxis.u2p;var J=G.yMidAxis.u2p;var l=G.xaxis.max/1000;var u=q(0);var f=q(l);var r=["xaxis","yaxis","x2axis","y2axis","yMidAxis"];D.save();D.clearRect(0,0,this._plotDimensions.width,this._plotDimensions.height);D.fillStyle=this.backgroundColor||this.background;D.fillRect(this._left,this._top,this._width,this._height);if(this.plotBands.show){D.save();var c=this.plotBands;D.fillStyle=c.color;var d;var o,n,p,I;if(c.axis.charAt(0)==="x"){if(G.xaxis.show){d=G.xaxis}}else{if(c.axis.charAt(0)==="y"){if(G.yaxis.show){d=G.yaxis}else{if(G.y2axis.show){d=G.y2axis}else{if(G.yMidAxis.show){d=G.yMidAxis}}}}}if(d!==undefined){var g=c.start;if(g===null){g=d.min}for(var H=g;H<d.max;H+=2*c.interval){if(d.name.charAt(0)==="y"){o=this._left;if((H+c.interval)<d.max){n=d.series_u2p(H+c.interval)+this._top}else{n=d.series_u2p(d.max)+this._top}p=this._right-this._left;I=d.series_u2p(g)-d.series_u2p(g+c.interval);D.fillRect(o,n,p,I)}}}D.restore()}D.save();D.lineJoin="miter";D.lineCap="butt";D.lineWidth=this.gridLineWidth;D.strokeStyle=this.gridLineColor;var L,K,A,C;for(var H=5;H>0;H--){var O=r[H-1];var d=G[O];var M=d._ticks;var B=M.length;if(d.show){if(d.drawBaseline){var N={};if(d.baselineWidth!==null){N.lineWid!
th=d.baselineWidth}if(d.baselineColor!==null){N.strokeStyle=d.baselineColor}switch(O){case"xaxis":if(G.yMidAxis.show){z(this._left,this._bottom,u,this._bottom,N);z(f,this._bottom,this._right,this._bottom,N)}else{z(this._left,this._bottom,this._right,this._bottom,N)}break;case"yaxis":z(this._left,this._bottom,this._left,this._top,N);break;case"yMidAxis":z(u,this._bottom,u,this._top,N);z(f,this._bottom,f,this._top,N);break;case"x2axis":if(G.yMidAxis.show){z(this._left,this._top,u,this._top,N);z(f,this._top,this._right,this._top,N)}else{z(this._left,this._bottom,this._right,this._bottom,N)}break;case"y2axis":z(this._right,this._bottom,this._right,this._top,N);break}}for(var E=B;E>0;E--){var v=M[E-1];if(v.show){var k=Math.round(d.u2p(v.value))+0.5;switch(O){case"xaxis":if(v.showGridline&&this.drawGridlines&&(!v.isMinorTick||d.showMinorTicks)){z(k,this._top,k,this._bottom)}if(v.showMark&&v.mark&&(!v.isMinorTick||d.showMinorTicks)){A=v.markSize;C=v.mark;var k=Math.round(d.u2p(v.value))+0.5;switch(C){case"outside":L=this._bottom;K=this._bottom+A;break;case"inside":L=this._bottom-A;K=this._bottom;break;case"cross":L=this._bottom-A;K=this._bottom+A;break;default:L=this._bottom;K=this._bottom+A;break}if(this.shadow){this.renderer.shadowRenderer.draw(D,[[k,L],[k,K]],{lineCap:"butt",lineWidth:this.gridLineWidth,offset:this.gridLineWidth*0.75,depth:2,fill:false,closePath:false})}z(k,L,k,K)}break;case"yaxis":if(v.showGridline&&this.drawGridlines&&(!v.isMinorTick||d.showMinorTicks)){z(this._right,k,this._left,k)}if(v.showMark&&v.mark&&(!v.isMinorTick||d.showMinorTicks)){A=v.markSize;C=v.mark;var k=Math.round(d.u2p(v.value))+0.5;switch(C){case"outside":L=this._left-A;K=this._left;break;case"inside":L=this._left;K=this._left+A;break;case"cross":L=this._left-A;K=this._left+A;break;default:L=this._left-A;K=this._left;break}if(this.shadow){this.renderer.shadowRenderer.draw(D,[[L,k],[K,k]],{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}z(L,k,K,k,{strokeStyle:d.borderColor!
})}break;case"yMidAxis":if(v.showGridline&&this.drawGridlines&&(!v.isMinorTick||d.showMinorTicks)){z(this._left,k,u,k);z(f,k,this._right,k)}if(v.showMark&&v.mark&&(!v.isMinorTick||d.showMinorTicks)){A=v.markSize;C=v.mark;var k=Math.round(d.u2p(v.value))+0.5;L=u;K=u+A;if(this.shadow){this.renderer.shadowRenderer.draw(D,[[L,k],[K,k]],{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}z(L,k,K,k,{strokeStyle:d.borderColor});L=f-A;K=f;if(this.shadow){this.renderer.shadowRenderer.draw(D,[[L,k],[K,k]],{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}z(L,k,K,k,{strokeStyle:d.borderColor})}break;case"x2axis":if(v.showGridline&&this.drawGridlines&&(!v.isMinorTick||d.showMinorTicks)){z(k,this._bottom,k,this._top)}if(v.showMark&&v.mark&&(!v.isMinorTick||d.showMinorTicks)){A=v.markSize;C=v.mark;var k=Math.round(d.u2p(v.value))+0.5;switch(C){case"outside":L=this._top-A;K=this._top;break;case"inside":L=this._top;K=this._top+A;break;case"cross":L=this._top-A;K=this._top+A;break;default:L=this._top-A;K=this._top;break}if(this.shadow){this.renderer.shadowRenderer.draw(D,[[k,L],[k,K]],{lineCap:"butt",lineWidth:this.gridLineWidth,offset:this.gridLineWidth*0.75,depth:2,fill:false,closePath:false})}z(k,L,k,K)}break;case"y2axis":if(v.showGridline&&this.drawGridlines&&(!v.isMinorTick||d.showMinorTicks)){z(this._left,k,this._right,k)}if(v.showMark&&v.mark&&(!v.isMinorTick||d.showMinorTicks)){A=v.markSize;C=v.mark;var k=Math.round(d.u2p(v.value))+0.5;switch(C){case"outside":L=this._right;K=this._right+A;break;case"inside":L=this._right-A;K=this._right;break;case"cross":L=this._right-A;K=this._right+A;break;default:L=this._right;K=this._right+A;break}if(this.shadow){this.renderer.shadowRenderer.draw(D,[[L,k],[K,k]],{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}z(L,k,K,k,{strokeStyle:d.borderColor})}break;default:break}}}v=null}d=null;M=null}D.restore();function!
z(j,i,e,b,h){D.save();h=h||{};if(h.lineWidth==null||h.lineWidth!=0){a.extend(true,D,h);D.beginPath();D.moveTo(j,i);D.lineTo(e,b);D.stroke()}D.restore()}if(this.shadow){if(G.yMidAxis.show){var F=[[this._left,this._bottom],[u,this._bottom]];this.renderer.shadowRenderer.draw(D,F);var F=[[f,this._bottom],[this._right,this._bottom],[this._right,this._top]];this.renderer.shadowRenderer.draw(D,F);var F=[[u,this._bottom],[u,this._top]];this.renderer.shadowRenderer.draw(D,F)}else{var F=[[this._left,this._bottom],[this._right,this._bottom],[this._right,this._top]];this.renderer.shadowRenderer.draw(D,F)}}if(this.borderWidth!=0&&this.drawBorder){if(G.yMidAxis.show){z(this._left,this._top,u,this._top,{lineCap:"round",strokeStyle:G.x2axis.borderColor,lineWidth:G.x2axis.borderWidth});z(f,this._top,this._right,this._top,{lineCap:"round",strokeStyle:G.x2axis.borderColor,lineWidth:G.x2axis.borderWidth});z(this._right,this._top,this._right,this._bottom,{lineCap:"round",strokeStyle:G.y2axis.borderColor,lineWidth:G.y2axis.borderWidth});z(this._right,this._bottom,f,this._bottom,{lineCap:"round",strokeStyle:G.xaxis.borderColor,lineWidth:G.xaxis.borderWidth});z(u,this._bottom,this._left,this._bottom,{lineCap:"round",strokeStyle:G.xaxis.borderColor,lineWidth:G.xaxis.borderWidth});z(this._left,this._bottom,this._left,this._top,{lineCap:"round",strokeStyle:G.yaxis.borderColor,lineWidth:G.yaxis.borderWidth});z(u,this._bottom,u,this._top,{lineCap:"round",strokeStyle:G.yaxis.borderColor,lineWidth:G.yaxis.borderWidth});z(f,this._bottom,f,this._top,{lineCap:"round",strokeStyle:G.yaxis.borderColor,lineWidth:G.yaxis.borderWidth})}else{z(this._left,this._top,this._right,this._top,{lineCap:"round",strokeStyle:G.x2axis.borderColor,lineWidth:G.x2axis.borderWidth});z(this._right,this._top,this._right,this._bottom,{lineCap:"round",strokeStyle:G.y2axis.borderColor,lineWidth:G.y2axis.borderWidth});z(this._right,this._bottom,this._left,this._bottom,{lineCap:"round",strokeStyle:G.xaxis.borderColor,lineWidth:G.xaxis.borderWidth});z(this._left,this._bottom!
,this._left,this._top,{lineCap:"round",strokeStyle:G.yaxis.borderColor,lineWidth:G.yaxis.borderWidth})}}D.restore();D=null;G=null}})(jQuery);
\ No newline at end of file
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.pyramidRenderer.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.pyramidRenderer.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.pyramidRenderer.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,514 @@
+/**
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
+ * jqPlot is currently available for use in all personal or commercial projects
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
+ * choose the license that best suits your project and use it accordingly.
+ *
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
+ *
+ * If you are feeling kind and generous, consider supporting the project by
+ * making a donation at: http://www.jqplot.com/donate.php .
+ *
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
+ *
+ */
+(function($) {
+
+ // Need to ensure pyramid axis and grid renderers are loaded.
+ // You should load these with script tags in the html head, that is more efficient
+ // as the browser will cache the request.
+ // Note, have to block with synchronous request in order to execute bar renderer code.
+ if ($.jqplot.PyramidAxisRenderer === undefined) {
+ $.ajax({
+ url: $.jqplot.pluginLocation + 'jqplot.pyramidAxisRenderer.js',
+ dataType: "script",
+ async: false
+ });
+ }
+
+ if ($.jqplot.PyramidGridRenderer === undefined) {
+ $.ajax({
+ url: $.jqplot.pluginLocation + 'jqplot.pyramidGridRenderer.js',
+ dataType: "script",
+ async: false
+ });
+ }
+
+ $.jqplot.PyramidRenderer = function(){
+ $.jqplot.LineRenderer.call(this);
+ };
+
+ $.jqplot.PyramidRenderer.prototype = new $.jqplot.LineRenderer();
+ $.jqplot.PyramidRenderer.prototype.constructor = $.jqplot.PyramidRenderer;
+
+ // called with scope of a series
+ $.jqplot.PyramidRenderer.prototype.init = function(options, plot) {
+ options = options || {};
+ this._type = 'pyramid';
+ // Group: Properties
+ //
+ // prop: barPadding
+ this.barPadding = 10;
+ this.barWidth = null;
+ // prop: fill
+ // True to fill the bars.
+ this.fill = true;
+ // prop: highlightMouseOver
+ // True to highlight slice when moused over.
+ // This must be false to enable highlightMouseDown to highlight when clicking on a slice.
+ this.highlightMouseOver = true;
+ // prop: highlightMouseDown
+ // True to highlight when a mouse button is pressed over a slice.
+ // This will be disabled if highlightMouseOver is true.
+ this.highlightMouseDown = false;
+ // prop: highlightColors
+ // an array of colors to use when highlighting a slice.
+ this.highlightColors = [];
+ // prop highlightThreshold
+ // Expand the highlightable region in the x direction.
+ // E.g. a value of 3 will highlight a bar when the mouse is
+ // within 3 pixels of the bar in the x direction.
+ this.highlightThreshold = 2;
+ // prop: synchronizeHighlight
+ // Index of another series to highlight when this series is highlighted.
+ // null or false to not synchronize.
+ this.synchronizeHighlight = false;
+ // prop: offsetBars
+ // False will center bars on their y value.
+ // True will push bars up by 1/2 bar width to fill between their y values.
+ // If true, there needs to be 1 more tick than there are bars.
+ this.offsetBars = false;
+
+ // if user has passed in highlightMouseDown option and not set highlightMouseOver, disable highlightMouseOver
+ if (options.highlightMouseDown && options.highlightMouseOver == null) {
+ options.highlightMouseOver = false;
+ }
+
+ this.side = 'right';
+
+ $.extend(true, this, options);
+
+ // if (this.fill === false) {
+ // this.shadow = false;
+ // }
+
+ if (this.side === 'left') {
+ this._highlightThreshold = [[-this.highlightThreshold, 0], [-this.highlightThreshold, 0], [0,0], [0,0]];
+ }
+
+ else {
+ this._highlightThreshold = [[0,0], [0,0], [this.highlightThreshold, 0], [this.highlightThreshold, 0]];
+ }
+
+ this.renderer.options = options;
+ // index of the currenty highlighted point, if any
+ this._highlightedPoint = null;
+ // Array of actual data colors used for each data point.
+ this._dataColors = [];
+ this._barPoints = [];
+ this.fillAxis = 'y';
+ this._primaryAxis = '_yaxis';
+ this._xnudge = 0;
+
+ // set the shape renderer options
+ var opts = {lineJoin:'miter', lineCap:'butt', fill:this.fill, fillRect:this.fill, isarc:false, strokeStyle:this.color, fillStyle:this.color, closePath:this.fill, lineWidth: this.lineWidth};
+ this.renderer.shapeRenderer.init(opts);
+ // set the shadow renderer options
+ var shadow_offset = options.shadowOffset;
+ // set the shadow renderer options
+ if (shadow_offset == null) {
+ // scale the shadowOffset to the width of the line.
+ if (this.lineWidth > 2.5) {
+ shadow_offset = 1.25 * (1 + (Math.atan((this.lineWidth/2.5))/0.785398163 - 1)*0.6);
+ // var shadow_offset = this.shadowOffset;
+ }
+ // for skinny lines, don't make such a big shadow.
+ else {
+ shadow_offset = 1.25 * Math.atan((this.lineWidth/2.5))/0.785398163;
+ }
+ }
+ var sopts = {lineJoin:'miter', lineCap:'butt', fill:this.fill, fillRect:this.fill, isarc:false, angle:this.shadowAngle, offset:shadow_offset, alpha:this.shadowAlpha, depth:this.shadowDepth, closePath:this.fill, lineWidth: this.lineWidth};
+ this.renderer.shadowRenderer.init(sopts);
+
+ plot.postDrawHooks.addOnce(postPlotDraw);
+ plot.eventListenerHooks.addOnce('jqplotMouseMove', handleMove);
+
+ // if this is the left side of pyramid, set y values to negative.
+ if (this.side === 'left') {
+ for (var i=0, l=this.data.length; i<l; i++) {
+ this.data[i][1] = -Math.abs(this.data[i][1]);
+ }
+ }
+ };
+
+ // setGridData
+ // converts the user data values to grid coordinates and stores them
+ // in the gridData array.
+ // Called with scope of a series.
+ $.jqplot.PyramidRenderer.prototype.setGridData = function(plot) {
+ // recalculate the grid data
+ var xp = this._xaxis.series_u2p;
+ var yp = this._yaxis.series_u2p;
+ var data = this._plotData;
+ var pdata = this._prevPlotData;
+ this.gridData = [];
+ this._prevGridData = [];
+ var l = data.length;
+ var adjust = false;
+ var i;
+
+ // if any data values are < 0, consider this a negative series
+ for (i = 0; i < l; i++) {
+ if (data[i][1] < 0) {
+ this.side = 'left';
+ }
+ }
+
+ if (this._yaxis.name === 'yMidAxis' && this.side === 'right') {
+ this._xnudge = this._xaxis.max/2000.0;
+ adjust = true;
+ }
+
+ for (i = 0; i < l; i++) {
+ // if not a line series or if no nulls in data, push the converted point onto the array.
+ if (data[i][0] != null && data[i][1] != null) {
+ this.gridData.push([xp(data[i][1]), yp(data[i][0])]);
+ }
+ // else if there is a null, preserve it.
+ else if (data[i][0] == null) {
+ this.gridData.push([xp(data[i][1]), null]);
+ }
+ else if (data[i][1] == null) {
+ this.gridData.push(null, [yp(data[i][0])]);
+ }
+ // finally, adjust x grid data if have to
+ if (data[i][1] === 0 && adjust) {
+ this.gridData[i][0] = xp(this._xnudge);
+ }
+ }
+ };
+
+ // makeGridData
+ // converts any arbitrary data values to grid coordinates and
+ // returns them. This method exists so that plugins can use a series'
+ // linerenderer to generate grid data points without overwriting the
+ // grid data associated with that series.
+ // Called with scope of a series.
+ $.jqplot.PyramidRenderer.prototype.makeGridData = function(data, plot) {
+ // recalculate the grid data
+ var xp = this._xaxis.series_u2p;
+ var yp = this._yaxis.series_u2p;
+ var gd = [];
+ var l = data.length;
+ var adjust = false;
+ var i;
+
+ // if any data values are < 0, consider this a negative series
+ for (i = 0; i < l; i++) {
+ if (data[i][1] < 0) {
+ this.side = 'left';
+ }
+ }
+
+ if (this._yaxis.name === 'yMidAxis' && this.side === 'right') {
+ this._xnudge = this._xaxis.max/2000.0;
+ adjust = true;
+ }
+
+ for (i = 0; i < l; i++) {
+ // if not a line series or if no nulls in data, push the converted point onto the array.
+ if (data[i][0] != null && data[i][1] != null) {
+ gd.push([xp(data[i][1]), yp(data[i][0])]);
+ }
+ // else if there is a null, preserve it.
+ else if (data[i][0] == null) {
+ gd.push([xp(data[i][1]), null]);
+ }
+ else if (data[i][1] == null) {
+ gd.push([null, yp(data[i][0])]);
+ }
+ // finally, adjust x grid data if have to
+ if (data[i][1] === 0 && adjust) {
+ gd[i][0] = xp(this._xnudge);
+ }
+ }
+
+ return gd;
+ };
+
+ $.jqplot.PyramidRenderer.prototype.setBarWidth = function() {
+ // need to know how many data values we have on the approprate axis and figure it out.
+ var i;
+ var nvals = 0;
+ var nseries = 0;
+ var paxis = this[this._primaryAxis];
+ var s, series, pos;
+ nvals = paxis.max - paxis.min;
+ var nticks = paxis.numberTicks;
+ var nbins = (nticks-1)/2;
+ // so, now we have total number of axis values.
+ var temp = (this.barPadding === 0) ? 1.0 : 0;
+ if (paxis.name == 'xaxis' || paxis.name == 'x2axis') {
+ this.barWidth = (paxis._offsets.max - paxis._offsets.min) / nvals - this.barPadding + temp;
+ }
+ else {
+ if (this.fill) {
+ this.barWidth = (paxis._offsets.min - paxis._offsets.max) / nvals - this.barPadding + temp;
+ }
+ else {
+ this.barWidth = (paxis._offsets.min - paxis._offsets.max) / nvals;
+ }
+ }
+ };
+
+ $.jqplot.PyramidRenderer.prototype.draw = function(ctx, gridData, options) {
+ var i;
+ // Ughhh, have to make a copy of options b/c it may be modified later.
+ var opts = $.extend({}, options);
+ var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow;
+ var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine;
+ var fill = (opts.fill != undefined) ? opts.fill : this.fill;
+ var xp = this._xaxis.series_u2p;
+ var yp = this._yaxis.series_u2p;
+ var pointx, pointy;
+ // clear out data colors.
+ this._dataColors = [];
+ this._barPoints = [];
+
+ if (this.renderer.options.barWidth == null) {
+ this.renderer.setBarWidth.call(this);
+ }
+
+ // var temp = this._plotSeriesInfo = this.renderer.calcSeriesNumbers.call(this);
+ // var nvals = temp[0];
+ // var nseries = temp[1];
+ // var pos = temp[2];
+ var points = [],
+ w,
+ h;
+
+ // this._barNudge = 0;
+
+ if (showLine) {
+ var negativeColors = new $.jqplot.ColorGenerator(this.negativeSeriesColors);
+ var positiveColors = new $.jqplot.ColorGenerator(this.seriesColors);
+ var negativeColor = negativeColors.get(this.index);
+ if (! this.useNegativeColors) {
+ negativeColor = opts.fillStyle;
+ }
+ var positiveColor = opts.fillStyle;
+ var base;
+ var xstart = this._xaxis.series_u2p(this._xnudge);
+ var ystart = this._yaxis.series_u2p(this._yaxis.min);
+ var yend = this._yaxis.series_u2p(this._yaxis.max);
+ var bw = this.barWidth;
+ var bw2 = bw/2.0;
+ var points = [];
+ var yadj = this.offsetBars ? bw2 : 0;
+
+ for (var i=0, l=gridData.length; i<l; i++) {
+ if (this.data[i][0] == null) {
+ continue;
+ }
+ base = gridData[i][1];
+ // not stacked and first series in stack
+
+ if (this._plotData[i][1] < 0) {
+ if (this.varyBarColor && !this._stack) {
+ if (this.useNegativeColors) {
+ opts.fillStyle = negativeColors.next();
+ }
+ else {
+ opts.fillStyle = positiveColors.next();
+ }
+ }
+ }
+ else {
+ if (this.varyBarColor && !this._stack) {
+ opts.fillStyle = positiveColors.next();
+ }
+ else {
+ opts.fillStyle = positiveColor;
+ }
+ }
+
+ if (this.fill) {
+
+ if (this._plotData[i][1] >= 0) {
+ // xstart = this._xaxis.series_u2p(this._xnudge);
+ w = gridData[i][0] - xstart;
+ h = this.barWidth;
+ points = [xstart, base - bw2 - yadj, w, h];
+ }
+ else {
+ // xstart = this._xaxis.series_u2p(0);
+ w = xstart - gridData[i][0];
+ h = this.barWidth;
+ points = [gridData[i][0], base - bw2 - yadj, w, h];
+ }
+
+ this._barPoints.push([[points[0], points[1] + h], [points[0], points[1]], [points[0] + w, points[1]], [points[0] + w, points[1] + h]]);
+
+ if (shadow) {
+ this.renderer.shadowRenderer.draw(ctx, points);
+ }
+ var clr = opts.fillStyle || this.color;
+ this._dataColors.push(clr);
+ this.renderer.shapeRenderer.draw(ctx, points, opts);
+ }
+
+ else {
+ if (i === 0) {
+ points =[[xstart, ystart], [gridData[i][0], ystart], [gridData[i][0], gridData[i][1] - bw2 - yadj]];
+ }
+
+ else if (i < l-1) {
+ points = points.concat([[gridData[i-1][0], gridData[i-1][1] - bw2 - yadj], [gridData[i][0], gridData[i][1] + bw2 - yadj], [gridData[i][0], gridData[i][1] - bw2 - yadj]]);
+ }
+
+ // finally, draw the line
+ else {
+ points = points.concat([[gridData[i-1][0], gridData[i-1][1] - bw2 - yadj], [gridData[i][0], gridData[i][1] + bw2 - yadj], [gridData[i][0], yend], [xstart, yend]]);
+
+ if (shadow) {
+ this.renderer.shadowRenderer.draw(ctx, points);
+ }
+ var clr = opts.fillStyle || this.color;
+ this._dataColors.push(clr);
+ this.renderer.shapeRenderer.draw(ctx, points, opts);
+ }
+ }
+ }
+ }
+
+ if (this.highlightColors.length == 0) {
+ this.highlightColors = $.jqplot.computeHighlightColors(this._dataColors);
+ }
+
+ else if (typeof(this.highlightColors) == 'string') {
+ this.highlightColors = [];
+ for (var i=0; i<this._dataColors.length; i++) {
+ this.highlightColors.push(this.highlightColors);
+ }
+ }
+
+ };
+
+
+ // setup default renderers for axes and legend so user doesn't have to
+ // called with scope of plot
+ function preInit(target, data, options) {
+ options = options || {};
+ options.axesDefaults = options.axesDefaults || {};
+ options.grid = options.grid || {};
+ options.legend = options.legend || {};
+ options.seriesDefaults = options.seriesDefaults || {};
+ // only set these if there is a pie series
+ var setopts = false;
+ if (options.seriesDefaults.renderer === $.jqplot.PyramidRenderer) {
+ setopts = true;
+ }
+ else if (options.series) {
+ for (var i=0; i < options.series.length; i++) {
+ if (options.series[i].renderer === $.jqplot.PyramidRenderer) {
+ setopts = true;
+ }
+ }
+ }
+
+ if (setopts) {
+ options.axesDefaults.renderer = $.jqplot.PyramidAxisRenderer;
+ options.grid.renderer = $.jqplot.PyramidGridRenderer;
+ options.seriesDefaults.pointLabels = {show: false};
+ }
+ }
+
+ // called within context of plot
+ // create a canvas which we can draw on.
+ // insert it before the eventCanvas, so eventCanvas will still capture events.
+ function postPlotDraw() {
+ // Memory Leaks patch
+ if (this.plugins.pyramidRenderer && this.plugins.pyramidRenderer.highlightCanvas) {
+
+ this.plugins.pyramidRenderer.highlightCanvas.resetCanvas();
+ this.plugins.pyramidRenderer.highlightCanvas = null;
+ }
+
+ this.plugins.pyramidRenderer = {highlightedSeriesIndex:null};
+ this.plugins.pyramidRenderer.highlightCanvas = new $.jqplot.GenericCanvas();
+
+ this.eventCanvas._elem.before(this.plugins.pyramidRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-pyramidRenderer-highlight-canvas', this._plotDimensions, this));
+ this.plugins.pyramidRenderer.highlightCanvas.setContext();
+ this.eventCanvas._elem.bind('mouseleave', {plot:this}, function (ev) { unhighlight(ev.data.plot); });
+ }
+
+ function highlight (plot, sidx, pidx, points) {
+ var s = plot.series[sidx];
+ var canvas = plot.plugins.pyramidRenderer.highlightCanvas;
+ canvas._ctx.clearRect(0,0,canvas._ctx.canvas.width, canvas._ctx.canvas.height);
+ s._highlightedPoint = pidx;
+ plot.plugins.pyramidRenderer.highlightedSeriesIndex = sidx;
+ var opts = {fillStyle: s.highlightColors[pidx], fillRect: false};
+ s.renderer.shapeRenderer.draw(canvas._ctx, points, opts);
+ if (s.synchronizeHighlight !== false && plot.series.length >= s.synchronizeHighlight && s.synchronizeHighlight !== sidx) {
+ s = plot.series[s.synchronizeHighlight];
+ opts = {fillStyle: s.highlightColors[pidx], fillRect: false};
+ s.renderer.shapeRenderer.draw(canvas._ctx, s._barPoints[pidx], opts);
+ }
+ canvas = null;
+ }
+
+ function unhighlight (plot) {
+ var canvas = plot.plugins.pyramidRenderer.highlightCanvas;
+ canvas._ctx.clearRect(0,0, canvas._ctx.canvas.width, canvas._ctx.canvas.height);
+ for (var i=0; i<plot.series.length; i++) {
+ plot.series[i]._highlightedPoint = null;
+ }
+ plot.plugins.pyramidRenderer.highlightedSeriesIndex = null;
+ plot.target.trigger('jqplotDataUnhighlight');
+ canvas = null;
+ }
+
+
+ function handleMove(ev, gridpos, datapos, neighbor, plot) {
+ if (neighbor) {
+ var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
+ var evt1 = jQuery.Event('jqplotDataMouseOver');
+ evt1.pageX = ev.pageX;
+ evt1.pageY = ev.pageY;
+ plot.target.trigger(evt1, ins);
+ if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.pyramidRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) {
+ var evt = jQuery.Event('jqplotDataHighlight');
+ evt.which = ev.which;
+ evt.pageX = ev.pageX;
+ evt.pageY = ev.pageY;
+ plot.target.trigger(evt, ins);
+ highlight (plot, neighbor.seriesIndex, neighbor.pointIndex, neighbor.points);
+ }
+ }
+ else if (neighbor == null) {
+ unhighlight (plot);
+ }
+ }
+
+ // Have to add hook here, becuase it needs called before series is inited.
+ $.jqplot.preInitHooks.push(preInit);
+
+
+})(jQuery);
\ No newline at end of file
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.pyramidRenderer.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.pyramidRenderer.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.pyramidRenderer.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(c){if(c.jqplot.PyramidAxisRenderer===undefined){c.ajax({url:c.jqplot.pluginLocation+"jqplot.pyramidAxisRenderer.js",dataType:"script",async:false})}if(c.jqplot.PyramidGridRenderer===undefined){c.ajax({url:c.jqplot.pluginLocation+"jqplot.pyramidGridRenderer.js",dataType:"script",async:false})}c.jqplot.PyramidRenderer=function(){c.jqplot.LineRenderer.call(this)};c.jqplot.PyramidRenderer.prototype=new c.jqplot.LineRenderer();c.jqplot.PyramidRenderer.prototype.constructor=c.jqplot.PyramidRenderer;c.jqplot.PyramidRenderer.prototype.init=function(j,o){j=j||{};this._type="pyramid";this.barPadding=10;this.barWidth=null;this.fill=true;this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColors=[];this.highlightThreshold=2;this.synchronizeHighlight=false;this.offsetBars=false;if(j.highlightMouseDown&&j.highlightMouseOver==null){j.highlightMouseOver=false}this.side="right";c.extend(true,this,j);if(this.side==="left"){this._highlightThreshold=[[-this.highlightThreshold,0],[-this.highlightThreshold,0],[0,0],[0,0]]}else{this._highlightThreshold=[[0,0],[0,0],[this.highlightThreshold,0],[this.highlightThreshold,0]]}this.renderer.options=j;this._highlightedPoint=null;this._dataColors=[];this._barPoints=[];this.fillAxis="y";this._primaryAxis="_yaxis";this._xnudge=0;var n={lineJoin:"miter",lineCap:"butt",fill:this.fill,fillRect:this.fill,isarc:false,strokeStyle:this.color,fillStyle:this.color,closePath:this.fill,lineWidth:this.lineWidth};this.renderer.shapeRenderer.init(n);var m=j.shadowOffset;if(m==null){if(this.lineWidth>2.5){m=1.25*(1+(Math.atan((this.lineWidth/2.5))/0.785398163-1)*0.6)}else{m=1.25*Math.atan((this.lineWidth/2.5))/0.785398163}}var h={lineJoin:"miter",lineCap:"butt",fill:this.fill,fillRect:this.fill,isarc:false,angle:this.shadowAngle,offset:m,alpha:this.shadowAlpha,depth:this.shadowDepth,closePath:this.fill,lineWidth:this.lineWidth};this.renderer.shadowRenderer.init(h);o.postDrawHooks.addOnce(f);o.eventListenerHooks.addOnce("jqplotMouseMove",e);if(this.side==="left"){for(!
var k=0,g=this.data.length;k<g;k++){this.data[k][1]=-Math.abs(this.data[k][1])}}};c.jqplot.PyramidRenderer.prototype.setGridData=function(p){var j=this._xaxis.series_u2p;var o=this._yaxis.series_u2p;var k=this._plotData;var n=this._prevPlotData;this.gridData=[];this._prevGridData=[];var g=k.length;var m=false;var h;for(h=0;h<g;h++){if(k[h][1]<0){this.side="left"}}if(this._yaxis.name==="yMidAxis"&&this.side==="right"){this._xnudge=this._xaxis.max/2000;m=true}for(h=0;h<g;h++){if(k[h][0]!=null&&k[h][1]!=null){this.gridData.push([j(k[h][1]),o(k[h][0])])}else{if(k[h][0]==null){this.gridData.push([j(k[h][1]),null])}else{if(k[h][1]==null){this.gridData.push(null,[o(k[h][0])])}}}if(k[h][1]===0&&m){this.gridData[h][0]=j(this._xnudge)}}};c.jqplot.PyramidRenderer.prototype.makeGridData=function(m,p){var k=this._xaxis.series_u2p;var o=this._yaxis.series_u2p;var j=[];var g=m.length;var n=false;var h;for(h=0;h<g;h++){if(m[h][1]<0){this.side="left"}}if(this._yaxis.name==="yMidAxis"&&this.side==="right"){this._xnudge=this._xaxis.max/2000;n=true}for(h=0;h<g;h++){if(m[h][0]!=null&&m[h][1]!=null){j.push([k(m[h][1]),o(m[h][0])])}else{if(m[h][0]==null){j.push([k(m[h][1]),null])}else{if(m[h][1]==null){j.push([null,o(m[h][0])])}}}if(m[h][1]===0&&n){j[h][0]=k(this._xnudge)}}return j};c.jqplot.PyramidRenderer.prototype.setBarWidth=function(){var k;var g=0;var h=0;var m=this[this._primaryAxis];var q,l,o;g=m.max-m.min;var n=m.numberTicks;var j=(n-1)/2;var p=(this.barPadding===0)?1:0;if(m.name=="xaxis"||m.name=="x2axis"){this.barWidth=(m._offsets.max-m._offsets.min)/g-this.barPadding+p}else{if(this.fill){this.barWidth=(m._offsets.min-m._offsets.max)/g-this.barPadding+p}else{this.barWidth=(m._offsets.min-m._offsets.max)/g}}};c.jqplot.PyramidRenderer.prototype.draw=function(B,I,k){var E;var u=c.extend({},k);var p=(u.shadow!=undefined)?u.shadow:this.shadow;var K=(u.showLine!=undefined)?u.showLine:this.showLine;var C=(u.fill!=undefined)?u.fill:this.fill;var t=this._xaxis.series_u2p;var G=this._yaxis.series_u2p;var z,x;this._dataColors=[];this.!
_barPoints=[];if(this.renderer.options.barWidth==null){this.renderer.setBarWidth.call(this)}var D=[],s,F;if(K){var q=new c.jqplot.ColorGenerator(this.negativeSeriesColors);var v=new c.jqplot.ColorGenerator(this.seriesColors);var J=q.get(this.index);if(!this.useNegativeColors){J=u.fillStyle}var o=u.fillStyle;var n;var L=this._xaxis.series_u2p(this._xnudge);var j=this._yaxis.series_u2p(this._yaxis.min);var m=this._yaxis.series_u2p(this._yaxis.max);var H=this.barWidth;var y=H/2;var D=[];var r=this.offsetBars?y:0;for(var E=0,A=I.length;E<A;E++){if(this.data[E][0]==null){continue}n=I[E][1];if(this._plotData[E][1]<0){if(this.varyBarColor&&!this._stack){if(this.useNegativeColors){u.fillStyle=q.next()}else{u.fillStyle=v.next()}}}else{if(this.varyBarColor&&!this._stack){u.fillStyle=v.next()}else{u.fillStyle=o}}if(this.fill){if(this._plotData[E][1]>=0){s=I[E][0]-L;F=this.barWidth;D=[L,n-y-r,s,F]}else{s=L-I[E][0];F=this.barWidth;D=[I[E][0],n-y-r,s,F]}this._barPoints.push([[D[0],D[1]+F],[D[0],D[1]],[D[0]+s,D[1]],[D[0]+s,D[1]+F]]);if(p){this.renderer.shadowRenderer.draw(B,D)}var g=u.fillStyle||this.color;this._dataColors.push(g);this.renderer.shapeRenderer.draw(B,D,u)}else{if(E===0){D=[[L,j],[I[E][0],j],[I[E][0],I[E][1]-y-r]]}else{if(E<A-1){D=D.concat([[I[E-1][0],I[E-1][1]-y-r],[I[E][0],I[E][1]+y-r],[I[E][0],I[E][1]-y-r]])}else{D=D.concat([[I[E-1][0],I[E-1][1]-y-r],[I[E][0],I[E][1]+y-r],[I[E][0],m],[L,m]]);if(p){this.renderer.shadowRenderer.draw(B,D)}var g=u.fillStyle||this.color;this._dataColors.push(g);this.renderer.shapeRenderer.draw(B,D,u)}}}}}if(this.highlightColors.length==0){this.highlightColors=c.jqplot.computeHighlightColors(this._dataColors)}else{if(typeof(this.highlightColors)=="string"){this.highlightColors=[];for(var E=0;E<this._dataColors.length;E++){this.highlightColors.push(this.highlightColors)}}}};function b(l,k,h){h=h||{};h.axesDefaults=h.axesDefaults||{};h.grid=h.grid||{};h.legend=h.legend||{};h.seriesDefaults=h.seriesDefaults||{};var g=false;if(h.seriesDefaults.renderer===c.jqplot.PyramidRenderer){g=true!
}else{if(h.series){for(var j=0;j<h.series.length;j++){if(h.series[j].renderer===c.jqplot.PyramidRenderer){g=true}}}}if(g){h.axesDefaults.renderer=c.jqplot.PyramidAxisRenderer;h.grid.renderer=c.jqplot.PyramidGridRenderer;h.seriesDefaults.pointLabels={show:false}}}function f(){if(this.plugins.pyramidRenderer&&this.plugins.pyramidRenderer.highlightCanvas){this.plugins.pyramidRenderer.highlightCanvas.resetCanvas();this.plugins.pyramidRenderer.highlightCanvas=null}this.plugins.pyramidRenderer={highlightedSeriesIndex:null};this.plugins.pyramidRenderer.highlightCanvas=new c.jqplot.GenericCanvas();this.eventCanvas._elem.before(this.plugins.pyramidRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-pyramidRenderer-highlight-canvas",this._plotDimensions,this));this.plugins.pyramidRenderer.highlightCanvas.setContext();this.eventCanvas._elem.bind("mouseleave",{plot:this},function(g){d(g.data.plot)})}function a(m,l,j,i){var h=m.series[l];var g=m.plugins.pyramidRenderer.highlightCanvas;g._ctx.clearRect(0,0,g._ctx.canvas.width,g._ctx.canvas.height);h._highlightedPoint=j;m.plugins.pyramidRenderer.highlightedSeriesIndex=l;var k={fillStyle:h.highlightColors[j],fillRect:false};h.renderer.shapeRenderer.draw(g._ctx,i,k);if(h.synchronizeHighlight!==false&&m.series.length>=h.synchronizeHighlight&&h.synchronizeHighlight!==l){h=m.series[h.synchronizeHighlight];k={fillStyle:h.highlightColors[j],fillRect:false};h.renderer.shapeRenderer.draw(g._ctx,h._barPoints[j],k)}g=null}function d(j){var g=j.plugins.pyramidRenderer.highlightCanvas;g._ctx.clearRect(0,0,g._ctx.canvas.width,g._ctx.canvas.height);for(var h=0;h<j.series.length;h++){j.series[h]._highlightedPoint=null}j.plugins.pyramidRenderer.highlightedSeriesIndex=null;j.target.trigger("jqplotDataUnhighlight");g=null}function e(k,j,n,m,l){if(m){var i=[m.seriesIndex,m.pointIndex,m.data];var h=jQuery.Event("jqplotDataMouseOver");h.pageX=k.pageX;h.pageY=k.pageY;l.target.trigger(h,i);if(l.series[i[0]].highlightMouseOver&&!(i[0]==l.plugins.pyramidRenderer.highlightedSeriesIndex&&i[1!
]==l.series[i[0]]._highlightedPoint)){var g=jQuery.Event("jqplotDataHighlight");g.which=k.which;g.pageX=k.pageX;g.pageY=k.pageY;l.target.trigger(g,i);a(l,m.seriesIndex,m.pointIndex,m.points)}}else{if(m==null){d(l)}}}c.jqplot.preInitHooks.push(b)})(jQuery);
\ No newline at end of file
Modified: gnucash/trunk/src/report/jqplot/plugins/jqplot.trendline.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.trendline.js 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.trendline.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -1,18 +1,31 @@
/**
- * Copyright (c) 2009 - 2010 Chris Leonello
+ * jqPlot
+ * Pure JavaScript plotting plugin using jQuery
+ *
+ * Version: 1.0.6
+ * Revision: 1138
+ *
+ * Copyright (c) 2009-2013 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
- * under both the MIT and GPL version 2.0 licenses. This means that you can
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
- * The author would appreciate an email letting him know of any substantial
- * use of jqPlot. You can reach the author at: chris at jqplot dot com
- * or see http://www.jqplot.com/info.php . This is, of course,
- * not required.
+ * Although not required, the author would appreciate an email letting him
+ * know of any substantial use of jqPlot. You can reach the author at:
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
- * Thanks for using jqPlot!
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
+ *
+ * version 2007.04.27
+ * author Ash Searle
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
+ * http://hexmen.com/js/sprintf.js
+ * The author (Ash Searle) has placed this code in the public domain:
+ * "This code is unrestricted: you are free to use it however you like."
*
*/
(function($) {
@@ -80,17 +93,19 @@
// current series passed in
// must return null or an object {label:label, color:color}
function addTrendlineLegend(series) {
- var lt = series.trendline.label.toString();
var ret = null;
- if (this.renderer.constructor != $.jqplot.PieRenderer && series.trendline.show && lt) {
- ret = {label:lt, color:series.trendline.color};
+ if (series.trendline && series.trendline.show) {
+ var lt = series.trendline.label.toString();
+ if (lt) {
+ ret = {label:lt, color:series.trendline.color};
+ }
}
return ret;
}
// called within scope of a series
function parseTrendLineOptions (target, data, seriesDefaults, options, plot) {
- if (this.renderer.constructor == $.jqplot.LineRenderer) {
+ if (this._type && (this._type === 'line' || this._type == 'bar')) {
this.trendline = new $.jqplot.Trendline();
options = options || {};
$.extend(true, this.trendline, {color:this.color}, seriesDefaults.trendline, options.trendline);
@@ -103,7 +118,7 @@
// if we have options, merge trendline options in with precedence
options = $.extend(true, {}, this.trendline, options);
- if (options.show && this.renderer.constructor != $.jqplot.PieRenderer) {
+ if (this.trendline && options.show) {
var fit;
// this.renderer.setGridData.call(this);
var data = options.data || this.data;
Added: gnucash/trunk/src/report/jqplot/plugins/jqplot.trendline.min.js
===================================================================
--- gnucash/trunk/src/report/jqplot/plugins/jqplot.trendline.min.js (rev 0)
+++ gnucash/trunk/src/report/jqplot/plugins/jqplot.trendline.min.js 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,3 @@
+/* jqPlot 1.0.6r1138 | (c) 2009-2013 Chris Leonello | jplot.com
+ jsDate | (c) 2010-2013 Chris Leonello
+ */(function(f){f.jqplot.Trendline=function(){this.show=f.jqplot.config.enablePlugins;this.color="#666666";this.renderer=new f.jqplot.LineRenderer();this.rendererOptions={marker:{show:false}};this.label="";this.type="linear";this.shadow=true;this.markerRenderer={show:false};this.lineWidth=1.5;this.shadowAngle=45;this.shadowOffset=1;this.shadowAlpha=0.07;this.shadowDepth=3;this.isTrendline=true};f.jqplot.postSeriesInitHooks.push(e);f.jqplot.postDrawSeriesHooks.push(g);f.jqplot.addLegendRowHooks.push(a);function a(k){var j=null;if(k.trendline&&k.trendline.show){var i=k.trendline.label.toString();if(i){j={label:i,color:k.trendline.color}}}return j}function e(m,k,j,i,l){if(this._type&&(this._type==="line"||this._type=="bar")){this.trendline=new f.jqplot.Trendline();i=i||{};f.extend(true,this.trendline,{color:this.color},j.trendline,i.trendline);this.trendline.renderer.init.call(this.trendline,null)}}function g(m,i){i=f.extend(true,{},this.trendline,i);if(this.trendline&&i.show){var k;var l=i.data||this.data;k=c(l,this.trendline.type);var j=i.gridData||this.renderer.makeGridData.call(this,k.data);this.trendline.renderer.draw.call(this.trendline,m,j,{showLine:true,shadow:this.trendline.shadow})}}function b(w,v,n){var u=(n==null)?"linear":n;var s=w.length;var t;var z;var o=0;var m=0;var r=0;var q=0;var l=0;var j=[];var k=[];if(u=="linear"){k=w;j=v}else{if(u=="exp"||u=="exponential"){for(var p=0;p<v.length;p++){if(v[p]<=0){s--}else{k.push(w[p]);j.push(Math.log(v[p]))}}}}for(var p=0;p<s;p++){o=o+k[p];m=m+j[p];q=q+k[p]*j[p];r=r+k[p]*k[p];l=l+j[p]*j[p]}t=(s*q-o*m)/(s*r-o*o);z=(m-t*o)/s;return[t,z]}function h(k,j){var i;i=b(k,j,"linear");return[i[0],i[1]]}function d(o,m){var k;var i=o;var n=m;k=b(i,n,"exp");var l=Math.exp(k[0]);var j=Math.exp(k[1]);return[l,j]}function c(l,j){var p=(j==null)?"linear":j;var n;var o;var r=[];var q=[];var m=[];for(k=0;k<l.length;k++){if(l[k]!=null&&l[k][0]!=null&&l[k][1]!=null){r.push(l[k][0]);q.push(l[k][1])}}if(p=="linear"){n=h(r,q);for(var k=0;k<r.length;k++){o=n[0]*r[k]+n[1];m.pus!
h([r[k],o])}}else{if(p=="exp"||p=="exponential"){n=d(r,q);for(var k=0;k<r.length;k++){o=n[1]*Math.pow(n[0],r[k]);m.push([r[k],o])}}}return{data:m,slope:n[0],intercept:n[1]}}})(jQuery);
\ No newline at end of file
Added: gnucash/trunk/src/report/jqplot/usage.txt
===================================================================
--- gnucash/trunk/src/report/jqplot/usage.txt (rev 0)
+++ gnucash/trunk/src/report/jqplot/usage.txt 2013-02-20 18:50:43 UTC (rev 22790)
@@ -0,0 +1,126 @@
+Title: jqPlot Usage
+
+Usage Documentation:
+
+Introduction:
+
+jqPlot is a jQuery plugin to generate pure client-side javascript charts in your web pages.
+
+The jqPlot home page is at <http://www.jqplot.com/>.
+
+The project page and downloads are at <http://www.bitbucket.org/cleonello/jqplot/>.
+
+Below are a few examples to demonstrate jqPlot usage. These plots are shown as static images.
+Many more examples of dynamically rendered plots can be seen on the test and examples pages here: <../../tests/>.
+
+Include the Files:
+
+jqPlot requires jQuery (1.4+ required for certain features). jQuery is included in the distribution.
+To use jqPlot include jquery, the jqPlot jQuery plugin, jqPlot css file and optionally the excanvas
+script for IE support in your web page. Note, excanvas is required only for IE versions below 9. IE 9 includes
+native support for the canvas element and does not require excanvas:
+
+> <!--[if lt IE 9]><script language="javascript" type="text/javascript" src="excanvas.js"></script><![endif]-->
+> <script language="javascript" type="text/javascript" src="jquery.min.js"></script>
+> <script language="javascript" type="text/javascript" src="jquery.jqplot.min.js"></script>
+> <link rel="stylesheet" type="text/css" href="jquery.jqplot.css" />
+
+Add a plot container:
+
+Add a container (target) to your web page where you want your plot to show up.
+Be sure to give your target a width and a height:
+
+> <div id="chartdiv" style="height:400px;width:300px; "></div>
+
+Create a plot:
+
+Then, create the actual plot by calling the
+$.jqplot plugin with the id of your target and some data:
+
+> $.jqplot('chartdiv', [[[1, 2],[3,5.12],[5,13.1],[7,33.6],[9,85.9],[11,219.9]]]);
+
+Which will produce a
+chart like:
+
+(see images/basicline.png)
+
+Plot Options:
+
+You can customize the plot by passing options to the $.jqplot function. Options are described in
+<jqPlot Options> in the jqPlotOptions.txt file. An example of options usage:
+
+> $.jqplot('chartdiv', [[[1, 2],[3,5.12],[5,13.1],[7,33.6],[9,85.9],[11,219.9]]],
+> { title:'Exponential Line',
+> axes:{yaxis:{min:-10, max:240}},
+> series:[{color:'#5FAB78'}]
+> });
+
+Which will produce
+a plot like:
+
+(see images/basicoptions.png)
+
+Using Plugins:
+
+You can use jqPlot plugins (that is, plugins to the jqPlot plugin) by including them in your html
+after you include the jqPlot plugin. Here is how to include the log axis plugin:
+
+> <link rel="stylesheet" type="text/css" href="jquery.jqplot.css" />
+> <!--[if IE]><script language="javascript" type="text/javascript" src="excanvas.js"></script><![endif]-->
+> <script language="javascript" type="text/javascript" src="jquery.min.js"></script>
+> <script language="javascript" type="text/javascript" src="jquery.jqplot.min.js"></script>
+> <script language="javascript" type="text/javascript" src="jqplot.logAxisRenderer.js"></script>
+
+Important note: For jqplot builds r529 and above (0.9.7r529 and higher), you must explicitly
+enable plugins via either the { show: true } plugin option to the plot or by using
+the $.jqplot.config.enablePlugins = true; config options set on the page before plot creation.
+Only plugins that can be immediately active upon loading are affected. This includes
+non-renderer plugins like cursor, dragable, highlighter, and trendline.
+
+Here is a the same $.jqplot call
+but with a log y axis:
+
+> $.jqplot('chartdiv', [[[1, 2],[3,5.12],[5,13.1],[7,33.6],[9,85.9],[11,219.9]]],
+> { title:'Exponential Line',
+> axes:{yaxis:{renderer: $.jqplot.LogAxisRenderer}},
+> series:[{color:'#5FAB78'}]
+> });
+
+Which produces
+a plot like:
+
+(see images/basiclogaxis.png)
+
+You can further customize with options specific
+to the log axis plugin:
+
+> $.jqplot('chartdiv', [[[1, 2],[3,5.12],[5,13.1],[7,33.6],[9,85.9],[11,219.9]]],
+> { title:'Exponential Line',
+> axes:{yaxis:{renderer: $.jqplot.LogAxisRenderer, tickDistribution:'power'}},
+> series:[{color:'#5FAB78'}]
+> });
+
+Which makes a
+plot like:
+
+(see images/basiclogoptions.png)
+
+For a full list of options, see <jqPlot Options> in the jqPlotOptions.txt file.
+
+You can add as many plugins as you wish. Order is generally not important.
+Some plugins, like the highlighter plugin which highlights data points near the
+mouse, don't need any extra options or setup to function. Highlighter does have
+additional options which the user can set.
+
+Other plugins, the barRenderer for example, provide functionality the must be specified
+in the chart options object. To render a series as a bar graph with the bar renderer,
+you would first include the plugin after jqPlot:
+
+> <script language="javascript" type="text/javascript" src="plugins/jqplot.barRenderer.min.js"></script>
+
+Then you would create
+a chart like:
+
+> $.jqplot('chartdiv', [[34.53, 56.32, 25.1, 18.6]], {series:[{renderer:$.jqplot.BarRenderer}]});
+
+Here the default LineRenderer is replaced by a BarRenderer to generate a bar graph for the first (an only) series.
\ No newline at end of file
Modified: gnucash/trunk/src/report/report-system/html-barchart.scm
===================================================================
--- gnucash/trunk/src/report/report-system/html-barchart.scm 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/report-system/html-barchart.scm 2013-02-20 18:50:43 UTC (rev 22790)
@@ -354,7 +354,7 @@
(not (null? data))
(gnc:not-all-zeros data))
(begin
- (push (gnc:html-js-include "jqplot/jquery-1.4.2.min.js"))
+ (push (gnc:html-js-include "jqplot/jquery.min.js"))
(push (gnc:html-js-include "jqplot/jquery.jqplot.js"))
(push (gnc:html-js-include "jqplot/jqplot.barRenderer.js"))
(push (gnc:html-js-include "jqplot/jqplot.categoryAxisRenderer.js"))
Modified: gnucash/trunk/src/report/report-system/html-piechart.scm
===================================================================
--- gnucash/trunk/src/report/report-system/html-piechart.scm 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/report-system/html-piechart.scm 2013-02-20 18:50:43 UTC (rev 22790)
@@ -199,7 +199,7 @@
(if (and (list? data)
(not (null? data)))
(begin
- (push (gnc:html-js-include "jqplot/jquery-1.4.2.min.js"))
+ (push (gnc:html-js-include "jqplot/jquery.min.js"))
(push (gnc:html-js-include "jqplot/jquery.jqplot.js"))
(push (gnc:html-js-include "jqplot/jqplot.pieRenderer.js"))
(push (gnc:html-css-include "jqplot/jquery.jqplot.css"))
Modified: gnucash/trunk/src/report/report-system/html-scatter.scm
===================================================================
--- gnucash/trunk/src/report/report-system/html-scatter.scm 2013-02-20 18:50:30 UTC (rev 22789)
+++ gnucash/trunk/src/report/report-system/html-scatter.scm 2013-02-20 18:50:43 UTC (rev 22790)
@@ -170,7 +170,7 @@
(if (and (list? data)
(not (null? data)))
(begin
- (push (gnc:html-js-include "jqplot/jquery-1.4.2.min.js"))
+ (push (gnc:html-js-include "jqplot/jquery.min.js"))
(push (gnc:html-js-include "jqplot/jquery.jqplot.js"))
(push (gnc:html-css-include "jqplot/jquery.jqplot.css"))
More information about the gnucash-changes
mailing list