PDF rausgenommen
This commit is contained in:
21
msd2/tracking/piwik/libs/jqplot/MIT-LICENSE.txt
Normal file
21
msd2/tracking/piwik/libs/jqplot/MIT-LICENSE.txt
Normal file
@ -0,0 +1,21 @@
|
||||
Title: MIT License
|
||||
|
||||
Copyright (c) 2009-2011 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.
|
26
msd2/tracking/piwik/libs/jqplot/build_minified_script.sh
Normal file
26
msd2/tracking/piwik/libs/jqplot/build_minified_script.sh
Normal file
@ -0,0 +1,26 @@
|
||||
# build jqplot-custom.min.js
|
||||
# the yuicompressor needs to be set up in piwik/js (see piwik/js/README.md)
|
||||
|
||||
cat jqplot.core.js > jqplot-custom.min.js-temp
|
||||
cat jqplot.linearAxisRenderer.js >> jqplot-custom.min.js-temp
|
||||
cat jqplot.axisTickRenderer.js >> jqplot-custom.min.js-temp
|
||||
cat jqplot.axisLabelRenderer.js >> jqplot-custom.min.js-temp
|
||||
cat jqplot.tableLegendRenderer.js >> jqplot-custom.min.js-temp
|
||||
cat jqplot.lineRenderer.js >> jqplot-custom.min.js-temp
|
||||
cat jqplot.linePattern.js >> jqplot-custom.min.js-temp
|
||||
cat jqplot.markerRenderer.js >> jqplot-custom.min.js-temp
|
||||
cat jqplot.divTitleRenderer.js >> jqplot-custom.min.js-temp
|
||||
cat jqplot.canvasGridRenderer.js >> jqplot-custom.min.js-temp
|
||||
cat jqplot.shadowRenderer.js >> jqplot-custom.min.js-temp
|
||||
cat jqplot.shapeRenderer.js >> jqplot-custom.min.js-temp
|
||||
cat jqplot.sprintf.js >> jqplot-custom.min.js-temp
|
||||
cat jqplot.themeEngine.js >> jqplot-custom.min.js-temp
|
||||
cat plugins/jqplot.pieRenderer.js >> jqplot-custom.min.js-temp
|
||||
cat plugins/jqplot.barRenderer.js >> jqplot-custom.min.js-temp
|
||||
cat plugins/jqplot.categoryAxisRenderer.js >> jqplot-custom.min.js-temp
|
||||
cat plugins/jqplot.canvasTextRenderer.js >> jqplot-custom.min.js-temp
|
||||
cat plugins/jqplot.canvasAxisTickRenderer.js >> jqplot-custom.min.js-temp
|
||||
|
||||
java -jar ../../js/yuicompressor-2.4.2/build/yuicompressor-2.4.2.jar --type js --line-break 1000 jqplot-custom.min.js-temp > jqplot-custom.min.js
|
||||
|
||||
rm ./jqplot-custom.min.js-temp
|
1
msd2/tracking/piwik/libs/jqplot/excanvas.min.js
vendored
Normal file
1
msd2/tracking/piwik/libs/jqplot/excanvas.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
280
msd2/tracking/piwik/libs/jqplot/gpl-2.0.txt
Normal file
280
msd2/tracking/piwik/libs/jqplot/gpl-2.0.txt
Normal file
@ -0,0 +1,280 @@
|
||||
Title: GPL Version 2
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
173
msd2/tracking/piwik/libs/jqplot/jqplot-custom.min.js
vendored
Normal file
173
msd2/tracking/piwik/libs/jqplot/jqplot-custom.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
97
msd2/tracking/piwik/libs/jqplot/jqplot.axisLabelRenderer.js
Normal file
97
msd2/tracking/piwik/libs/jqplot/jqplot.axisLabelRenderer.js
Normal file
@ -0,0 +1,97 @@
|
||||
/**
|
||||
* jqPlot
|
||||
* Pure JavaScript plotting plugin using jQuery
|
||||
*
|
||||
* Version: @VERSION
|
||||
* Revision: @REVISION
|
||||
*
|
||||
* 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.AxisLabelRenderer
|
||||
// Renderer to place labels on the axes.
|
||||
$.jqplot.AxisLabelRenderer = function(options) {
|
||||
// Group: Properties
|
||||
$.jqplot.ElemContainer.call(this);
|
||||
// name of the axis associated with this tick
|
||||
this.axis;
|
||||
// prop: show
|
||||
// whether or not to show the tick (mark and label).
|
||||
this.show = true;
|
||||
// prop: label
|
||||
// The text or html for the label.
|
||||
this.label = '';
|
||||
this.fontFamily = null;
|
||||
this.fontSize = null;
|
||||
this.textColor = null;
|
||||
this._elem;
|
||||
// prop: escapeHTML
|
||||
// true to escape HTML entities in the label.
|
||||
this.escapeHTML = false;
|
||||
|
||||
$.extend(true, this, options);
|
||||
};
|
||||
|
||||
$.jqplot.AxisLabelRenderer.prototype = new $.jqplot.ElemContainer();
|
||||
$.jqplot.AxisLabelRenderer.prototype.constructor = $.jqplot.AxisLabelRenderer;
|
||||
|
||||
$.jqplot.AxisLabelRenderer.prototype.init = function(options) {
|
||||
$.extend(true, this, options);
|
||||
};
|
||||
|
||||
$.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)) {
|
||||
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;
|
||||
};
|
||||
|
||||
$.jqplot.AxisLabelRenderer.prototype.pack = function() {
|
||||
};
|
||||
})(jQuery);
|
191
msd2/tracking/piwik/libs/jqplot/jqplot.axisTickRenderer.js
Normal file
191
msd2/tracking/piwik/libs/jqplot/jqplot.axisTickRenderer.js
Normal file
@ -0,0 +1,191 @@
|
||||
/**
|
||||
* jqPlot
|
||||
* Pure JavaScript plotting plugin using jQuery
|
||||
*
|
||||
* Version: @VERSION
|
||||
* Revision: @REVISION
|
||||
*
|
||||
* 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.AxisTickRenderer
|
||||
// A "tick" object showing the value of a tick/gridline on the plot.
|
||||
$.jqplot.AxisTickRenderer = function(options) {
|
||||
// Group: Properties
|
||||
$.jqplot.ElemContainer.call(this);
|
||||
// prop: mark
|
||||
// tick mark on the axis. One of 'inside', 'outside', 'cross', '' or null.
|
||||
this.mark = 'outside';
|
||||
// name of the axis associated with this tick
|
||||
this.axis;
|
||||
// prop: showMark
|
||||
// whether or not to show the mark on the axis.
|
||||
this.showMark = true;
|
||||
// prop: showGridline
|
||||
// whether or not to draw the gridline on the grid at this tick.
|
||||
this.showGridline = true;
|
||||
// prop: isMinorTick
|
||||
// if this is a minor tick.
|
||||
this.isMinorTick = false;
|
||||
// prop: size
|
||||
// Length of the tick beyond the grid in pixels.
|
||||
// DEPRECATED: This has been superceeded by markSize
|
||||
this.size = 4;
|
||||
// prop: markSize
|
||||
// Length of the tick marks in pixels. For 'cross' style, length
|
||||
// will be stoked above and below axis, so total length will be twice this.
|
||||
this.markSize = 6;
|
||||
// prop: show
|
||||
// whether or not to show the tick (mark and label).
|
||||
// Setting this to false requires more testing. It is recommended
|
||||
// to set showLabel and showMark to false instead.
|
||||
this.show = true;
|
||||
// prop: showLabel
|
||||
// whether or not to show the label.
|
||||
this.showLabel = true;
|
||||
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 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 = '';
|
||||
// prop: fontFamily
|
||||
// css spec for the font-family css attribute.
|
||||
this.fontFamily;
|
||||
// prop: fontSize
|
||||
// css spec for the font-size css attribute.
|
||||
this.fontSize;
|
||||
// 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);
|
||||
};
|
||||
|
||||
$.jqplot.AxisTickRenderer.prototype.init = function(options) {
|
||||
$.extend(true, this, options);
|
||||
};
|
||||
|
||||
$.jqplot.AxisTickRenderer.prototype = new $.jqplot.ElemContainer();
|
||||
$.jqplot.AxisTickRenderer.prototype.constructor = $.jqplot.AxisTickRenderer;
|
||||
|
||||
$.jqplot.AxisTickRenderer.prototype.setTick = function(value, axisName, isMinor) {
|
||||
this.value = value;
|
||||
this.axis = axisName;
|
||||
if (isMinor) {
|
||||
this.isMinorTick = true;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
$.jqplot.AxisTickRenderer.prototype.draw = function() {
|
||||
if (this.label === null) {
|
||||
this.label = this.prefix + this.formatter(this.formatString, this.value) + this.suffix;
|
||||
}
|
||||
var style = {position: 'absolute'};
|
||||
if (Number(this.label)) {
|
||||
style['whitSpace'] = 'nowrap';
|
||||
}
|
||||
|
||||
// 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]);
|
||||
}
|
||||
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;
|
||||
};
|
||||
|
||||
$.jqplot.DefaultTickFormatter = function (format, val) {
|
||||
if (typeof val == 'number') {
|
||||
if (!format) {
|
||||
format = $.jqplot.config.defaultTickFormatString;
|
||||
}
|
||||
return $.jqplot.sprintf(format, val);
|
||||
}
|
||||
else {
|
||||
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() {
|
||||
};
|
||||
})(jQuery);
|
383
msd2/tracking/piwik/libs/jqplot/jqplot.canvasGridRenderer.js
Normal file
383
msd2/tracking/piwik/libs/jqplot/jqplot.canvasGridRenderer.js
Normal file
@ -0,0 +1,383 @@
|
||||
/**
|
||||
* jqPlot
|
||||
* Pure JavaScript plotting plugin using jQuery
|
||||
*
|
||||
* Version: @VERSION
|
||||
* Revision: @REVISION
|
||||
*
|
||||
* 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.CanvasGridRenderer = function(){
|
||||
this.shadowRenderer = new $.jqplot.ShadowRenderer();
|
||||
};
|
||||
|
||||
// called with context of Grid object
|
||||
$.jqplot.CanvasGridRenderer.prototype.init = function(options) {
|
||||
this._ctx;
|
||||
$.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);
|
||||
};
|
||||
|
||||
// called with context of Grid.
|
||||
$.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;
|
||||
elem.height = h;
|
||||
this._elem = $(elem);
|
||||
this._elem.addClass('jqplot-grid-canvas');
|
||||
this._elem.css({ position: 'absolute', left: 0, top: 0 });
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
$.jqplot.CanvasGridRenderer.prototype.draw = function() {
|
||||
this._ctx = this._elem.get(0).getContext("2d");
|
||||
var ctx = this._ctx;
|
||||
var axes = this._axes;
|
||||
// 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);
|
||||
|
||||
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 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.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});
|
||||
}
|
||||
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});
|
||||
}
|
||||
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});
|
||||
}
|
||||
drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor});
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
t = null;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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) {
|
||||
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) {
|
||||
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);
|
4105
msd2/tracking/piwik/libs/jqplot/jqplot.core.js
Normal file
4105
msd2/tracking/piwik/libs/jqplot/jqplot.core.js
Normal file
File diff suppressed because it is too large
Load Diff
120
msd2/tracking/piwik/libs/jqplot/jqplot.divTitleRenderer.js
Normal file
120
msd2/tracking/piwik/libs/jqplot/jqplot.divTitleRenderer.js
Normal file
@ -0,0 +1,120 @@
|
||||
/**
|
||||
* jqPlot
|
||||
* Pure JavaScript plotting plugin using jQuery
|
||||
*
|
||||
* Version: @VERSION
|
||||
* Revision: @REVISION
|
||||
*
|
||||
* 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.DivTitleRenderer
|
||||
// The default title renderer for jqPlot. This class has no options beyond the <Title> class.
|
||||
$.jqplot.DivTitleRenderer = function() {
|
||||
};
|
||||
|
||||
$.jqplot.DivTitleRenderer.prototype.init = function(options) {
|
||||
$.extend(true, this, options);
|
||||
};
|
||||
|
||||
$.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.height(0);
|
||||
this._elem.width(0);
|
||||
}
|
||||
else if (this.text) {
|
||||
var color;
|
||||
if (this.color) {
|
||||
color = this.color;
|
||||
}
|
||||
else if (this.textColor) {
|
||||
color = this.textColor;
|
||||
}
|
||||
|
||||
// don't trust that a stylesheet is present, set the position.
|
||||
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) {
|
||||
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;
|
||||
};
|
||||
|
||||
$.jqplot.DivTitleRenderer.prototype.pack = function() {
|
||||
// nothing to do here
|
||||
};
|
||||
})(jQuery);
|
149
msd2/tracking/piwik/libs/jqplot/jqplot.linePattern.js
Normal file
149
msd2/tracking/piwik/libs/jqplot/jqplot.linePattern.js
Normal file
@ -0,0 +1,149 @@
|
||||
/**
|
||||
* jqPlot
|
||||
* Pure JavaScript plotting plugin using jQuery
|
||||
*
|
||||
* Version: @VERSION
|
||||
* Revision: @REVISION
|
||||
*
|
||||
* 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."
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* The following dashed line support contributed by Cory Sharp.
|
||||
* After I implemented an inferior method, Cory responded with a generous
|
||||
* contribution of code and input which proved a more powerful and
|
||||
* elegant solution.
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
|
||||
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
|
||||
};
|
||||
};
|
||||
})(jQuery);
|
1227
msd2/tracking/piwik/libs/jqplot/jqplot.lineRenderer.js
Normal file
1227
msd2/tracking/piwik/libs/jqplot/jqplot.lineRenderer.js
Normal file
File diff suppressed because it is too large
Load Diff
1006
msd2/tracking/piwik/libs/jqplot/jqplot.linearAxisRenderer.js
Normal file
1006
msd2/tracking/piwik/libs/jqplot/jqplot.linearAxisRenderer.js
Normal file
File diff suppressed because it is too large
Load Diff
229
msd2/tracking/piwik/libs/jqplot/jqplot.markerRenderer.js
Normal file
229
msd2/tracking/piwik/libs/jqplot/jqplot.markerRenderer.js
Normal file
@ -0,0 +1,229 @@
|
||||
/**
|
||||
* jqPlot
|
||||
* Pure JavaScript plotting plugin using jQuery
|
||||
*
|
||||
* Version: @VERSION
|
||||
* Revision: @REVISION
|
||||
*
|
||||
* 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.MarkerRenderer
|
||||
// The default jqPlot marker renderer, rendering the points on the line.
|
||||
$.jqplot.MarkerRenderer = function(options){
|
||||
// Group: Properties
|
||||
|
||||
// prop: show
|
||||
// whether or not to show the marker.
|
||||
this.show = true;
|
||||
// prop: style
|
||||
// One of diamond, circle, square, x, plus, dash, filledDiamond, filledCircle, filledSquare
|
||||
this.style = 'filledCircle';
|
||||
// prop: lineWidth
|
||||
// size of the line for non-filled markers.
|
||||
this.lineWidth = 2;
|
||||
// prop: size
|
||||
// Size of the marker (diameter or circle, length of edge of square, etc.)
|
||||
this.size = 9.0;
|
||||
// prop: color
|
||||
// color of marker. Will be set to color of series by default on init.
|
||||
this.color = '#666666';
|
||||
// prop: shadow
|
||||
// whether or not to draw a shadow on the line
|
||||
this.shadow = true;
|
||||
// prop: shadowAngle
|
||||
// Shadow angle in degrees
|
||||
this.shadowAngle = 45;
|
||||
// prop: shadowOffset
|
||||
// Shadow offset from line in pixels
|
||||
this.shadowOffset = 1;
|
||||
// prop: shadowDepth
|
||||
// Number of times shadow is stroked, each stroke offset shadowOffset from the last.
|
||||
this.shadowDepth = 3;
|
||||
// prop: shadowAlpha
|
||||
// Alpha channel transparency of shadow. 0 = transparent.
|
||||
this.shadowAlpha = '0.07';
|
||||
// prop: shadowRenderer
|
||||
// Renderer that will draws the shadows on the marker.
|
||||
this.shadowRenderer = new $.jqplot.ShadowRenderer();
|
||||
// prop: shapeRenderer
|
||||
// Renderer that will draw the marker.
|
||||
this.shapeRenderer = new $.jqplot.ShapeRenderer();
|
||||
|
||||
$.extend(true, this, options);
|
||||
};
|
||||
|
||||
$.jqplot.MarkerRenderer.prototype.init = function(options) {
|
||||
$.extend(true, this, options);
|
||||
var sdopt = {angle:this.shadowAngle, offset:this.shadowOffset, alpha:this.shadowAlpha, lineWidth:this.lineWidth, depth:this.shadowDepth, closePath:true};
|
||||
if (this.style.indexOf('filled') != -1) {
|
||||
sdopt.fill = true;
|
||||
}
|
||||
if (this.style.indexOf('ircle') != -1) {
|
||||
sdopt.isarc = true;
|
||||
sdopt.closePath = false;
|
||||
}
|
||||
this.shadowRenderer.init(sdopt);
|
||||
|
||||
var shopt = {fill:false, isarc:false, strokeStyle:this.color, fillStyle:this.color, lineWidth:this.lineWidth, closePath:true};
|
||||
if (this.style.indexOf('filled') != -1) {
|
||||
shopt.fill = true;
|
||||
}
|
||||
if (this.style.indexOf('ircle') != -1) {
|
||||
shopt.isarc = true;
|
||||
shopt.closePath = false;
|
||||
}
|
||||
this.shapeRenderer.init(shopt);
|
||||
};
|
||||
|
||||
$.jqplot.MarkerRenderer.prototype.drawDiamond = function(x, y, ctx, fill, options) {
|
||||
var stretch = 1.2;
|
||||
var dx = this.size/2/stretch;
|
||||
var dy = this.size/2*stretch;
|
||||
var points = [[x-dx, y], [x, y+dy], [x+dx, y], [x, y-dy]];
|
||||
if (this.shadow) {
|
||||
this.shadowRenderer.draw(ctx, points);
|
||||
}
|
||||
this.shapeRenderer.draw(ctx, points, options);
|
||||
};
|
||||
|
||||
$.jqplot.MarkerRenderer.prototype.drawPlus = function(x, y, ctx, fill, options) {
|
||||
var stretch = 1.0;
|
||||
var dx = this.size/2*stretch;
|
||||
var dy = this.size/2*stretch;
|
||||
var points1 = [[x, y-dy], [x, y+dy]];
|
||||
var points2 = [[x+dx, y], [x-dx, y]];
|
||||
var opts = $.extend(true, {}, this.options, {closePath:false});
|
||||
if (this.shadow) {
|
||||
this.shadowRenderer.draw(ctx, points1, {closePath:false});
|
||||
this.shadowRenderer.draw(ctx, points2, {closePath:false});
|
||||
}
|
||||
this.shapeRenderer.draw(ctx, points1, opts);
|
||||
this.shapeRenderer.draw(ctx, points2, opts);
|
||||
};
|
||||
|
||||
$.jqplot.MarkerRenderer.prototype.drawX = function(x, y, ctx, fill, options) {
|
||||
var stretch = 1.0;
|
||||
var dx = this.size/2*stretch;
|
||||
var dy = this.size/2*stretch;
|
||||
var opts = $.extend(true, {}, this.options, {closePath:false});
|
||||
var points1 = [[x-dx, y-dy], [x+dx, y+dy]];
|
||||
var points2 = [[x-dx, y+dy], [x+dx, y-dy]];
|
||||
if (this.shadow) {
|
||||
this.shadowRenderer.draw(ctx, points1, {closePath:false});
|
||||
this.shadowRenderer.draw(ctx, points2, {closePath:false});
|
||||
}
|
||||
this.shapeRenderer.draw(ctx, points1, opts);
|
||||
this.shapeRenderer.draw(ctx, points2, opts);
|
||||
};
|
||||
|
||||
$.jqplot.MarkerRenderer.prototype.drawDash = function(x, y, ctx, fill, options) {
|
||||
var stretch = 1.0;
|
||||
var dx = this.size/2*stretch;
|
||||
var dy = this.size/2*stretch;
|
||||
var points = [[x-dx, y], [x+dx, y]];
|
||||
if (this.shadow) {
|
||||
this.shadowRenderer.draw(ctx, points);
|
||||
}
|
||||
this.shapeRenderer.draw(ctx, points, options);
|
||||
};
|
||||
|
||||
$.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;
|
||||
var dy = this.size/2*stretch;
|
||||
var points = [[x-dx, y-dy], [x-dx, y+dy], [x+dx, y+dy], [x+dx, y-dy]];
|
||||
if (this.shadow) {
|
||||
this.shadowRenderer.draw(ctx, points);
|
||||
}
|
||||
this.shapeRenderer.draw(ctx, points, options);
|
||||
};
|
||||
|
||||
$.jqplot.MarkerRenderer.prototype.drawCircle = function(x, y, ctx, fill, options) {
|
||||
var radius = this.size/2;
|
||||
var end = 2*Math.PI;
|
||||
var points = [x, y, radius, 0, end, true];
|
||||
if (this.shadow) {
|
||||
this.shadowRenderer.draw(ctx, points);
|
||||
}
|
||||
this.shapeRenderer.draw(ctx, points, options);
|
||||
};
|
||||
|
||||
$.jqplot.MarkerRenderer.prototype.draw = function(x, y, ctx, options) {
|
||||
options = options || {};
|
||||
// hack here b/c shape renderer uses canvas based color style options
|
||||
// and marker uses css style names.
|
||||
if (options.show == null || options.show != false) {
|
||||
if (options.color && !options.fillStyle) {
|
||||
options.fillStyle = options.color;
|
||||
}
|
||||
if (options.color && !options.strokeStyle) {
|
||||
options.strokeStyle = options.color;
|
||||
}
|
||||
switch (this.style) {
|
||||
case 'diamond':
|
||||
this.drawDiamond(x,y,ctx, false, options);
|
||||
break;
|
||||
case 'filledDiamond':
|
||||
this.drawDiamond(x,y,ctx, true, options);
|
||||
break;
|
||||
case 'circle':
|
||||
this.drawCircle(x,y,ctx, false, options);
|
||||
break;
|
||||
case 'filledCircle':
|
||||
this.drawCircle(x,y,ctx, true, options);
|
||||
break;
|
||||
case 'square':
|
||||
this.drawSquare(x,y,ctx, false, options);
|
||||
break;
|
||||
case 'filledSquare':
|
||||
this.drawSquare(x,y,ctx, true, options);
|
||||
break;
|
||||
case 'x':
|
||||
this.drawX(x,y,ctx, true, options);
|
||||
break;
|
||||
case 'plus':
|
||||
this.drawPlus(x,y,ctx, true, options);
|
||||
break;
|
||||
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;
|
||||
}
|
||||
}
|
||||
};
|
||||
})(jQuery);
|
140
msd2/tracking/piwik/libs/jqplot/jqplot.shadowRenderer.js
Normal file
140
msd2/tracking/piwik/libs/jqplot/jqplot.shadowRenderer.js
Normal file
@ -0,0 +1,140 @@
|
||||
/**
|
||||
* jqPlot
|
||||
* Pure JavaScript plotting plugin using jQuery
|
||||
*
|
||||
* Version: @VERSION
|
||||
* Revision: @REVISION
|
||||
*
|
||||
* 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.shadowRenderer
|
||||
// The default jqPlot shadow renderer, rendering shadows behind shapes.
|
||||
$.jqplot.ShadowRenderer = function(options){
|
||||
// Group: Properties
|
||||
|
||||
// prop: angle
|
||||
// Angle of the shadow in degrees. Measured counter-clockwise from the x axis.
|
||||
this.angle = 45;
|
||||
// prop: offset
|
||||
// Pixel offset at the given shadow angle of each shadow stroke from the last stroke.
|
||||
this.offset = 1;
|
||||
// prop: alpha
|
||||
// alpha transparency of shadow stroke.
|
||||
this.alpha = 0.07;
|
||||
// prop: lineWidth
|
||||
// width of the shadow line stroke.
|
||||
this.lineWidth = 1.5;
|
||||
// prop: lineJoin
|
||||
// How line segments of the shadow are joined.
|
||||
this.lineJoin = 'miter';
|
||||
// prop: lineCap
|
||||
// how ends of the shadow line are rendered.
|
||||
this.lineCap = 'round';
|
||||
// prop; closePath
|
||||
// whether line path segment is closed upon itself.
|
||||
this.closePath = false;
|
||||
// prop: fill
|
||||
// whether to fill the shape.
|
||||
this.fill = false;
|
||||
// prop: depth
|
||||
// how many times the shadow is stroked. Each stroke will be offset by offset at angle degrees.
|
||||
this.depth = 3;
|
||||
this.strokeStyle = 'rgba(0,0,0,0.1)';
|
||||
// prop: isarc
|
||||
// whether the shadow is an arc or not.
|
||||
this.isarc = false;
|
||||
|
||||
$.extend(true, this, options);
|
||||
};
|
||||
|
||||
$.jqplot.ShadowRenderer.prototype.init = function(options) {
|
||||
$.extend(true, this, options);
|
||||
};
|
||||
|
||||
// function: draw
|
||||
// draws an transparent black (i.e. gray) shadow.
|
||||
//
|
||||
// ctx - canvas drawing context
|
||||
// points - array of points or [x, y, radius, start angle (rad), end angle (rad)]
|
||||
$.jqplot.ShadowRenderer.prototype.draw = function(ctx, points, options) {
|
||||
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);
|
||||
ctxPattern.beginPath();
|
||||
if (isarc) {
|
||||
ctx.arc(points[0], points[1], points[2], points[3], points[4], true);
|
||||
}
|
||||
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) {
|
||||
ctxPattern.moveTo(points[i][0], points[i][1]);
|
||||
move = false;
|
||||
}
|
||||
else {
|
||||
ctxPattern.lineTo(points[i][0], points[i][1]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
move = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (closePath) {
|
||||
ctxPattern.closePath();
|
||||
}
|
||||
if (fill) {
|
||||
ctx.fill();
|
||||
}
|
||||
else {
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
ctx.restore();
|
||||
};
|
||||
})(jQuery);
|
166
msd2/tracking/piwik/libs/jqplot/jqplot.shapeRenderer.js
Normal file
166
msd2/tracking/piwik/libs/jqplot/jqplot.shapeRenderer.js
Normal file
@ -0,0 +1,166 @@
|
||||
/**
|
||||
* jqPlot
|
||||
* Pure JavaScript plotting plugin using jQuery
|
||||
*
|
||||
* Version: @VERSION
|
||||
* Revision: @REVISION
|
||||
*
|
||||
* 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.shapeRenderer
|
||||
// The default jqPlot shape renderer. Given a set of points will
|
||||
// plot them and either stroke a line (fill = false) or fill them (fill = true).
|
||||
// If a filled shape is desired, closePath = true must also be set to close
|
||||
// the shape.
|
||||
$.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';
|
||||
// prop: lineCap
|
||||
// how ends of the shadow line are rendered.
|
||||
this.lineCap = 'round';
|
||||
// prop; closePath
|
||||
// whether line path segment is closed upon itself.
|
||||
this.closePath = false;
|
||||
// prop: fill
|
||||
// whether to fill the shape.
|
||||
this.fill = false;
|
||||
// prop: isarc
|
||||
// whether the shadow is an arc or not.
|
||||
this.isarc = false;
|
||||
// prop: fillRect
|
||||
// true to draw shape as a filled rectangle.
|
||||
this.fillRect = false;
|
||||
// prop: strokeRect
|
||||
// true to draw shape as a stroked rectangle.
|
||||
this.strokeRect = false;
|
||||
// prop: clearRect
|
||||
// true to cear a rectangle.
|
||||
this.clearRect = false;
|
||||
// prop: strokeStyle
|
||||
// css color spec for the stoke style
|
||||
this.strokeStyle = '#999999';
|
||||
// prop: fillStyle
|
||||
// css color spec for the fill style.
|
||||
this.fillStyle = '#999999';
|
||||
|
||||
$.extend(true, this, options);
|
||||
};
|
||||
|
||||
$.jqplot.ShapeRenderer.prototype.init = function(options) {
|
||||
$.extend(true, this, options);
|
||||
};
|
||||
|
||||
// function: draw
|
||||
// draws the shape.
|
||||
//
|
||||
// ctx - canvas drawing context
|
||||
// points - array of points for shapes or
|
||||
// [x, y, width, height] for rectangles or
|
||||
// [x, y, radius, start angle (rad), end angle (rad)] for circles and arcs.
|
||||
$.jqplot.ShapeRenderer.prototype.draw = function(ctx, points, options) {
|
||||
ctx.save();
|
||||
var opts = (options != null) ? options : {};
|
||||
var fill = (opts.fill != null) ? opts.fill : this.fill;
|
||||
var closePath = (opts.closePath != null) ? opts.closePath : this.closePath;
|
||||
var fillRect = (opts.fillRect != null) ? opts.fillRect : this.fillRect;
|
||||
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.lineJoin || this.lineJoin;
|
||||
ctx.lineCap = opts.lineCap || this.lineCap;
|
||||
ctx.strokeStyle = (opts.strokeStyle || opts.color) || this.strokeStyle;
|
||||
ctx.fillStyle = opts.fillStyle || this.fillStyle;
|
||||
ctx.beginPath();
|
||||
if (isarc) {
|
||||
ctx.arc(points[0], points[1], points[2], points[3], points[4], true);
|
||||
if (closePath) {
|
||||
ctx.closePath();
|
||||
}
|
||||
if (fill) {
|
||||
ctx.fill();
|
||||
}
|
||||
else {
|
||||
ctx.stroke();
|
||||
}
|
||||
ctx.restore();
|
||||
return;
|
||||
}
|
||||
else if (clearRect) {
|
||||
ctx.clearRect(points[0], points[1], points[2], points[3]);
|
||||
ctx.restore();
|
||||
return;
|
||||
}
|
||||
else if (fillRect || strokeRect) {
|
||||
if (fillRect) {
|
||||
ctx.fillRect(points[0], points[1], points[2], points[3]);
|
||||
}
|
||||
if (strokeRect) {
|
||||
ctx.strokeRect(points[0], points[1], points[2], points[3]);
|
||||
ctx.restore();
|
||||
return;
|
||||
}
|
||||
}
|
||||
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) {
|
||||
ctxPattern.moveTo(points[i][0], points[i][1]);
|
||||
move = false;
|
||||
}
|
||||
else {
|
||||
ctxPattern.lineTo(points[i][0], points[i][1]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
move = true;
|
||||
}
|
||||
}
|
||||
if (closePath) {
|
||||
ctxPattern.closePath();
|
||||
}
|
||||
if (fill) {
|
||||
ctx.fill();
|
||||
}
|
||||
else {
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
ctx.restore();
|
||||
};
|
||||
})(jQuery);
|
326
msd2/tracking/piwik/libs/jqplot/jqplot.sprintf.js
Normal file
326
msd2/tracking/piwik/libs/jqplot/jqplot.sprintf.js
Normal file
@ -0,0 +1,326 @@
|
||||
/**
|
||||
* jqPlot
|
||||
* Pure JavaScript plotting plugin using jQuery
|
||||
*
|
||||
* Version: @VERSION
|
||||
* Revision: @REVISION
|
||||
*
|
||||
* 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($) {
|
||||
/**
|
||||
* JavaScript printf/sprintf functions.
|
||||
*
|
||||
* This code has been adapted from the publicly available sprintf methods
|
||||
* by Ash Searle. His original header follows:
|
||||
*
|
||||
* This code is unrestricted: you are free to use it however you like.
|
||||
*
|
||||
* The functions should work as expected, performing left or right alignment,
|
||||
* truncating strings, outputting numbers with a required precision etc.
|
||||
*
|
||||
* For complex cases, these functions follow the Perl implementations of
|
||||
* (s)printf, allowing arguments to be passed out-of-order, and to set the
|
||||
* precision or length of the output based on arguments instead of fixed
|
||||
* numbers.
|
||||
*
|
||||
* See http://perldoc.perl.org/functions/sprintf.html for more information.
|
||||
*
|
||||
* Implemented:
|
||||
* - zero and space-padding
|
||||
* - right and left-alignment,
|
||||
* - base X prefix (binary, octal and hex)
|
||||
* - positive number prefix
|
||||
* - (minimum) width
|
||||
* - precision / truncation / maximum width
|
||||
* - out of order arguments
|
||||
*
|
||||
* Not implemented (yet):
|
||||
* - vector flag
|
||||
* - size (bytes, words, long-words etc.)
|
||||
*
|
||||
* Will not implement:
|
||||
* - %n or %p (no pass-by-reference in JavaScript)
|
||||
*
|
||||
* @version 2007.04.27
|
||||
* @author Ash Searle
|
||||
*
|
||||
* You can see the original work and comments on his blog:
|
||||
* http://hexmen.com/blog/2007/03/printf-sprintf/
|
||||
* http://hexmen.com/js/sprintf.js
|
||||
*/
|
||||
|
||||
/**
|
||||
* @Modifications 2009.05.26
|
||||
* @author Chris Leonello
|
||||
*
|
||||
* Added %p %P specifier
|
||||
* Acts like %g or %G but will not add more significant digits to the output than present in the input.
|
||||
* Example:
|
||||
* Format: '%.3p', Input: 0.012, Output: 0.012
|
||||
* Format: '%.3g', Input: 0.012, Output: 0.0120
|
||||
* Format: '%.4p', Input: 12.0, Output: 12.0
|
||||
* 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) {
|
||||
var padding = (str.length >= len) ? '' : Array(1 + len - str.length >>> 0).join(chr);
|
||||
return leftJustify ? str + padding : padding + str;
|
||||
|
||||
}
|
||||
|
||||
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) {
|
||||
var spchar = ' ';
|
||||
if (htmlSpace) { spchar = ' '; }
|
||||
if (leftJustify || !zeroPad) {
|
||||
value = pad(value, minWidth, spchar, leftJustify);
|
||||
} else {
|
||||
value = value.slice(0, prefix.length) + pad('', diff, '0', true) + value.slice(prefix.length);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function formatBaseX(value, base, prefix, leftJustify, minWidth, precision, zeroPad, htmlSpace) {
|
||||
// Note: casts negative numbers to positive ones
|
||||
var number = value >>> 0;
|
||||
prefix = prefix && number && {'2': '0b', '8': '0', '16': '0x'}[base] || '';
|
||||
value = prefix + pad(number.toString(base), precision || 0, '0', false);
|
||||
return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace);
|
||||
}
|
||||
|
||||
function formatString(value, leftJustify, minWidth, precision, zeroPad, htmlSpace) {
|
||||
if (precision != null) {
|
||||
value = value.slice(0, precision);
|
||||
}
|
||||
return justify(value, '', leftJustify, minWidth, zeroPad, htmlSpace);
|
||||
}
|
||||
|
||||
var a = arguments, i = 0, format = a[i++];
|
||||
|
||||
return format.replace($.jqplot.sprintf.regex, function(substring, valueIndex, flags, minWidth, _, precision, type) {
|
||||
if (substring == '%%') { return '%'; }
|
||||
|
||||
// parse flags
|
||||
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
|
||||
// we want to ignore null, undefined and empty-string values
|
||||
|
||||
if (!minWidth) {
|
||||
minWidth = 0;
|
||||
}
|
||||
else if (minWidth == '*') {
|
||||
minWidth = +a[i++];
|
||||
}
|
||||
else if (minWidth.charAt(0) == '*') {
|
||||
minWidth = +a[minWidth.slice(1, -1)];
|
||||
}
|
||||
else {
|
||||
minWidth = +minWidth;
|
||||
}
|
||||
|
||||
// Note: undocumented perl feature:
|
||||
if (minWidth < 0) {
|
||||
minWidth = -minWidth;
|
||||
leftJustify = true;
|
||||
}
|
||||
|
||||
if (!isFinite(minWidth)) {
|
||||
throw new Error('$.jqplot.sprintf: (minimum-)width must be finite');
|
||||
}
|
||||
|
||||
if (!precision) {
|
||||
precision = 'fFeE'.indexOf(type) > -1 ? 6 : (type == 'd') ? 0 : void(0);
|
||||
}
|
||||
else if (precision == '*') {
|
||||
precision = +a[i++];
|
||||
}
|
||||
else if (precision.charAt(0) == '*') {
|
||||
precision = +a[precision.slice(1, -1)];
|
||||
}
|
||||
else {
|
||||
precision = +precision;
|
||||
}
|
||||
|
||||
// grab value using valueIndex if required?
|
||||
var value = valueIndex ? a[valueIndex.slice(0, -1)] : a[i++];
|
||||
|
||||
switch (type) {
|
||||
case 's': {
|
||||
if (value == null) {
|
||||
return '';
|
||||
}
|
||||
return formatString(String(value), leftJustify, minWidth, precision, zeroPad, htmlSpace);
|
||||
}
|
||||
case 'c': return formatString(String.fromCharCode(+value), leftJustify, minWidth, precision, zeroPad, htmlSpace);
|
||||
case 'b': return formatBaseX(value, 2, prefixBaseX, leftJustify, minWidth, precision, zeroPad,htmlSpace);
|
||||
case 'o': return formatBaseX(value, 8, prefixBaseX, leftJustify, minWidth, precision, zeroPad, htmlSpace);
|
||||
case 'x': return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad, htmlSpace);
|
||||
case 'X': return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad, htmlSpace).toUpperCase();
|
||||
case 'u': return formatBaseX(value, 10, prefixBaseX, leftJustify, minWidth, precision, zeroPad, htmlSpace);
|
||||
case 'i': {
|
||||
var number = parseInt(+value, 10);
|
||||
if (isNaN(number)) {
|
||||
return '';
|
||||
}
|
||||
var prefix = number < 0 ? '-' : positivePrefix;
|
||||
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': {
|
||||
var number = Math.round(+value);
|
||||
if (isNaN(number)) {
|
||||
return '';
|
||||
}
|
||||
var prefix = number < 0 ? '-' : positivePrefix;
|
||||
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':
|
||||
case 'E':
|
||||
case 'f':
|
||||
case 'F':
|
||||
case 'g':
|
||||
case 'G':
|
||||
{
|
||||
var number = +value;
|
||||
if (isNaN(number)) {
|
||||
return '';
|
||||
}
|
||||
var prefix = number < 0 ? '-' : positivePrefix;
|
||||
var method = ['toExponential', 'toFixed', 'toPrecision']['efg'.indexOf(type.toLowerCase())];
|
||||
var textTransform = ['toString', 'toUpperCase']['eEfFgG'.indexOf(type) % 2];
|
||||
var number_str = Math.abs(number)[method](precision);
|
||||
|
||||
// Apply the decimal mark properly by splitting the number by the
|
||||
// decimalMark, applying thousands separator, and then placing it
|
||||
// back in.
|
||||
var parts = number_str.toString().split('.');
|
||||
parts[0] = thousandSeparation ? thousand_separate(parts[0]) : parts[0];
|
||||
number_str = parts.join($.jqplot.sprintf.decimalMark);
|
||||
|
||||
value = prefix + number_str;
|
||||
var justified = justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace)[textTransform]();
|
||||
|
||||
return justified;
|
||||
}
|
||||
case 'p':
|
||||
case 'P':
|
||||
{
|
||||
// make sure number is a number
|
||||
var number = +value;
|
||||
if (isNaN(number)) {
|
||||
return '';
|
||||
}
|
||||
var prefix = number < 0 ? '-' : positivePrefix;
|
||||
|
||||
var parts = String(Number(Math.abs(number)).toExponential()).split(/e|E/);
|
||||
var sd = (parts[0].indexOf('.') != -1) ? parts[0].length - 1 : String(number).length;
|
||||
var zeros = (parts[1] < 0) ? -parts[1] - 1 : 0;
|
||||
|
||||
if (Math.abs(number) < 1) {
|
||||
if (sd + zeros <= precision) {
|
||||
value = prefix + Math.abs(number).toPrecision(sd);
|
||||
}
|
||||
else {
|
||||
if (sd <= precision - 1) {
|
||||
value = prefix + Math.abs(number).toExponential(sd-1);
|
||||
}
|
||||
else {
|
||||
value = prefix + Math.abs(number).toExponential(precision-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
var prec = (sd <= precision) ? sd : precision;
|
||||
value = prefix + Math.abs(number).toPrecision(prec);
|
||||
}
|
||||
var textTransform = ['toString', 'toUpperCase']['pP'.indexOf(type) % 2];
|
||||
return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace)[textTransform]();
|
||||
}
|
||||
case 'n': return '';
|
||||
default: return substring;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$.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.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;
|
||||
};
|
||||
|
||||
})(jQuery);
|
323
msd2/tracking/piwik/libs/jqplot/jqplot.tableLegendRenderer.js
Normal file
323
msd2/tracking/piwik/libs/jqplot/jqplot.tableLegendRenderer.js
Normal file
@ -0,0 +1,323 @@
|
||||
/**
|
||||
* jqPlot
|
||||
* Pure JavaScript plotting plugin using jQuery
|
||||
*
|
||||
* Version: @VERSION
|
||||
* Revision: @REVISION
|
||||
*
|
||||
* 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.TableLegendRenderer
|
||||
// The default legend renderer for jqPlot.
|
||||
$.jqplot.TableLegendRenderer = function(){
|
||||
//
|
||||
};
|
||||
|
||||
$.jqplot.TableLegendRenderer.prototype.init = function(options) {
|
||||
$.extend(true, this, options);
|
||||
};
|
||||
|
||||
$.jqplot.TableLegendRenderer.prototype.addrow = function (label, color, pad, reverse) {
|
||||
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){
|
||||
tr.prependTo(this._elem);
|
||||
}
|
||||
|
||||
else{
|
||||
tr.appendTo(this._elem);
|
||||
}
|
||||
|
||||
if (this.showSwatches) {
|
||||
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) {
|
||||
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) {
|
||||
td.text(label);
|
||||
}
|
||||
else {
|
||||
td.html(label);
|
||||
}
|
||||
}
|
||||
td = null;
|
||||
div0 = null;
|
||||
div1 = null;
|
||||
tr = null;
|
||||
elem = null;
|
||||
};
|
||||
|
||||
// called with scope of legend
|
||||
$.jqplot.TableLegendRenderer.prototype.draw = function() {
|
||||
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 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,
|
||||
s;
|
||||
for (var i = 0; i< series.length; i++) {
|
||||
s = series[i];
|
||||
if (s._stack || s.renderer.constructor == $.jqplot.BezierCurveRenderer){
|
||||
reverse = true;
|
||||
}
|
||||
if (s.show && s.showLabel) {
|
||||
var lt = this.labels[i] || s.label.toString();
|
||||
if (lt) {
|
||||
var color = s.color;
|
||||
if (reverse && i < series.length - 1){
|
||||
pad = true;
|
||||
}
|
||||
else if (reverse && i == series.length - 1){
|
||||
pad = false;
|
||||
}
|
||||
this.renderer.addrow.call(this, lt, color, pad, reverse);
|
||||
pad = true;
|
||||
}
|
||||
// let plugins add more rows to legend. Used by trend line plugin.
|
||||
for (var j=0; j<$.jqplot.addLegendRowHooks.length; j++) {
|
||||
var item = $.jqplot.addLegendRowHooks[j].call(this, s);
|
||||
if (item) {
|
||||
this.renderer.addrow.call(this, item.label, item.color, pad);
|
||||
pad = true;
|
||||
}
|
||||
}
|
||||
lt = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this._elem;
|
||||
};
|
||||
|
||||
$.jqplot.TableLegendRenderer.prototype.pack = function(offsets) {
|
||||
if (this.show) {
|
||||
if (this.placement == 'insideGrid') {
|
||||
switch (this.location) {
|
||||
case 'nw':
|
||||
var a = offsets.left;
|
||||
var b = offsets.top;
|
||||
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 = offsets.top;
|
||||
this._elem.css('left', a);
|
||||
this._elem.css('top', b);
|
||||
break;
|
||||
case 'ne':
|
||||
var a = offsets.right;
|
||||
var b = offsets.top;
|
||||
this._elem.css({right:a, top:b});
|
||||
break;
|
||||
case 'e':
|
||||
var a = offsets.right;
|
||||
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;
|
||||
var b = offsets.bottom;
|
||||
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._elem.css({left:a, bottom:b});
|
||||
break;
|
||||
case 'sw':
|
||||
var a = offsets.left;
|
||||
var b = offsets.bottom;
|
||||
this._elem.css({left:a, bottom:b});
|
||||
break;
|
||||
case 'w':
|
||||
var a = offsets.left;
|
||||
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 = offsets.right;
|
||||
var b = offsets.bottom;
|
||||
this._elem.css({right:a, bottom:b});
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
else if (this.placement == 'outside'){
|
||||
switch (this.location) {
|
||||
case 'nw':
|
||||
var a = this._plotDimensions.width - offsets.left;
|
||||
var b = offsets.top;
|
||||
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 - offsets.top;
|
||||
this._elem.css('left', a);
|
||||
this._elem.css('bottom', b);
|
||||
break;
|
||||
case 'ne':
|
||||
var a = this._plotDimensions.width - offsets.right;
|
||||
var b = offsets.top;
|
||||
this._elem.css({left:a, top:b});
|
||||
break;
|
||||
case 'e':
|
||||
var a = this._plotDimensions.width - offsets.right;
|
||||
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;
|
||||
var b = offsets.bottom;
|
||||
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._elem.css({left:a, top:b});
|
||||
break;
|
||||
case 'sw':
|
||||
var a = this._plotDimensions.width - offsets.left;
|
||||
var b = offsets.bottom;
|
||||
this._elem.css({right:a, bottom:b});
|
||||
break;
|
||||
case 'w':
|
||||
var a = this._plotDimensions.width - offsets.left;
|
||||
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 = offsets.right;
|
||||
var b = offsets.bottom;
|
||||
this._elem.css({right:a, bottom:b});
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (this.location) {
|
||||
case 'nw':
|
||||
this._elem.css({left:0, top:offsets.top});
|
||||
break;
|
||||
case 'n':
|
||||
var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2;
|
||||
this._elem.css({left: a, top:offsets.top});
|
||||
break;
|
||||
case 'ne':
|
||||
this._elem.css({right:0, top:offsets.top});
|
||||
break;
|
||||
case 'e':
|
||||
var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2;
|
||||
this._elem.css({right:offsets.right, top:b});
|
||||
break;
|
||||
case 'se':
|
||||
this._elem.css({right:offsets.right, bottom:offsets.bottom});
|
||||
break;
|
||||
case 's':
|
||||
var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2;
|
||||
this._elem.css({left: a, bottom:offsets.bottom});
|
||||
break;
|
||||
case 'sw':
|
||||
this._elem.css({left:offsets.left, bottom:offsets.bottom});
|
||||
break;
|
||||
case 'w':
|
||||
var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2;
|
||||
this._elem.css({left:offsets.left, top:b});
|
||||
break;
|
||||
default: // same as 'se'
|
||||
this._elem.css({right:offsets.right, bottom:offsets.bottom});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
})(jQuery);
|
917
msd2/tracking/piwik/libs/jqplot/jqplot.themeEngine.js
Normal file
917
msd2/tracking/piwik/libs/jqplot/jqplot.themeEngine.js
Normal file
@ -0,0 +1,917 @@
|
||||
/**
|
||||
* jqPlot
|
||||
* Pure JavaScript plotting plugin using jQuery
|
||||
*
|
||||
* Version: @VERSION
|
||||
* Revision: @REVISION
|
||||
*
|
||||
* 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.ThemeEngine
|
||||
* Theme Engine provides a programatic way to change some of the more
|
||||
* common jqplot styling options such as fonts, colors and grid options.
|
||||
* A theme engine instance is created with each plot. The theme engine
|
||||
* manages a collection of themes which can be modified, added to, or
|
||||
* applied to the plot.
|
||||
*
|
||||
* The themeEngine class is not instantiated directly.
|
||||
* When a plot is initialized, the current plot options are scanned
|
||||
* an a default theme named "Default" is created. This theme is
|
||||
* used as the basis for other themes added to the theme engine and
|
||||
* is always available.
|
||||
*
|
||||
* A theme is a simple javascript object with styling parameters for
|
||||
* various entities of the plot. A theme has the form:
|
||||
*
|
||||
*
|
||||
* > {
|
||||
* > _name:f "Default",
|
||||
* > target: {
|
||||
* > backgroundColor: "transparent"
|
||||
* > },
|
||||
* > legend: {
|
||||
* > textColor: null,
|
||||
* > fontFamily: null,
|
||||
* > fontSize: null,
|
||||
* > border: null,
|
||||
* > background: null
|
||||
* > },
|
||||
* > title: {
|
||||
* > textColor: "rgb(102, 102, 102)",
|
||||
* > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif",
|
||||
* > fontSize: "19.2px",
|
||||
* > textAlign: "center"
|
||||
* > },
|
||||
* > seriesStyles: {},
|
||||
* > series: [{
|
||||
* > color: "#4bb2c5",
|
||||
* > lineWidth: 2.5,
|
||||
* > linePattern: "solid",
|
||||
* > shadow: true,
|
||||
* > fillColor: "#4bb2c5",
|
||||
* > showMarker: true,
|
||||
* > markerOptions: {
|
||||
* > color: "#4bb2c5",
|
||||
* > show: true,
|
||||
* > style: 'filledCircle',
|
||||
* > lineWidth: 1.5,
|
||||
* > size: 4,
|
||||
* > shadow: true
|
||||
* > }
|
||||
* > }],
|
||||
* > grid: {
|
||||
* > drawGridlines: true,
|
||||
* > gridLineColor: "#cccccc",
|
||||
* > gridLineWidth: 1,
|
||||
* > backgroundColor: "#fffdf6",
|
||||
* > borderColor: "#999999",
|
||||
* > borderWidth: 2,
|
||||
* > shadow: true
|
||||
* > },
|
||||
* > axesStyles: {
|
||||
* > label: {},
|
||||
* > ticks: {}
|
||||
* > },
|
||||
* > axes: {
|
||||
* > xaxis: {
|
||||
* > borderColor: "#999999",
|
||||
* > borderWidth: 2,
|
||||
* > ticks: {
|
||||
* > show: true,
|
||||
* > showGridline: true,
|
||||
* > showLabel: true,
|
||||
* > showMark: true,
|
||||
* > size: 4,
|
||||
* > textColor: "",
|
||||
* > whiteSpace: "nowrap",
|
||||
* > fontSize: "12px",
|
||||
* > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif"
|
||||
* > },
|
||||
* > label: {
|
||||
* > textColor: "rgb(102, 102, 102)",
|
||||
* > whiteSpace: "normal",
|
||||
* > fontSize: "14.6667px",
|
||||
* > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif",
|
||||
* > fontWeight: "400"
|
||||
* > }
|
||||
* > },
|
||||
* > yaxis: {
|
||||
* > borderColor: "#999999",
|
||||
* > borderWidth: 2,
|
||||
* > ticks: {
|
||||
* > show: true,
|
||||
* > showGridline: true,
|
||||
* > showLabel: true,
|
||||
* > showMark: true,
|
||||
* > size: 4,
|
||||
* > textColor: "",
|
||||
* > whiteSpace: "nowrap",
|
||||
* > fontSize: "12px",
|
||||
* > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif"
|
||||
* > },
|
||||
* > label: {
|
||||
* > textColor: null,
|
||||
* > whiteSpace: null,
|
||||
* > fontSize: null,
|
||||
* > fontFamily: null,
|
||||
* > fontWeight: null
|
||||
* > }
|
||||
* > },
|
||||
* > x2axis: {...
|
||||
* > },
|
||||
* > ...
|
||||
* > y9axis: {...
|
||||
* > }
|
||||
* > }
|
||||
* > }
|
||||
*
|
||||
* "seriesStyles" is a style object that will be applied to all series in the plot.
|
||||
* It will forcibly override any styles applied on the individual series. "axesStyles" is
|
||||
* a style object that will be applied to all axes in the plot. It will also forcibly
|
||||
* override any styles on the individual axes.
|
||||
*
|
||||
* The example shown above has series options for a line series. Options for other
|
||||
* series types are shown below:
|
||||
*
|
||||
* Bar Series:
|
||||
*
|
||||
* > {
|
||||
* > color: "#4bb2c5",
|
||||
* > seriesColors: ["#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"],
|
||||
* > lineWidth: 2.5,
|
||||
* > shadow: true,
|
||||
* > barPadding: 2,
|
||||
* > barMargin: 10,
|
||||
* > barWidth: 15.09375,
|
||||
* > highlightColors: ["rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)"]
|
||||
* > }
|
||||
*
|
||||
* Pie Series:
|
||||
*
|
||||
* > {
|
||||
* > seriesColors: ["#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"],
|
||||
* > padding: 20,
|
||||
* > sliceMargin: 0,
|
||||
* > fill: true,
|
||||
* > shadow: true,
|
||||
* > startAngle: 0,
|
||||
* > lineWidth: 2.5,
|
||||
* > highlightColors: ["rgb(129,201,214)", "rgb(240,189,104)", "rgb(214,202,165)", "rgb(137,180,158)", "rgb(168,180,137)", "rgb(180,174,89)", "rgb(180,113,161)", "rgb(129,141,236)", "rgb(227,205,120)", "rgb(255,138,76)", "rgb(76,169,219)", "rgb(215,126,190)", "rgb(220,232,135)", "rgb(200,167,96)", "rgb(103,202,235)", "rgb(208,154,215)"]
|
||||
* > }
|
||||
*
|
||||
* Funnel Series:
|
||||
*
|
||||
* > {
|
||||
* > color: "#4bb2c5",
|
||||
* > lineWidth: 2,
|
||||
* > shadow: true,
|
||||
* > padding: {
|
||||
* > top: 20,
|
||||
* > right: 20,
|
||||
* > bottom: 20,
|
||||
* > left: 20
|
||||
* > },
|
||||
* > sectionMargin: 6,
|
||||
* > seriesColors: ["#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"],
|
||||
* > highlightColors: ["rgb(147,208,220)", "rgb(242,199,126)", "rgb(220,210,178)", "rgb(154,191,172)", "rgb(180,191,154)", "rgb(191,186,112)", "rgb(191,133,174)", "rgb(147,157,238)", "rgb(231,212,139)", "rgb(255,154,102)", "rgb(102,181,224)", "rgb(221,144,199)", "rgb(225,235,152)", "rgb(200,167,96)", "rgb(124,210,238)", "rgb(215,169,221)"]
|
||||
* > }
|
||||
*
|
||||
*/
|
||||
$.jqplot.ThemeEngine = function(){
|
||||
// Group: Properties
|
||||
//
|
||||
// prop: themes
|
||||
// hash of themes managed by the theme engine.
|
||||
// Indexed by theme name.
|
||||
this.themes = {};
|
||||
// prop: activeTheme
|
||||
// Pointer to currently active theme
|
||||
this.activeTheme=null;
|
||||
|
||||
};
|
||||
|
||||
// called with scope of plot
|
||||
$.jqplot.ThemeEngine.prototype.init = function() {
|
||||
// get the Default theme from the current plot settings.
|
||||
var th = new $.jqplot.Theme({_name:'Default'});
|
||||
var n, i, nn;
|
||||
|
||||
for (n in th.target) {
|
||||
if (n == "textColor") {
|
||||
th.target[n] = this.target.css('color');
|
||||
}
|
||||
else {
|
||||
th.target[n] = this.target.css(n);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.title.show && this.title._elem) {
|
||||
for (n in th.title) {
|
||||
if (n == "textColor") {
|
||||
th.title[n] = this.title._elem.css('color');
|
||||
}
|
||||
else {
|
||||
th.title[n] = this.title._elem.css(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (n in th.grid) {
|
||||
th.grid[n] = this.grid[n];
|
||||
}
|
||||
if (th.grid.backgroundColor == null && this.grid.background != null) {
|
||||
th.grid.backgroundColor = this.grid.background;
|
||||
}
|
||||
if (this.legend.show && this.legend._elem) {
|
||||
for (n in th.legend) {
|
||||
if (n == 'textColor') {
|
||||
th.legend[n] = this.legend._elem.css('color');
|
||||
}
|
||||
else {
|
||||
th.legend[n] = this.legend._elem.css(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
var s;
|
||||
|
||||
for (i=0; i<this.series.length; i++) {
|
||||
s = this.series[i];
|
||||
if (s.renderer.constructor == $.jqplot.LineRenderer) {
|
||||
th.series.push(new LineSeriesProperties());
|
||||
}
|
||||
else if (s.renderer.constructor == $.jqplot.BarRenderer) {
|
||||
th.series.push(new BarSeriesProperties());
|
||||
}
|
||||
else if (s.renderer.constructor == $.jqplot.PieRenderer) {
|
||||
th.series.push(new PieSeriesProperties());
|
||||
}
|
||||
else if (s.renderer.constructor == $.jqplot.DonutRenderer) {
|
||||
th.series.push(new DonutSeriesProperties());
|
||||
}
|
||||
else if (s.renderer.constructor == $.jqplot.FunnelRenderer) {
|
||||
th.series.push(new FunnelSeriesProperties());
|
||||
}
|
||||
else if (s.renderer.constructor == $.jqplot.MeterGaugeRenderer) {
|
||||
th.series.push(new MeterSeriesProperties());
|
||||
}
|
||||
else {
|
||||
th.series.push({});
|
||||
}
|
||||
for (n in th.series[i]) {
|
||||
th.series[i][n] = s[n];
|
||||
}
|
||||
}
|
||||
var a, ax;
|
||||
for (n in this.axes) {
|
||||
ax = this.axes[n];
|
||||
a = th.axes[n] = new AxisProperties();
|
||||
a.borderColor = ax.borderColor;
|
||||
a.borderWidth = ax.borderWidth;
|
||||
if (ax._ticks && ax._ticks[0]) {
|
||||
for (nn in a.ticks) {
|
||||
if (ax._ticks[0].hasOwnProperty(nn)) {
|
||||
a.ticks[nn] = ax._ticks[0][nn];
|
||||
}
|
||||
else if (ax._ticks[0]._elem){
|
||||
a.ticks[nn] = ax._ticks[0]._elem.css(nn);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ax._label && ax._label.show) {
|
||||
for (nn in a.label) {
|
||||
// a.label[nn] = ax._label._elem.css(nn);
|
||||
if (ax._label[nn]) {
|
||||
a.label[nn] = ax._label[nn];
|
||||
}
|
||||
else if (ax._label._elem){
|
||||
if (nn == 'textColor') {
|
||||
a.label[nn] = ax._label._elem.css('color');
|
||||
}
|
||||
else {
|
||||
a.label[nn] = ax._label._elem.css(nn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.themeEngine._add(th);
|
||||
this.themeEngine.activeTheme = this.themeEngine.themes[th._name];
|
||||
};
|
||||
/**
|
||||
* Group: methods
|
||||
*
|
||||
* method: get
|
||||
*
|
||||
* Get and return the named theme or the active theme if no name given.
|
||||
*
|
||||
* parameter:
|
||||
*
|
||||
* name - name of theme to get.
|
||||
*
|
||||
* returns:
|
||||
*
|
||||
* Theme instance of given name.
|
||||
*/
|
||||
$.jqplot.ThemeEngine.prototype.get = function(name) {
|
||||
if (!name) {
|
||||
// return the active theme
|
||||
return this.activeTheme;
|
||||
}
|
||||
else {
|
||||
return this.themes[name];
|
||||
}
|
||||
};
|
||||
|
||||
function numericalOrder(a,b) { return a-b; }
|
||||
|
||||
/**
|
||||
* method: getThemeNames
|
||||
*
|
||||
* Return the list of theme names in this manager in alpha-numerical order.
|
||||
*
|
||||
* parameter:
|
||||
*
|
||||
* None
|
||||
*
|
||||
* returns:
|
||||
*
|
||||
* A the list of theme names in this manager in alpha-numerical order.
|
||||
*/
|
||||
$.jqplot.ThemeEngine.prototype.getThemeNames = function() {
|
||||
var tn = [];
|
||||
for (var n in this.themes) {
|
||||
tn.push(n);
|
||||
}
|
||||
return tn.sort(numericalOrder);
|
||||
};
|
||||
|
||||
/**
|
||||
* method: getThemes
|
||||
*
|
||||
* Return a list of themes in alpha-numerical order by name.
|
||||
*
|
||||
* parameter:
|
||||
*
|
||||
* None
|
||||
*
|
||||
* returns:
|
||||
*
|
||||
* A list of themes in alpha-numerical order by name.
|
||||
*/
|
||||
$.jqplot.ThemeEngine.prototype.getThemes = function() {
|
||||
var tn = [];
|
||||
var themes = [];
|
||||
for (var n in this.themes) {
|
||||
tn.push(n);
|
||||
}
|
||||
tn.sort(numericalOrder);
|
||||
for (var i=0; i<tn.length; i++) {
|
||||
themes.push(this.themes[tn[i]]);
|
||||
}
|
||||
return themes;
|
||||
};
|
||||
|
||||
$.jqplot.ThemeEngine.prototype.activate = function(plot, name) {
|
||||
// sometimes need to redraw whole plot.
|
||||
var redrawPlot = false;
|
||||
if (!name && this.activeTheme && this.activeTheme._name) {
|
||||
name = this.activeTheme._name;
|
||||
}
|
||||
if (!this.themes.hasOwnProperty(name)) {
|
||||
throw new Error("No theme of that name");
|
||||
}
|
||||
else {
|
||||
var th = this.themes[name];
|
||||
this.activeTheme = th;
|
||||
var val, checkBorderColor = false, checkBorderWidth = false;
|
||||
var arr = ['xaxis', 'x2axis', 'yaxis', 'y2axis'];
|
||||
|
||||
for (i=0; i<arr.length; i++) {
|
||||
var ax = arr[i];
|
||||
if (th.axesStyles.borderColor != null) {
|
||||
plot.axes[ax].borderColor = th.axesStyles.borderColor;
|
||||
}
|
||||
if (th.axesStyles.borderWidth != null) {
|
||||
plot.axes[ax].borderWidth = th.axesStyles.borderWidth;
|
||||
}
|
||||
}
|
||||
|
||||
for (var axname in plot.axes) {
|
||||
var axis = plot.axes[axname];
|
||||
if (axis.show) {
|
||||
var thaxis = th.axes[axname] || {};
|
||||
var thaxstyle = th.axesStyles;
|
||||
var thax = $.jqplot.extend(true, {}, thaxis, thaxstyle);
|
||||
val = (th.axesStyles.borderColor != null) ? th.axesStyles.borderColor : thax.borderColor;
|
||||
if (thax.borderColor != null) {
|
||||
axis.borderColor = thax.borderColor;
|
||||
redrawPlot = true;
|
||||
}
|
||||
val = (th.axesStyles.borderWidth != null) ? th.axesStyles.borderWidth : thax.borderWidth;
|
||||
if (thax.borderWidth != null) {
|
||||
axis.borderWidth = thax.borderWidth;
|
||||
redrawPlot = true;
|
||||
}
|
||||
if (axis._ticks && axis._ticks[0]) {
|
||||
for (var nn in thax.ticks) {
|
||||
// val = null;
|
||||
// if (th.axesStyles.ticks && th.axesStyles.ticks[nn] != null) {
|
||||
// val = th.axesStyles.ticks[nn];
|
||||
// }
|
||||
// else if (thax.ticks[nn] != null){
|
||||
// val = thax.ticks[nn]
|
||||
// }
|
||||
val = thax.ticks[nn];
|
||||
if (val != null) {
|
||||
axis.tickOptions[nn] = val;
|
||||
axis._ticks = [];
|
||||
redrawPlot = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (axis._label && axis._label.show) {
|
||||
for (var nn in thax.label) {
|
||||
// val = null;
|
||||
// if (th.axesStyles.label && th.axesStyles.label[nn] != null) {
|
||||
// val = th.axesStyles.label[nn];
|
||||
// }
|
||||
// else if (thax.label && thax.label[nn] != null){
|
||||
// val = thax.label[nn]
|
||||
// }
|
||||
val = thax.label[nn];
|
||||
if (val != null) {
|
||||
axis.labelOptions[nn] = val;
|
||||
redrawPlot = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for (var n in th.grid) {
|
||||
if (th.grid[n] != null) {
|
||||
plot.grid[n] = th.grid[n];
|
||||
}
|
||||
}
|
||||
if (!redrawPlot) {
|
||||
plot.grid.draw();
|
||||
}
|
||||
|
||||
if (plot.legend.show) {
|
||||
for (n in th.legend) {
|
||||
if (th.legend[n] != null) {
|
||||
plot.legend[n] = th.legend[n];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (plot.title.show) {
|
||||
for (n in th.title) {
|
||||
if (th.title[n] != null) {
|
||||
plot.title[n] = th.title[n];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var i;
|
||||
for (i=0; i<th.series.length; i++) {
|
||||
var opts = {};
|
||||
var redrawSeries = false;
|
||||
for (n in th.series[i]) {
|
||||
val = (th.seriesStyles[n] != null) ? th.seriesStyles[n] : th.series[i][n];
|
||||
if (val != null) {
|
||||
opts[n] = val;
|
||||
if (n == 'color') {
|
||||
plot.series[i].renderer.shapeRenderer.fillStyle = val;
|
||||
plot.series[i].renderer.shapeRenderer.strokeStyle = val;
|
||||
plot.series[i][n] = val;
|
||||
}
|
||||
else if ((n == 'lineWidth') || (n == 'linePattern')) {
|
||||
plot.series[i].renderer.shapeRenderer[n] = val;
|
||||
plot.series[i][n] = val;
|
||||
}
|
||||
else if (n == 'markerOptions') {
|
||||
merge (plot.series[i].markerOptions, val);
|
||||
merge (plot.series[i].markerRenderer, val);
|
||||
}
|
||||
else {
|
||||
plot.series[i][n] = val;
|
||||
}
|
||||
redrawPlot = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (redrawPlot) {
|
||||
plot.target.empty();
|
||||
plot.draw();
|
||||
}
|
||||
|
||||
for (n in th.target) {
|
||||
if (th.target[n] != null) {
|
||||
plot.target.css(n, th.target[n]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$.jqplot.ThemeEngine.prototype._add = function(theme, name) {
|
||||
if (name) {
|
||||
theme._name = name;
|
||||
}
|
||||
if (!theme._name) {
|
||||
theme._name = Date.parse(new Date());
|
||||
}
|
||||
if (!this.themes.hasOwnProperty(theme._name)) {
|
||||
this.themes[theme._name] = theme;
|
||||
}
|
||||
else {
|
||||
throw new Error("jqplot.ThemeEngine Error: Theme already in use");
|
||||
}
|
||||
};
|
||||
|
||||
// method remove
|
||||
// Delete the named theme, return true on success, false on failure.
|
||||
|
||||
|
||||
/**
|
||||
* method: remove
|
||||
*
|
||||
* Remove the given theme from the themeEngine.
|
||||
*
|
||||
* parameters:
|
||||
*
|
||||
* name - name of the theme to remove.
|
||||
*
|
||||
* returns:
|
||||
*
|
||||
* true on success, false on failure.
|
||||
*/
|
||||
$.jqplot.ThemeEngine.prototype.remove = function(name) {
|
||||
if (name == 'Default') {
|
||||
return false;
|
||||
}
|
||||
return delete this.themes[name];
|
||||
};
|
||||
|
||||
/**
|
||||
* method: newTheme
|
||||
*
|
||||
* Create a new theme based on the default theme, adding it the themeEngine.
|
||||
*
|
||||
* parameters:
|
||||
*
|
||||
* name - name of the new theme.
|
||||
* obj - optional object of styles to be applied to this new theme.
|
||||
*
|
||||
* returns:
|
||||
*
|
||||
* new Theme object.
|
||||
*/
|
||||
$.jqplot.ThemeEngine.prototype.newTheme = function(name, obj) {
|
||||
if (typeof(name) == 'object') {
|
||||
obj = obj || name;
|
||||
name = null;
|
||||
}
|
||||
if (obj && obj._name) {
|
||||
name = obj._name;
|
||||
}
|
||||
else {
|
||||
name = name || Date.parse(new Date());
|
||||
}
|
||||
// var th = new $.jqplot.Theme(name);
|
||||
var th = this.copy(this.themes['Default']._name, name);
|
||||
$.jqplot.extend(th, obj);
|
||||
return th;
|
||||
};
|
||||
|
||||
// function clone(obj) {
|
||||
// return eval(obj.toSource());
|
||||
// }
|
||||
|
||||
function clone(obj){
|
||||
if(obj == null || typeof(obj) != 'object'){
|
||||
return obj;
|
||||
}
|
||||
|
||||
var temp = new obj.constructor();
|
||||
for(var key in obj){
|
||||
temp[key] = clone(obj[key]);
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
$.jqplot.clone = clone;
|
||||
|
||||
function merge(obj1, obj2) {
|
||||
if (obj2 == null || typeof(obj2) != 'object') {
|
||||
return;
|
||||
}
|
||||
for (var key in obj2) {
|
||||
if (key == 'highlightColors') {
|
||||
obj1[key] = clone(obj2[key]);
|
||||
}
|
||||
if (obj2[key] != null && typeof(obj2[key]) == 'object') {
|
||||
if (!obj1.hasOwnProperty(key)) {
|
||||
obj1[key] = {};
|
||||
}
|
||||
merge(obj1[key], obj2[key]);
|
||||
}
|
||||
else {
|
||||
obj1[key] = obj2[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$.jqplot.merge = merge;
|
||||
|
||||
// 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;
|
||||
|
||||
// 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 = {};
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Return the modified object
|
||||
return target;
|
||||
};
|
||||
|
||||
/**
|
||||
* method: rename
|
||||
*
|
||||
* Rename a theme.
|
||||
*
|
||||
* parameters:
|
||||
*
|
||||
* oldName - current name of the theme.
|
||||
* newName - desired name of the theme.
|
||||
*
|
||||
* returns:
|
||||
*
|
||||
* new Theme object.
|
||||
*/
|
||||
$.jqplot.ThemeEngine.prototype.rename = function (oldName, newName) {
|
||||
if (oldName == 'Default' || newName == 'Default') {
|
||||
throw new Error ("jqplot.ThemeEngine Error: Cannot rename from/to Default");
|
||||
}
|
||||
if (this.themes.hasOwnProperty(newName)) {
|
||||
throw new Error ("jqplot.ThemeEngine Error: New name already in use.");
|
||||
}
|
||||
else if (this.themes.hasOwnProperty(oldName)) {
|
||||
var th = this.copy (oldName, newName);
|
||||
this.remove(oldName);
|
||||
return th;
|
||||
}
|
||||
throw new Error("jqplot.ThemeEngine Error: Old name or new name invalid");
|
||||
};
|
||||
|
||||
/**
|
||||
* method: copy
|
||||
*
|
||||
* Create a copy of an existing theme in the themeEngine, adding it the themeEngine.
|
||||
*
|
||||
* parameters:
|
||||
*
|
||||
* sourceName - name of the existing theme.
|
||||
* targetName - name of the copy.
|
||||
* obj - optional object of style parameter to apply to the new theme.
|
||||
*
|
||||
* returns:
|
||||
*
|
||||
* new Theme object.
|
||||
*/
|
||||
$.jqplot.ThemeEngine.prototype.copy = function (sourceName, targetName, obj) {
|
||||
if (targetName == 'Default') {
|
||||
throw new Error ("jqplot.ThemeEngine Error: Cannot copy over Default theme");
|
||||
}
|
||||
if (!this.themes.hasOwnProperty(sourceName)) {
|
||||
var s = "jqplot.ThemeEngine Error: Source name invalid";
|
||||
throw new Error(s);
|
||||
}
|
||||
if (this.themes.hasOwnProperty(targetName)) {
|
||||
var s = "jqplot.ThemeEngine Error: Target name invalid";
|
||||
throw new Error(s);
|
||||
}
|
||||
else {
|
||||
var th = clone(this.themes[sourceName]);
|
||||
th._name = targetName;
|
||||
$.jqplot.extend(true, th, obj);
|
||||
this._add(th);
|
||||
return th;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$.jqplot.Theme = function(name, obj) {
|
||||
if (typeof(name) == 'object') {
|
||||
obj = obj || name;
|
||||
name = null;
|
||||
}
|
||||
name = name || Date.parse(new Date());
|
||||
this._name = name;
|
||||
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(obj) == 'string') {
|
||||
this._name = obj;
|
||||
}
|
||||
else if(typeof(obj) == 'object') {
|
||||
$.jqplot.extend(true, this, obj);
|
||||
}
|
||||
};
|
||||
|
||||
var AxisProperties = function() {
|
||||
this.borderColor = null;
|
||||
this.borderWidth = null;
|
||||
this.ticks = new AxisTicks();
|
||||
this.label = new AxisLabel();
|
||||
};
|
||||
|
||||
var AxisTicks = 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 AxisLabel = function() {
|
||||
this.textColor = null;
|
||||
this.whiteSpace = null;
|
||||
this.fontSize = null;
|
||||
this.fontFamily = null;
|
||||
this.fontWeight = null;
|
||||
};
|
||||
|
||||
var LineSeriesProperties = function() {
|
||||
this.color=null;
|
||||
this.lineWidth=null;
|
||||
this.linePattern=null;
|
||||
this.shadow=null;
|
||||
this.fillColor=null;
|
||||
this.showMarker=null;
|
||||
this.markerOptions = new MarkerOptions();
|
||||
};
|
||||
|
||||
var MarkerOptions = function() {
|
||||
this.show = null;
|
||||
this.style = null;
|
||||
this.lineWidth = null;
|
||||
this.size = null;
|
||||
this.color = null;
|
||||
this.shadow = null;
|
||||
};
|
||||
|
||||
var BarSeriesProperties = 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 PieSeriesProperties = 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 DonutSeriesProperties = 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 FunnelSeriesProperties = function() {
|
||||
this.color=null;
|
||||
this.lineWidth=null;
|
||||
this.shadow=null;
|
||||
this.padding=null;
|
||||
this.sectionMargin=null;
|
||||
this.seriesColors=null;
|
||||
this.highlightColors=null;
|
||||
};
|
||||
|
||||
var MeterSeriesProperties = 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;
|
||||
};
|
||||
|
||||
|
||||
})(jQuery);
|
801
msd2/tracking/piwik/libs/jqplot/plugins/jqplot.barRenderer.js
Normal file
801
msd2/tracking/piwik/libs/jqplot/plugins/jqplot.barRenderer.js
Normal file
@ -0,0 +1,801 @@
|
||||
/**
|
||||
* jqPlot
|
||||
* Pure JavaScript plotting plugin using jQuery
|
||||
*
|
||||
* Version: @VERSION
|
||||
* Revision: @REVISION
|
||||
*
|
||||
* 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.BarRenderer
|
||||
// A plugin renderer for jqPlot to draw a bar plot.
|
||||
// Draws series as a line.
|
||||
|
||||
$.jqplot.BarRenderer = function(){
|
||||
$.jqplot.LineRenderer.call(this);
|
||||
};
|
||||
|
||||
$.jqplot.BarRenderer.prototype = new $.jqplot.LineRenderer();
|
||||
$.jqplot.BarRenderer.prototype.constructor = $.jqplot.BarRenderer;
|
||||
|
||||
// called with scope of series.
|
||||
$.jqplot.BarRenderer.prototype.init = function(options, plot) {
|
||||
// Group: Properties
|
||||
//
|
||||
// prop: barPadding
|
||||
// Number of pixels between adjacent bars at the same axis value.
|
||||
this.barPadding = 8;
|
||||
// prop: barMargin
|
||||
// Number of pixels between groups of bars at adjacent axis values.
|
||||
this.barMargin = 10;
|
||||
// prop: barDirection
|
||||
// 'vertical' = up and down bars, 'horizontal' = side to side bars
|
||||
this.barDirection = 'vertical';
|
||||
// prop: barWidth
|
||||
// Width of the bar in pixels (auto by devaul). null = calculated automatically.
|
||||
this.barWidth = null;
|
||||
// prop: shadowOffset
|
||||
// offset of the shadow from the slice and offset of
|
||||
// each succesive stroke of the shadow from the last.
|
||||
this.shadowOffset = 2;
|
||||
// prop: shadowDepth
|
||||
// number of strokes to apply to the shadow,
|
||||
// each stroke offset shadowOffset from the last.
|
||||
this.shadowDepth = 5;
|
||||
// prop: shadowAlpha
|
||||
// transparency of the shadow (0 = transparent, 1 = opaque)
|
||||
this.shadowAlpha = 0.08;
|
||||
// prop: waterfall
|
||||
// true to enable waterfall plot.
|
||||
this.waterfall = false;
|
||||
// prop: groups
|
||||
// group bars into this many groups
|
||||
this.groups = 1;
|
||||
// prop: varyBarColor
|
||||
// true to color each bar of a series separately rather than
|
||||
// have every bar of a given series the same color.
|
||||
// If used for non-stacked multiple series bar plots, user should
|
||||
// specify a separate 'seriesColors' array for each series.
|
||||
// Otherwise, each series will set their bars to the same color array.
|
||||
// This option has no Effect for stacked bar charts and is disabled.
|
||||
this.varyBarColor = false;
|
||||
// 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 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 whether 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;
|
||||
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';
|
||||
}
|
||||
// index of the currenty highlighted point, if any
|
||||
this._highlightedPoint = null;
|
||||
// total number of values for all bar series, total number of bar series, and position of this series
|
||||
this._plotSeriesInfo = null;
|
||||
// Array of actual data colors used for each data point.
|
||||
this._dataColors = [];
|
||||
this._barPoints = [];
|
||||
|
||||
// set the shape renderer options
|
||||
var opts = {lineJoin:'miter', lineCap:'round', fill:true, isarc:false, strokeStyle:this.color, fillStyle:this.color, closePath:this.fill};
|
||||
this.renderer.shapeRenderer.init(opts);
|
||||
// set the shadow renderer options
|
||||
var sopts = {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(sopts);
|
||||
|
||||
plot.postInitHooks.addOnce(postInit);
|
||||
plot.postDrawHooks.addOnce(postPlotDraw);
|
||||
plot.eventListenerHooks.addOnce('jqplotMouseMove', handleMove);
|
||||
plot.eventListenerHooks.addOnce('jqplotMouseDown', handleMouseDown);
|
||||
plot.eventListenerHooks.addOnce('jqplotMouseUp', handleMouseUp);
|
||||
plot.eventListenerHooks.addOnce('jqplotClick', handleClick);
|
||||
plot.eventListenerHooks.addOnce('jqplotRightClick', handleRightClick);
|
||||
};
|
||||
|
||||
// called with scope of series
|
||||
function barPreInit(target, data, seriesDefaults, options) {
|
||||
if (this.rendererOptions.barDirection == 'horizontal') {
|
||||
this._stackAxis = 'x';
|
||||
this._primaryAxis = '_yaxis';
|
||||
}
|
||||
if (this.rendererOptions.waterfall == true) {
|
||||
this._data = $.extend(true, [], this.data);
|
||||
var sum = 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) {
|
||||
this.data[i][pos] += this.data[i-1][pos];
|
||||
}
|
||||
}
|
||||
this.data[this.data.length] = (pos == 1) ? [this.data.length+1, sum] : [sum, this.data.length+1];
|
||||
this._data[this._data.length] = (pos == 1) ? [this._data.length+1, sum] : [sum, this._data.length+1];
|
||||
}
|
||||
if (this.rendererOptions.groups > 1) {
|
||||
this.breakOnNull = true;
|
||||
var l = this.data.length;
|
||||
var skip = parseInt(l/this.rendererOptions.groups, 10);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$.jqplot.preSeriesInitHooks.push(barPreInit);
|
||||
|
||||
// needs to be called with scope of series, not renderer.
|
||||
$.jqplot.BarRenderer.prototype.calcSeriesNumbers = function() {
|
||||
var nvals = 0;
|
||||
var nseries = 0;
|
||||
var paxis = this[this._primaryAxis];
|
||||
var s, series, pos;
|
||||
// loop through all series on this axis
|
||||
for (var i=0; i < paxis._series.length; i++) {
|
||||
series = paxis._series[i];
|
||||
if (series === this) {
|
||||
pos = i;
|
||||
}
|
||||
// is the series rendered as a bar?
|
||||
if (series.renderer.constructor == $.jqplot.BarRenderer) {
|
||||
// gridData may not be computed yet, use data length insted
|
||||
nvals += series.data.length;
|
||||
nseries += 1;
|
||||
}
|
||||
}
|
||||
// return total number of values for all bar series, total number of bar series, and position of this series
|
||||
return [nvals, nseries, pos];
|
||||
};
|
||||
|
||||
$.jqplot.BarRenderer.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;
|
||||
var temp = this._plotSeriesInfo = this.renderer.calcSeriesNumbers.call(this);
|
||||
nvals = temp[0];
|
||||
nseries = temp[1];
|
||||
var nticks = paxis.numberTicks;
|
||||
var nbins = (nticks-1)/2;
|
||||
// so, now we have total number of axis values.
|
||||
if (paxis.name == 'xaxis' || paxis.name == 'x2axis') {
|
||||
if (this._stack) {
|
||||
this.barWidth = (paxis._offsets.max - paxis._offsets.min) / nvals * nseries - this.barMargin;
|
||||
}
|
||||
else {
|
||||
this.barWidth = ((paxis._offsets.max - paxis._offsets.min)/nbins - this.barPadding * (nseries-1) - this.barMargin*2)/nseries;
|
||||
// this.barWidth = (paxis._offsets.max - paxis._offsets.min) / nvals - this.barPadding - this.barMargin/nseries;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this._stack) {
|
||||
this.barWidth = (paxis._offsets.min - paxis._offsets.max) / nvals * nseries - this.barMargin;
|
||||
}
|
||||
else {
|
||||
this.barWidth = ((paxis._offsets.min - paxis._offsets.max)/nbins - this.barPadding * (nseries-1) - this.barMargin*2)/nseries;
|
||||
// this.barWidth = (paxis._offsets.min - paxis._offsets.max) / nvals - this.barPadding - this.barMargin/nseries;
|
||||
}
|
||||
}
|
||||
return [nvals, nseries];
|
||||
};
|
||||
|
||||
function computeHighlightColors (colors) {
|
||||
var ret = [];
|
||||
for (var i=0; i<colors.length; i++){
|
||||
var rgba = $.jqplot.getColorComponents(colors[i]);
|
||||
var newrgb = [rgba[0], rgba[1], rgba[2]];
|
||||
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] = parseInt(newrgb[j], 10);
|
||||
}
|
||||
ret.push('rgb('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+')');
|
||||
}
|
||||
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, plot) {
|
||||
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 xaxis = this.xaxis;
|
||||
var yaxis = this.yaxis;
|
||||
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.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 = [];
|
||||
|
||||
if (this._stack) {
|
||||
this._barNudge = 0;
|
||||
}
|
||||
else {
|
||||
this._barNudge = (-Math.abs(nseries/2 - 0.5) + pos) * (this.barWidth + this.barPadding);
|
||||
}
|
||||
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;
|
||||
var ystart;
|
||||
|
||||
if (this.barDirection == 'vertical') {
|
||||
for (var i=0; i<gridData.length; i++) {
|
||||
if (!this._stack && this.data[i][1] == null) {
|
||||
continue;
|
||||
}
|
||||
points = [];
|
||||
base = gridData[i][0] + this._barNudge;
|
||||
|
||||
// stacked
|
||||
if (this._stack && this._prevGridData.length) {
|
||||
ystart = getStart(this.index, i, this._plotData[i][1], plot, 'y');
|
||||
}
|
||||
|
||||
// not stacked
|
||||
else {
|
||||
if (this.fillToZero) {
|
||||
ystart = this._yaxis.series_u2p(0);
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
if ((this.fillToZero && this._plotData[i][1] < 0) || (this.waterfall && this._data[i][1] < 0)) {
|
||||
if (this.varyBarColor && !this._stack) {
|
||||
if (this.useNegativeColors) {
|
||||
opts.fillStyle = negativeColors.next();
|
||||
}
|
||||
else {
|
||||
opts.fillStyle = positiveColors.next();
|
||||
}
|
||||
}
|
||||
else {
|
||||
opts.fillStyle = negativeColor;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.varyBarColor && !this._stack) {
|
||||
opts.fillStyle = positiveColors.next();
|
||||
}
|
||||
else {
|
||||
opts.fillStyle = positiveColor;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
if (shadow && !this._stack) {
|
||||
var sopts = $.extend(true, {}, opts);
|
||||
// need to get rid of fillStyle on shadow.
|
||||
delete sopts.fillStyle;
|
||||
this.renderer.shadowRenderer.draw(ctx, points, sopts);
|
||||
}
|
||||
var clr = opts.fillStyle || this.color;
|
||||
this._dataColors.push(clr);
|
||||
this.renderer.shapeRenderer.draw(ctx, points, opts);
|
||||
}
|
||||
}
|
||||
|
||||
else if (this.barDirection == 'horizontal'){
|
||||
for (var i=0; i<gridData.length; i++) {
|
||||
if (!this._stack && this.data[i][0] == null) {
|
||||
continue;
|
||||
}
|
||||
points = [];
|
||||
base = gridData[i][1] - this._barNudge;
|
||||
xstart;
|
||||
|
||||
if (this._stack && this._prevGridData.length) {
|
||||
xstart = getStart(this.index, i, this._plotData[i][0], plot, 'x');
|
||||
}
|
||||
// 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][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;
|
||||
}
|
||||
}
|
||||
if ((this.fillToZero && this._plotData[i][0] < 0) || (this.waterfall && this._data[i][0] < 0)) {
|
||||
if (this.varyBarColor && !this._stack) {
|
||||
if (this.useNegativeColors) {
|
||||
opts.fillStyle = negativeColors.next();
|
||||
}
|
||||
else {
|
||||
opts.fillStyle = positiveColors.next();
|
||||
}
|
||||
}
|
||||
else {
|
||||
opts.fillStyle = negativeColor;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.varyBarColor && !this._stack) {
|
||||
opts.fillStyle = positiveColors.next();
|
||||
}
|
||||
else {
|
||||
opts.fillStyle = positiveColor;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
if (shadow && !this._stack) {
|
||||
var sopts = $.extend(true, {}, opts);
|
||||
delete sopts.fillStyle;
|
||||
this.renderer.shadowRenderer.draw(ctx, points, sopts);
|
||||
}
|
||||
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') {
|
||||
var temp = this.highlightColors;
|
||||
this.highlightColors = [];
|
||||
for (var i=0; i<this._dataColors.length; i++) {
|
||||
this.highlightColors.push(temp);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// for stacked plots, shadows will be pre drawn by drawShadow.
|
||||
$.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;
|
||||
var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine;
|
||||
var fill = (opts.fill != undefined) ? opts.fill : this.fill;
|
||||
var xaxis = this.xaxis;
|
||||
var yaxis = this.yaxis;
|
||||
var xp = this._xaxis.series_u2p;
|
||||
var yp = this._yaxis.series_u2p;
|
||||
var pointx, points, pointy, nvals, nseries, pos;
|
||||
|
||||
if (this._stack && this.shadow) {
|
||||
if (this.barWidth == null) {
|
||||
this.renderer.setBarWidth.call(this);
|
||||
}
|
||||
|
||||
var temp = this._plotSeriesInfo = this.renderer.calcSeriesNumbers.call(this);
|
||||
nvals = temp[0];
|
||||
nseries = temp[1];
|
||||
pos = temp[2];
|
||||
|
||||
if (this._stack) {
|
||||
this._barNudge = 0;
|
||||
}
|
||||
else {
|
||||
this._barNudge = (-Math.abs(nseries/2 - 0.5) + pos) * (this.barWidth + this.barPadding);
|
||||
}
|
||||
if (showLine) {
|
||||
|
||||
if (this.barDirection == 'vertical') {
|
||||
for (var i=0; i<gridData.length; i++) {
|
||||
if (this.data[i][1] == null) {
|
||||
continue;
|
||||
}
|
||||
points = [];
|
||||
var base = gridData[i][0] + this._barNudge;
|
||||
var ystart;
|
||||
|
||||
if (this._stack && this._prevGridData.length) {
|
||||
ystart = getStart(this.index, i, this._plotData[i][1], plot, 'y');
|
||||
}
|
||||
else {
|
||||
if (this.fillToZero) {
|
||||
ystart = this._yaxis.series_u2p(0);
|
||||
}
|
||||
else {
|
||||
ystart = ctx.canvas.height;
|
||||
}
|
||||
}
|
||||
|
||||
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]);
|
||||
this.renderer.shadowRenderer.draw(ctx, points, opts);
|
||||
}
|
||||
}
|
||||
|
||||
else if (this.barDirection == 'horizontal'){
|
||||
for (var i=0; i<gridData.length; i++) {
|
||||
if (this.data[i][0] == null) {
|
||||
continue;
|
||||
}
|
||||
points = [];
|
||||
var base = gridData[i][1] - this._barNudge;
|
||||
var xstart;
|
||||
|
||||
if (this._stack && this._prevGridData.length) {
|
||||
xstart = getStart(this.index, i, this._plotData[i][0], plot, 'x');
|
||||
}
|
||||
else {
|
||||
if (this.fillToZero) {
|
||||
xstart = this._xaxis.series_u2p(0);
|
||||
}
|
||||
else {
|
||||
xstart = 0;
|
||||
}
|
||||
}
|
||||
|
||||
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]);
|
||||
points.push([xstart, base-this.barWidth/2]);
|
||||
this.renderer.shadowRenderer.draw(ctx, points, opts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
function postInit(target, data, options) {
|
||||
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) {
|
||||
this.series[i].highlightMouseDown = 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.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, 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) {
|
||||
var s = plot.series[sidx];
|
||||
var canvas = plot.plugins.barRenderer.highlightCanvas;
|
||||
canvas._ctx.clearRect(0,0,canvas._ctx.canvas.width, canvas._ctx.canvas.height);
|
||||
s._highlightedPoint = pidx;
|
||||
plot.plugins.barRenderer.highlightedSeriesIndex = sidx;
|
||||
var opts = {fillStyle: s.highlightColors[pidx]};
|
||||
s.renderer.shapeRenderer.draw(canvas._ctx, points, opts);
|
||||
canvas = null;
|
||||
}
|
||||
|
||||
function unhighlight (plot) {
|
||||
var canvas = plot.plugins.barRenderer.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.barRenderer.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]].show && 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);
|
||||
highlight (plot, neighbor.seriesIndex, neighbor.pointIndex, neighbor.points);
|
||||
}
|
||||
}
|
||||
else if (neighbor == null) {
|
||||
unhighlight (plot);
|
||||
}
|
||||
}
|
||||
|
||||
function handleMouseDown(ev, gridpos, datapos, neighbor, plot) {
|
||||
if (neighbor) {
|
||||
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);
|
||||
highlight (plot, neighbor.seriesIndex, neighbor.pointIndex, neighbor.points);
|
||||
}
|
||||
}
|
||||
else if (neighbor == null) {
|
||||
unhighlight (plot);
|
||||
}
|
||||
}
|
||||
|
||||
function handleMouseUp(ev, gridpos, datapos, neighbor, plot) {
|
||||
var idx = plot.plugins.barRenderer.highlightedSeriesIndex;
|
||||
if (idx != null && plot.series[idx].highlightMouseDown) {
|
||||
unhighlight(plot);
|
||||
}
|
||||
}
|
||||
|
||||
function handleClick(ev, gridpos, datapos, neighbor, plot) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
function handleRightClick(ev, gridpos, datapos, neighbor, plot) {
|
||||
if (neighbor) {
|
||||
var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
|
||||
var idx = plot.plugins.barRenderer.highlightedSeriesIndex;
|
||||
if (idx != null && plot.series[idx].highlightMouseDown) {
|
||||
unhighlight(plot);
|
||||
}
|
||||
var evt = jQuery.Event('jqplotDataRightClick');
|
||||
evt.which = ev.which;
|
||||
evt.pageX = ev.pageX;
|
||||
evt.pageY = ev.pageY;
|
||||
plot.target.trigger(evt, ins);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
})(jQuery);
|
@ -0,0 +1,253 @@
|
||||
/**
|
||||
* jqPlot
|
||||
* Pure JavaScript plotting plugin using jQuery
|
||||
*
|
||||
* Version: @VERSION
|
||||
* Revision: @REVISION
|
||||
*
|
||||
* 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.CanvasAxisTickRenderer
|
||||
* Renderer to draw axis ticks with a canvas element to support advanced
|
||||
* featrues such as rotated text. This renderer uses a separate rendering engine
|
||||
* to draw the text on the canvas. Two modes of rendering the text are available.
|
||||
* If the browser has native font support for canvas fonts (currently Mozila 3.5
|
||||
* and Safari 4), you can enable text rendering with the canvas fillText method.
|
||||
* You do so by setting the "enableFontSupport" option to true.
|
||||
*
|
||||
* Browsers lacking native font support will have the text drawn on the canvas
|
||||
* using the Hershey font metrics. Even if the "enableFontSupport" option is true
|
||||
* non-supporting browsers will still render with the Hershey font.
|
||||
*/
|
||||
$.jqplot.CanvasAxisTickRenderer = function(options) {
|
||||
// Group: Properties
|
||||
|
||||
// prop: mark
|
||||
// tick mark on the axis. One of 'inside', 'outside', 'cross', '' or null.
|
||||
this.mark = 'outside';
|
||||
// prop: showMark
|
||||
// whether or not to show the mark on the axis.
|
||||
this.showMark = true;
|
||||
// prop: showGridline
|
||||
// whether or not to draw the gridline on the grid at this tick.
|
||||
this.showGridline = true;
|
||||
// prop: isMinorTick
|
||||
// if this is a minor tick.
|
||||
this.isMinorTick = false;
|
||||
// prop: angle
|
||||
// angle of text, measured clockwise from x axis.
|
||||
this.angle = 0;
|
||||
// prop: markSize
|
||||
// Length of the tick marks in pixels. For 'cross' style, length
|
||||
// will be stoked above and below axis, so total length will be twice this.
|
||||
this.markSize = 4;
|
||||
// prop: show
|
||||
// whether or not to show the tick (mark and label).
|
||||
this.show = true;
|
||||
// prop: showLabel
|
||||
// whether or not to show the label.
|
||||
this.showLabel = true;
|
||||
// prop: labelPosition
|
||||
// 'auto', 'start', 'middle' or 'end'.
|
||||
// Whether tick label should be positioned so the start, middle, or end
|
||||
// of the tick mark.
|
||||
this.labelPosition = 'auto';
|
||||
this.label = '';
|
||||
this.value = null;
|
||||
this._styles = {};
|
||||
// prop: formatter
|
||||
// A class of a formatter for the tick text.
|
||||
// The default $.jqplot.DefaultTickFormatter uses sprintf.
|
||||
this.formatter = $.jqplot.DefaultTickFormatter;
|
||||
// prop: formatString
|
||||
// string passed to the formatter.
|
||||
this.formatString = '';
|
||||
// prop: prefix
|
||||
// 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.
|
||||
this.fontFamily = '"Trebuchet MS", Arial, Helvetica, sans-serif';
|
||||
// prop: fontSize
|
||||
// CSS spec for font size.
|
||||
this.fontSize = '10pt';
|
||||
// prop: fontWeight
|
||||
// CSS spec for fontWeight
|
||||
this.fontWeight = 'normal';
|
||||
// prop: fontStretch
|
||||
// Multiplier to condense or expand font width.
|
||||
// Applies only to browsers which don't support canvas native font rendering.
|
||||
this.fontStretch = 1.0;
|
||||
// prop: textColor
|
||||
// css spec for the color attribute.
|
||||
this.textColor = '#666666';
|
||||
// prop: enableFontSupport
|
||||
// true to turn on native canvas font support in Mozilla 3.5+ and Safari 4+.
|
||||
// If true, tick label will be drawn with canvas tag native support for fonts.
|
||||
// If false, tick label will be drawn with Hershey font metrics.
|
||||
this.enableFontSupport = true;
|
||||
// prop: pt2px
|
||||
// Point to pixel scaling factor, used for computing height of bounding box
|
||||
// around a label. The labels text renderer has a default setting of 1.4, which
|
||||
// should be suitable for most fonts. Leave as null to use default. If tops of
|
||||
// letters appear clipped, increase this. If bounding box seems too big, decrease.
|
||||
// This is an issue only with the native font renderering capabilities of Mozilla
|
||||
// 3.5 and Safari 4 since they do not provide a method to determine the font height.
|
||||
this.pt2px = null;
|
||||
|
||||
this._elem;
|
||||
this._ctx;
|
||||
this._plotWidth;
|
||||
this._plotHeight;
|
||||
this._plotDimensions = {height:null, width:null};
|
||||
|
||||
$.extend(true, this, options);
|
||||
|
||||
var ropts = {fontSize:this.fontSize, fontWeight:this.fontWeight, fontStretch:this.fontStretch, fillStyle:this.textColor, angle:this.getAngleRad(), fontFamily:this.fontFamily};
|
||||
if (this.pt2px) {
|
||||
ropts.pt2px = this.pt2px;
|
||||
}
|
||||
|
||||
if (this.enableFontSupport) {
|
||||
if ($.jqplot.support_canvas_text()) {
|
||||
this._textRenderer = new $.jqplot.CanvasFontRenderer(ropts);
|
||||
}
|
||||
|
||||
else {
|
||||
this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts);
|
||||
}
|
||||
};
|
||||
|
||||
$.jqplot.CanvasAxisTickRenderer.prototype.init = function(options) {
|
||||
$.extend(true, this, options);
|
||||
this._textRenderer.init({fontSize:this.fontSize, fontWeight:this.fontWeight, fontStretch:this.fontStretch, fillStyle:this.textColor, angle:this.getAngleRad(), fontFamily:this.fontFamily});
|
||||
};
|
||||
|
||||
// return width along the x axis
|
||||
// will check first to see if an element exists.
|
||||
// if not, will return the computed text box width.
|
||||
$.jqplot.CanvasAxisTickRenderer.prototype.getWidth = function(ctx) {
|
||||
if (this._elem) {
|
||||
return this._elem.outerWidth(true);
|
||||
}
|
||||
else {
|
||||
var tr = this._textRenderer;
|
||||
var l = tr.getWidth(ctx);
|
||||
var h = tr.getHeight(ctx);
|
||||
var w = Math.abs(Math.sin(tr.angle)*h) + Math.abs(Math.cos(tr.angle)*l);
|
||||
return w;
|
||||
}
|
||||
};
|
||||
|
||||
// return height along the y axis.
|
||||
$.jqplot.CanvasAxisTickRenderer.prototype.getHeight = function(ctx) {
|
||||
if (this._elem) {
|
||||
return this._elem.outerHeight(true);
|
||||
}
|
||||
else {
|
||||
var tr = this._textRenderer;
|
||||
var l = tr.getWidth(ctx);
|
||||
var h = tr.getHeight(ctx);
|
||||
var w = Math.abs(Math.cos(tr.angle)*h) + Math.abs(Math.sin(tr.angle)*l);
|
||||
return w;
|
||||
}
|
||||
};
|
||||
|
||||
// return top.
|
||||
$.jqplot.CanvasAxisTickRenderer.prototype.getTop = function(ctx) {
|
||||
if (this._elem) {
|
||||
return this._elem.position().top;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
$.jqplot.CanvasAxisTickRenderer.prototype.getAngleRad = function() {
|
||||
var a = this.angle * Math.PI/180;
|
||||
return a;
|
||||
};
|
||||
|
||||
|
||||
$.jqplot.CanvasAxisTickRenderer.prototype.setTick = function(value, axisName, isMinor) {
|
||||
this.value = value;
|
||||
if (isMinor) {
|
||||
this.isMinorTick = true;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
$.jqplot.CanvasAxisTickRenderer.prototype.draw = function(ctx, plot) {
|
||||
if (!this.label) {
|
||||
this.label = this.prefix + this.formatter(this.formatString, this.value);
|
||||
}
|
||||
|
||||
// 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 elem = plot.canvasManager.getCanvas();
|
||||
|
||||
this._textRenderer.setText(this.label, ctx);
|
||||
var w = this.getWidth(ctx);
|
||||
var h = this.getHeight(ctx);
|
||||
// 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() {
|
||||
this._textRenderer.draw(this._elem.get(0).getContext("2d"), this.label);
|
||||
};
|
||||
|
||||
})(jQuery);
|
@ -0,0 +1,449 @@
|
||||
/**
|
||||
* jqPlot
|
||||
* Pure JavaScript plotting plugin using jQuery
|
||||
*
|
||||
* Version: @VERSION
|
||||
* Revision: @REVISION
|
||||
*
|
||||
* 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 original 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:
|
||||
//
|
||||
// This code is released to the public domain by Jim Studt, 2007.
|
||||
// He may keep some sort of up to date copy at http://www.federated.com/~jim/canvastext/
|
||||
//
|
||||
$.jqplot.CanvasTextRenderer = function(options){
|
||||
this.fontStyle = 'normal'; // normal, italic, oblique [not implemented]
|
||||
this.fontVariant = 'normal'; // normal, small caps [not implemented]
|
||||
this.fontWeight = 'normal'; // normal, bold, bolder, lighter, 100 - 900
|
||||
this.fontSize = '10px';
|
||||
this.fontFamily = 'sans-serif';
|
||||
this.fontStretch = 1.0;
|
||||
this.fillStyle = '#666666';
|
||||
this.angle = 0;
|
||||
this.textAlign = 'start';
|
||||
this.textBaseline = 'alphabetic';
|
||||
this.text;
|
||||
this.width;
|
||||
this.height;
|
||||
this.pt2px = 1.28;
|
||||
|
||||
$.extend(true, this, options);
|
||||
this.normalizedFontSize = this.normalizeFontSize(this.fontSize);
|
||||
this.setHeight();
|
||||
};
|
||||
|
||||
$.jqplot.CanvasTextRenderer.prototype.init = function(options) {
|
||||
$.extend(true, this, options);
|
||||
this.normalizedFontSize = this.normalizeFontSize(this.fontSize);
|
||||
this.setHeight();
|
||||
};
|
||||
|
||||
// convert css spec into point size
|
||||
// returns float
|
||||
$.jqplot.CanvasTextRenderer.prototype.normalizeFontSize = function(sz) {
|
||||
sz = String(sz);
|
||||
var n = parseFloat(sz);
|
||||
if (sz.indexOf('px') > -1) {
|
||||
return n/this.pt2px;
|
||||
}
|
||||
else if (sz.indexOf('pt') > -1) {
|
||||
return n;
|
||||
}
|
||||
else if (sz.indexOf('em') > -1) {
|
||||
return n*12;
|
||||
}
|
||||
else if (sz.indexOf('%') > -1) {
|
||||
return n*12/100;
|
||||
}
|
||||
// default to pixels;
|
||||
else {
|
||||
return n/this.pt2px;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$.jqplot.CanvasTextRenderer.prototype.fontWeight2Float = function(w) {
|
||||
// w = normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900
|
||||
// return values adjusted for Hershey font.
|
||||
if (Number(w)) {
|
||||
return w/400;
|
||||
}
|
||||
else {
|
||||
switch (w) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$.jqplot.CanvasTextRenderer.prototype.getText = function() {
|
||||
return this.text;
|
||||
};
|
||||
|
||||
$.jqplot.CanvasTextRenderer.prototype.setText = function(t, ctx) {
|
||||
this.text = t;
|
||||
this.setWidth(ctx);
|
||||
return this;
|
||||
};
|
||||
|
||||
$.jqplot.CanvasTextRenderer.prototype.getWidth = function(ctx) {
|
||||
return this.width;
|
||||
};
|
||||
|
||||
$.jqplot.CanvasTextRenderer.prototype.setWidth = function(ctx, w) {
|
||||
if (!w) {
|
||||
this.width = this.measure(ctx, this.text);
|
||||
}
|
||||
else {
|
||||
this.width = w;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
// return height in pixels.
|
||||
$.jqplot.CanvasTextRenderer.prototype.getHeight = function(ctx) {
|
||||
return this.height;
|
||||
};
|
||||
|
||||
// w - height in pt
|
||||
// set heigh in px
|
||||
$.jqplot.CanvasTextRenderer.prototype.setHeight = function(w) {
|
||||
if (!w) {
|
||||
//height = this.fontSize /0.75;
|
||||
this.height = this.normalizedFontSize * this.pt2px;
|
||||
}
|
||||
else {
|
||||
this.height = w;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
$.jqplot.CanvasTextRenderer.prototype.letter = function (ch)
|
||||
{
|
||||
return this.letters[ch];
|
||||
};
|
||||
|
||||
$.jqplot.CanvasTextRenderer.prototype.ascent = function()
|
||||
{
|
||||
return this.normalizedFontSize;
|
||||
};
|
||||
|
||||
$.jqplot.CanvasTextRenderer.prototype.descent = function()
|
||||
{
|
||||
return 7.0*this.normalizedFontSize/25.0;
|
||||
};
|
||||
|
||||
$.jqplot.CanvasTextRenderer.prototype.measure = function(ctx, str)
|
||||
{
|
||||
var total = 0;
|
||||
var len = str.length;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
return total;
|
||||
};
|
||||
|
||||
$.jqplot.CanvasTextRenderer.prototype.draw = function(ctx,str)
|
||||
{
|
||||
var x = 0;
|
||||
// leave room at bottom for descenders.
|
||||
var y = this.height*0.72;
|
||||
var total = 0;
|
||||
var len = str.length;
|
||||
var mag = this.normalizedFontSize / 25.0;
|
||||
|
||||
ctx.save();
|
||||
var tx, ty;
|
||||
|
||||
// 1st quadrant
|
||||
if ((-Math.PI/2 <= this.angle && this.angle <= 0) || (Math.PI*3/2 <= this.angle && this.angle <= Math.PI*2)) {
|
||||
tx = 0;
|
||||
ty = -Math.sin(this.angle) * this.width;
|
||||
}
|
||||
// 4th quadrant
|
||||
else if ((0 < this.angle && this.angle <= Math.PI/2) || (-Math.PI*2 <= this.angle && this.angle <= -Math.PI*3/2)) {
|
||||
tx = Math.sin(this.angle) * this.height;
|
||||
ty = 0;
|
||||
}
|
||||
// 2nd quadrant
|
||||
else if ((-Math.PI < this.angle && this.angle < -Math.PI/2) || (Math.PI <= this.angle && this.angle <= Math.PI*3/2)) {
|
||||
tx = -Math.cos(this.angle) * this.width;
|
||||
ty = -Math.sin(this.angle) * this.width - Math.cos(this.angle) * this.height;
|
||||
}
|
||||
// 3rd quadrant
|
||||
else if ((-Math.PI*3/2 < this.angle && this.angle < Math.PI) || (Math.PI/2 < this.angle && this.angle < Math.PI)) {
|
||||
tx = Math.sin(this.angle) * this.height - Math.cos(this.angle)*this.width;
|
||||
ty = -Math.cos(this.angle) * this.height;
|
||||
}
|
||||
|
||||
ctx.strokeStyle = this.fillStyle;
|
||||
ctx.fillStyle = this.fillStyle;
|
||||
ctx.translate(tx, ty);
|
||||
ctx.rotate(this.angle);
|
||||
ctx.lineCap = "round";
|
||||
// multiplier was 2.0
|
||||
var fact = (this.normalizedFontSize > 30) ? 2.0 : 2 + (30 - this.normalizedFontSize)/20;
|
||||
ctx.lineWidth = fact * mag * this.fontWeight2Float(this.fontWeight);
|
||||
|
||||
for ( var i = 0; i < len; i++) {
|
||||
var c = this.letter( str.charAt(i));
|
||||
if ( !c) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ctx.beginPath();
|
||||
|
||||
var penUp = 1;
|
||||
var needStroke = 0;
|
||||
for ( var j = 0; j < c.points.length; j++) {
|
||||
var a = c.points[j];
|
||||
if ( a[0] == -1 && a[1] == -1) {
|
||||
penUp = 1;
|
||||
continue;
|
||||
}
|
||||
if ( penUp) {
|
||||
ctx.moveTo( x + a[0]*mag*this.fontStretch, y - a[1]*mag);
|
||||
penUp = false;
|
||||
} else {
|
||||
ctx.lineTo( x + a[0]*mag*this.fontStretch, y - a[1]*mag);
|
||||
}
|
||||
}
|
||||
ctx.stroke();
|
||||
x += c.width*mag*this.fontStretch;
|
||||
}
|
||||
ctx.restore();
|
||||
return total;
|
||||
};
|
||||
|
||||
$.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]] }
|
||||
};
|
||||
|
||||
$.jqplot.CanvasFontRenderer = function(options) {
|
||||
options = options || {};
|
||||
if (!options.pt2px) {
|
||||
options.pt2px = 1.5;
|
||||
}
|
||||
$.jqplot.CanvasTextRenderer.call(this, options);
|
||||
};
|
||||
|
||||
$.jqplot.CanvasFontRenderer.prototype = new $.jqplot.CanvasTextRenderer({});
|
||||
$.jqplot.CanvasFontRenderer.prototype.constructor = $.jqplot.CanvasFontRenderer;
|
||||
|
||||
$.jqplot.CanvasFontRenderer.prototype.measure = function(ctx, str)
|
||||
{
|
||||
// var fstyle = this.fontStyle+' '+this.fontVariant+' '+this.fontWeight+' '+this.fontSize+' '+this.fontFamily;
|
||||
var fstyle = this.fontSize+' '+this.fontFamily;
|
||||
ctx.save();
|
||||
ctx.font = fstyle;
|
||||
var w = ctx.measureText(str).width;
|
||||
ctx.restore();
|
||||
return w;
|
||||
};
|
||||
|
||||
$.jqplot.CanvasFontRenderer.prototype.draw = function(ctx, str)
|
||||
{
|
||||
var x = 0;
|
||||
// leave room at bottom for descenders.
|
||||
var y = this.height*0.72;
|
||||
//var y = 12;
|
||||
|
||||
ctx.save();
|
||||
var tx, ty;
|
||||
|
||||
// 1st quadrant
|
||||
if ((-Math.PI/2 <= this.angle && this.angle <= 0) || (Math.PI*3/2 <= this.angle && this.angle <= Math.PI*2)) {
|
||||
tx = 0;
|
||||
ty = -Math.sin(this.angle) * this.width;
|
||||
}
|
||||
// 4th quadrant
|
||||
else if ((0 < this.angle && this.angle <= Math.PI/2) || (-Math.PI*2 <= this.angle && this.angle <= -Math.PI*3/2)) {
|
||||
tx = Math.sin(this.angle) * this.height;
|
||||
ty = 0;
|
||||
}
|
||||
// 2nd quadrant
|
||||
else if ((-Math.PI < this.angle && this.angle < -Math.PI/2) || (Math.PI <= this.angle && this.angle <= Math.PI*3/2)) {
|
||||
tx = -Math.cos(this.angle) * this.width;
|
||||
ty = -Math.sin(this.angle) * this.width - Math.cos(this.angle) * this.height;
|
||||
}
|
||||
// 3rd quadrant
|
||||
else if ((-Math.PI*3/2 < this.angle && this.angle < Math.PI) || (Math.PI/2 < this.angle && this.angle < Math.PI)) {
|
||||
tx = Math.sin(this.angle) * this.height - Math.cos(this.angle)*this.width;
|
||||
ty = -Math.cos(this.angle) * this.height;
|
||||
}
|
||||
ctx.strokeStyle = this.fillStyle;
|
||||
ctx.fillStyle = this.fillStyle;
|
||||
// var fstyle = this.fontStyle+' '+this.fontVariant+' '+this.fontWeight+' '+this.fontSize+' '+this.fontFamily;
|
||||
var fstyle = this.fontSize+' '+this.fontFamily;
|
||||
ctx.font = fstyle;
|
||||
ctx.translate(tx, ty);
|
||||
ctx.rotate(this.angle);
|
||||
ctx.fillText(str, x, y);
|
||||
// ctx.strokeText(str, x, y);
|
||||
|
||||
ctx.restore();
|
||||
};
|
||||
|
||||
})(jQuery);
|
@ -0,0 +1,679 @@
|
||||
/**
|
||||
* jqPlot
|
||||
* Pure JavaScript plotting plugin using jQuery
|
||||
*
|
||||
* Version: @VERSION
|
||||
* Revision: @REVISION
|
||||
*
|
||||
* 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.CategoryAxisRenderer
|
||||
* A plugin for jqPlot to render a category style axis, with equal pixel spacing between y data values of a series.
|
||||
*
|
||||
* To use this renderer, include the plugin in your source
|
||||
* > <script type="text/javascript" language="javascript" src="plugins/jqplot.categoryAxisRenderer.js"></script>
|
||||
*
|
||||
* and supply the appropriate options to your plot
|
||||
*
|
||||
* > {axes:{xaxis:{renderer:$.jqplot.CategoryAxisRenderer}}}
|
||||
**/
|
||||
$.jqplot.CategoryAxisRenderer = function(options) {
|
||||
$.jqplot.LinearAxisRenderer.call(this);
|
||||
// prop: sortMergedLabels
|
||||
// True to sort tick labels when labels are created by merging
|
||||
// x axis values from multiple series. That is, say you have
|
||||
// two series like:
|
||||
// > line1 = [[2006, 4], [2008, 9], [2009, 16]];
|
||||
// > line2 = [[2006, 3], [2007, 7], [2008, 6]];
|
||||
// If no label array is specified, tick labels will be collected
|
||||
// from the x values of the series. With sortMergedLabels
|
||||
// set to true, tick labels will be:
|
||||
// > [2006, 2007, 2008, 2009]
|
||||
// With sortMergedLabels set to false, tick labels will be:
|
||||
// > [2006, 2008, 2009, 2007]
|
||||
//
|
||||
// Note, this property is specified on the renderOptions for the
|
||||
// axes when creating a plot:
|
||||
// > axes:{xaxis:{renderer:$.jqplot.CategoryAxisRenderer, rendererOptions:{sortMergedLabels:true}}}
|
||||
this.sortMergedLabels = false;
|
||||
};
|
||||
|
||||
$.jqplot.CategoryAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer();
|
||||
$.jqplot.CategoryAxisRenderer.prototype.constructor = $.jqplot.CategoryAxisRenderer;
|
||||
|
||||
$.jqplot.CategoryAxisRenderer.prototype.init = function(options){
|
||||
this.groups = 1;
|
||||
this.groupLabels = [];
|
||||
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>.
|
||||
// this.tickRenderer = $.jqplot.AxisTickRenderer;
|
||||
// this.labelRenderer = $.jqplot.AxisLabelRenderer;
|
||||
$.extend(true, this, {tickOptions:{formatString:'%d'}}, 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];
|
||||
if (s.groups) {
|
||||
this.groups = s.groups;
|
||||
}
|
||||
var d = s.data;
|
||||
|
||||
for (var j=0; j<d.length; j++) {
|
||||
if (this.name == 'xaxis' || this.name == 'x2axis') {
|
||||
if (d[j][0] < db.min || db.min == null) {
|
||||
db.min = 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];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.groupLabels.length) {
|
||||
this.groups = this.groupLabels.length;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$.jqplot.CategoryAxisRenderer.prototype.createTicks = function() {
|
||||
// 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 min, max;
|
||||
var pos1, pos2;
|
||||
var tt, i;
|
||||
|
||||
// if we already have ticks, use them.
|
||||
if (userTicks.length) {
|
||||
// adjust with blanks if we have groups
|
||||
if (this.groups > 1 && !this._grouped) {
|
||||
var l = userTicks.length;
|
||||
var skip = parseInt(l/this.groups, 10);
|
||||
var count = 0;
|
||||
for (var i=skip; i<l; i+=skip) {
|
||||
userTicks.splice(i+count, 0, ' ');
|
||||
count++;
|
||||
}
|
||||
this._grouped = true;
|
||||
}
|
||||
this.min = 0.5;
|
||||
this.max = userTicks.length + 0.5;
|
||||
var range = this.max - this.min;
|
||||
this.numberTicks = 2*userTicks.length + 1;
|
||||
for (i=0; i<userTicks.length; i++){
|
||||
tt = this.min + 2 * i * range / (this.numberTicks-1);
|
||||
// need a marker before and after the tick
|
||||
var t = new this.tickRenderer(this.tickOptions);
|
||||
t.showLabel = false;
|
||||
// t.showMark = true;
|
||||
t.setTick(tt, this.name);
|
||||
this._ticks.push(t);
|
||||
var t = new this.tickRenderer(this.tickOptions);
|
||||
t.label = userTicks[i];
|
||||
// t.showLabel = true;
|
||||
t.showMark = false;
|
||||
t.showGridline = false;
|
||||
t.setTick(tt+0.5, this.name);
|
||||
this._ticks.push(t);
|
||||
}
|
||||
// now add the last tick at the end
|
||||
var t = new this.tickRenderer(this.tickOptions);
|
||||
t.showLabel = false;
|
||||
// t.showMark = true;
|
||||
t.setTick(tt+1, this.name);
|
||||
this._ticks.push(t);
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// if min, max and number of ticks specified, user can't specify interval.
|
||||
if (this.min != null && this.max != null && this.numberTicks != null) {
|
||||
this.tickInterval = null;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
// find out how many categories are in the lines and collect labels
|
||||
var labels = [];
|
||||
var numcats = 0;
|
||||
var min = 0.5;
|
||||
var max, val;
|
||||
var isMerged = false;
|
||||
for (var i=0; i<this._series.length; i++) {
|
||||
var s = this._series[i];
|
||||
for (var j=0; j<s.data.length; j++) {
|
||||
if (this.name == 'xaxis' || this.name == 'x2axis') {
|
||||
val = s.data[j][0];
|
||||
}
|
||||
else {
|
||||
val = s.data[j][1];
|
||||
}
|
||||
if ($.inArray(val, labels) == -1) {
|
||||
isMerged = true;
|
||||
numcats += 1;
|
||||
labels.push(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isMerged && this.sortMergedLabels) {
|
||||
if (typeof labels[0] == "string") {
|
||||
labels.sort();
|
||||
} else {
|
||||
labels.sort(function(a,b) { return a - b; });
|
||||
}
|
||||
}
|
||||
|
||||
// keep a reference to these tick labels to use for redrawing plot (see bug #57)
|
||||
this.ticks = labels;
|
||||
|
||||
// now bin the data values to the right lables.
|
||||
for (var i=0; i<this._series.length; i++) {
|
||||
var s = this._series[i];
|
||||
for (var j=0; j<s.data.length; j++) {
|
||||
if (this.name == 'xaxis' || this.name == 'x2axis') {
|
||||
val = s.data[j][0];
|
||||
}
|
||||
else {
|
||||
val = s.data[j][1];
|
||||
}
|
||||
// for category axis, force the values into category bins.
|
||||
// we should have the value in the label array now.
|
||||
var idx = $.inArray(val, labels)+1;
|
||||
if (this.name == 'xaxis' || this.name == 'x2axis') {
|
||||
s.data[j][0] = idx;
|
||||
}
|
||||
else {
|
||||
s.data[j][1] = idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// adjust with blanks if we have groups
|
||||
if (this.groups > 1 && !this._grouped) {
|
||||
var l = labels.length;
|
||||
var skip = parseInt(l/this.groups, 10);
|
||||
var count = 0;
|
||||
for (var i=skip; i<l; i+=skip+1) {
|
||||
labels[i] = ' ';
|
||||
}
|
||||
this._grouped = true;
|
||||
}
|
||||
|
||||
max = numcats + 0.5;
|
||||
if (this.numberTicks == null) {
|
||||
this.numberTicks = 2*numcats + 1;
|
||||
}
|
||||
|
||||
var range = max - min;
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
var track = 0;
|
||||
|
||||
// todo: adjust this so more ticks displayed.
|
||||
var maxVisibleTicks = parseInt(3+dim/10, 10);
|
||||
var skip = parseInt(numcats/maxVisibleTicks, 10);
|
||||
|
||||
if (this.tickInterval == null) {
|
||||
|
||||
this.tickInterval = range / (this.numberTicks-1);
|
||||
|
||||
}
|
||||
// if tickInterval is specified, we will ignore any computed maximum.
|
||||
for (var i=0; i<this.numberTicks; i++){
|
||||
tt = this.min + i * this.tickInterval;
|
||||
var t = new this.tickRenderer(this.tickOptions);
|
||||
// if even tick, it isn't a category, it's a divider
|
||||
if (i/2 == parseInt(i/2, 10)) {
|
||||
t.showLabel = false;
|
||||
t.showMark = true;
|
||||
}
|
||||
else {
|
||||
if (skip>0 && track<skip) {
|
||||
t.showLabel = false;
|
||||
track += 1;
|
||||
}
|
||||
else {
|
||||
t.showLabel = true;
|
||||
track = 0;
|
||||
}
|
||||
t.label = t.formatter(t.formatString, labels[(i-1)/2]);
|
||||
t.showMark = false;
|
||||
t.showGridline = false;
|
||||
}
|
||||
t.setTick(tt, this.name);
|
||||
this._ticks.push(t);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// called with scope of axis
|
||||
$.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
|
||||
// call it within the scope of the axis.
|
||||
this.renderer.createTicks.call(this);
|
||||
// fill a div with axes labels in the right direction.
|
||||
// Need to pregenerate each axis to get its bounds and
|
||||
// position it and the labels correctly on the plot.
|
||||
var dim=0;
|
||||
var temp;
|
||||
// Added for theming.
|
||||
if (this._elem) {
|
||||
// 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') {
|
||||
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);
|
||||
}
|
||||
|
||||
var t = this._ticks;
|
||||
for (var i=0; i<t.length; i++) {
|
||||
var tick = t[i];
|
||||
if (tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) {
|
||||
var elem = tick.draw(ctx, plot);
|
||||
elem.appendTo(this._elem);
|
||||
}
|
||||
}
|
||||
|
||||
this._groupLabels = [];
|
||||
// now make group labels
|
||||
for (var i=0; i<this.groupLabels.length; i++)
|
||||
{
|
||||
var elem = $('<div style="position:absolute;" class="jqplot-'+this.name+'-groupLabel"></div>');
|
||||
elem.html(this.groupLabels[i]);
|
||||
this._groupLabels.push(elem);
|
||||
elem.appendTo(this._elem);
|
||||
}
|
||||
}
|
||||
return this._elem;
|
||||
};
|
||||
|
||||
// called with scope of axis
|
||||
$.jqplot.CategoryAxisRenderer.prototype.set = function() {
|
||||
var dim = 0;
|
||||
var temp;
|
||||
var w = 0;
|
||||
var h = 0;
|
||||
var lshow = (this._label == null) ? false : this._label.show;
|
||||
if (this.show) {
|
||||
var t = this._ticks;
|
||||
for (var i=0; i<t.length; i++) {
|
||||
var tick = t[i];
|
||||
if (tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) {
|
||||
if (this.name == 'xaxis' || this.name == 'x2axis') {
|
||||
temp = tick._elem.outerHeight(true);
|
||||
}
|
||||
else {
|
||||
temp = tick._elem.outerWidth(true);
|
||||
}
|
||||
if (temp > dim) {
|
||||
dim = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var dim2 = 0;
|
||||
for (var i=0; i<this._groupLabels.length; i++) {
|
||||
var l = this._groupLabels[i];
|
||||
if (this.name == 'xaxis' || this.name == 'x2axis') {
|
||||
temp = l.outerHeight(true);
|
||||
}
|
||||
else {
|
||||
temp = l.outerWidth(true);
|
||||
}
|
||||
if (temp > dim2) {
|
||||
dim2 = temp;
|
||||
}
|
||||
}
|
||||
|
||||
if (lshow) {
|
||||
w = this._label._elem.outerWidth(true);
|
||||
h = this._label._elem.outerHeight(true);
|
||||
}
|
||||
if (this.name == 'xaxis') {
|
||||
dim += dim2 + h;
|
||||
this._elem.css({'height':dim+'px', left:'0px', bottom:'0px'});
|
||||
}
|
||||
else if (this.name == 'x2axis') {
|
||||
dim += dim2 + h;
|
||||
this._elem.css({'height':dim+'px', left:'0px', top:'0px'});
|
||||
}
|
||||
else if (this.name == 'yaxis') {
|
||||
dim += dim2 + 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 {
|
||||
dim += dim2 + 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');
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// called with scope of axis
|
||||
$.jqplot.CategoryAxisRenderer.prototype.pack = function(pos, 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;
|
||||
var i;
|
||||
|
||||
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;
|
||||
|
||||
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.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 {
|
||||
// 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.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') {
|
||||
for (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();
|
||||
}
|
||||
}
|
||||
|
||||
var labeledge=['bottom', 0];
|
||||
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');
|
||||
labeledge = ['bottom', this._label._elem.outerHeight(true)];
|
||||
}
|
||||
else {
|
||||
this._label._elem.css('top', '0px');
|
||||
labeledge = ['top', this._label._elem.outerHeight(true)];
|
||||
}
|
||||
this._label.pack();
|
||||
}
|
||||
|
||||
// draw the group labels
|
||||
var step = parseInt(this._ticks.length/this.groups, 10) + 1;
|
||||
for (i=0; i<this._groupLabels.length; i++) {
|
||||
var mid = 0;
|
||||
var count = 0;
|
||||
for (var j=i*step; j<(i+1)*step; j++) {
|
||||
if (j >= this._ticks.length-1) continue; // the last tick does not exist as there is no other group in order to have an empty one.
|
||||
if (this._ticks[j]._elem && this._ticks[j].label != " ") {
|
||||
var t = this._ticks[j]._elem;
|
||||
var p = t.position();
|
||||
mid += p.left + t.outerWidth(true)/2;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
mid = mid/count;
|
||||
this._groupLabels[i].css({'left':(mid - this._groupLabels[i].outerWidth(true)/2)});
|
||||
this._groupLabels[i].css(labeledge[0], labeledge[1]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (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 == '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();
|
||||
}
|
||||
}
|
||||
|
||||
var labeledge=['left', 0];
|
||||
if (lshow) {
|
||||
var h = this._label._elem.outerHeight(true);
|
||||
this._label._elem.css('top', offmax - pixellength/2 - h/2 + 'px');
|
||||
if (this.name == 'yaxis') {
|
||||
this._label._elem.css('left', '0px');
|
||||
labeledge = ['left', this._label._elem.outerWidth(true)];
|
||||
}
|
||||
else {
|
||||
this._label._elem.css('right', '0px');
|
||||
labeledge = ['right', this._label._elem.outerWidth(true)];
|
||||
}
|
||||
this._label.pack();
|
||||
}
|
||||
|
||||
// draw the group labels, position top here, do left after label position.
|
||||
var step = parseInt(this._ticks.length/this.groups, 10) + 1; // step is one more than before as we don't want to have overlaps in loops
|
||||
for (i=0; i<this._groupLabels.length; i++) {
|
||||
var mid = 0;
|
||||
var count = 0;
|
||||
for (var j=i*step; j<(i+1)*step; j++) { // j must never reach (i+1)*step as we don't want to have overlap between loops
|
||||
if (j >= this._ticks.length-1) continue; // the last tick does not exist as there is no other group in order to have an empty one.
|
||||
if (this._ticks[j]._elem && this._ticks[j].label != " ") {
|
||||
var t = this._ticks[j]._elem;
|
||||
var p = t.position();
|
||||
mid += p.top + t.outerHeight()/2;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
mid = mid/count;
|
||||
this._groupLabels[i].css({'top':mid - this._groupLabels[i].outerHeight()/2});
|
||||
this._groupLabels[i].css(labeledge[0], labeledge[1]);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
})(jQuery);
|
904
msd2/tracking/piwik/libs/jqplot/plugins/jqplot.pieRenderer.js
Normal file
904
msd2/tracking/piwik/libs/jqplot/plugins/jqplot.pieRenderer.js
Normal file
@ -0,0 +1,904 @@
|
||||
/**
|
||||
* jqPlot
|
||||
* Pure JavaScript plotting plugin using jQuery
|
||||
*
|
||||
* Version: @VERSION
|
||||
* Revision: @REVISION
|
||||
*
|
||||
* 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.PieRenderer
|
||||
* Plugin renderer to draw a pie chart.
|
||||
* x values, if present, will be used as slice labels.
|
||||
* y values give slice size.
|
||||
*
|
||||
* To use this renderer, you need to include the
|
||||
* pie renderer plugin, for example:
|
||||
*
|
||||
* > <script type="text/javascript" src="plugins/jqplot.pieRenderer.js"></script>
|
||||
*
|
||||
* Properties described here are passed into the $.jqplot function
|
||||
* as options on the series renderer. For example:
|
||||
*
|
||||
* > plot2 = $.jqplot('chart2', [s1, s2], {
|
||||
* > seriesDefaults: {
|
||||
* > renderer:$.jqplot.PieRenderer,
|
||||
* > rendererOptions:{
|
||||
* > sliceMargin: 2,
|
||||
* > startAngle: -90
|
||||
* > }
|
||||
* > }
|
||||
* > });
|
||||
*
|
||||
* A pie plot will trigger events on the plot target
|
||||
* according to user interaction. All events return the event object,
|
||||
* the series index, the point (slice) index, and the point data for
|
||||
* the appropriate slice.
|
||||
*
|
||||
* 'jqplotDataMouseOver' - triggered when user mouseing over a slice.
|
||||
* 'jqplotDataHighlight' - triggered the first time user mouses over a slice,
|
||||
* if highlighting is enabled.
|
||||
* 'jqplotDataUnhighlight' - triggered when a user moves the mouse out of
|
||||
* a highlighted slice.
|
||||
* 'jqplotDataClick' - triggered when the user clicks on a slice.
|
||||
* 'jqplotDataRightClick' - tiggered when the user right clicks on a slice if
|
||||
* the "captureRightClick" option is set to true on the plot.
|
||||
*/
|
||||
$.jqplot.PieRenderer = function(){
|
||||
$.jqplot.LineRenderer.call(this);
|
||||
};
|
||||
|
||||
$.jqplot.PieRenderer.prototype = new $.jqplot.LineRenderer();
|
||||
$.jqplot.PieRenderer.prototype.constructor = $.jqplot.PieRenderer;
|
||||
|
||||
// called with scope of a series
|
||||
$.jqplot.PieRenderer.prototype.init = function(options, plot) {
|
||||
// Group: Properties
|
||||
//
|
||||
// prop: diameter
|
||||
// Outer diameter of the pie, auto computed by default
|
||||
this.diameter = null;
|
||||
// prop: padding
|
||||
// padding between the pie and plot edges, legend, etc.
|
||||
this.padding = 20;
|
||||
// prop: sliceMargin
|
||||
// angular spacing between pie slices in degrees.
|
||||
this.sliceMargin = 0;
|
||||
// prop: fill
|
||||
// true or false, whether to fil the slices.
|
||||
this.fill = true;
|
||||
// prop: shadowOffset
|
||||
// offset of the shadow from the slice and offset of
|
||||
// each succesive stroke of the shadow from the last.
|
||||
this.shadowOffset = 2;
|
||||
// prop: shadowAlpha
|
||||
// transparency of the shadow (0 = transparent, 1 = opaque)
|
||||
this.shadowAlpha = 0.07;
|
||||
// prop: shadowDepth
|
||||
// number of strokes to apply to the shadow,
|
||||
// each stroke offset shadowOffset from the last.
|
||||
this.shadowDepth = 5;
|
||||
// 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: dataLabels
|
||||
// Either 'label', 'value', 'percent' or an array of labels to place on the pie slices.
|
||||
// Defaults to percentage of each pie slice.
|
||||
this.dataLabels = 'percent';
|
||||
// prop: showDataLabels
|
||||
// true to show data labels on slices.
|
||||
this.showDataLabels = false;
|
||||
// prop: dataLabelFormatString
|
||||
// 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.
|
||||
// This applies to all label types, not just to percentage labels.
|
||||
this.dataLabelThreshold = 3;
|
||||
// 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.52;
|
||||
// prop: dataLabelNudge
|
||||
// Number of pixels to slide the label away from (+) or toward (-) the center of the pie.
|
||||
this.dataLabelNudge = 2;
|
||||
// prop: dataLabelCenterOn
|
||||
// True to center the data label at its position.
|
||||
// False to set the inside facing edge of the label at its position.
|
||||
this.dataLabelCenterOn = true;
|
||||
// prop: startAngle
|
||||
// Angle to start drawing pie in degrees.
|
||||
// According to orientation of canvas coordinate system:
|
||||
// 0 = on the positive x axis
|
||||
// -90 = on the positive y axis.
|
||||
// 90 = on the negaive y axis.
|
||||
// 180 or - 180 = on the negative x axis.
|
||||
this.startAngle = 0;
|
||||
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) {
|
||||
options.highlightMouseOver = false;
|
||||
}
|
||||
|
||||
$.extend(true, this, options);
|
||||
|
||||
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.
|
||||
this._sliceAngles = [];
|
||||
// index of the currenty highlighted point, if any
|
||||
this._highlightedPoint = null;
|
||||
|
||||
// set highlight colors if none provided
|
||||
if (this.highlightColors.length == 0) {
|
||||
for (var i=0; i<this.seriesColors.length; i++){
|
||||
var rgba = $.jqplot.getColorComponents(this.seriesColors[i]);
|
||||
var newrgb = [rgba[0], rgba[1], rgba[2]];
|
||||
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] = parseInt(newrgb[j], 10);
|
||||
}
|
||||
this.highlightColors.push('rgb('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+')');
|
||||
}
|
||||
}
|
||||
|
||||
this.highlightColorGenerator = new $.jqplot.ColorGenerator(this.highlightColors);
|
||||
|
||||
plot.postParseOptionsHooks.addOnce(postParseOptions);
|
||||
plot.postInitHooks.addOnce(postInit);
|
||||
plot.eventListenerHooks.addOnce('jqplotMouseMove', handleMove);
|
||||
plot.eventListenerHooks.addOnce('jqplotMouseDown', handleMouseDown);
|
||||
plot.eventListenerHooks.addOnce('jqplotMouseUp', handleMouseUp);
|
||||
plot.eventListenerHooks.addOnce('jqplotClick', handleClick);
|
||||
plot.eventListenerHooks.addOnce('jqplotRightClick', handleRightClick);
|
||||
plot.postDrawHooks.addOnce(postPlotDraw);
|
||||
};
|
||||
|
||||
$.jqplot.PieRenderer.prototype.setGridData = function(plot) {
|
||||
// set gridData property. This will hold angle in radians of each data point.
|
||||
var stack = [];
|
||||
var td = [];
|
||||
var sa = this.startAngle/180*Math.PI;
|
||||
var tot = 0;
|
||||
// don't know if we have any valid data yet, so set plot to not draw.
|
||||
this._drawData = false;
|
||||
for (var i=0; i<this.data.length; i++){
|
||||
if (this.data[i][1] != 0) {
|
||||
// we have data, O.K. to draw.
|
||||
this._drawData = true;
|
||||
}
|
||||
stack.push(this.data[i][1]);
|
||||
td.push([this.data[i][0]]);
|
||||
if (i>0) {
|
||||
stack[i] += stack[i-1];
|
||||
}
|
||||
tot += this.data[i][1];
|
||||
}
|
||||
var fact = Math.PI*2/stack[stack.length - 1];
|
||||
|
||||
for (var i=0; i<stack.length; i++) {
|
||||
td[i][1] = stack[i] * fact;
|
||||
td[i][2] = this.data[i][1]/tot;
|
||||
}
|
||||
this.gridData = td;
|
||||
};
|
||||
|
||||
$.jqplot.PieRenderer.prototype.makeGridData = function(data, plot) {
|
||||
var stack = [];
|
||||
var td = [];
|
||||
var tot = 0;
|
||||
var sa = this.startAngle/180*Math.PI;
|
||||
// don't know if we have any valid data yet, so set plot to not draw.
|
||||
this._drawData = false;
|
||||
for (var i=0; i<data.length; i++){
|
||||
if (this.data[i][1] != 0) {
|
||||
// we have data, O.K. to draw.
|
||||
this._drawData = true;
|
||||
}
|
||||
stack.push(data[i][1]);
|
||||
td.push([data[i][0]]);
|
||||
if (i>0) {
|
||||
stack[i] += stack[i-1];
|
||||
}
|
||||
tot += data[i][1];
|
||||
}
|
||||
var fact = Math.PI*2/stack[stack.length - 1];
|
||||
|
||||
for (var i=0; i<stack.length; i++) {
|
||||
td[i][1] = stack[i] * fact;
|
||||
td[i][2] = data[i][1]/tot;
|
||||
}
|
||||
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._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]);
|
||||
|
||||
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, 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(r);
|
||||
}
|
||||
for (var i=0, l=this.shadowDepth; i<l; i++) {
|
||||
ctx.restore();
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
doDraw(r);
|
||||
}
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
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) {
|
||||
ang1 = 6.281 + this.startAngle;
|
||||
}
|
||||
}
|
||||
// Fix for IE, where it can't seem to handle 0 degree angles. Also avoids
|
||||
// ugly line on unfilled pies.
|
||||
if (ang1 >= ang2) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.fillStyle = color;
|
||||
ctx.strokeStyle = color;
|
||||
ctx.lineWidth = lineWidth;
|
||||
ctx.arc(0, 0, rad, ang1, ang2, false);
|
||||
ctx.lineTo(0,0);
|
||||
ctx.closePath();
|
||||
|
||||
if (fill) {
|
||||
ctx.fill();
|
||||
}
|
||||
else {
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// called with scope of series
|
||||
$.jqplot.PieRenderer.prototype.draw = function (ctx, gd, options, plot) {
|
||||
var i;
|
||||
var opts = (options != undefined) ? options : {};
|
||||
// offset and direction of offset due to legend placement
|
||||
var offx = 0;
|
||||
var offy = 0;
|
||||
var trans = 1;
|
||||
var colorGenerator = new $.jqplot.ColorGenerator(this.seriesColors);
|
||||
if (options.legendInfo && options.legendInfo.placement == 'insideGrid') {
|
||||
var li = options.legendInfo;
|
||||
switch (li.location) {
|
||||
case 'nw':
|
||||
offx = li.width + li.xoffset;
|
||||
break;
|
||||
case 'w':
|
||||
offx = li.width + li.xoffset;
|
||||
break;
|
||||
case 'sw':
|
||||
offx = li.width + li.xoffset;
|
||||
break;
|
||||
case 'ne':
|
||||
offx = li.width + li.xoffset;
|
||||
trans = -1;
|
||||
break;
|
||||
case 'e':
|
||||
offx = li.width + li.xoffset;
|
||||
trans = -1;
|
||||
break;
|
||||
case 'se':
|
||||
offx = li.width + li.xoffset;
|
||||
trans = -1;
|
||||
break;
|
||||
case 'n':
|
||||
offy = li.height + li.yoffset;
|
||||
break;
|
||||
case 's':
|
||||
offy = li.height + li.yoffset;
|
||||
trans = -1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow;
|
||||
var fill = (opts.fill != undefined) ? opts.fill : this.fill;
|
||||
var cw = parseInt(ctx.canvas.style.width);
|
||||
var ch = parseInt(ctx.canvas.style.height);
|
||||
var w = cw - offx - 2 * this.padding;
|
||||
var h = ch - offy - 2 * this.padding;
|
||||
var mindim = Math.min(w,h);
|
||||
var d = mindim;
|
||||
|
||||
// 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;
|
||||
|
||||
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) {
|
||||
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++) {
|
||||
|
||||
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 = (this._sliceAngles[i][0] + this._sliceAngles[i][1])/2, label;
|
||||
|
||||
if (this.dataLabels == 'label') {
|
||||
fstr = this.dataLabelFormatString || '%s';
|
||||
label = $.jqplot.sprintf(fstr, gd[i][0]);
|
||||
}
|
||||
else if (this.dataLabels == 'value') {
|
||||
fstr = this.dataLabelFormatString || '%d';
|
||||
label = $.jqplot.sprintf(fstr, this.data[i][1]);
|
||||
}
|
||||
else if (this.dataLabels == 'percent') {
|
||||
fstr = this.dataLabelFormatString || '%d%%';
|
||||
label = $.jqplot.sprintf(fstr, gd[i][2]*100);
|
||||
}
|
||||
else if (this.dataLabels.constructor == Array) {
|
||||
fstr = this.dataLabelFormatString || '%s';
|
||||
label = $.jqplot.sprintf(fstr, this.dataLabels[i]);
|
||||
}
|
||||
|
||||
var fact = (this._radius ) * this.dataLabelPositionFactor + this.sliceMargin + this.dataLabelNudge;
|
||||
|
||||
var x = this._center[0] + Math.cos(avgang) * fact + this.canvas._offsets.left;
|
||||
var y = this._center[1] + Math.sin(avgang) * fact + this.canvas._offsets.top;
|
||||
|
||||
var labelelem = $('<div class="jqplot-pie-series jqplot-data-label" style="position:absolute;">' + label + '</div>').insertBefore(plot.eventCanvas._elem);
|
||||
if (this.dataLabelCenterOn) {
|
||||
x -= labelelem.width()/2;
|
||||
y -= labelelem.height()/2;
|
||||
}
|
||||
else {
|
||||
x -= labelelem.width() * Math.sin(avgang/2);
|
||||
y -= labelelem.height()/2;
|
||||
}
|
||||
x = Math.round(x);
|
||||
y = Math.round(y);
|
||||
labelelem.css({left: x, top: y});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$.jqplot.PieAxisRenderer = function() {
|
||||
$.jqplot.LinearAxisRenderer.call(this);
|
||||
};
|
||||
|
||||
$.jqplot.PieAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer();
|
||||
$.jqplot.PieAxisRenderer.prototype.constructor = $.jqplot.PieAxisRenderer;
|
||||
|
||||
|
||||
// There are no traditional axes on a pie chart. We just need to provide
|
||||
// dummy objects with properties so the plot will render.
|
||||
// called with scope of axis object.
|
||||
$.jqplot.PieAxisRenderer.prototype.init = function(options){
|
||||
//
|
||||
this.tickRenderer = $.jqplot.PieTickRenderer;
|
||||
$.extend(true, this, options);
|
||||
// I don't think I'm going to need _dataBounds here.
|
||||
// have to go Axis scaling in a way to fit chart onto plot area
|
||||
// and provide u2p and p2u functionality for mouse cursor, etc.
|
||||
// for convienence set _dataBounds to 0 and 100 and
|
||||
// set min/max to 0 and 100.
|
||||
this._dataBounds = {min:0, max:100};
|
||||
this.min = 0;
|
||||
this.max = 100;
|
||||
this.showTicks = false;
|
||||
this.ticks = [];
|
||||
this.showMark = false;
|
||||
this.show = false;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
$.jqplot.PieLegendRenderer = function(){
|
||||
$.jqplot.TableLegendRenderer.call(this);
|
||||
};
|
||||
|
||||
$.jqplot.PieLegendRenderer.prototype = new $.jqplot.TableLegendRenderer();
|
||||
$.jqplot.PieLegendRenderer.prototype.constructor = $.jqplot.PieLegendRenderer;
|
||||
|
||||
/**
|
||||
* Class: $.jqplot.PieLegendRenderer
|
||||
* Legend Renderer specific to pie plots. Set by default
|
||||
* when user creates a pie plot.
|
||||
*/
|
||||
$.jqplot.PieLegendRenderer.prototype.init = function(options) {
|
||||
// Group: Properties
|
||||
//
|
||||
// prop: numberRows
|
||||
// Maximum number of rows in the legend. 0 or null for unlimited.
|
||||
this.numberRows = null;
|
||||
// prop: numberColumns
|
||||
// Maximum number of columns in the legend. 0 or null for unlimited.
|
||||
this.numberColumns = null;
|
||||
$.extend(true, this, options);
|
||||
};
|
||||
|
||||
// called with context of legend
|
||||
$.jqplot.PieLegendRenderer.prototype.draw = function() {
|
||||
var legend = this;
|
||||
if (this.show) {
|
||||
var series = this._series;
|
||||
|
||||
|
||||
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;
|
||||
var s = series[0];
|
||||
var colorGenerator = new $.jqplot.ColorGenerator(s.seriesColors);
|
||||
|
||||
if (s.show) {
|
||||
var pd = s.data;
|
||||
if (this.numberRows) {
|
||||
nr = this.numberRows;
|
||||
if (!this.numberColumns){
|
||||
nc = Math.ceil(pd.length/nr);
|
||||
}
|
||||
else{
|
||||
nc = this.numberColumns;
|
||||
}
|
||||
}
|
||||
else if (this.numberColumns) {
|
||||
nc = this.numberColumns;
|
||||
nr = Math.ceil(pd.length/this.numberColumns);
|
||||
}
|
||||
else {
|
||||
nr = pd.length;
|
||||
nc = 1;
|
||||
}
|
||||
|
||||
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.prependTo(this._elem);
|
||||
}
|
||||
|
||||
else{
|
||||
tr.appendTo(this._elem);
|
||||
}
|
||||
|
||||
for (j=0; j<nc; j++) {
|
||||
if (idx < pd.length){
|
||||
lt = this.labels[idx] || pd[idx][0].toString();
|
||||
color = colorGenerator.next();
|
||||
if (!reverse){
|
||||
if (i>0){
|
||||
pad = true;
|
||||
}
|
||||
else{
|
||||
pad = false;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (i == nr -1){
|
||||
pad = false;
|
||||
}
|
||||
else{
|
||||
pad = true;
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
if (this.escapeHtml){
|
||||
td2.text(lt);
|
||||
}
|
||||
else {
|
||||
td2.html(lt);
|
||||
}
|
||||
if (reverse) {
|
||||
td2.prependTo(tr);
|
||||
td1.prependTo(tr);
|
||||
}
|
||||
else {
|
||||
td1.appendTo(tr);
|
||||
td2.appendTo(tr);
|
||||
}
|
||||
pad = true;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this._elem;
|
||||
};
|
||||
|
||||
$.jqplot.PieRenderer.prototype.handleMove = function(ev, gridpos, datapos, neighbor, plot) {
|
||||
if (neighbor) {
|
||||
var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
|
||||
plot.target.trigger('jqplotDataMouseOver', ins);
|
||||
if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.pieRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) {
|
||||
plot.target.trigger('jqplotDataHighlight', ins);
|
||||
highlight (plot, ins[0], ins[1]);
|
||||
}
|
||||
}
|
||||
else if (neighbor == null) {
|
||||
unhighlight (plot);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// this.eventCanvas._elem.bind($.jqplot.eventListenerHooks[i][0], {plot:this}, $.jqplot.eventListenerHooks[i][1]);
|
||||
|
||||
// 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.legend = options.legend || {};
|
||||
options.seriesDefaults = options.seriesDefaults || {};
|
||||
// only set these if there is a pie series
|
||||
var setopts = false;
|
||||
if (options.seriesDefaults.renderer == $.jqplot.PieRenderer) {
|
||||
setopts = true;
|
||||
}
|
||||
else if (options.series) {
|
||||
for (var i=0; i < options.series.length; i++) {
|
||||
if (options.series[i].renderer == $.jqplot.PieRenderer) {
|
||||
setopts = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (setopts) {
|
||||
options.axesDefaults.renderer = $.jqplot.PieAxisRenderer;
|
||||
options.legend.renderer = $.jqplot.PieLegendRenderer;
|
||||
options.legend.preDraw = true;
|
||||
options.seriesDefaults.pointLabels = {show: false};
|
||||
}
|
||||
}
|
||||
|
||||
function postInit(target, data, options) {
|
||||
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) {
|
||||
this.series[i].highlightMouseDown = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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 = $.jqplot.colorGenerator;
|
||||
}
|
||||
}
|
||||
|
||||
function highlight (plot, sidx, pidx) {
|
||||
var s = plot.series[sidx];
|
||||
var canvas = plot.plugins.pieRenderer.highlightCanvas;
|
||||
canvas._ctx.clearRect(0,0,canvas._ctx.canvas.width, canvas._ctx.canvas.height);
|
||||
s._highlightedPoint = pidx;
|
||||
plot.plugins.pieRenderer.highlightedSeriesIndex = sidx;
|
||||
s.renderer.drawSlice.call(s, canvas._ctx, s._sliceAngles[pidx][0], s._sliceAngles[pidx][1], s.highlightColorGenerator.get(pidx), false);
|
||||
}
|
||||
|
||||
function unhighlight (plot) {
|
||||
var canvas = plot.plugins.pieRenderer.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.pieRenderer.highlightedSeriesIndex = null;
|
||||
plot.target.trigger('jqplotDataUnhighlight');
|
||||
}
|
||||
|
||||
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.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);
|
||||
highlight (plot, ins[0], ins[1]);
|
||||
}
|
||||
}
|
||||
else if (neighbor == null) {
|
||||
unhighlight (plot);
|
||||
}
|
||||
}
|
||||
|
||||
function handleMouseDown(ev, gridpos, datapos, neighbor, plot) {
|
||||
if (neighbor) {
|
||||
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);
|
||||
highlight (plot, ins[0], ins[1]);
|
||||
}
|
||||
}
|
||||
else if (neighbor == null) {
|
||||
unhighlight (plot);
|
||||
}
|
||||
}
|
||||
|
||||
function handleMouseUp(ev, gridpos, datapos, neighbor, plot) {
|
||||
var idx = plot.plugins.pieRenderer.highlightedSeriesIndex;
|
||||
if (idx != null && plot.series[idx].highlightMouseDown) {
|
||||
unhighlight(plot);
|
||||
}
|
||||
}
|
||||
|
||||
function handleClick(ev, gridpos, datapos, neighbor, plot) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
function handleRightClick(ev, gridpos, datapos, neighbor, plot) {
|
||||
if (neighbor) {
|
||||
var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
|
||||
var idx = plot.plugins.pieRenderer.highlightedSeriesIndex;
|
||||
if (idx != null && plot.series[idx].highlightMouseDown) {
|
||||
unhighlight(plot);
|
||||
}
|
||||
var evt = jQuery.Event('jqplotDataRightClick');
|
||||
evt.which = ev.which;
|
||||
evt.pageX = ev.pageX;
|
||||
evt.pageY = ev.pageY;
|
||||
plot.target.trigger(evt, ins);
|
||||
}
|
||||
}
|
||||
|
||||
// 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.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, 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));
|
||||
}
|
||||
|
||||
var hctx = this.plugins.pieRenderer.highlightCanvas.setContext();
|
||||
this.eventCanvas._elem.bind('mouseleave', {plot:this}, function (ev) { unhighlight(ev.data.plot); });
|
||||
}
|
||||
|
||||
$.jqplot.preInitHooks.push(preInit);
|
||||
|
||||
$.jqplot.PieTickRenderer = function() {
|
||||
$.jqplot.AxisTickRenderer.call(this);
|
||||
};
|
||||
|
||||
$.jqplot.PieTickRenderer.prototype = new $.jqplot.AxisTickRenderer();
|
||||
$.jqplot.PieTickRenderer.prototype.constructor = $.jqplot.PieTickRenderer;
|
||||
|
||||
})(jQuery);
|
||||
|
||||
|
Reference in New Issue
Block a user